CSE4001 Fall 2005 Exam #2, open book, open notes. Name ___________________ 1. Suppose that fd is a file descriptor. How do you find the position of the file pointer without moving it (5 pts)? ANSWER: lseek(fd, 0, SEEK_CUR); 2. Under what conditions does read() block (5 pts)? ANSWER: when reading from a terminal, pipe, or socket, no input is available, and O_NDELAY or O_NONBLOCK is not set. 3. Write C or C++ code to write "hello" to standard output using the write() system call (10 pts). ANSWER: write(1, "hello", 5); 4. Write C or C++ code to set the permissions of file "foo" so that only the owner may read or write it (10 pts). ANSWER: chmod("foo", 0600); 5. How many processes exist after the following? (5 pts) if (fork()) fork(); ANSWER: 3 6. What does this print (10 pts)? int s=2, p=fork(); if (p) { p -= wait(&s); printf("s=%d p=%d\n", s, p); } else exit(s); ANSWER: s=512 p=0 (fork() and wait() both return the child pid, so their difference is always 0. exit(2) in the child sets the high 8 bits of s in the parent: 2 << 8 is 512). 7. When a network server accepts a client, it normally forks a child to handle it. What should a server do to avoid creating zombies and still handle more than one client at a time (10 pts)? ANSWER: signal(SIGCHLD, SIG_IGN); (or install a handler for SIGCHLD. It is incorrect for the parent to wait() because then it could not handle more than one client at a time). 8. Why would a process change its process group ID? (5 pts) ANSWER: To ignore signals from the terminal (Ctrl-C or Ctrl-Z). 9. What happens if a process reads from a pipe after the writing process has exited? (5 pts) ANSWER: after reading all pending input, read() returns 0. 10. How would a child suspend its parent? (5 pts) ANSWER: kill(getppid(), SIGSTOP); 11. Write a C or C++ function run(cmd, file) that executes cmd with the output redirected to file. If the command cmd exists, then the function should return its exit status, otherwise it should print an error message (command cmd not found) and return 0, for example (30 pts): int status = run("ls", "foo")) // equivalent to ls > foo printf("ls exited with status %d\n", status); status = run("blah", "foo"); // prints "command blah not found", status=0 // ANSWER int run(char *cmd, char *file) { if (fork()) { // parent int status; wait(&status); return status >> 8; } else { // child int fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0600); // may want to check for errors here dup2(fd, 1); close(fd); // optinal, but a good idea execlp(cmd, cmd, 0); // parent returns cmd's exit status fprintf(stderr, "command %s not found\n", cmd); // remember stdout is redirected exit(0); // parent returns 0 } }