CIS 350, Process Creation in Unix 1. My files on astro % ls a.out execl2.c fork2.c fork4.c fork6.c hello.out execl1.c fork1.c fork3.c fork5.c hello.c 2. Program hello.c % cat hello.c main() { printf("Hello\n"); } % cc hello.c -o hello.out % hello.out Hello % 3. The execl system call overlays the calling process with the named file. Here, execl is used to execute my "hello.c" program. % cat execl1.c main() { printf("I am execl1 and I am about to execl to hello.out \n"); execl("/usr2/cis/stafford/cis120/code/hello.out", "hello.out", 0); printf("This statement will never be executed \n"); } % cc execl1.c % a.out I am execl1 and I am about to execl to hello.out Hello % CIS 350, Process Creation in Unix, page 2 4. Execl is used here to execute /bin/ls. Note that the second argument to execl is the name of the program (ls), followed by any arguments to ls. % cat execl2.c main() { printf("I am execl2 and I am about to execl the ls program \n"); execl("/bin/ls", "ls", "-al", 0); printf("This statement will never be executed \n"); } % cc execl2.c % a.out I am execl2 and I am about to execl the ls program total 195 drwxr-xr-x 2 stafford staff 512 Apr 8 08:38 . drwxr-xr-x 4 stafford staff 512 Apr 6 12:53 .. -rwxr-xr-x 1 stafford staff 46512 Apr 8 08:38 a.out -rw-r--r-- 1 stafford staff 217 Apr 7 17:20 execl1.c -rw-r--r-- 1 stafford staff 186 Apr 7 17:31 execl2.c -rw-r--r-- 1 stafford staff 46 Apr 6 14:28 fork1.c -rw-r--r-- 1 stafford staff 175 Apr 6 14:46 fork2.c -rw-r--r-- 1 stafford staff 262 Apr 6 15:02 fork3.c -rw-r--r-- 1 stafford staff 363 Apr 6 15:20 fork4.c -rw-r--r-- 1 stafford staff 546 Apr 7 12:58 fork5.c -rw-r--r-- 1 stafford staff 273 Apr 7 18:04 fork6.c -rw-r--r-- 1 stafford staff 34 Apr 6 15:13 hello.c -rwxr-xr-x 1 stafford staff 45680 Apr 8 08:37 hello.out % 5. The "fork" system call creates a child process that is a duplicate of the calling process (the parent process) except for different process ID's. % cat fork1.c main() { fork(); printf("Hello\n"); } % cc fork1.c % a.out Hello Hello % CIS 350, Process Creation in Unix, page 3 6. To the parent, fork returns the child's process ID (pid). To the child, fork returns zero. You can use an if or case statement to do one thing in the parent and another in the child. Note that the childs line could have been printed before the parents line. However, in this case, the parent exits (dies) first. When the child exits (dies), it tries to notify (signal) its parent. Since the parent has died, it is possible for the child to become a "zombie" process that will stay around forever trying to tell its parent about its own imminent demise. % cat fork2.c main() { int pid; pid=fork(); if (pid == 0) { printf("I am the child %d \n", pid); } else { printf("I am the parent %d \n", pid); } } % cc fork2.c % a.out I am the parent 5915 I am the child 0 % 7. The wait system call causes a parent to wait until one or more of its children exits. (If a process has no children, wait will return -1.) Note that no zombies are created by the following code. cat fork3.c main() { int pid, qid; pid=fork(); if (pid == 0) { printf("I am the child %d \n", pid); } else { printf("I am the parent %d \n", pid); qid=wait(0); printf("I am the parent after the wait %d \n", qid); } } % cc fork3.c % a.out I am the child 0 I am the parent 5932 I am the parent after the wait 5932 % CIS 350, Process Creation in Unix, page 4 8. The following program combines the execl, fork, and wait system calls % cat fork4.c main() { int pid, qid; pid=fork(); if (pid == 0) { printf("I am the child %d \n", pid); execl("/bin/ls", "ls", "-l", 0); printf("This statement will never be executed \n"); } else { printf("I am the parent %d \n", pid); qid=wait(0); printf("I am the parent after the wait %d \n", qid); } } % cc fork4.c % a.out I am the parent 5968 I am the child 0 total 194 -rwxr-xr-x 1 stafford staff 47068 Apr 8 08:39 a.out -rw-r--r-- 1 stafford staff 217 Apr 7 17:20 execl1.c -rw-r--r-- 1 stafford staff 186 Apr 7 17:31 execl2.c -rw-r--r-- 1 stafford staff 46 Apr 6 14:28 fork1.c -rw-r--r-- 1 stafford staff 175 Apr 6 14:46 fork2.c -rw-r--r-- 1 stafford staff 262 Apr 6 15:02 fork3.c -rw-r--r-- 1 stafford staff 363 Apr 6 15:20 fork4.c -rw-r--r-- 1 stafford staff 546 Apr 7 12:58 fork5.c -rw-r--r-- 1 stafford staff 273 Apr 7 18:04 fork6.c -rw-r--r-- 1 stafford staff 34 Apr 6 15:13 hello.c -rwxr-xr-x 1 stafford staff 45680 Apr 8 08:37 hello.out I am the parent after the wait 5968 % CIS 350, Process Creation in Unix, page 5 9. The getpid and getppid system calls return the processes ID (pid) and the process ID of the processes parent (ppid for parent process ID. The "ps" command will give you a list of your processes. "ps -lax" will give you a long listing of all proesses running in the computer, beginning with process 0001, init. % cat fork5.c main() { int pid, ppid, cpid, cpid2; cpid=fork(); if (cpid == 0) { pid=getpid(); ppid=getppid(); printf("I am the child, pid=%d ppid=%d \n", pid, ppid); execl("/bin/ps", "ps", "-l", 0); printf("This statement will never be executed \n"); } else { pid=getpid(); ppid=getppid(); printf("I am the parent, pid=%d ppid=%d cpid=%d\n", pid, ppid, cpid); cpid2=wait(0); printf("Parent after wait, pid=%d ppid=%d cpid=%d\n", pid, ppid, cpid2); } } % cc fork5.c % a.out I am the parent, pid=6006 ppid=5606 cpid=6007 I am the child, pid=6007 ppid=6006 F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME COMD 10 S 124 6006 5606 10 30 20 801bd918 5 801bd808 ttyx3 0:00 a.out 18 O 124 6007 6006 12 61 20 801befd8 18 ttyx3 0:00 ps 0 S 0 5604 286 0 30 20 801c3418 18 801c3308 ttyx3 0:00 telnetd 10 S 124 5606 5604 9 39 20 801c82d8 36 ffffc000 ttyx3 0:01 csh Parent after wait, pid=6006 ppid=5606 cpid=6007 % CIS 350, Process Creation in Unix, page 6 10. Here is a nice simple program. Can you predict the output? % cat fork6.c main() { int pid1, pid2, pid3, pid4; pid1=fork(); pid2=fork(); pid3=fork(); printf ("%d, %d, %d, %d, %d \n", getpid(), getppid(), pid1, pid2, pid3); while ((pid4=wait(0)) != -1) printf ("%d, %d, %d \n", getpid(), getppid(), pid4); } % cc fork6.c % a.out 6067, 6066, 6064, 0, 0 6069, 6065, 0, 0, 0 6070, 6063, 6064, 6066, 0 6066, 6063, 6064, 0, 6067 6066, 6063, 6067 6064, 6063, 0, 6065, 6068 6068, 6064, 0, 6065, 0 6064, 6063, 6068 6065, 6064, 0, 0, 6069 6065, 6064, 6069 6064, 6063, 6065 6063, 5606, 6064, 6066, 6070 6063, 5606, 6070 6063, 5606, 6066 6063, 5606, 6064 %