Handling Terminated Processes - child_died

Cogent Tools Demo and Tutorials: Version 4.0
Prev | Chapter 9. Common Functions for Any Program (in `lib/common.g`) | Next

# 9.6. Handling Terminated Processes - `child_died`

This function is used by the Controller, Log, and History programs, because each of them can start child processes. This function is necessary because we want to handle two possibilities: the user untoggles a button to terminate a child program, or the child program gets terminated some other way. In the second case, we want the button to untoggle when the child program exits. We handle both of these cases the same, by detecting a `SIGCHLD` (child has died) signal as set up in the common function `program_startup`. Then we use the Gamma `wait` function to recover the child's process ID.

       /*--------------------------------------------------------------------
        * Function:    child_died
        * Returns:     t or nil
        * Description: Attached to SIGCHLD, this function wait()s for the child
        *              to die, extracts its process ID, and looks it up in the
        *              list of known children.  It then updates the list and if
        *              there is a GUI button attached, evaluates the cmd argument
        *              to pop out the button. Since this is attached to SIGCHLD,
        *              wait() should never block, as the data must be available
        *              immediately in order for SIGCHLD to have occurred. However,
        *              the Linux OS 'system' call creates spurious SIGCHLD calls,
        *              and as a general safety measure, we use the WNOHANG option,
        *              and call wait() on any signal (task ID parameter is 0).
        *------------------------------------------------------------------*/
       function child_died (cmd)
       {
         local child_data;
         local child, button;

         child_data = wait (0, WNOHANG);

         if(list_p(child_data))
           {
             child = car (assoc_equal (car(child_data), Children));
             Children = nremove (child, Children);

The child must be removed from the `Children` association list of the parent program (explained in the commentary on `start_process` for the `control.g` program). We use the Gamma `assoc_equal` function to find the sub-list containing the process ID of the dead child. Then we use `nremove` to remove that sub-list from `Children`. Other Gamma functions used are variations of `car` for accessing parts of a list.

             if(cadr(child))
               princ (cadr(child), " died\n");
             if(button = caddr(child))
               if (!destroyed_p(button))
                 eval (cmd);
           }
       }

Prev | Home | Next
Start a Process - `start_process`, `find_on_path` | Up | Kill a Child Process - `kill_child`

Copyright 1995-2002 by Cogent Real-Time Systems, Inc.