In this assignment, you will practice making child processes, exec’ing other programs, and connecting child processes with pipes.
As usual, you should aim for reasonably efficient algorithms and reasonably organized, comprehensible code.
Correctness (mostly auto-testing) is worth 90% of the marks; code quality is worth 10%.
Overview: Implement the function chain_piping()
(chainpiping.c) that takes an array of commands and creates a pipeline
of them. Conceptually
cmd_0 | cmd_1 | ... | cmd_n-1
The array of commands is given in the command_list
struct. Please see command.h and sample.c for the definition and an
example.
The parent should spawn 1 child per command. At the end, the parent should wait for all n children to terminate, then return from the function. We do not need wait statuses in this assignment.
stdin of cmd_0
and stdout of cmd_n-1
should
be inherited from the parent (i.e., not redirected at all). Other
stdin’s and stdout’s should be read ends and write ends of respective
pipes, e.g., cmd_0
’s stdout should be the write end of some
pipe; that pipe’s read end should become cmd_1
’s stdin.
If a relevant system call fails, print an error message to stderr
(e.g., perror()
or strerror()
), then (for
simplicity) exit with a non-zero exit code. (This is only to catch your
mistakes or DOSing yourself in the track; the relevant system calls
should be successful if used correctly.)
A simple test case is in sample.c. If you test with
$ gcc -O2 -Wall sample.c chainpiping.c
$ ./a.out < cscb09-2023-5-a3.md > out.txt
then it should be equivalent to
$ tr -cs A-Za-z '\n' < cscb09-2023-5-a3.md | tr A-Z a-z | sort | uniq > out.txt
If you like to print debugging or extra error messages, please send them to stderr only.
Marks can be deducted from this assignment if, on the Mathlab server or BV lab PCs, you have left-over processes that have been consuming more than 24 hours of CPU time (the TIME+ field in htop).
Please hand in chainpiping.c