Exercises

  1. Suppose a parent process performs the following steps:

    /* Call fork() to create a number of child processes, each of which
       remains in same process group as the parent */
    
    /* Sometime later... */
    signal(SIGUSR1, SIG_IGN);     /* Parent makes itself immune to SIGUSR1 */
    
    killpg(getpgrp(), SIGUSR1);   /* Send signal to children created earlier */

    What problem might be encountered with this application design? (Consider shell pipelines.) How could this problem be avoided?

  2. Write a program to verify that a parent process can change the process group ID of one of its children before the child performs an exec(), but not afterward.

  3. Write a program to verify that a call to setsid() from a process group leader fails.

  4. Modify the program in Example 34-4 (disc_SIGHUP.c) to verify that, if the controlling process doesn’t terminate as a consequence of receiving SIGHUP, then the kernel doesn’t send SIGHUP to the members of the foreground process.

  5. Suppose that, in the signal handler of Example 34-6, the code that unblocks the SIGTSTP signal was moved to the start of the handler. What potential race condition does this create?

  6. Write a program to verify that when a process in an orphaned process group attempts to read() from the controlling terminal, the read() fails with the error EIO.

  7. Write a program to verify that if one of the signals SIGTTIN, SIGTTOU, or SIGTSTP is sent to a member of an orphaned process group, then the signal is discarded (i.e., has no effect) if it would stop the process (i.e., the disposition is SIG_DFL), but is delivered if a handler is installed for the signal.