[BACK]Return to job.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / make

Diff for /src/usr.bin/make/job.c between version 1.49 and 1.50

version 1.49, 2002/03/02 13:42:51 version 1.50, 2002/03/19 00:08:31
Line 128 
Line 128 
 #include "timestamp.h"  #include "timestamp.h"
 #include "main.h"  #include "main.h"
   
   #define TMPPAT  "/tmp/makeXXXXXXXXXX"
   
 /*  /*
    * The SEL_ constants determine the maximum amount of time spent in select
    * before coming out to see if a child has finished. SEL_SEC is the number of
    * seconds and SEL_USEC is the number of micro-seconds
    */
   #define SEL_SEC         0
   #define SEL_USEC        500000
   
   
   /*-
    * Job Table definitions.
    *
    * Each job has several things associated with it:
    *      1) The process id of the child shell
    *      2) The graph node describing the target being made by this job
    *      3) A LstNode for the first command to be saved after the job
    *         completes. This is NULL if there was no "..." in the job's
    *         commands.
    *      4) An FILE* for writing out the commands. This is only
    *         used before the job is actually started.
    *      5) A union of things used for handling the shell's output. Different
    *         parts of the union are used based on the value of the usePipes
    *         flag. If it is true, the output is being caught via a pipe and
    *         the descriptors of our pipe, an array in which output is line
    *         buffered and the current position in that buffer are all
    *         maintained for each job. If, on the other hand, usePipes is false,
    *         the output is routed to a temporary file and all that is kept
    *         is the name of the file and the descriptor open to the file.
    *      6) An identifier provided by and for the exclusive use of the
    *         Rmt module.
    *      7) A word of flags which determine how the module handles errors,
    *         echoing, etc. for the job
    *
    * The job "table" is kept as a linked Lst in 'jobs', with the number of
    * active jobs maintained in the 'nJobs' variable. At no time will this
    * exceed the value of 'maxJobs', initialized by the Job_Init function.
    *
    * When a job is finished, the Make_Update function is called on each of the
    * parents of the node which was just remade. This takes care of the upward
    * traversal of the dependency graph.
    */
   #define JOB_BUFSIZE     1024
   typedef struct Job_ {
       int         pid;        /* The child's process ID */
       GNode       *node;      /* The target the child is making */
       LstNode     tailCmds;   /* The node of the first command to be
                                * saved when the job has been run */
       FILE        *cmdFILE;   /* When creating the shell script, this is
                                * where the commands go */
       int         rmtID;     /* ID returned from Rmt module */
       short       flags;      /* Flags to control treatment of job */
   #define JOB_IGNERR      0x001   /* Ignore non-zero exits */
   #define JOB_SILENT      0x002   /* no output */
   #define JOB_SPECIAL     0x004   /* Target is a special one. i.e. run it locally
                                    * if we can't export it and maxLocal is 0 */
   #define JOB_IGNDOTS     0x008   /* Ignore "..." lines when processing
                                    * commands */
   #define JOB_FIRST       0x020   /* Job is first job for the node */
   #define JOB_RESTART     0x080   /* Job needs to be completely restarted */
   #define JOB_RESUME      0x100   /* Job needs to be resumed b/c it stopped,
                                    * for some reason */
   #define JOB_CONTINUING  0x200   /* We are in the process of resuming this job.
                                    * Used to avoid infinite recursion between
                                    * JobFinish and JobRestart */
       union {
           struct {
               int         op_inPipe;      /* Input side of pipe associated
                                            * with job's output channel */
               int         op_outPipe;     /* Output side of pipe associated with
                                            * job's output channel */
               char        op_outBuf[JOB_BUFSIZE + 1];
                                           /* Buffer for storing the output of the
                                            * job, line by line */
               int         op_curPos;      /* Current position in op_outBuf */
           }           o_pipe;         /* data used when catching the output via
                                        * a pipe */
           struct {
               char        of_outFile[sizeof(TMPPAT)];
                                           /* Name of file to which shell output
                                            * was rerouted */
               int         of_outFd;       /* Stream open to the output
                                            * file. Used to funnel all
                                            * from a single job to one file
                                            * while still allowing
                                            * multiple shell invocations */
           }           o_file;         /* Data used when catching the output in
                                        * a temporary file */
       }           output;     /* Data for tracking a shell's output */
   } Job;
   
   #define outPipe         output.o_pipe.op_outPipe
   #define inPipe          output.o_pipe.op_inPipe
   #define outBuf          output.o_pipe.op_outBuf
   #define curPos          output.o_pipe.op_curPos
   #define outFile         output.o_file.of_outFile
   #define outFd           output.o_file.of_outFd
   
   
   /*-
    * Shell Specifications:
    * Each shell type has associated with it the following information:
    *      1) The string which must match the last character of the shell name
    *         for the shell to be considered of this type. The longest match
    *         wins.
    *      2) A command to issue to turn off echoing of command lines
    *      3) A command to issue to turn echoing back on again
    *      4) What the shell prints, and its length, when given the echo-off
    *         command. This line will not be printed when received from the shell
    *      5) A boolean to tell if the shell has the ability to control
    *         error checking for individual commands.
    *      6) The string to turn this checking on.
    *      7) The string to turn it off.
    *      8) The command-flag to give to cause the shell to start echoing
    *         commands right away.
    *      9) The command-flag to cause the shell to Lib_Exit when an error is
    *         detected in one of the commands.
    *
    * Some special stuff goes on if a shell doesn't have error control. In such
    * a case, errCheck becomes a printf template for echoing the command,
    * should echoing be on and ignErr becomes another printf template for
    * executing the command while ignoring the return status. If either of these
    * strings is empty when hasErrCtl is false, the command will be executed
    * anyway as is and if it causes an error, so be it.
    */
   typedef struct Shell_ {
       char          *name;        /* the name of the shell. For Bourne and C
                                    * shells, this is used only to find the
                                    * shell description when used as the single
                                    * source of a .SHELL target. For user-defined
                                    * shells, this is the full path of the shell.
                                    */
       bool          hasEchoCtl;   /* True if both echoOff and echoOn defined */
       char          *echoOff;     /* command to turn off echo */
       char          *echoOn;      /* command to turn it back on again */
       char          *noPrint;     /* command to skip when printing output from
                                    * shell. This is usually the command which
                                    * was executed to turn off echoing */
       int           noPLen;       /* length of noPrint command */
       bool          hasErrCtl;    /* set if can control error checking for
                                    * individual commands */
       char          *errCheck;    /* string to turn error checking on */
       char          *ignErr;      /* string to turn off error checking */
       /*
        * command-line flags
        */
       char          *echo;        /* echo commands */
       char          *exit;        /* exit on error */
   }               Shell;
   
   /*
  * error handling variables   * error handling variables
  */   */
 static int      errors = 0;         /* number of errors reported */  static int      errors = 0;         /* number of errors reported */
Line 243 
Line 394 
         (void)fprintf(fp, targFmt, gn->name);          (void)fprintf(fp, targFmt, gn->name);
   
 /*  /*
  * When JobStart attempts to run a job remotely but can't, and isn't allowed   * When JobStart attempts to run a job but isn't allowed to,
  * to run the job locally, or when Job_CatchChildren detects a job that has   * the job is placed on the stoppedJobs queue to be run
  * been migrated home, the job is placed on the stoppedJobs queue to be run  
  * when the next job finishes.   * when the next job finishes.
  */   */
 static LIST     stoppedJobs;    /* Lst of Job structures describing  static LIST     stoppedJobs;    /* Lst of Job structures describing
Line 303 
Line 453 
 /*-  /*-
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  * JobCondPassSig --   * JobCondPassSig --
  *      Pass a signal to a job if the job is remote or if USE_PGRP   *      Pass a signal to a job if USE_PGRP
  *      is defined.   *      is defined.
  *   *
  * Side Effects:   * Side Effects:
Line 317 
Line 467 
 {  {
     Job *job = (Job *)jobp;      Job *job = (Job *)jobp;
     int signo = *(int *)signop;      int signo = *(int *)signop;
     /*  
      * Assume that sending the signal to job->pid will signal any remote  
      * job as well.  
      */  
     if (DEBUG(JOB)) {      if (DEBUG(JOB)) {
         (void)fprintf(stdout,          (void)fprintf(stdout,
                        "JobCondPassSig passing signal %d to child %d.\n",                         "JobCondPassSig passing signal %d to child %d.\n",
Line 333 
Line 479 
 /*-  /*-
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  * JobPassSig --   * JobPassSig --
  *      Pass a signal on to all remote jobs and to all local jobs if   *      Pass a signal to all local jobs if USE_PGRP is defined,
  *      USE_PGRP is defined, then die ourselves.   *      then die ourselves.
  *   *
  * Side Effects:   * Side Effects:
  *      We die by the same signal.   *      We die by the same signal.
Line 1299 
Line 1445 
            ) && nJobs != maxJobs)             ) && nJobs != maxJobs)
         {          {
             /*              /*
              * If the job is remote, it's ok to resume it as long as the               * If we haven't reached the concurrency limit already (or
              * maximum concurrency won't be exceeded. If it's local and               * maxLocal is 0), it's ok to resume the job.
              * we haven't reached the local concurrency limit already (or the  
              * job must be run locally and maxLocal is 0), it's also ok to  
              * resume it.  
              */               */
             bool error;              bool error;
             int status;              int status;

Legend:
Removed from v.1.49  
changed lines
  Added in v.1.50