Script started on Mon Dec 1 17:29:38 2025 macbook:logs> cd ../programs/unix_ch13 macbook:unix_ch13> cat pgrp1.c // Unix page 500 #include #include #include void sigintHandler() { printf("Process %d got a SIGINT\n", getpid()); } int main() { signal(SIGINT, sigintHandler); /* Handle Control-C */ if (fork () == 0) printf("Child PID %d PGRP %d waits\n", getpid(), getpgid(0)); else printf("Parent PID %d PGRP %d waits\n", getpid (), getpgid(0)); pause(); /* Wait for asignal */ return 0; } macbook:unix_ch13> gcc pgrp1.c macbook:unix_ch13> ./a.out Parent PID 13329 PGRP 13329 waits Child PID 13330 PGRP 13329 waits ^CProcess 13330 got a SIGINT Process 13329 got a SIGINT macbook:unix_ch13> gcc pgrp2.c macbook:unix_ch13> cat pgrp2.c // Unix page 501 #include #include #include #include /* needed for "exit" call */ void sigintHandler() { printf("Process %d got a SIGINT\n", getpid()); exit(1); } int main() { int i; signal(SIGINT, sigintHandler); /* Install signal handler */ if (fork () == 0) setpgid(0, getpid()); /* Place child in its own process group */ printf("Process PID %d PGRP %d waits\n", getpid(), getpgid(0)); for (i=0; i<=3; i++) { /* Loop three times */ printf("Process %d is alive\n", getpid()); sleep(1); } return 0; } macbook:unix_ch13> gcc pgrp2.c macbook:unix_ch13> ./a.out Process PID 13418 PGRP 13418 waits Process 13418 is alive Process PID 13419 PGRP 13419 waits Process 13419 is alive çProcess 13418 is alive Process 13419 is alive Process 13419 is alive Process 13418 is alive ^CProcess 13418 got a SIGINT macbook:unix_ch13> Process 13419 is alive macbook:unix_ch13> macbook:unix_ch13> macbook:unix_ch13> ./a.out Process PID 13426 PGRP 13426 waits Process 13426 is alive Process PID 13427 PGRP 13427 waits Process 13427 is alive Process 13427 is alive Process 13426 is alive ^CProcess 13426 got a SIGINT macbook:unix_ch13> Process 13427 is alive Process 13427 is alive macbook:unix_ch13> cat wait.c // This is called "mywait.c" in the // Unix book by Glass and Ables, pages 478-479. // I made some updates. -MCW #include #include // exit() #include // for fork, sleep #include // for wait int main () { int pid, status, childPid; printf ("I'm the parent process and my PID is %d\n", getpid()); pid = fork (); /* Duplicate */ if (pid != 0) /* Branch based on return value from fork () */ { printf ("I'm the parent process with PID %d and PPID %d\n", getpid (), getppid ()); /* Wait for a child to terminate. */ childPid = wait (&status); printf("A child with PID %d terminated with exit code %d\n", childPid, status >> 8); } else { printf ("I'm the child process with PID %d and PPID %d\n", getpid (), getppid ()); exit (42); /* Exit with a silly number */ } printf ("PID %d terminates\n", getpid () ); return 0; } macbook:unix_ch13> gcc wait.c macbook:unix_ch13> ./a.out I'm the parent process and my PID is 13746 I'm the parent process with PID 13746 and PPID 12703 I'm the child process with PID 13747 and PPID 13746 A child with PID 13747 terminated with exit code 42 PID 13746 terminates macbook:unix_ch13> grep terminates *.c myfork.c: printf ("PID %d terminates.\n", getpid () ); /* Both processes execute this */ myfork2.c: printf("PID %d terminates. \n", getpid() ); /* Both processes */ myfork3.c: printf("PID %d terminates. \n", getpid() ); /* Both processes */ myfork4.c: printf("PID %d terminates. \n", getpid() ); /* Both processes */ orphan.c: sleep (10); /* Make sure that the parent terminates first */ orphan.c: printf ("PID %d terminates.\n", getpid () ); /* Both processes execute this */ wait.c: printf ("PID %d terminates\n", getpid () ); macbook:unix_ch13> cat orphan.c #include #include // exit() #include // for fork, sleep #include // for wait int main () { int pid; printf ("I'm the original process with PID %d and PPID %d.\n", getpid (), getppid ()); pid = fork (); /* Duplicate. Child & parent continue from here */ if (pid != 0) /* Branch based on return value from fork () */ { /* pid is non-zero, so I must be the parent */ printf ("I'm the parent process with PID %d and PPID %d.\n", getpid (), getppid ()); printf ("My child's PID is %d\n", pid); } else { /* pid is zero, so I must be the child */ sleep (10); /* Make sure that the parent terminates first */ printf ("I'm the child process with PID %d and PPID %d.\n", getpid (), getppid ()); } printf ("PID %d terminates.\n", getpid () ); /* Both processes execute this */ return 0; } macbook:unix_ch13> gcc orphan.c macbook:unix_ch13> ./a.out I'm the original process with PID 23015 and PPID 12703. I'm the parent process with PID 23015 and PPID 12703. My child's PID is 23016 PID 23015 terminates. macbook:unix_ch13> I'm the child process with PID 23016 and PPID 1. PID 23016 terminates. macbook:unix_ch13> sftp mweeks@snowball.cs.gsu.edu mweeks@snowball.cs.gsu.edu's password: Connected to snowball.cs.gsu.edu. sftp> put zomb* Uploading zombie.c to /home/mweeks/zombie.c zombie.c 100% 463 78.2KB/s 00:00 sftp> quit macbook:unix_ch13> ^ftp^sh^ ssh mweeks@snowball.cs.gsu.edu mweeks@snowball.cs.gsu.edu's password: Last login: Mon Nov 10 08:59:57 2025 from c-24-99-154-26.hsd1.ga.comcast.net + | GSU Computer Science | Instructional Server | SNOWBALL.cs.gsu.edu + [mweeks@gsuad.gsu.edu@snowball ~]$ gcc zombie.c [mweeks@gsuad.gsu.edu@snowball ~]$ ./a.out & [1] 7657 [mweeks@gsuad.gsu.edu@snowball ~]$ ps PID TTY TIME CMD 7545 pts/3 00:00:00 bash 7657 pts/3 00:00:00 a.out 7658 pts/3 00:00:00 a.out 7662 pts/3 00:00:00 ps [mweeks@gsuad.gsu.edu@snowball ~]$ ps PID TTY TIME CMD 7545 pts/3 00:00:00 bash 7657 pts/3 00:00:00 a.out 7658 pts/3 00:00:00 a.out 7678 pts/3 00:00:00 ps [mweeks@gsuad.gsu.edu@snowball ~]$ kill 7658 [mweeks@gsuad.gsu.edu@snowball ~]$ ps PID TTY TIME CMD 7545 pts/3 00:00:00 bash 7657 pts/3 00:00:00 a.out 7658 pts/3 00:00:00 a.out 7691 pts/3 00:00:00 ps [mweeks@gsuad.gsu.edu@snowball ~]$ kill -KILL 7658 [mweeks@gsuad.gsu.edu@snowball ~]$ ps PID TTY TIME CMD 7545 pts/3 00:00:00 bash 7657 pts/3 00:00:00 a.out 7658 pts/3 00:00:00 a.out 7700 pts/3 00:00:00 ps [mweeks@gsuad.gsu.edu@snowball ~]$ kill 7657 [mweeks@gsuad.gsu.edu@snowball ~]$ ps PID TTY TIME CMD 7545 pts/3 00:00:00 bash 7726 pts/3 00:00:00 ps [1]+ Terminated ./a.out [mweeks@gsuad.gsu.edu@snowball ~]$ ./a.out & [1] 7737 [mweeks@gsuad.gsu.edu@snowball ~]$ exit logout Connection to snowball.cs.gsu.edu closed. macbook:unix_ch13> ssh mweeks@snowball.cs.gsu.edu mweeks@snowball.cs.gsu.edu's password: Last login: Mon Dec 1 18:13:47 2025 from 131.96.222.113 + | GSU Computer Science | Instructional Server | SNOWBALL.cs.gsu.edu + [mweeks@gsuad.gsu.edu@snowball ~]$ ps PID TTY TIME CMD 7755 pts/6 00:00:00 bash 7791 pts/6 00:00:00 ps [mweeks@gsuad.gsu.edu@snowball ~]$ ./a.out & [1] 7798 [mweeks@gsuad.gsu.edu@snowball ~]$ [mweeks@gsuad.gsu.edu@snowball ~]$ [mweeks@gsuad.gsu.edu@snowball ~]$ [mweeks@gsuad.gsu.edu@snowball ~]$ ps -U mweeks PID TTY TIME CMD 7737 ? 00:00:00 a.out 7738 ? 00:00:00 a.out 7754 ? 00:00:00 sshd 7755 pts/6 00:00:00 bash 7798 pts/6 00:00:00 a.out 7799 pts/6 00:00:00 a.out 7808 pts/6 00:00:00 ps [mweeks@gsuad.gsu.edu@snowball ~]$ ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 Nov24 ? 00:02:43 /usr/lib/systemd/s root 2 0 0 Nov24 ? 00:00:00 [kthreadd] [Many lines deleted] mweeks@+ 7754 7747 0 18:15 ? 00:00:00 sshd: mweeks@gsuad mweeks@+ 7755 7754 0 18:15 pts/6 00:00:00 -bash mweeks@+ 7798 7755 0 18:15 pts/6 00:00:00 ./a.out mweeks@+ 7799 7798 0 18:15 pts/6 00:00:00 [a.out] mweeks@+ 7893 7755 0 18:16 pts/6 00:00:00 ps -ef [mweeks@gsuad.gsu.edu@snowball ~]$ top top - 18:17:49 up 7 days, 16:53, 13 users, load average: 1.01, 1. Tasks: 181 total, 1 running, 178 sleeping, 0 stopped, 2 zomb [mweeks@gsuad.gsu.edu@snowball ~]$ ps -U mweeks PID TTY TIME CMD 7737 ? 00:00:00 a.out 7738 ? 00:00:00 a.out 7754 ? 00:00:00 sshd 7755 pts/6 00:00:00 bash 7798 pts/6 00:00:00 a.out 7799 pts/6 00:00:00 a.out 8043 pts/6 00:00:00 ps [mweeks@gsuad.gsu.edu@snowball ~]$ kill 7737 [mweeks@gsuad.gsu.edu@snowball ~]$ kill 7798 [mweeks@gsuad.gsu.edu@snowball ~]$ ps -U mweeks PID TTY TIME CMD 7754 ? 00:00:00 sshd 7755 pts/6 00:00:00 bash 8055 pts/6 00:00:00 ps [1]+ Terminated ./a.out [mweeks@gsuad.gsu.edu@snowball ~]$ exit logout Connection to snowball.cs.gsu.edu closed. macbook:unix_ch13> macbook:unix_ch13> cat myexec.c #include #include // for fork, sleep #include // for wait int main () { printf ("I'm process %d and I'm about to exec an ls -l\n", getpid ()); // NULL indicates last command. There could be more than 1 execl ("/bin/ls", "ls", "-l", NULL); /* Execute ls */ printf ("This line should never be executed\n"); return 0; } macbook:unix_ch13> sftp snowball.cs.gsu.edu mweeks@snowball.cs.gsu.edu's password: Connected to snowball.cs.gsu.edu. sftp> put myexec.c Uploading myexec.c to /home/mweeks/myexec.c myexec.c 100% 366 65.4KB/s 00:00 sftp> quit macbook:unix_ch13> ssh snowball.cs.gsu.edu mweeks@snowball.cs.gsu.edu's password: Last login: Mon Dec 1 18:15:46 2025 from 131.96.222.113 + | GSU Computer Science | Instructional Server | SNOWBALL.cs.gsu.edu + [mweeks@gsuad.gsu.edu@snowball ~]$ gcc myexec.c [mweeks@gsuad.gsu.edu@snowball ~]$ ./a.out I'm process 8682 and I'm about to exec an ls -l total 2144 -rwxrwxr-x. 1 mweeks@gsuad.gsu.edu mweeks@gsuad.gsu.edu 8512 Dec 1 18:25 a.out -rw-r--r--. 1 mweeks@gsuad.gsu.edu mweeks@gsuad.gsu.edu 688 Oct 22 18:10 args.c -rw-r--r--. 1 mweeks@gsuad.gsu.edu mweeks@gsuad.gsu.edu 974 Oct 22 18:24 args_v2.c [Many similar lines removed] -rw-rw-r--. 1 mweeks@gsuad.gsu.edu mweeks@gsuad.gsu.edu 2209 Aug 27 18:22 who_output.txt -rw-r--r--. 1 mweeks@gsuad.gsu.edu mweeks@gsuad.gsu.edu 463 Dec 1 18:13 zombie.c [mweeks@gsuad.gsu.edu@snowball ~]$ cat myexec.c #include #include // for fork, sleep #include // for wait int main () { printf ("I'm process %d and I'm about to exec an ls -l\n", getpid ()); // NULL indicates last command. There could be more than 1 execl ("/bin/ls", "ls", "-l", NULL); /* Execute ls */ printf ("This line should never be executed\n"); return 0; } [mweeks@gsuad.gsu.edu@snowball ~]$ grep fork *.c myexec.c:#include // for fork, sleep zombie.c:#include // fork() zombie.c: pid = fork (); /* Duplicate */ zombie.c: /* Branch based on return value from fork () */ [mweeks@gsuad.gsu.edu@snowball ~]$ vi fork_and_exec.c [mweeks@gsuad.gsu.edu@snowball ~]$ ps PID TTY TIME CMD 9503 pts/1 00:00:00 bash 9540 pts/1 00:00:00 ps [mweeks@gsuad.gsu.edu@snowball ~]$ ps -U mweeks PID TTY TIME CMD 8630 ? 00:00:00 sshd 8631 pts/6 00:00:00 bash 9502 ? 00:00:00 sshd 9503 pts/1 00:00:00 bash 9547 pts/1 00:00:00 ps [mweeks@gsuad.gsu.edu@snowball ~]$ which echo /usr/bin/echo [mweeks@gsuad.gsu.edu@snowball ~]$ vi fork_and_exec.c [mweeks@gsuad.gsu.edu@snowball ~]$ gcc fork_and_exec.c [mweeks@gsuad.gsu.edu@snowball ~]$ ./a.out I'm process 9699 and I'm about to exec an ls -l I'm process 9703 and I'm about to exec an ls -l hello The parent is ending [mweeks@gsuad.gsu.edu@snowball ~]$ cat fork_and_exec.c // See the // Unix book by Glass and Ables, page 478 // -MCW #include #include // exit() #include // fork() #include // for fork, sleep #include // for wait int main () { int pid, status; pid = fork (); /* Duplicate */ printf ("I'm process %d and I'm about to exec an ls -l\n", getpid ()); int childPid = 0; /* Branch based on return value from fork () */ if (pid != 0) { /* Wait for a child to terminate. */ childPid = wait (&status); } else { // NULL indicates last command. There could be more than 1 execl ("/bin/echo", "echo", "hello", NULL); /* Execute ls */ } printf ("The parent is ending\n"); return 0; } [mweeks@gsuad.gsu.edu@snowball ~]$ vi fork_and_exec.c [mweeks@gsuad.gsu.edu@snowball ~]$ gcc fork_and_exec.c [mweeks@gsuad.gsu.edu@snowball ~]$ ./a.out I'm process 9967 As parent, I will wait for the child I'm process 9968 As child, I will call echo hello The parent is ending [mweeks@gsuad.gsu.edu@snowball ~]$ exit logout Connection to snowball.cs.gsu.edu closed.