while (1) { write (1, "$ ", 2); // 1 = STDOUT_FILENO readcommand (0, command, args); // parse user input, 0 = STDIN_FILENO 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"); } }
read
, write
,
fork
, exec
, wait
.
conventions: -1 return value signals error,
error code stored in errno
,
perror
prints out a descriptive error
message based on errno
.
$ ls
read (0, buf, bufsize)
write (1, "hello\n", strlen("hello\n"))
fcntl(fd, F_SETFD, FD_CLOEXEC)
$ ls > tmp1just before exec insert:
close(1); creat("tmp1", 0666); // fd will be 1
The kernel always uses the first free file descriptor, 1 in this case.
Could use dup2()
to clone a file descriptor to a new number.