0) { /* parent process */ execlp("ps","ps","-le", NULL); perror("exec problem"); exit(1); } else { /* child process */ } execlp("sort","sort",NULL); perror("exec problem"); exit(1); } return(0); }"> 0) { /* parent process */ execlp("ps","ps","-le", NULL); perror("exec problem"); exit(1); } else { /* child process */ } execlp("sort","sort",NULL); perror("exec problem"); exit(1); } return(0); }">
Download presentation
Presentation is loading. Please wait.
Published byNatalie Woods Modified over 9 years ago
1
Shell (Part 2)
2
Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute sort r By default a command like ps requires that its output goes to standard output i.e., the terminal (stdout) r The sort command requires that a file be provided as a command line argument from standard input (stdin)
3
First Attempt pid = fork(); if (pid<0) { perror("Problem forking"); exit(1); } else if (pid>0) { /* parent process */ execlp("ps","ps","-le", NULL); perror("exec problem"); exit(1); } else { /* child process */ } execlp("sort","sort",NULL); perror("exec problem"); exit(1); } return(0); }
4
Example r Why doesn’t this work? m The output of the ps -le goes to the terminal r We want it to be the input to the sort r The diagram on the next page shows the status of the file descriptor tables after the fork
5
Fork and Files Parent File Descriptor table 0123401234 stdin stdout stderr System file table Terminal info 0123401234 stdin stdout stderr Child File Descriptor table Terminal info
6
What is Needed? r Assume process P 1 is to execute ps –le and that P 2 is to execute sort r There is a need for shared memory that allows P 1 to write the results of ps –le to the shared memory r P 2 should be able to read the results from the shared memory and provide the results to the sort command
7
Pipes r The pipe function can be used to provide the shared memory r We will first provide a general discussion of the pipe function which is to be followed by a discussion of how it applies to executing ps –le | sort
8
Pipes r Pipes can be used between processes that have a common ancestor r Typical use: m Pipe created by a process m Process calls fork() m Pipe used between parent and child m Allows for communication between processes
9
Creating a Pipe #include int pipe(int filedes[2]); r Returns 0 if ok, -1 on error r Returns two file descriptors m filedes[0] is open for reading m filedes[1] is open for writing
10
Example #include int main(void){ int n; // track of num bytes read int fd[2]; // hold fds of both ends of pipe pid_t pid; // pid of child process char line[80]; // hold text read/written
11
Continued … if (pipe(fd) < 0) // create the pipe perror("pipe error"); if ((pid = fork()) < 0) { // fork off a child perror("fork error"); } else if (pid > 0) { // parent process close(fd[0]); // close read end write(fd[1], "hello world\n", 12); // write to it wait(NULL); }…
12
Continued… else { // child process close(fd[1]); // close write end n = read(fd[0], line, 80); // read from pipe write(1, line, n); // echo to screen } exit(0); }
13
Fork and Pipes r A fork copies the file descriptor table to the child r The parent should close one of the file descriptors while the child should close the other r Example code on the two previous slides: m Parent closes fd[0] since it does not read from it m Child closes fd[1] since it does not write
14
Fork and Pipes Parent File Descriptor table 0123401234 stdin stdout stderr fd[0] System file table pipe info e.g., read offset 0123401234 stdin stdout stderr fd[0] Child File Descriptor table fd[1] pipe info e.g., write offset After Fork
15
Fork and Pipes Parent File Descriptor table 0123401234 stdin stdout stderr fd[0] = NULL System file table pipe info e.g., read offset 0123401234 stdin stdout stderr fd[0] Child File Descriptor table fd[1] fd[1] = NULL pipe info e.g., write offset After Closing Ends
16
Pipes r By default, if a writing process attempts to write to a full pipe, the system will automatically block the process until the pipe is able to receive the data r Likewise, if a read is attempted on an empty pipe, the process will block until data is available r In addition, the process will block if a specified pipe has been opened for reading, but another process has not opened the pipe for writing
17
Pipe Capacity r The OS has a limit on the buffer space used by the pipe m If you hit the limit, write will block
18
Example r We will now show how pipes can be used for supporting the execution of ps –le | sort
19
Example r First let us m Create shared memory that is to be used by the parent and child processes m This is done using the pipe function r The pipe function is executed before the fork function r The results of ps –le should be put into the shared memory to be used by the child process for sort r See next slide for code r The slide after code slide depicts the file descriptor table and System File table
20
Example int main(int argc, char **argv) { int fds[2]; pid_t pid; /* attempt to create a pipe */ if (pipe(fds)<0) { perror("Fatal Error"); exit(1); }
21
Example Parent File Desc. table 0123401234 fds[0] fds[1] stdin stdout stderr System file table Terminal info Shared mem. info: read Shared mem. Info: write
22
Example System file table Terminal info Shared mem. Info: read Shared mem. Info: write Shared Memory
23
Example r Each entry in the system file table has information about the “file” which could be the terminal, disk file or pipe (shared memory) r For shared memory created by the pipe function: m The read descriptor includes information about the last location read from m The write descriptor includes information about the last location written to.
24
Example r Let us now add the code for the fork r See next slide for the code
25
Example /* create another process */ pid = fork(); if (pid<0) { perror("Problem forking"); exit(1); } …………….. What is the status of the file descriptor table
26
Example Parent File Desc. table 0123401234 fds[0] fds[1] stdin stdout stderr System file table 0123401234 fds[0] fds[1] stdin stdout stderr Child File Desc. table Terminal info Shared mem. Info: read Shared mem. Info: write
27
Fork and Pipes r A fork copies the file descriptor table to the child r The parent should close one of the file descriptors while the child should close the other
28
Fork and Pipes Parent File Descriptor table 0123401234 stdin stdout stderr fd[0] System file table pipe info e.g., read offset 0123401234 stdin stdout stderr fd[0] Child File Descriptor table fd[1] pipe info e.g., write offset After Fork
29
Fork and Pipes Parent File Descriptor table 0123401234 stdin stdout stderr fd[0] = NULL System file table pipe info e.g., read offset 0123401234 stdin stdout stderr fd[0] Child File Descriptor table fd[1] fd[1] = NULL pipe info e.g., write offset After Closing Ends
30
Example r We want the output of the ps –le command to be put into the shared memory r The sort command should read from the shared memory r Two issues: m The sort command assumes that it receives its input from stdin m The ps command assumes that it outputs to stdout r We need to “reroute” m This can be done using the dup() function
31
dup() and dup2 #include int dup(int filedes1); int dup2(int filedes1, int filedes2); r Both will duplicate an existing file descriptor r dup() returns lowest available file descriptor, now referring to whatever filedes1 refers to r dup2() - filedes2 (if open) will be closed and then set to refer to whatever filedes1 refers to
32
Example r Now we want what would normally go to the standard output to go to the shared memory r This is done with the following code: if ( dup2(fds[1],STDOUT_FILENO)<0) { perror("can't dup"); exit(1); } r The new parent file descriptor table is on the next page
33
Example Parent File Desc. table 0123401234 fds[0]=NULL fds[1] stdin stdout stderr System file table 0123401234 fds[0] fds[1]=NULL stdin stdout stderr Child File Desc. table Terminal info Shared mem. info: read Shared mem. info: write
34
Example r Now want to set it up so that the child reads from the shared memory r This is done with the following code: if ( dup2(fds[0],STDIN_FILENO)<0) { perror("can't dup"); exit(1); } r The new child file descriptor is on the next page
35
Example Parent File Desc. table 0123401234 fds[0]=NULL fds[1] stdin stdout stderr System file table 0123401234 fds[0] fds[1]=NULL stdin stdout stderr Child File Desc. table Terminal info Shared mem. info: read Shared mem. info: write
36
Example r Let us now put it together
37
Example /* create another process */ pid = fork(); if (pid<0) { perror("Problem forking"); exit(1); } else if (pid>0) { /* parent process */ close(fds[0]); /* close stdout, reconnect to the writing end of the pipe */ if ( dup2(fds[1],STDOUT_FILENO)<0) { perror("can't dup"); exit(1); } execlp("ps","ps","-le", NULL); perror("exec problem"); exit(1);
38
Example } else { /* child process */ close(fds[1]); if (dup2(fds[0],STDIN_FILENO) < 0) { perror("can't dup"); exit(1); } execlp("sort","sort",NULL); perror("exec problem"); exit(1); } return(0); }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.