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); }">

Presentation is loading. Please wait.

Presentation is loading. Please wait.

Shell (Part 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.

Similar presentations


Presentation on theme: "Shell (Part 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."— Presentation transcript:

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); }


Download ppt "Shell (Part 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."

Similar presentations


Ads by Google