Script started on Wed Nov 20 12:30:07 2024 mweeks@air:unix_ch13$ echo 6126 6126 mweeks@air:unix_ch13$ ls sparse* sparse.c sparse.txt mweeks@air:unix_ch13$ cat sparse.c #include #include #include #include /**************************************/ int main () { int i, fd; /* Create a sparse file */ fd = open ("sparse.txt", O_CREAT | O_RDWR, 0600); write (fd, "sparse", 6); lseek (fd, 60006, SEEK_SET); write (fd, "file", 4); close (fd); /* Create a normal file */ fd = open ("normal.txt", O_CREAT | O_RDWR, 0600); //write (fd, "normal", 6); write (fd, "sparse", 6); for (i = 1; i <= 60000; i++) write (fd, "\0", 1); /** Different from book! **/ write (fd, "file", 4); close (fd); return 0; } mweeks@air:unix_ch13$ gcc sparse.c mweeks@air:unix_ch13$ ./a.out mweeks@air:unix_ch13$ ls -l sparse.txt normal.txt -rw-r--r-- 1 mweeks staff 60010 Nov 20 12:36 normal.txt -rw-r--r-- 1 mweeks staff 60010 Nov 20 12:36 sparse.txt mweeks@air:unix_ch13$ diff normal.txt sparse.txt mweeks@air:unix_ch13$ cat fork_example.c /* Simple fork() example. -Michael Weeks */ #include #include #include // for fork, sleep int main (int argc, char* argv[]) { if (fork() == 0) { printf("Fork() returned 0\n"); sleep(4); printf(" 0 fork part returning\n"); } else { printf("Fork() did not return 0\n"); sleep(2); printf(" non-0 fork part returning\n"); } return 0; } mweeks@air:unix_ch13$ gcc fork_example.c mweeks@air:unix_ch13$ ./a.out Fork() did not return 0 Fork() returned 0 non-0 fork part returning mweeks@air:unix_ch13$ 0 fork part returning mweeks@air:unix_ch13$ cat myfork.c // This is called "myfork.c" in the // Unix book by Glass and Ables, pages 478-479. // I made some updates. -MCW #include #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) /* 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 */ { 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; } mweeks@air:unix_ch13$ gcc myfork.c mweeks@air:unix_ch13$ ./a.out I'm the original process with PID 95925 and PPID 95496. I'm the parent process with PID 95925 and PPID 95496. My child's PID is 95926 PID 95925 terminates. I'm the child process with PID 95926 and PPID 1. PID 95926 terminates. mweeks@air:unix_ch13$ gcc myfork2.c mweeks@air:unix_ch13$ cat myfork2.c #include #include // for fork, sleep // p475 of the Unix book int main() { int pid; int X = 10; printf("I'm the original process with PID %d and PPID %d. \n", getpid(), getppid() ); printf("About to call fork...\n"); pid = fork(); /* Duplicate. Child and parent continue from here */ if ( pid!= 0 ) /* pid is non-zero, so I must be the parent */ { X++; printf("I'm the parent process with PID %d and PPID %d. \n", getpid(), getppid() ); printf("My child's PID is %d \n", pid ); printf("X is %d\n", X); sleep(2); } else /* pid is zero, so I must be the child */ { printf("I'm the child process with PID %d and PPID %d. \n", getpid(), getppid() ); printf("X is %d\n", X); } printf("PID %d terminates. \n", getpid() ); /* Both processes */ /* execute this */ return 0; } mweeks@air:unix_ch13$ ./a.out I'm the original process with PID 96137 and PPID 95496. About to call fork... I'm the parent process with PID 96137 and PPID 95496. My child's PID is 96138 X is 11 I'm the child process with PID 96138 and PPID 96137. X is 10 PID 96138 terminates. PID 96137 terminates. mweeks@air:unix_ch13$ cat mydup.c #include #include #include #include int main() { int fd1, fd2, fd3; fd1 = open("test.txt", O_RDWR | O_TRUNC | O_CREAT); printf("fd1 = %d\n", fd1); write(fd1,"what's",6); fd2 = dup(fd1); printf("fd2 = %d\n", fd2); write(fd2," up",3); close(0); // yes, this closes stdin fd3 = dup(fd1); // dup gives first avail. fd printf("fd3 = %d\n", fd3); write(fd3," doc",4); dup2(3,2); write(2,"?\n",2); return 0; } mweeks@air:unix_ch13$ gcc mydup.c mweeks@air:unix_ch13$ ls -l test.txt -rw-r--r-- 1 mweeks staff 15 Aug 5 23:48 test.txt mweeks@air:unix_ch13$ rm test.txt mweeks@air:unix_ch13$ ls -l test.txt ls: test.txt: No such file or directory mweeks@air:unix_ch13$ ./a.out fd1 = 3 fd2 = 4 fd3 = 0 mweeks@air:unix_ch13$ ls -l test.txt ---x--x--- 1 mweeks staff 15 Nov 20 12:58 test.txt mweeks@air:unix_ch13$ chmod 644 test.txt mweeks@air:unix_ch13$ cat test.txt what's up doc? mweeks@air: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 (5); /* 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; } mweeks@air:unix_ch13$ gcc orphan.c mweeks@air:unix_ch13$ ./a.out I'm the original process with PID 96448 and PPID 95496. I'm the parent process with PID 96448 and PPID 95496. My child's PID is 96449 PID 96448 terminates. mweeks@air:unix_ch13$ I'm the child process with PID 96449 and PPID 1. PID 96449 terminates. mweeks@air:unix_ch13$ vi orphan.c mweeks@air:unix_ch13$ echo changed 5 to 10 in sleep changed 5 to 10 in sleep mweeks@air:unix_ch13$ gcc orphan.c mweeks@air:unix_ch13$ ./a.out I'm the original process with PID 96473 and PPID 95496. I'm the parent process with PID 96473 and PPID 95496. My child's PID is 96474 PID 96473 terminates. mweeks@air:unix_ch13$ ps PID TTY TIME CMD 23213 ttys000 0:05.80 -bash 95495 ttys000 0:00.06 script Nov21_2024.log 52960 ttys001 0:03.38 -bash 57730 ttys002 0:01.07 -bash 21990 ttys003 0:02.76 -bash 95496 ttys004 0:00.08 /bin/bash -i 96474 ttys004 0:00.00 ./a.out 87215 ttys005 0:03.93 -bash mweeks@air:unix_ch13$ I'm the child process with PID 96474 and PPID 1. PID 96474 terminates. mweeks@air:unix_ch13$ ps PID TTY TIME CMD 23213 ttys000 0:05.80 -bash 95495 ttys000 0:00.06 script Nov21_2024.log 52960 ttys001 0:03.38 -bash 57730 ttys002 0:01.07 -bash 21990 ttys003 0:02.76 -bash 95496 ttys004 0:00.09 /bin/bash -i 87215 ttys005 0:03.93 -bash mweeks@air:unix_ch13$ kill -TERM 95496 mweeks@air:unix_ch13$ ps PID TTY TIME CMD 23213 ttys000 0:05.80 -bash 95495 ttys000 0:00.06 script Nov21_2024.log 52960 ttys001 0:03.38 -bash 57730 ttys002 0:01.07 -bash 21990 ttys003 0:02.76 -bash 95496 ttys004 0:00.09 /bin/bash -i 87215 ttys005 0:03.93 -bash mweeks@air:unix_ch13$ cat mywait.c #include #include // for fork, sleep #include // for wait int main (int argc, char* argv[]) { if (fork () == 0) /* Child */ { /* Execute other program */ execvp (argv[1], &argv[1]); fprintf (stderr, "Could not execute %s\n", argv[1]); } return 0; } mweeks@air:unix_ch13$ gcc mywait.c mweeks@air:unix_ch13$ ./a.out ls mweeks@air:unix_ch13$ Nov21_2024.log pgrp1.c a.out pgrp2.c fileIOerror.c pipe_example.c fork_example.c pipe_example_3.c fork_example2.c pipe_example_v2.c lstat_example.c pipe_fork_signal_wait.c monitor.c process2.c monitor_original.c processDirectory.c mychdir.c processDirectory_v2.c mydup.c reverse_unix_ch13.c myexec.c reverse_unix_ch13_original.c myexit.c sparse.c myfork.c sparse.txt myfork2.c talk.c myfork3.c test.txt myfork4.c unnamed_pipes_figure.txt mywait.c wait.c normal.txt zombie.c orphan.c mweeks@air: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; } mweeks@air:unix_ch13$ gcc wait.c mweeks@air:unix_ch13$ ./a.out I'm the parent process and my PID is 96766 I'm the parent process with PID 96766 and PPID 95496 I'm the child process with PID 96767 and PPID 96766 A child with PID 96767 terminated with exit code 42 PID 96766 terminates mweeks@air:unix_ch13$ echo pop-quiz pop-quiz mweeks@air:unix_ch13$ echo question 1 what is your name question 1 what is your name mweeks@air:unix_ch13$ echo question 2 what does fork do question 2 what does fork do mweeks@air:unix_ch13$ echo question 3 what does wait do question 3 what does wait do mweeks@air:unix_ch13$ echo question 4 why did we only get PID 96766 terminates question 4 why did we only get PID 96766 terminates mweeks@air:unix_ch13$ mweeks@air:unix_ch13$ cat pipe_example.c /* https://www.cs.rutgers.edu/~pxk/416/notes/c-tutorials/pipe.html The simplest example of pipe I could think of Paul Krzyzanowski */ #include #include /* for printf */ #include /* for strlen */ #include /* for pipe */ int main(int argc, char **argv) { int n; int fd[2]; char buf[1025]; char *data = "hello... this is sample data"; pipe(fd); write(fd[1], data, strlen(data)); if ((n = read(fd[0], buf, 1024)) >= 0) { buf[n] = 0; /* terminate the string */ printf("read %d bytes from the pipe: \"%s\"\n", n, buf); } else perror("read"); exit(0); } mweeks@air:unix_ch13$ cat unnamed_pipes_figure.txt |-----------------------------------------------------------| | | | | | | | | ,,,,|,,, write end + fd[0] : + : ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,, : : : : fd[1] : + : : : ---> Pipe ---> : : ,,,,|,,, ::::::::::::::::::::::::::::::::::::::::::::: | + read end | | | | | | | | ---------------------- ASCII figure by Michael Weeks based on figure 13.54 (p504) of the Glass/Ables Unix for Programmers and Users, Third Ed. mweeks@air:unix_ch13$ gcc pipe_example.c mweeks@air:unix_ch13$ ./a.out read 28 bytes from the pipe: "hello... this is sample data" mweeks@air:unix_ch13$ cat pipe_example_v2.c /* This is based on the "simplest example of pipe I could think of" by Paul Krzyzanowski https://www.cs.rutgers.edu/~pxk/416/notes/c-tutorials/pipe.html Modified by Michael Weeks with code from p475 of the Glass/Ables Unix book */ #include #include /* for printf */ #include /* for strlen */ #include /* for pipe */ int main(int argc, char **argv) { int n; int fd[2]; char buf[1025]; char *data = "hello... this is sample data"; pipe(fd); printf("About to fork into 2 processes\n"); int pid = fork(); if (pid < 0) { // There must be a problem! perror("fork"); exit(1); } if (pid > 0) { /* pid is positive and non-zero, so I must be the parent */ // close the side of the pipe that parent doesn't use. close(fd[0]); // Now send a message to the child. printf("parent: sending a message to the child\n"); write(fd[1], data, strlen(data)); int child_status; // Wait for the child process to exit. printf("parent: wait for child to exit\n"); wait(&child_status); printf("parent: done\n"); } else { // If I'm not the parent, I must be the child. // close the side of the pipe that child doesn't use. close(fd[1]); // Now get a message from the parent. printf("child: getting a message from the parent\n"); if ((n = read(fd[0], buf, 1024)) >= 0) { buf[n] = 0; /* terminate the string */ printf("child: read %d bytes from the pipe: \"%s\"\n", n, buf); } else perror("read"); printf("child: exiting\n"); exit(0); } return 0; } mweeks@air:unix_ch13$ gcc pipe_example_v2.c mweeks@air:unix_ch13$ ./a.out About to fork into 2 processes parent: sending a message to the child parent: wait for child to exit child: getting a message from the parent child: read 28 bytes from the pipe: "hello... this is sample data" child: exiting parent: done mweeks@air:unix_ch13$ exit exit Script done on Wed Nov 20 13:47:42 2024