Processes





                    CHAPTER 15: PROCESSES


   Process Management 

     - Creating a new process (fork, exec, system, backquotes)

     - Awaiting process completion (wait)

     - Terminating a process (exit)

     - Pipes (Process Filehandles)

     - Signals (kill, %SIG)

     - Environment variables (%ENV)


   Fork Function

     - Creates a new process

     - fork 

     - Returns the Process ID (PID) of the new process to the parent 
       process.  Returns 0 to the child process.

     - On failure $! is set to the value of errno

     - Uses fork(2)

     - The following items are inherited by the new process from the
       invoking Perl process:

         Standard Input
         Standard Output
         Standard Error
         Current Working Directory
         Umask

     - Typical use:

         $pid = fork;

   
   Exec Function

     - Overlays a process with a new program

     - exec (LIST)
       exec LIST

     - If successful, exec does not return.  Otherwise, it always
       returns False

     - On failure $! is set to the value of errno

     - Uses execvp(3)

     - If the LIST has more than one argument or LIST is an array with 
       more than one value, execvp(3) is called with the arguments in 
       LIST   

     - BUT if LIST is only one scalar argument, the argument is checked 
       for Bourne shell metacharacters.  If there are any Bourne shell 
       metacharacters, the entire argument is passed to "/bin/sh -c" for 
       parsing.  Thus, any valid Bourne shell command line can be run, 
       including a command which performs I/O redirection.  If there are 
       NO shell metacharacters, the argument is split into words and 
       execvp(3) invoked.

     - The LIST elements are variable interpolated

     - Typical use:

         $status = exec ("date");  # No Bourne shell created 

         $status = exec ("ls -l | wc -l > wc.out");
                                   # Bourne shell created


   Exit Function

     - Causes program termination

     - exit (EXIT_STATUS)
       exit EXIT_STATUS

     - Terminates the program with an Exit Status set to EXIT_STATUS.
       If EXIT_STATUS is omitted, an Exit Status of 0 is used.

     - Uses exit(2)

     - Typical use:

         exit (1);


   Wait Function

     - Waits for a child process to terminate

     - wait 

     - Returns the Process ID (PID) of the terminated child process or 
       -1 if there are no child processes

     - On failure $! is set to the value of errno

     - The Termination Status of the terminated child is returned in 
       the special variable $?.  To get the Exit Status divide this by 
       256.

     - Uses wait(2)

     - Typical use:

         $status = wait;


   Example Program

     - Here is an example of a program segment which forks and execs 
       "ls -l > dir.out":

       if (($pid = fork) == 0)
       {
         exec ("ls -l > dir.out");
         print ("Could not exec: errno is $!\n");
         exit (1);
       }
       elsif ($pid > 0)
       {
         wait;
       }
       else
       {
         print ("Could not fork: errno is $!\n");
       }

       
   System Function

     - Creates a new process, runs a program in it and waits for its 
       completion

     - system (LIST)
       system LIST

     - Returns the Termination Status of the program.  To get the Exit 
       Status of the program divide the returned value by 256.

     - On failure $! is set to the value of errno

     - Uses the fork function to create a new process, does an "exec 
       LIST" in the child process and awaits for the child process to 
       complete using the wait function

     - Uses fork(2) and execvp(3)

     - Typical use:

         $term_status = system ("date");

         $term_status = system ("ls -l | wc -l > wc.out");

         $term_status = system ("long_cmd &");

     - Note that in the last example, where the process is to be 
       executed in the background, the return value of the system 
       function is the termination status of the Bourne shell process 
       which started the background process.  So if this status 
       indicates success, we know that the Bourne shell successfully 
       started the process, but we do NOT know if the program actually 
       executed successfully.


   Process Filehandles

     - Can also create processes using process filehandles

     - open (FILEHANDLE, "|cmd");  # Fork/exec cmd; STDIN of 
                                   #   cmd is the Read end of 
                                   #   the pipe.  The FILEHANDLE
                                   #   is the Write end of the
                                   #   pipe.

     - open (FILEHANDLE, "cmd|");  # Fork/exec cmd; STDOUT of 
                                   #   cmd is the Write end of 
                                   #   the pipe.  The FILEHANDLE
                                   #   is the Read end of the
                                   #   pipe.

     - Returns Process ID of child process on success, undef (False) 
       on failure.  Note that failure only occurs if the fork failed.  
       If the fork succeeded, but the exec failed, the open still 
       returns the PID of the child.  This is a bad situation, since 
       its looks like the open succeeded (return value is True), but 
       the child process has actually died.  When this happens, Perl 
       writes an error message to STDERR.

     - On failure $! is set to the value of errno

     - Uses popen(3)

     - Typical use:

         open (IN, "who|");        # Launch "who" command.
                                   #   Read output of "who"
                                   #   with the IN FH

         open (OUT, "|wc -l");     # Launch "wc -l" command.
                                   #   Write data to "wc -l"
                                   #   with the OUT FH

     - When a process filehandle is closed, the invoking Perl program 
       waits until the process exits.  To cause the close to return 
       immediately, send a SIGKILL signal to the process before closing 
       the process filehandle.


   Backquotes

     - Can also run any valid Bourne shell command line and wait for 
       its completion by enclosing a command in backquotes

     - Similar to command substitution in the shell

     - When used in a scalar context, a single string consisting of
       all of the output (including any embedded newlines) from the 
       command is returned

     - When used in an array context, an array of values is returned,
       one for each line of output.  (Actually, the output is split
       using the Input Record Separator, $/, which is "\n" by default.)

     - The Termination Status of the command is returned in $?

     - On failure $! is set to the value of errno

     - Variable interpolation is done on the command

       NOTE: Single quotes inside backquotes do NOT prevent variable
             interpolation!

     - Typical use:

         @files = `ls -l`;

     - Ex.

         foreach ($perms, $links, $owner, $group, $size,
                  $month, $day, $year_time, $file) (`ls -l`)
         {
           print ("File $file has $size bytes\n");
         }


   Signals

     - Perl provides minimal support for sending a UNIX signal to a 
       process and for defining the desired action on receipt of a 
       signal

     - Use the kill function to send (generate) a signal

     - Use the special %SIG associative array to define the action for 
       a signal


   Kill Function

     - Sends (generates) a signal to one or more processes

     - kill (LIST)
       kill LIST 

     - The first element of LIST must be either the number of the signal 
       to send or the name of the signal (WITHOUT the "SIG" prefix) 
       enclosed in quotes

     - The remaining LIST elements are the Process IDs of the processes 
       to receive the signal

     - Returns the number of processes successfully signaled

     - On failure $! is set to the value of errno

     - Uses kill(2)

     - Typical use:

         $cnt = kill (9, $proc1, $proc2);
         $cnt = kill ("INT", @daemons);


   %SIG Associative Array

     - The special %SIG array contains signal actions

     - Changing a key-value pair of the %SIG array changes the action 
       for a signal

     - The signal name (again without the "SIG" prefix) is used as a 
       key into the %SIG array.  The signal catching action is the 
       corresponding value.

     - The action can be:

         'DEFAULT'      Default action
         'IGNORE'       Ignore signal
         'handler'      Name of signal-handling function

     - Typical use:

         $SIG{'INT'} = 'sigint_handler';

     - Ex.

         sub sigint_handler
         {
           print ("Caught SIGINT\n");
           print ("Better close TMP file and exit!\n");
           close (TMP);
           exit (1);
         }

         ...

         $SIG{'INT'} = 'sigint_handler';

         ...                       # Close TMP and exit if
                                   #   SIGINT occurs

         close (TMP);
         $SIG{'INT} = 'DEFAULT';

         ...                       # Done with TMP, can take
                                   #   normal SIGINT action


   Environment Variables

     - The special %ENV array contains the current environment variables 
       for the Perl process

     - Changing a key-value pair of the %ENV array changes the the value 
       of an environment variable

     - The name of the environment variable is used as a key into the 
       %ENV array.  The value of the environmental variable is the 
       corresponding value.

     - Ex.

         Here is a simple printenv program:

         #!/usr/bin/perl

         for $var (sort keys %ENV)
         {
           print ("$var=$ENV{$var}\n");
         }


   Special Variables

         $?             Termination Status of the last process
                          started by backquotes, started by the
                          system function or completed due to the
                          closing of a process filehandle
         $$             The Process ID of the current Perl program
                          (useful for generating temporary filenames)

         %SIG           Signal action associative array
         %ENV           Environment variables associative array


   Other Process Management Functions

     - alarm (SECS)
       alarm SECS   : causes the alarm signal (SIGALRM) to be sent
                      in SECS seconds

     - getpgrp (PID)
       getpgrp PID  : returns the Process Group ID of the process
                      whose PID is specified (returns PGID of 
                      current process if PID is 0)

     - getppid      : returns the Process ID of the parent process

     - getpriority (WHICH, WHO)
                    : returns the current priority of a process, 
                      process group or user

     - setpgrp (PID, PGID) 
                    : sets the Process Group ID of the process
                      whose PID is specified (sets the PGID of 
                      current process if PID is 0)

     - setpriority (WHICH, WHO, PRIORITY)
                    : sets the current priority of a process, 
                      process group or user

     - sleep (EXPR)
       sleep EXPR
       sleep        : causes the Perl script to sleep for EXPR 
                      seconds

     - times        : returns a four-element array with the user 
                      and system CPU times (in seconds) for the
                      process and its children

     - waitpid (PID, FLAGS)
                    : waits for a specific process to terminate





Bob Tarr
University of Maryland, Baltimore County
tarr@umbc.edu