Question

In: Computer Science

Using C or C++, write a program which implements the command pipeline ”ls -la | tr...

Using C or C++, write a program which implements the command pipeline ”ls -la | tr [a-zA-Z0-9] a”. Use any combination of fork, exec, wait, read, and write necessary to create this functionality. Note: the parent process must be the one to output the data to the console.

Solutions

Expert Solution

Creating Pipes in C:

Creating ``pipelines'' with the C programming language can be a bit more involved than our simple shell example. To create a simple pipe with C, we make use of the pipe() system call. It takes a single argument, which is an array of two integers, and if successful, the array will contain two new file descriptors to be used for the pipeline. After creating a pipe, the process typically spawns a new process .

How to use a pipe:

A pipe is a system call that creates a unidirectional communication link between two file descriptors. The pipe system call is called with a pointer to an array of two integers. Upon return, the first element of the array contains the file descriptor that corresponds to the output of the pipe (stuff to be read). The second element of the array contains the file descriptor that corresponds to the input of the pipe (the place where you write stuff). Whatever bytes are sent into the input of the pipe can be read from the other end of the pipe.

SYSTEM CALL: pipe();                                                          

  PROTOTYPE: int pipe( int fd[2] );                                             
    RETURNS: 0 on success                                                       
             -1 on error: errno = EMFILE (no free descriptors)                  
                                  EMFILE (system file table is full)            
                                  EFAULT (fd array is not valid)                

  NOTES: fd[0] is set up for reading, fd[1] is set up for writing.

The first integer in the array (element 0) is set up and opened for reading, while the second integer (element 1) is set up and opened for writing. Visually speaking, the output of fd1 becomes the input for fd0. Once again, all data traveling through the pipe moves through the kernel.

        #include <stdio.h>
        #include <unistd.h>
        #include <sys/types.h>

        main()
        {
                int     fd[2];
                
                pipe(fd);
                .
                .
        }

Remember that an array name in C decays into a pointer to its first member. Above, fd is equivalent to &fd[0]. Once we have established the pipeline, we then fork our new child process:

        #include <stdio.h>
        #include <unistd.h>
        #include <sys/types.h>

        main()
        {
                int     fd[2];
                pid_t   childpid;

                pipe(fd);
        
                if((childpid = fork()) == -1)
                {
                        perror("fork");
                        exit(1);
                }
                .
                .
        }

If the parent wants to receive data from the child, it should close fd1, and the child should close fd0. If the parent wants to send data to the child, it should close fd0, and the child should close fd1. Since descriptors are shared between the parent and child, we should always be sure to close the end of pipe we aren't concerned with. On a technical note, the EOF will never be returned if the unnecessary ends of the pipe are not explicitly closed.

        #include <stdio.h>
        #include <unistd.h>
        #include <sys/types.h>

        main()
        {
                int     fd[2];
                pid_t   childpid;

                pipe(fd);
        
                if((childpid = fork()) == -1)
                {
                        perror("fork");
                        exit(1);
                }

                if(childpid == 0)
                {
                        /* Child process closes up input side of pipe */
                        close(fd[0]);
                }
                else
                {
                        /* Parent process closes up output side of pipe */
                        close(fd[1]);
                }
                .
                .
        }

A program which implements the command pipeline ”ls -la | tr [a-zA-Z0-9] a”. Use any combination of fork, exec, wait, read, and write necessary to create this functionality:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

char *cmd1[] = { "/bin/ls", "-al", "/", 0 }; char *cmd2[] = { "/usr/bin/tr", "a-z", "A-Z", "0-9",0 };

void runsource(int pfd[]);

void rundest(int pfd[]); int main(int argc, char **argv) { int pid, status; int fd[2]; pipe(fd); runsource(fd); rundest(fd); close(fd[0]); close(fd[1]);

while ((pid = wait(&status)) != -1) fprintf(stderr, "process %d exits with %d\n", pid, WEXITSTATUS(status)); exit(0); }

void runsource(int pfd[]) { int pid; switch (pid = fork()) { case 0: //child process dup2(pfd[1], 1); close(pfd[0]); execvp(cmd1[0], cmd1); perror(cmd1[0]); default: //parent process break; case -1: perror("fork"); exit(1); } }

void rundest(int pfd[]) /* run the second part of the pipeline, cmd2 */ { pipe(fd);

        
        if((childpid = fork()) == -1)
        {
                perror("fork");
                exit(1);
        }

if(childpid == 0)

        {
                /* Child process closes up input side of pipe */
               close(fd[0]);
                dup2(pfd[0], 0);        /* this end of the pipe becomes the standard input */

exit(0);

        }
        else
        {
                /* Parent process closes up output side of pipe */

close(pfd[1]); /* this process doesn't need the other end */ execvp(cmd2[0], cmd2); /* run the command */ perror(cmd2[0]); /* it failed! */

printf("Received command line: %c", readbuffer);
        }
        
        return(0);
}

Related Solutions

Systems Programming in Linux using C Remake the version of the ls -ialR command in C.....
Systems Programming in Linux using C Remake the version of the ls -ialR command in C.. In this version of ls, you must also consider symbolic file types. Make sure you have file header comments and function header comments. Also, write inline comments whenever necessary.
C++ Write a C++ program that implements a tree using a linked representation Each node will...
C++ Write a C++ program that implements a tree using a linked representation Each node will contain a single integer data element. Initialize the tree to contain 10 nodes. The program should allow for the insertion and deletion of data. The program should allow the user to output data in Preorder, Inorder and Postorder.
please write a C program that implements Quick Sort algorithm.
please write a C program that implements Quick Sort algorithm.
Introduction Write in C++ at the Linux command line a program that is the same as...
Introduction Write in C++ at the Linux command line a program that is the same as the previous collection app project but now uses a class to store the items and also can save the items to a file that can be read back into the array by the user when the program is re-started. You can use your project 1 submission as a starting point or you can do something new as long as it meets the listed requirements....
Write a program in C++ that efficiently implements a skip list that holds integers. Your program...
Write a program in C++ that efficiently implements a skip list that holds integers. Your program should: 1. Accurately implement the skip list ADT using a random number generator and nodes that contain an integer as well as the addresses of adjacent nodes to the left, right, up, and down. 2. Correctly implement the Insert, Search, and Delete operations. 3. Read a series of unique, newline-delineated integers from a file and insert them (one at a time in the order...
Write a C++ program that implements a simple scanner for a source file given as a...
Write a C++ program that implements a simple scanner for a source file given as a command-line argument. The format of the tokens is described below. You may assume that the input is syntactically correct. Optionally, your program can build a symbol table (a hash table is a good choice), which contains an entry for each token that was found in the input. When all the input has been read, your program should produce a summary report that includes a...
Write a C++ program that implements a simple scanner for a source file given as a...
Write a C++ program that implements a simple scanner for a source file given as a command-line argument. The format of the tokens is described below. You may assume that the input is syntactically correct. Optionally, your program can build a symbol table (a hash table is a good choice), which contains an entry for each token that was found in the input. When all the input has been read, your program should produce a summary report that includes a...
Write a C++ program that implements a simple scanner for a source file given as a...
Write a C++ program that implements a simple scanner for a source file given as a command-line argument. The format of the tokens is described below. You may assume that the input is syntactically correct. Optionally, your program can build a symbol table (a hash table is a good choice), which contains an entry for each token that was found in the input. When all the input has been read, your program should produce a summary report that includes a...
Write a program in C that implements Conway's Game of Life. You will be expected to...
Write a program in C that implements Conway's Game of Life. You will be expected to apply the principles of Design by Contract to your code. The rules for the Game of Life are simple. The universe consists of a two-dimensional matrix of cells with each cell being alive or dead. For each generation every cell determines its next phase of life as follows: If the cell is alive: it dies if it has 0, 1, 4 or more living...
Complete 2a-b 2a) Write a C program which displays the sum of the command line arguments....
Complete 2a-b 2a) Write a C program which displays the sum of the command line arguments. Hint: use sscanf to convert the decimal arguments (which are strings) to binary numbers that can be added. Use the file name sum.c for your program. Test your program with sum 5 -10 3 and sum 8 and sum 2b) Write a C program that reads in a file and outputs it in reverse order. Use recursion. Test your program with the file reverse.txt...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT