100 likes | 209 Views
Shell Execution. Call fork. Basic: fork, child execs, parent waits code of program in box RC == return value from fork(). No. RC=0. Yes. Wait on. Call exec. child. Subsequent. instructions. Useful Facts. A process exec’d retains its caller’s file table redirection is maintained
E N D
Shell Execution Call fork Basic: • fork, child execs, parent waits • code of program in box • RC == return value from fork() No RC=0 Yes Wait on Call exec child Subsequent instructions
Useful Facts • A process exec’d retains its caller’s file table • redirection is maintained • pipes are maintained • Note that the data space is not maintained, so variables in caller are not available to callee • How does this affect < , > , and | ??
Shell Execution:Additional Considerations • Piping (using pipe symbol | in command) • e.g. >ls –l | more • displays long directory listing with pagination • Input/Output Redirection (< or > symbols) • e.g. >ls > dir.txt • outputs directory listing to file dir.txt (no display) • e.g. more < ls –l • same result as first example above
Complex Shell Execution >ls –l | more • Requires concurrent execution of two programs, ls and more • must fork twice to get one process for each • must set up pipe to allow ls to send data to more. When to set it up? • ls produces data that is piped to more • ls’ std. output is redirected to write end of pipe • more’s std input is redirected to read end of pipe
Parent Child ls Child more pipe Redirect cout to write end of pipe Redirect cout to write end of pipe Call fork Yes Close unused pipe end(s) (how many?) Close unused pipe end(s) (how many?) RC=0 No Call fork Call exec more Call exec ls Yes RC=0 Error Handling Error Handling No Wait on children
Complex Shell Execution >ls > dir.txt • Requires only one process • Redirect cout to file “dir.txt” • Exec ls
Buffering of I/O • Line Buffering • stream buffer is flushed when newline enters stream • cout • Full Buffering • stream buffer is flushed only when full; minimizes disk access • files • No Buffering – Direct • cerr • redirected cout becomes fully buffered - almost
Buffering of I/O: Example // File: Buffer.cpp // Demonstrate full vs. line buffering. // Write a string to cout. // If run with output redirected, should appear twice! // Try changing cout to cerr – Surprise! Need to use >& // to redirect. But, it still isn’t buffered #include <sys/types.h> #include <unistd.h> #include <iostream> using namespace std; int main() {cout << "ABCD\n"; fork(); cout.flush(); }
Buffering of I/O: Another Example // File: Buffer2.cpp // Demonstrate full vs. line buffering. Check when things come out! // Note that parent is forced to follow child // Try changing cout to cerr #include <sys/types.h> #include <unistd.h> #include <iostream> using namespace std; int main() {pid_t pid; cout << "ABCD\n"; // if sub endl for \n, still line buffered!!! if (pid=fork()) { wait(NULL); cout << "Parent!\n"; } else cout << "Child!\n"; cout.flush(); }
Exercises • Show possible execution of > ls –l | more with only one fork in the parent • Describe steps necessary to execute command >ls | grep “g” | more