Top of page

# Pipeline

## Mandatory assignment

Your task is to create a system with one parent process and two child processes where the children communicate using a pipe.

## Open a terminal

Open a terminal and navigate to the module-2/mandatory directory.

## List directory contents (ls)

The ls shell command list directory content. Execute the ls command in the terminal.

$ls Makefile bin obj src  The -F option appends a slash / to directory entries. $ ls -F
Makefile     bin/     obj/     src/


The only file in the directory is Makefile. The directory contains the subdirectories bin, obj and src.

$ls -F -1 Makefile bin/ obj/ src/  ## Line numbering filter (nl) The nl shell command is a filter that reads lines from stdin and echoes each line prefixed with a line number to stdout. In the terminal, type nl and press enter. $ nl


The nl command now waits for stdin input. Type Some text and press enter.

$nl Some text 1 Some text  Type More text and press enter. $ nl
Some text
1 Some text
More text
2 More text


For each line you type, the line is echoed back with a line number. Play around some more with the nl command. Press Ctrl+D (End Of File) to make the nl command exit.

## Pipeline

One of the philosophies behind Unix is the motto do one thing and do it well. In this spirit, each shell command usually have a very specific purpose. More complicated commands can be constructed by combining simpler commands in a pipeline such that the output of one command becomes the input to another command.

The standard shell syntax for pipelines is to list multiple commands, separated by vertical bars | (the pipe character). In the below example the output from the ls -F -1 command is piped to input of the nl command.

/bin/ls
$which nl /bin/nl  The executables for the ls and nl command programs are both located in the /bin directory. ## System overview Your task is to create a program that mimics the ls -F -1 | nl pipeline. The parent process uses fork to create two child processes. Child A uses exec to execute the ls -F -1 command and Child B uses exec to execute the nl command. The children uses a pipe to communicate. The stdout of Child A is redirected to the write end of the pipe. The stdin of the Child B is redirected to the read end of the pipe. ## Pipe How can you make the child process share a pipe? Which process should create the pipe? When should the pipe be created? ## Parent forks twice The parent must use fork twice, once for each child process. ## Parent waits twice The parent should use wait to twice to wait for both child process to terminate. ## The children uses execlp The child process should use execlp to execute their commands. ## The children uses dup2 The child process should use dup2 to redirect stdout and stdin. • Process A redirects stdout to write to the pipe. • Process B redirects stdin to read from the pipe. ## Close unused pipe file descriptors Don’t forget to close unused pipe file descriptors, otherwise a reader or writer might be blocked . Attempt Conditions Result Read Empty pipe, writers attached Reader blocked Read Empty pipe, no writer attached End Of File (EOF) returned Write Full pipe, readers attached Writer blocked Write No readers attached SIGPIPE Closing a read descriptor to early may cause a SIGPIPE. Beware of SIGPIPE The default SIGPIPE signal handler causes the process to terminate. ## Check return values You should check the return values of all system calls to detect errors. On error use perror to print an error message and then terminate with exit(EXIT_FAILURE). ## pipeline.c Use the file module-2/mandatory/pipeline.c to implement your solution. • You must add code the the main function. You must add code here. • After fork, Child A should execute the child_a function. You must add code here. • After fork, Child B should execute the child_b function. You must add code here. • You may add your own functions to further structure your solution. ## Compile and run Use make to compile. $ make


Run the program.

$./bin/pipeline  When running the finished program you should see output similar to this. $ ./bin/pipeline
1 Makefile
2 bin/
3 obj/
4 src/
$ Make sure you get the shell prompt $ back.