CS 354 Lab 2: Process Creation and Inter-process Communication

Goal

The goal of this lab is to introduce you to some of the UNIX system calls, and also to give you insight into how shell programs like bash or csh are implemented. The assignment is designed to help you understand the functions of fork/exec and the techniques for inter-process communication, such as pipes.

Assignment

In this lab, you will implement a program that will emulate a command of the form cat <arg1>| grep <arg2> | wc, where arg1 and arg2 are two arguments passed to your program at command line. (Make sure to check you are passed two and only two arguments; otherwise, print an error message and exit.) The output of your program must exactly match with the output of the shell when you type this command at the same prompt. You will have to create your own .c source file, as well as a Makefile which must produce a binary (i.e., executable file) named cgw when make is typed.

Strategy

As a first step, you will need to duplicate the file handles for stdin and stdout using the dup call. Before a call to fork is made you need to create a pipe and attach one end to the output of one process, and the other end to the input for the next process. When a child process starts to execute (fork returns a pid of 0), you will have to close the open file descriptors. After that you can execute a binary (e.g., cat, grep, or wc), using execlp in the child process. Since you need to make a chain of three processes connected by a pipeline you will have to use two pipes to link them up. You will have to use the dup2() function to redirect input or output.

Example

The snippet below will demonstrate some of the steps that you need to take when making your program. First, the file descriptors for stdin and stdout are duplicated. In the second step, a pipe is created and stdout is directed into one end of the pipe. After that the code calls fork that causes a child process to be created that is almost identical to the parent and has a duplicate set of file descriptors. The child is differentiated from the parent by the value of pid returned by fork. A value of 0 indicates a child process, while the non-zero value is the parent. The child process needs to close all of its open file descriptors and then execute some program (say 'cat') by using the execlp function. The main process continues on and changes the stdout to its default value, and then proceeds to close all of the open file descriptors. Finally, the main process calls waitpid to block until the child process finishes its execution.

int defin = dup(0);
int defout = dup(1);
int pid;
int fdpipe[2];

if (pipe(fdpipe) < 0) // create a pipe
{
printf("failed to make a pipe\n");
exit(1);
}
dup2(fdpipe[1], 1); // redirect output to the pipe
pid = fork(); // create child
if (!pid) // if pid==0 then its a child process
{
close(fdpipe[0]);
close(fdpipe[1]);
close(defin);
close(defout);
execlp(some program, some program, argument1, argument2, ..., 0);
}
dup2(defout, 1); // redirect output back to stdout
close(fdpipe[0]);
close(fdpipe[1]);
close(defin);
close(defout);
waitpid(pid, 0, 0); // wait until last child finishes

More information on the fork, execlp, dup, dup2, pipe, open, close, and waitpid functions can be found in their respective man pages, and in the Stevens book (chapters 3, 8, and 14) available on reserve at the math library. Also see the link on the class web page (under "Some Links" near the bottom of the page) for more information on dup() and dup2(). Note that you should not use the "system" function in your code (otherwise, you will receive a score of zero for the lab). Also, make sure NOT to print any extra output when the input is valid: the only output should be the output from "wc."

Turning in the project

This project is due on Sunday, September 19th, 2004 before 11:59 PM.
  1. Place your source file and make file in a directory called lab2-src.
  2. Change directories to your lab2-src directory.
  3. Type 'make' and ensure that everything built correctly.
  4. Type 'make clean' to clean up the object file (make sure to include the target "clean" in your make file for deleting the object file and any core file or other files that may have been created).
  5. Use 'cd ..' to change to the parent directory of your lab2-src directory.
  6. Type 'turnin -c cs354 -p lab2 lab2-src' to submit your work for lab 2.
  7. Type 'turnin -c cs354 -p lab2 -v' and verify that the files you submitted are correct. Do not forget the -v. If you forget -v, your original submission will be corrupted.