[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.110 and 1.111

version 1.110, 2007/12/01 15:14:34 version 1.111, 2008/01/12 13:08:59
Line 43 
Line 43 
  * Interface:   * Interface:
  *      Job_Make                Start the creation of the given target.   *      Job_Make                Start the creation of the given target.
  *   *
  *      Job_CatchChildren       Check for and handle the termination of any  
  *                              children. This must be called reasonably  
  *                              frequently to keep the whole make going at  
  *                              a decent clip, since job table entries aren't  
  *                              removed until their process is caught this way.  
  *  
  *      Job_CatchOutput         Print any output our children have produced.  
  *                              Should also be called fairly frequently to  
  *                              keep the user informed of what's going on.  
  *                              If no output is waiting, it will block for  
  *                              a time given by the SEL_* constants, below,  
  *                              or until output is ready.  
  *  
  *      Job_Init                Called to initialize this module. in addition,   *      Job_Init                Called to initialize this module. in addition,
  *                              any commands attached to the .BEGIN target   *                              any commands attached to the .BEGIN target
  *                              are executed before this function returns.   *                              are executed before this function returns.
Line 159 
Line 146 
 #define JOB_CONTINUING  0x200   /* We are in the process of resuming this job.  #define JOB_CONTINUING  0x200   /* We are in the process of resuming this job.
                                  * Used to avoid infinite recursion between                                   * Used to avoid infinite recursion between
                                  * JobFinish and JobRestart */                                   * JobFinish and JobRestart */
   #define JOB_DIDOUTPUT   0x001
     struct job_pipe in[2];      struct job_pipe in[2];
 } Job;  } Job;
   
Line 189 
Line 177 
 static int      errors;  static int      errors;
 struct error_info {  struct error_info {
         int status;          int status;
         char *name;          GNode *n;
 };  };
   
   
Line 246 
Line 234 
 static void prepare_pipe(struct job_pipe *, int *);  static void prepare_pipe(struct job_pipe *, int *);
 static void handle_job_output(Job *, int, bool);  static void handle_job_output(Job *, int, bool);
 static void register_error(int, Job *);  static void register_error(int, Job *);
   static void loop_handle_running_jobs(void);
   static void Job_CatchChildren(void);
   static void Job_CatchOutput(void);
   
 static void  static void
 register_error(int status, Job *job)  register_error(int status, Job *job)
Line 255 
Line 246 
         errors++;          errors++;
         p = emalloc(sizeof(struct error_info));          p = emalloc(sizeof(struct error_info));
         p->status = status;          p->status = status;
         p->name = job->node->name;          p->n = job->node;
         if (p)          Lst_AtEnd(&errorsList, p);
                 Lst_AtEnd(&errorsList, p);  
 }  }
   
 void  void
Line 265 
Line 255 
 {  {
         LstNode ln;          LstNode ln;
         struct error_info *p;          struct error_info *p;
           const char *type;
           int r;
   
         for (ln = Lst_First(&errorsList); ln != NULL; ln = Lst_Adv(ln)) {          for (ln = Lst_First(&errorsList); ln != NULL; ln = Lst_Adv(ln)) {
                 p = (struct error_info *)Lst_Datum(ln);                  p = (struct error_info *)Lst_Datum(ln);
                 if (WIFEXITED(p->status)) {                  if (WIFEXITED(p->status)) {
                         Error("\tExit status %d in target %s",                          type = "Exit status";
                             WEXITSTATUS(p->status), p->name);                          r = WEXITSTATUS(p->status);
                 } else if (WIFSIGNALED(p->status)) {                  } else if (WIFSIGNALED(p->status)) {
                         Error("\tReceived signal %d in target s",                          type = "Received signal";
                             WTERMSIG(p->status), p->name);                          r = WTERMSIG(p->status);
                 } else {                  } else {
                         Error("\tStatus %d in target %s", p->status, p->name);                          type = "Status";
                           r = p->status;
                 }                  }
           if (p->n->lineno)
                   Error(" %s %d (%s, line %lu of %s)",
                       type, r, p->n->name, p->n->lineno, p->n->fname);
           else
                   Error(" %s %d (%s)", type, r, p->n->name);
         }          }
 }  }
   
Line 549 
Line 547 
                         debug_printf("Process %ld exited.\n", (long)job->pid);                          debug_printf("Process %ld exited.\n", (long)job->pid);
                         if (WEXITSTATUS(status) != 0) {                          if (WEXITSTATUS(status) != 0) {
                                 banner(job, stdout);                                  banner(job, stdout);
                                 (void)fprintf(stdout, "*** Error code %d%s\n",                                  (void)fprintf(stdout, "*** Error code %d %s\n",
                                     WEXITSTATUS(status),                                      WEXITSTATUS(status),
                                     (job->node->type & OP_IGNORE) ?                                      (job->node->type & OP_IGNORE) ?
                                     "(ignored)" : "");                                      "(ignored)" : "");
Line 635 
Line 633 
                 free(job);                  free(job);
         }          }
   
         JobRestartJobs();  
   
         /*          /*
          * Set aborting if any error.           * Set aborting if any error.
          */           */
Line 650 
Line 646 
                 aborting = ABORT_ERROR;                  aborting = ABORT_ERROR;
         }          }
   
           if (aborting != ABORT_ERROR)
                   JobRestartJobs();
   
         if (aborting == ABORT_ERROR && Job_Empty()) {          if (aborting == ABORT_ERROR && Job_Empty()) {
                 /*                  /*
                  * If we are aborting and the job table is now empty, we finish.                   * If we are aborting and the job table is now empty, we finish.
Line 1027 
Line 1026 
         size_t i;          size_t i;
   
         banner(job, out);          banner(job, out);
           job->flags |= JOB_DIDOUTPUT;
         for (i = 0; i < endPos; i++)          for (i = 0; i < endPos; i++)
                 putc(p->buffer[i], out);                  putc(p->buffer[i], out);
 }  }
Line 1062 
Line 1062 
         }          }
         return false;          return false;
 }  }
   
 /*-  /*-
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  * handle_pipe  --   * handle_pipe  --
Line 1122 
Line 1123 
 /*-  /*-
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  * Job_CatchChildren --   * Job_CatchChildren --
  *      Handle the exit of a child. Called from Make_Make.   *      Handle the exit of a child. Called by handle_running_jobs
  *   *
  * Side Effects:   * Side Effects:
  *      The job descriptor is removed from the list of children.   *      The job descriptor is removed from the list of children.
Line 1185 
Line 1186 
 /*-  /*-
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  * Job_CatchOutput --   * Job_CatchOutput --
  *      Catch the output from our children, if we're using   *      Catch the output from our children.
  *      pipes do so. Otherwise just block time until we get a  
  *      signal (most likely a SIGCHLD) since there's no point in  
  *      just spinning when there's nothing to do and the reaping  
  *      of a child can wait for a while.  
  *  
  * Side Effects:  
  *      Output is read from pipes if we're piping.  
  * -----------------------------------------------------------------------   * -----------------------------------------------------------------------
  */   */
 void  void
Line 1200 
Line 1194 
 {  {
         int nfds;          int nfds;
         struct timeval timeout;          struct timeval timeout;
         LstNode ln;          LstNode ln, ln2;
         Job *job;          Job *job;
         int i;          int i;
           int status;
   
         int count = howmany(outputsn+1, NFDBITS) * sizeof(fd_mask);          int count = howmany(outputsn+1, NFDBITS) * sizeof(fd_mask);
         fd_set *readfdsp = malloc(count);          fd_set *readfdsp = malloc(count);
Line 1217 
Line 1212 
   
         nfds = select(outputsn+1, readfdsp, NULL, NULL, &timeout);          nfds = select(outputsn+1, readfdsp, NULL, NULL, &timeout);
         handle_all_signals();          handle_all_signals();
         if (nfds > 0) {          for (ln = Lst_First(&runningJobs); nfds && ln != NULL;
                 for (ln = Lst_First(&runningJobs); nfds && ln != NULL;              ln = ln2) {
                     ln = Lst_Adv(ln)) {                  ln2 = Lst_Adv(ln);
                         job = (Job *)Lst_Datum(ln);                  job = (Job *)Lst_Datum(ln);
                         for (i = 0; i < 2; i++) {                  job->flags &= ~JOB_DIDOUTPUT;
                                 if (FD_ISSET(job->in[i].fd, readfdsp)) {                  for (i = 1; i >= 0; i--) {
                                         handle_job_output(job, i, false);                          if (FD_ISSET(job->in[i].fd, readfdsp)) {
                                         nfds--;                                  nfds--;
                                 }                                  handle_job_output(job, i, false);
                         }                          }
                 }                  }
                   if (job->flags & JOB_DIDOUTPUT) {
                           if (wait4(job->pid, &status, WNOHANG|WUNTRACED, NULL) ==
                               job->pid) {
                                   Lst_Remove(&runningJobs, ln);
                                   nJobs--;
                                   jobFull = false;
                                   JobFinish(job, status);
                           } else {
                                   Lst_Requeue(&runningJobs, ln);
                           }
                   }
         }          }
         free(readfdsp);          free(readfdsp);
 }  }
   
   void
   handle_running_jobs()
   {
           Job_CatchOutput();
           Job_CatchChildren();
   }
   
   static void
   loop_handle_running_jobs()
   {
           while (nJobs)
                   handle_running_jobs();
   }
 /*-  /*-
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  * Job_Make --   * Job_Make --
Line 1275 
Line 1294 
   
         if ((begin_node->type & OP_DUMMY) == 0) {          if ((begin_node->type & OP_DUMMY) == 0) {
                 JobStart(begin_node, JOB_SPECIAL);                  JobStart(begin_node, JOB_SPECIAL);
                 while (nJobs) {                  loop_handle_running_jobs();
                         Job_CatchOutput();  
                         Job_CatchChildren();  
                 }  
         }          }
 }  }
   
Line 1374 
Line 1390 
                         ignoreErrors = false;                          ignoreErrors = false;
   
                         JobStart(interrupt_node, 0);                          JobStart(interrupt_node, 0);
                         while (nJobs) {                          loop_handle_running_jobs();
                                 Job_CatchOutput();  
                                 Job_CatchChildren();  
                         }  
                 }                  }
         }          }
         exit(signo);          exit(signo);
Line 1402 
Line 1415 
                         Error("Errors reported so .END ignored");                          Error("Errors reported so .END ignored");
                 } else {                  } else {
                         JobStart(end_node, JOB_SPECIAL);                          JobStart(end_node, JOB_SPECIAL);
                           loop_handle_running_jobs();
                         while (nJobs) {  
                                 Job_CatchOutput();  
                                 Job_CatchChildren();  
                         }  
                 }                  }
         }          }
         return errors;          return errors;
Line 1434 
Line 1443 
 Job_Wait(void)  Job_Wait(void)
 {  {
         aborting = ABORT_WAIT;          aborting = ABORT_WAIT;
         while (nJobs != 0) {          loop_handle_running_jobs();
                 Job_CatchOutput();  
                 Job_CatchChildren();  
         }  
         aborting = 0;          aborting = 0;
 }  }
   
Line 1498 
Line 1504 
 {  {
         Job *job;          Job *job;
   
         while (!jobFull && (job = (Job *)Lst_DeQueue(&stoppedJobs)) != NULL) {          while (!Job_Full() &&
               (job = (Job *)Lst_DeQueue(&stoppedJobs)) != NULL) {
                 debug_printf("Job queue is not full. "                  debug_printf("Job queue is not full. "
                     "Restarting a stopped job.\n");                      "Restarting a stopped job.\n");
                 JobRestart(job);                  JobRestart(job);

Legend:
Removed from v.1.110  
changed lines
  Added in v.1.111