Comp111: Operating Systems
Classroom Exercise 4
Implementing glue
Fall 2017

group member 1: ____________________________ login: ______________
group member 2: ____________________________ login: ______________
group member 3: ____________________________ login: ______________
group member 4: ____________________________ login: ______________
group member 5: ____________________________ login: ______________
group member 6: ____________________________ login: ______________
group member 7: ____________________________ login: ______________
group member 8: ____________________________ login: ______________

In class we have discussed the basic pattern of fork and exec, and how system calls allow us to fool processes into writing to files instead of terminals. Let's make sure we understand the important issues. The exercise refers to the following program:

 
01 #define SIZE 256
02 #define READ 0
03 #define WRITE 1
04 main()
05 { 
06     pid_t pid1, pid2; int status;
07     int fd[2]; char buf[SIZE];
08     struct rusage usage;
09     pipe(fd);
10     if ((pid1=fork())) { // parent
11         close(fd[WRITE]); 
12         FILE *read = fdopen(fd[READ],"r"); 
13         while (!feof(read)) {
14             fgets(buf,SIZE,read);
15             printf("child says: %s",buf);
16         }
17         pid2=wait3(&status, 0, &usage);       
18     } else { // child
19         close(fd[READ]); 
20         close(fileno(stdout)); 
21         dup(fd[WRITE]); 
22         execl("/bin/ps", "ps", "-ef", NULL); 
23 	printf("that's all, folks!\n"); 
24     }
25 }
  1. Precisely what does this program do?
  2. What is the impact of omitting the close(fd[READ]) and close(fd[WRITE]) statements?







  3. What is the impact of omitting the close(fileno(stdout)) statement?







  4. (Advanced) One disadvantage of pipes is that they are block buffered; the output is blocked in (typically 4096-byte) blocks rather than by line. Why does this not mess up this example?







  5. (Advanced) Explain exactly how the shell implements
    ps -ef |& ./a.out
    
    by describing how to modify the above program to do the same thing. Hint: you need to dup stderr.










  6. (Advanced) I claim that the programming patterns what I just demonstrated are pretty much the opposite of functional programming. Why?