CSCI 4061 HW04: Parent/Child Pipes and I/O Redirection
- Due: 11:59pm Mon 2/22/2021
- Approximately 0.83% of total grade
- Homework and Quizzes are open resource/open collaboration. You must submit your own work but you may freely discuss HW topics with other members of the class.
CODE DISTRIBUTION: hw04-code.zip
CHANGELOG: Empty
1 Rationale
Parents can often communicate with children through I/O operations,
most often via pipes. Such communications are also possible via I/O
redirection of standard output. These techniques are demonstrated in
the provided HW code. Insight on how how pipelines of commands like
cat file.txt | wc
can be set up is present in the code examples.
I/O redirection is a powerful tool that allows output that would
normally be printed to the screen or read from keyboard typing to come
from other sources without the program needing to take any special
actions. The basic system calls that facilitate this are the dup()
and dup2()
calls which manipulate a process file table. This lab
demonstrates how these are used.
1.1 Associated Reading
- Ch 3 of Stevens and Rago discusses basic I/O functions like
read()/write()
and thedup2()
function for I/O redirection- 3.10 discusses specific aspects of file "sharing"; e.g. internal
OS mechanisms for files that explain the behavior of
open()
followed byfork()
- 3.12 Discusses how
dup()
anddup2()
affect the internal OS structures for I/O
- 3.10 discusses specific aspects of file "sharing"; e.g. internal
OS mechanisms for files that explain the behavior of
- Ch 15.2-3 of Stevens and Rago discusses pipe basics such as the
effects of the
pipe()
system call. It includes some useful diagrams to relate the intent of pipes
1.2 Grading Policy
Credit for this HW is earned by taking the associate Quiz which is
linked under Gradescope
. The quiz will ask similar questions as
those that are present in the QUESTIONS.txt
file and those that
complete all answers in QUESTIONS.txt
should have no trouble with
the quiz.
See the full policy in the syllabus.
2 Codepack
The codepack for the HW contains the following files:
File | State | Description |
---|---|---|
QUESTIONS.txt |
Edit | Answer questions in the file to complete the lab |
parent_listen.c |
Edit | Problem 1 file to analyze/edit |
capture_stdout.c |
Edit | Problem 2 file to analyze/edit |
3 What to Understand
Make sure you get a good understanding of
- how
read()/write()
work to manipulate information in file descriptors - how forked processed share open file descriptors
- how
dup2()
can be used to redirect output from one file descriptor to another - the basics of getting a child which would normally print to the screen to print into a different source such as a pipe
- How
dup2()
can be used to redirect output from one file descriptor to another
All of these things will show up in projects.
4 Questions
_________________ HW 04 QUESTIONS _________________ - Name: (FILL THIS in) - NetID: (THE kauf0095 IN kauf0095@umn.edu) Write your answers to the questions below directly in this text file. HW quiz questions will be related to the questions in this file. PROBLEM 1 `parent_listen.c' =========================== `parent_listen.c' demonstrates setting up a parent to 'listen' to output that is `write()''n to a pipe. Examine its contents carefully as it demonstrates several new system calls including `pipe()' along with the common error reporting function `perror()'. Comments give some indication of their use but some textbook or man-page reading will give additional detail. A ~ Compile and run the program in `parent_listen.c'. Show it's output below. B ~ Consider the call to `pipe()'. Do some research on Unix pipes to figure out what a pipe does and explain in a few sentences. C ~ Observe the calls to `read()' and `write()'. Their meaning should be self-evident (read and write data) but the parameters to these functions are interesting. Do some reading and explain the 3 parameters to each of them. Also explain their return value. D ~ If you run the program a number of times, you may see output in different orders: the parent may report reading the data before the child has written it. Data is `write()''n and `read()' from pipes much faster than it can be put onto the screen. This in combination with the unpredictable OS scheduler leads to output that can be a bit mixed up. (Note that the `usleep()' call is used to exacerbate these concurrency issues to make them occur more frequently; removing these calls will make the problem less frequent but will not eliminate it). Adjust the position of the wait() call to guarantee that the order that the messages are printed is always follows: 1. Parent creating child process 2. Child wrote 17 bytes 3. Parent read 17 bytes 4. Child said: 'Send $$$ please!' Paste your full code below. PROBLEM 2 `capture_stdout.c' ============================ A ~ Compile and run the program in `capture_stdout.c'. Show its output. B ~ The calls `dup()' and `dup2()' are used in this program to manipulate file descriptors. Explain the effects of the lines below. You may need to consult a programming manual to learn more about `dup()' and `dup2()'. ,---- | int stdout_bak = dup(STDOUT_FILENO); | dup2(my_pipe[PWRITE], STDOUT_FILENO); | ... | dup2(stdout_bak, STDOUT_FILENO); `---- C ~ The use of `printf()' normally puts output directly on the screen. Explain why the statement ,---- | printf("%d In the pipe, five by five", | getpid()); | `---- does not print to screen as usual. D ~ Modify the code so that the `In the pipe...' expression is printed by a child process. - Add a `fork()' AFTER `dup2()' redirects standard output but before the print - Add an `if()' to distinguish between parent and child - The child should print then exit - The parent should restore stdout then read from the pipe - Add a `wait()' to guarantee the parent waits for the child to complete prior to reading from the pipe Paste your completed code below. NOTE on Large Child Output ~~~~~~~~~~~~~~~~~~~~~~~~~~ The completed `capture_stdout.c' file should get a child to write into a pipe and the parent to read from that pipe. The parent reading is currently reading as the lines ,---- | char buf[2048]; | int bytes_read = read(my_pipe[PREAD], buf, 2048); `---- assume that the child output will be no larger than 2048 bytes. The next problem demonstrates a useful allocation pattern which can be used to handle large / unknown input sizes.
5 Again, What to Understand
Make sure you get a good understanding of
- how
read()/write()
work to manipulate information in file descriptors - how forked processed share open file descriptors
- how
dup2()
can be used to redirect output from one file descriptor to another - the basics of getting a child which would normally print to the screen to print into a different source such as a pipe
- How
dup2()
can be used to redirect output from one file descriptor to another
All of these things will show up in projects.