See the reference page for links to the early Unix papers.
while (1) { printf ("$"); readcommand (command, args); // parse user input if ((pid = fork ()) == 0) { // child? exec (command, args, 0); } else if (pid > 0) { // parent? wait (0); // wait for child to terminate } else { perror ("Failed to fork\n"); } }
The split of creating a process with a new program in fork and exec is mostly a historical accident. See the assigned paper for today.
$ ls
read (1, buf, bufsize)
write (1, "hello\n", strlen("hello\n")+1)
$ls > tmp1just before exec insert:
close (1); fd = open ("tmp1", O_CREAT|O_WRONLY); // fd will be 1!
The kernel will return the first free file descriptor, 1 in this case.
$ls 2> tmp1 > tmp1replace last code with:
close (1); close (2); fd1 = open ("tmp1", O_CREAT|O_WRONLY); // fd will be 1! fd2 = dup (fd1);both file descriptors share offset
$ sort file.txt | uniq | wcor
$ sort file.txt > tmp1 $ uniq tmp1 > tmp2 $ wc tmp2 $ rm tmp1 tmp2or
$ kill -9
int fdarray[2]; if (pipe(fdarray) < 0) panic ("error"); if ((pid = fork()) < 0) panic ("error"); else if (pid > 0) { close(fdarray[0]); write(fdarray[1], "hello world\n", 12); } else { close(fdarray[1]); n = read (fdarray[0], buf, MAXBUF); write (1, buf, n); }
int fdarray[2]; if (pipe(fdarray) < 0) panic ("error"); if ((pid = fork ()) == 0) { child (left end of pipe) close (1); tmp = dup (fdarray[1]); // fdarray[1] is the write end, tmp will be 1 close (fdarray[0]); // close read end close (fdarray[1]); // close fdarray[1] exec (command1, args1, 0); } else if (pid > 0) { // parent (right end of pipe) close (0); tmp = dup (fdarray[0]); // fdarray[0] is the read end, tmp will be 0 close (fdarray[0]); close (fdarray[1]); // close write end exec (command2, args2, 0); } else { printf ("Unable to fork\n"); }
$ compute &