1 /* 2 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 3 * Copyright (c) 1988, 1989 by Adam de Boor 4 * Copyright (c) 1989 by Berkeley Softworks 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Adam de Boor. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 */ 38 39 #ifndef lint 40 /* from: static char sccsid[] = "@(#)job.c 5.15 (Berkeley) 3/1/91"; */ 41 static char *rcsid = "$Id: job.c,v 1.9 1994/12/24 16:54:28 cgd Exp $"; 42 #endif /* not lint */ 43 44 /*- 45 * job.c -- 46 * handle the creation etc. of our child processes. 47 * 48 * Interface: 49 * Job_Make Start the creation of the given target. 50 * 51 * Job_CatchChildren Check for and handle the termination of any 52 * children. This must be called reasonably 53 * frequently to keep the whole make going at 54 * a decent clip, since job table entries aren't 55 * removed until their process is caught this way. 56 * Its single argument is TRUE if the function 57 * should block waiting for a child to terminate. 58 * 59 * Job_CatchOutput Print any output our children have produced. 60 * Should also be called fairly frequently to 61 * keep the user informed of what's going on. 62 * If no output is waiting, it will block for 63 * a time given by the SEL_* constants, below, 64 * or until output is ready. 65 * 66 * Job_Init Called to intialize this module. in addition, 67 * any commands attached to the .BEGIN target 68 * are executed before this function returns. 69 * Hence, the makefile must have been parsed 70 * before this function is called. 71 * 72 * Job_Full Return TRUE if the job table is filled. 73 * 74 * Job_Empty Return TRUE if the job table is completely 75 * empty. 76 * 77 * Job_ParseShell Given the line following a .SHELL target, parse 78 * the line as a shell specification. Returns 79 * FAILURE if the spec was incorrect. 80 * 81 * Job_End Perform any final processing which needs doing. 82 * This includes the execution of any commands 83 * which have been/were attached to the .END 84 * target. It should only be called when the 85 * job table is empty. 86 * 87 * Job_AbortAll Abort all currently running jobs. It doesn't 88 * handle output or do anything for the jobs, 89 * just kills them. It should only be called in 90 * an emergency, as it were. 91 * 92 * Job_CheckCommands Verify that the commands for a target are 93 * ok. Provide them if necessary and possible. 94 * 95 * Job_Touch Update a target without really updating it. 96 * 97 * Job_Wait Wait for all currently-running jobs to finish. 98 */ 99 100 #include <sys/types.h> 101 #include <sys/signal.h> 102 #include <sys/stat.h> 103 #include <sys/file.h> 104 #include <sys/time.h> 105 #include <sys/wait.h> 106 #include <fcntl.h> 107 #include <errno.h> 108 #include <stdio.h> 109 #include <string.h> 110 #include <signal.h> 111 #include "make.h" 112 #include "hash.h" 113 #include "dir.h" 114 #include "job.h" 115 #include "pathnames.h" 116 117 extern int errno; 118 119 /* 120 * error handling variables 121 */ 122 static int errors = 0; /* number of errors reported */ 123 static int aborting = 0; /* why is the make aborting? */ 124 #define ABORT_ERROR 1 /* Because of an error */ 125 #define ABORT_INTERRUPT 2 /* Because it was interrupted */ 126 #define ABORT_WAIT 3 /* Waiting for jobs to finish */ 127 128 129 /* 130 * post-make command processing. The node postCommands is really just the 131 * .END target but we keep it around to avoid having to search for it 132 * all the time. 133 */ 134 static GNode *postCommands; /* node containing commands to execute when 135 * everything else is done */ 136 static int numCommands; /* The number of commands actually printed 137 * for a target. Should this number be 138 * 0, no shell will be executed. */ 139 140 141 /* 142 * Return values from JobStart. 143 */ 144 #define JOB_RUNNING 0 /* Job is running */ 145 #define JOB_ERROR 1 /* Error in starting the job */ 146 #define JOB_FINISHED 2 /* The job is already finished */ 147 #define JOB_STOPPED 3 /* The job is stopped */ 148 149 /* 150 * tfile is the name of a file into which all shell commands are put. It is 151 * used over by removing it before the child shell is executed. The XXXXX in 152 * the string are replaced by the pid of the make process in a 5-character 153 * field with leading zeroes. 154 */ 155 static char tfile[] = TMPPAT; 156 157 158 /* 159 * Descriptions for various shells. 160 */ 161 static Shell shells[] = { 162 /* 163 * CSH description. The csh can do echo control by playing 164 * with the setting of the 'echo' shell variable. Sadly, 165 * however, it is unable to do error control nicely. 166 */ 167 { 168 "csh", 169 TRUE, "unset verbose", "set verbose", "unset verbose", 10, 170 FALSE, "echo \"%s\"\n", "csh -c \"%s || exit 0\"", 171 "v", "e", 172 }, 173 /* 174 * SH description. Echo control is also possible and, under 175 * sun UNIX anyway, one can even control error checking. 176 */ 177 { 178 "sh", 179 TRUE, "set -", "set -v", "set -", 5, 180 FALSE, "echo \"%s\"\n", "sh -c '%s || exit 0'\n", 181 "v", "e", 182 }, 183 /* 184 * UNKNOWN. 185 */ 186 { 187 (char *)0, 188 FALSE, (char *)0, (char *)0, (char *)0, 0, 189 FALSE, (char *)0, (char *)0, 190 (char *)0, (char *)0, 191 } 192 }; 193 static Shell *commandShell = &shells[DEFSHELL];/* this is the shell to 194 * which we pass all 195 * commands in the Makefile. 196 * It is set by the 197 * Job_ParseShell function */ 198 static char *shellPath = (char *) NULL, /* full pathname of 199 * executable image */ 200 *shellName; /* last component of shell */ 201 202 203 static int maxJobs; /* The most children we can run at once */ 204 static int maxLocal; /* The most local ones we can have */ 205 int nJobs; /* The number of children currently running */ 206 int nLocal; /* The number of local children */ 207 Lst jobs; /* The structures that describe them */ 208 Boolean jobFull; /* Flag to tell when the job table is full. It 209 * is set TRUE when (1) the total number of 210 * running jobs equals the maximum allowed or 211 * (2) a job can only be run locally, but 212 * nLocal equals maxLocal */ 213 #ifndef RMT_WILL_WATCH 214 static fd_set outputs; /* Set of descriptors of pipes connected to 215 * the output channels of children */ 216 #endif 217 218 GNode *lastNode; /* The node for which output was most recently 219 * produced. */ 220 char *targFmt; /* Format string to use to head output from a 221 * job when it's not the most-recent job heard 222 * from */ 223 #define TARG_FMT "--- %s ---\n" /* Default format */ 224 225 /* 226 * When JobStart attempts to run a job remotely but can't, and isn't allowed 227 * to run the job locally, or when Job_CatchChildren detects a job that has 228 * been migrated home, the job is placed on the stoppedJobs queue to be run 229 * when the next job finishes. 230 */ 231 Lst stoppedJobs; /* Lst of Job structures describing 232 * jobs that were stopped due to concurrency 233 * limits or migration home */ 234 235 236 #if defined(USE_PGRP) && defined(SYSV) 237 #define KILL(pid,sig) killpg (-(pid),(sig)) 238 #else 239 # if defined(USE_PGRP) 240 #define KILL(pid,sig) killpg ((pid),(sig)) 241 # else 242 #define KILL(pid,sig) kill ((pid),(sig)) 243 # endif 244 #endif 245 246 static int JobCondPassSig __P((ClientData, ClientData)); 247 static void JobPassSig __P((int)); 248 static int JobCmpPid __P((ClientData, ClientData)); 249 static int JobPrintCommand __P((ClientData, ClientData)); 250 static int JobSaveCommand __P((ClientData, ClientData)); 251 static void JobFinish __P((Job *, union wait)); 252 static void JobExec __P((Job *, char **)); 253 static void JobMakeArgv __P((Job *, char **)); 254 static void JobRestart __P((Job *)); 255 static int JobStart __P((GNode *, int, Job *)); 256 static void JobDoOutput __P((Job *, Boolean)); 257 static Shell *JobMatchShell __P((char *)); 258 static void JobInterrupt __P((int)); 259 260 /*- 261 *----------------------------------------------------------------------- 262 * JobCondPassSig -- 263 * Pass a signal to a job if the job is remote or if USE_PGRP 264 * is defined. 265 * 266 * Results: 267 * === 0 268 * 269 * Side Effects: 270 * None, except the job may bite it. 271 * 272 *----------------------------------------------------------------------- 273 */ 274 static int 275 JobCondPassSig(jobp, signop) 276 ClientData jobp; /* Job to biff */ 277 ClientData signop; /* Signal to send it */ 278 { 279 Job *job = (Job *) jobp; 280 int signo = *(int *) signop; 281 #ifdef RMT_WANTS_SIGNALS 282 if (job->flags & JOB_REMOTE) { 283 (void)Rmt_Signal(job, signo); 284 } else { 285 KILL(job->pid, signo); 286 } 287 #else 288 /* 289 * Assume that sending the signal to job->pid will signal any remote 290 * job as well. 291 */ 292 KILL(job->pid, signo); 293 #endif 294 return(0); 295 } 296 297 /*- 298 *----------------------------------------------------------------------- 299 * JobPassSig -- 300 * Pass a signal on to all remote jobs and to all local jobs if 301 * USE_PGRP is defined, then die ourselves. 302 * 303 * Results: 304 * None. 305 * 306 * Side Effects: 307 * We die by the same signal. 308 * 309 *----------------------------------------------------------------------- 310 */ 311 static void 312 JobPassSig(signo) 313 int signo; /* The signal number we've received */ 314 { 315 int mask; 316 317 Lst_ForEach(jobs, JobCondPassSig, (ClientData)(long)signo); 318 319 /* 320 * Deal with proper cleanup based on the signal received. We only run 321 * the .INTERRUPT target if the signal was in fact an interrupt. The other 322 * three termination signals are more of a "get out *now*" command. 323 */ 324 if (signo == SIGINT) { 325 JobInterrupt(TRUE); 326 } else if ((signo == SIGHUP) || (signo == SIGTERM) || (signo == SIGQUIT)) { 327 JobInterrupt(FALSE); 328 } 329 330 /* 331 * Leave gracefully if SIGQUIT, rather than core dumping. 332 */ 333 if (signo == SIGQUIT) { 334 Finish(0); 335 } 336 337 /* 338 * Send ourselves the signal now we've given the message to everyone else. 339 * Note we block everything else possible while we're getting the signal. 340 * This ensures that all our jobs get continued when we wake up before 341 * we take any other signal. 342 */ 343 mask = sigblock(0); 344 (void) sigsetmask(~0 & ~(1 << (signo-1))); 345 signal(signo, SIG_DFL); 346 347 kill(getpid(), signo); 348 349 signo = SIGCONT; 350 Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo); 351 352 sigsetmask(mask); 353 signal(signo, JobPassSig); 354 355 } 356 357 /*- 358 *----------------------------------------------------------------------- 359 * JobCmpPid -- 360 * Compare the pid of the job with the given pid and return 0 if they 361 * are equal. This function is called from Job_CatchChildren via 362 * Lst_Find to find the job descriptor of the finished job. 363 * 364 * Results: 365 * 0 if the pid's match 366 * 367 * Side Effects: 368 * None 369 *----------------------------------------------------------------------- 370 */ 371 static int 372 JobCmpPid (job, pid) 373 ClientData job; /* job to examine */ 374 ClientData pid; /* process id desired */ 375 { 376 return ( *(int *) pid - ((Job *) job)->pid); 377 } 378 379 /*- 380 *----------------------------------------------------------------------- 381 * JobPrintCommand -- 382 * Put out another command for the given job. If the command starts 383 * with an @ or a - we process it specially. In the former case, 384 * so long as the -s and -n flags weren't given to make, we stick 385 * a shell-specific echoOff command in the script. In the latter, 386 * we ignore errors for the entire job, unless the shell has error 387 * control. 388 * If the command is just "..." we take all future commands for this 389 * job to be commands to be executed once the entire graph has been 390 * made and return non-zero to signal that the end of the commands 391 * was reached. These commands are later attached to the postCommands 392 * node and executed by Job_End when all things are done. 393 * This function is called from JobStart via Lst_ForEach. 394 * 395 * Results: 396 * Always 0, unless the command was "..." 397 * 398 * Side Effects: 399 * If the command begins with a '-' and the shell has no error control, 400 * the JOB_IGNERR flag is set in the job descriptor. 401 * If the command is "..." and we're not ignoring such things, 402 * tailCmds is set to the successor node of the cmd. 403 * numCommands is incremented if the command is actually printed. 404 *----------------------------------------------------------------------- 405 */ 406 static int 407 JobPrintCommand (cmdp, jobp) 408 ClientData cmdp; /* command string to print */ 409 ClientData jobp; /* job for which to print it */ 410 { 411 Boolean noSpecials; /* true if we shouldn't worry about 412 * inserting special commands into 413 * the input stream. */ 414 Boolean shutUp = FALSE; /* true if we put a no echo command 415 * into the command file */ 416 Boolean errOff = FALSE; /* true if we turned error checking 417 * off before printing the command 418 * and need to turn it back on */ 419 char *cmdTemplate; /* Template to use when printing the 420 * command */ 421 char *cmdStart; /* Start of expanded command */ 422 LstNode cmdNode; /* Node for replacing the command */ 423 char *cmd = (char *) cmdp; 424 Job *job = (Job *) jobp; 425 426 noSpecials = (noExecute && ! (job->node->type & OP_MAKE)); 427 428 if (strcmp (cmd, "...") == 0) { 429 job->node->type |= OP_SAVE_CMDS; 430 if ((job->flags & JOB_IGNDOTS) == 0) { 431 job->tailCmds = Lst_Succ (Lst_Member (job->node->commands, 432 (ClientData)cmd)); 433 return (1); 434 } 435 return (0); 436 } 437 438 #define DBPRINTF(fmt, arg) if (DEBUG(JOB)) printf (fmt, arg); fprintf (job->cmdFILE, fmt, arg) 439 440 numCommands += 1; 441 442 /* 443 * For debugging, we replace each command with the result of expanding 444 * the variables in the command. 445 */ 446 cmdNode = Lst_Member (job->node->commands, (ClientData)cmd); 447 cmdStart = cmd = Var_Subst (NULL, cmd, job->node, FALSE); 448 Lst_Replace (cmdNode, (ClientData)cmdStart); 449 450 cmdTemplate = "%s\n"; 451 452 /* 453 * Check for leading @' and -'s to control echoing and error checking. 454 */ 455 while (*cmd == '@' || *cmd == '-') { 456 if (*cmd == '@') { 457 shutUp = TRUE; 458 } else { 459 errOff = TRUE; 460 } 461 cmd++; 462 } 463 464 while (isspace((unsigned char) *cmd)) 465 cmd++; 466 467 if (shutUp) { 468 if (! (job->flags & JOB_SILENT) && !noSpecials && 469 commandShell->hasEchoCtl) { 470 DBPRINTF ("%s\n", commandShell->echoOff); 471 } else { 472 shutUp = FALSE; 473 } 474 } 475 476 if (errOff) { 477 if ( ! (job->flags & JOB_IGNERR) && !noSpecials) { 478 if (commandShell->hasErrCtl) { 479 /* 480 * we don't want the error-control commands showing 481 * up either, so we turn off echoing while executing 482 * them. We could put another field in the shell 483 * structure to tell JobDoOutput to look for this 484 * string too, but why make it any more complex than 485 * it already is? 486 */ 487 if (! (job->flags & JOB_SILENT) && !shutUp && 488 commandShell->hasEchoCtl) { 489 DBPRINTF ("%s\n", commandShell->echoOff); 490 DBPRINTF ("%s\n", commandShell->ignErr); 491 DBPRINTF ("%s\n", commandShell->echoOn); 492 } else { 493 DBPRINTF ("%s\n", commandShell->ignErr); 494 } 495 } else if (commandShell->ignErr && 496 (*commandShell->ignErr != '\0')) 497 { 498 /* 499 * The shell has no error control, so we need to be 500 * weird to get it to ignore any errors from the command. 501 * If echoing is turned on, we turn it off and use the 502 * errCheck template to echo the command. Leave echoing 503 * off so the user doesn't see the weirdness we go through 504 * to ignore errors. Set cmdTemplate to use the weirdness 505 * instead of the simple "%s\n" template. 506 */ 507 if (! (job->flags & JOB_SILENT) && !shutUp && 508 commandShell->hasEchoCtl) { 509 DBPRINTF ("%s\n", commandShell->echoOff); 510 DBPRINTF (commandShell->errCheck, cmd); 511 shutUp = TRUE; 512 } 513 cmdTemplate = commandShell->ignErr; 514 /* 515 * The error ignoration (hee hee) is already taken care 516 * of by the ignErr template, so pretend error checking 517 * is still on. 518 */ 519 errOff = FALSE; 520 } else { 521 errOff = FALSE; 522 } 523 } else { 524 errOff = FALSE; 525 } 526 } 527 528 DBPRINTF (cmdTemplate, cmd); 529 530 if (errOff) { 531 /* 532 * If echoing is already off, there's no point in issuing the 533 * echoOff command. Otherwise we issue it and pretend it was on 534 * for the whole command... 535 */ 536 if (!shutUp && !(job->flags & JOB_SILENT) && commandShell->hasEchoCtl){ 537 DBPRINTF ("%s\n", commandShell->echoOff); 538 shutUp = TRUE; 539 } 540 DBPRINTF ("%s\n", commandShell->errCheck); 541 } 542 if (shutUp) { 543 DBPRINTF ("%s\n", commandShell->echoOn); 544 } 545 return (0); 546 } 547 548 /*- 549 *----------------------------------------------------------------------- 550 * JobSaveCommand -- 551 * Save a command to be executed when everything else is done. 552 * Callback function for JobFinish... 553 * 554 * Results: 555 * Always returns 0 556 * 557 * Side Effects: 558 * The command is tacked onto the end of postCommands's commands list. 559 * 560 *----------------------------------------------------------------------- 561 */ 562 static int 563 JobSaveCommand (cmd, gn) 564 ClientData cmd; 565 ClientData gn; 566 { 567 cmd = (ClientData) Var_Subst (NULL, (char *) cmd, (GNode *) gn, FALSE); 568 (void)Lst_AtEnd (postCommands->commands, cmd); 569 return (0); 570 } 571 572 /*- 573 *----------------------------------------------------------------------- 574 * JobFinish -- 575 * Do final processing for the given job including updating 576 * parents and starting new jobs as available/necessary. Note 577 * that we pay no attention to the JOB_IGNERR flag here. 578 * This is because when we're called because of a noexecute flag 579 * or something, jstat.w_status is 0 and when called from 580 * Job_CatchChildren, the status is zeroed if it s/b ignored. 581 * 582 * Results: 583 * None 584 * 585 * Side Effects: 586 * Some nodes may be put on the toBeMade queue. 587 * Final commands for the job are placed on postCommands. 588 * 589 * If we got an error and are aborting (aborting == ABORT_ERROR) and 590 * the job list is now empty, we are done for the day. 591 * If we recognized an error (errors !=0), we set the aborting flag 592 * to ABORT_ERROR so no more jobs will be started. 593 *----------------------------------------------------------------------- 594 */ 595 /*ARGSUSED*/ 596 static void 597 JobFinish (job, status) 598 Job *job; /* job to finish */ 599 union wait status; /* sub-why job went away */ 600 { 601 Boolean done; 602 603 if ((WIFEXITED(status) && 604 (((status.w_retcode != 0) && !(job->flags & JOB_IGNERR)))) || 605 (WIFSIGNALED(status) && (status.w_termsig != SIGCONT))) 606 { 607 /* 608 * If it exited non-zero and either we're doing things our 609 * way or we're not ignoring errors, the job is finished. 610 * Similarly, if the shell died because of a signal 611 * the job is also finished. In these 612 * cases, finish out the job's output before printing the exit 613 * status... 614 */ 615 if (usePipes) { 616 #ifdef RMT_WILL_WATCH 617 Rmt_Ignore(job->inPipe); 618 #else 619 FD_CLR(job->inPipe, &outputs); 620 #endif /* RMT_WILL_WATCH */ 621 if (job->outPipe != job->inPipe) { 622 (void)close (job->outPipe); 623 } 624 JobDoOutput (job, TRUE); 625 (void)close (job->inPipe); 626 } else { 627 (void)close (job->outFd); 628 JobDoOutput (job, TRUE); 629 } 630 631 if (job->cmdFILE != NULL && job->cmdFILE != stdout) { 632 fclose(job->cmdFILE); 633 } 634 done = TRUE; 635 } else if (WIFEXITED(status) && status.w_retcode != 0) { 636 /* 637 * Deal with ignored errors in -B mode. We need to print a message 638 * telling of the ignored error as well as setting status.w_status 639 * to 0 so the next command gets run. To do this, we set done to be 640 * TRUE if in -B mode and the job exited non-zero. Note we don't 641 * want to close down any of the streams until we know we're at the 642 * end. 643 */ 644 done = TRUE; 645 } else { 646 /* 647 * No need to close things down or anything. 648 */ 649 done = FALSE; 650 } 651 652 if (done || 653 WIFSTOPPED(status) || 654 (WIFSIGNALED(status) && (status.w_termsig == SIGCONT)) || 655 DEBUG(JOB)) 656 { 657 FILE *out; 658 659 if (!usePipes && (job->flags & JOB_IGNERR)) { 660 /* 661 * If output is going to a file and this job is ignoring 662 * errors, arrange to have the exit status sent to the 663 * output file as well. 664 */ 665 out = fdopen (job->outFd, "w"); 666 } else { 667 out = stdout; 668 } 669 670 if (WIFEXITED(status)) { 671 if (status.w_retcode != 0) { 672 if (usePipes && job->node != lastNode) { 673 fprintf (out, targFmt, job->node->name); 674 lastNode = job->node; 675 } 676 fprintf (out, "*** Error code %d%s\n", status.w_retcode, 677 (job->flags & JOB_IGNERR) ? " (ignored)" : ""); 678 679 if (job->flags & JOB_IGNERR) { 680 status.w_status = 0; 681 } 682 } else if (DEBUG(JOB)) { 683 if (usePipes && job->node != lastNode) { 684 fprintf (out, targFmt, job->node->name); 685 lastNode = job->node; 686 } 687 fprintf (out, "*** Completed successfully\n"); 688 } 689 } else if (WIFSTOPPED(status)) { 690 if (usePipes && job->node != lastNode) { 691 fprintf (out, targFmt, job->node->name); 692 lastNode = job->node; 693 } 694 if (! (job->flags & JOB_REMIGRATE)) { 695 fprintf (out, "*** Stopped -- signal %d\n", status.w_stopsig); 696 } 697 job->flags |= JOB_RESUME; 698 (void)Lst_AtEnd(stoppedJobs, (ClientData)job); 699 fflush(out); 700 return; 701 } else if (status.w_termsig == SIGCONT) { 702 /* 703 * If the beastie has continued, shift the Job from the stopped 704 * list to the running one (or re-stop it if concurrency is 705 * exceeded) and go and get another child. 706 */ 707 if (job->flags & (JOB_RESUME|JOB_REMIGRATE|JOB_RESTART)) { 708 if (usePipes && job->node != lastNode) { 709 fprintf (out, targFmt, job->node->name); 710 lastNode = job->node; 711 } 712 fprintf (out, "*** Continued\n"); 713 } 714 if (! (job->flags & JOB_CONTINUING)) { 715 JobRestart(job); 716 } else { 717 Lst_AtEnd(jobs, (ClientData)job); 718 nJobs += 1; 719 if (! (job->flags & JOB_REMOTE)) { 720 nLocal += 1; 721 } 722 if (nJobs == maxJobs) { 723 jobFull = TRUE; 724 if (DEBUG(JOB)) { 725 printf("Job queue is full.\n"); 726 } 727 } 728 } 729 fflush(out); 730 return; 731 } else { 732 if (usePipes && job->node != lastNode) { 733 fprintf (out, targFmt, job->node->name); 734 lastNode = job->node; 735 } 736 fprintf (out, "*** Signal %d\n", status.w_termsig); 737 } 738 739 fflush (out); 740 } 741 742 /* 743 * Now handle the -B-mode stuff. If the beast still isn't finished, 744 * try and restart the job on the next command. If JobStart says it's 745 * ok, it's ok. If there's an error, this puppy is done. 746 */ 747 if ((status.w_status == 0) && 748 !Lst_IsAtEnd (job->node->commands)) 749 { 750 switch (JobStart (job->node, 751 job->flags & JOB_IGNDOTS, 752 job)) 753 { 754 case JOB_RUNNING: 755 done = FALSE; 756 break; 757 case JOB_ERROR: 758 done = TRUE; 759 status.w_retcode = 1; 760 break; 761 case JOB_FINISHED: 762 /* 763 * If we got back a JOB_FINISHED code, JobStart has already 764 * called Make_Update and freed the job descriptor. We set 765 * done to false here to avoid fake cycles and double frees. 766 * JobStart needs to do the update so we can proceed up the 767 * graph when given the -n flag.. 768 */ 769 done = FALSE; 770 break; 771 } 772 } else { 773 done = TRUE; 774 } 775 776 777 if (done && 778 (aborting != ABORT_ERROR) && 779 (aborting != ABORT_INTERRUPT) && 780 (status.w_status == 0)) 781 { 782 /* 783 * As long as we aren't aborting and the job didn't return a non-zero 784 * status that we shouldn't ignore, we call Make_Update to update 785 * the parents. In addition, any saved commands for the node are placed 786 * on the .END target. 787 */ 788 if (job->tailCmds != NILLNODE) { 789 Lst_ForEachFrom (job->node->commands, job->tailCmds, 790 JobSaveCommand, 791 (ClientData)job->node); 792 } 793 job->node->made = MADE; 794 Make_Update (job->node); 795 free((Address)job); 796 } else if (status.w_status) { 797 errors += 1; 798 free((Address)job); 799 } 800 801 while (!errors && !jobFull && !Lst_IsEmpty(stoppedJobs)) { 802 JobRestart((Job *)Lst_DeQueue(stoppedJobs)); 803 } 804 805 /* 806 * Set aborting if any error. 807 */ 808 if (errors && !keepgoing && (aborting != ABORT_INTERRUPT)) { 809 /* 810 * If we found any errors in this batch of children and the -k flag 811 * wasn't given, we set the aborting flag so no more jobs get 812 * started. 813 */ 814 aborting = ABORT_ERROR; 815 } 816 817 if ((aborting == ABORT_ERROR) && Job_Empty()) { 818 /* 819 * If we are aborting and the job table is now empty, we finish. 820 */ 821 (void) unlink (tfile); 822 Finish (errors); 823 } 824 } 825 826 /*- 827 *----------------------------------------------------------------------- 828 * Job_Touch -- 829 * Touch the given target. Called by JobStart when the -t flag was 830 * given 831 * 832 * Results: 833 * None 834 * 835 * Side Effects: 836 * The data modification of the file is changed. In addition, if the 837 * file did not exist, it is created. 838 *----------------------------------------------------------------------- 839 */ 840 void 841 Job_Touch (gn, silent) 842 GNode *gn; /* the node of the file to touch */ 843 Boolean silent; /* TRUE if should not print messages */ 844 { 845 int streamID; /* ID of stream opened to do the touch */ 846 struct timeval times[2]; /* Times for utimes() call */ 847 848 if (gn->type & (OP_JOIN|OP_USE|OP_EXEC|OP_OPTIONAL)) { 849 /* 850 * .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual" targets 851 * and, as such, shouldn't really be created. 852 */ 853 return; 854 } 855 856 if (!silent) { 857 printf ("touch %s\n", gn->name); 858 } 859 860 if (noExecute) { 861 return; 862 } 863 864 if (gn->type & OP_ARCHV) { 865 Arch_Touch (gn); 866 } else if (gn->type & OP_LIB) { 867 Arch_TouchLib (gn); 868 } else { 869 char *file = gn->path ? gn->path : gn->name; 870 871 times[0].tv_sec = times[1].tv_sec = now; 872 times[0].tv_usec = times[1].tv_usec = 0; 873 if (utimes(file, times) < 0){ 874 streamID = open (file, O_RDWR | O_CREAT, 0666); 875 876 if (streamID >= 0) { 877 char c; 878 879 /* 880 * Read and write a byte to the file to change the 881 * modification time, then close the file. 882 */ 883 if (read(streamID, &c, 1) == 1) { 884 lseek(streamID, 0L, L_SET); 885 write(streamID, &c, 1); 886 } 887 888 (void)close (streamID); 889 } else 890 printf("*** couldn't touch %s: %s", file, strerror(errno)); 891 } 892 } 893 } 894 895 /*- 896 *----------------------------------------------------------------------- 897 * Job_CheckCommands -- 898 * Make sure the given node has all the commands it needs. 899 * 900 * Results: 901 * TRUE if the commands list is/was ok. 902 * 903 * Side Effects: 904 * The node will have commands from the .DEFAULT rule added to it 905 * if it needs them. 906 *----------------------------------------------------------------------- 907 */ 908 Boolean 909 Job_CheckCommands (gn, abortProc) 910 GNode *gn; /* The target whose commands need 911 * verifying */ 912 void (*abortProc) __P((char *, ...)); 913 /* Function to abort with message */ 914 { 915 if (OP_NOP(gn->type) && Lst_IsEmpty (gn->commands) && 916 (gn->type & OP_LIB) == 0) { 917 /* 918 * No commands. Look for .DEFAULT rule from which we might infer 919 * commands 920 */ 921 if ((DEFAULT != NILGNODE) && !Lst_IsEmpty(DEFAULT->commands)) { 922 char *p1; 923 /* 924 * Make only looks for a .DEFAULT if the node was never the 925 * target of an operator, so that's what we do too. If 926 * a .DEFAULT was given, we substitute its commands for gn's 927 * commands and set the IMPSRC variable to be the target's name 928 * The DEFAULT node acts like a transformation rule, in that 929 * gn also inherits any attributes or sources attached to 930 * .DEFAULT itself. 931 */ 932 Make_HandleUse(DEFAULT, gn); 933 Var_Set (IMPSRC, Var_Value (TARGET, gn, &p1), gn); 934 if (p1) 935 free(p1); 936 } else if (Dir_MTime (gn) == 0) { 937 /* 938 * The node wasn't the target of an operator we have no .DEFAULT 939 * rule to go on and the target doesn't already exist. There's 940 * nothing more we can do for this branch. If the -k flag wasn't 941 * given, we stop in our tracks, otherwise we just don't update 942 * this node's parents so they never get examined. 943 */ 944 if (gn->type & OP_OPTIONAL) { 945 printf ("make: don't know how to make %s (ignored)\n", 946 gn->name); 947 } else if (keepgoing) { 948 printf ("make: don't know how to make %s (continuing)\n", 949 gn->name); 950 return (FALSE); 951 } else { 952 (*abortProc) ("make: don't know how to make %s. Stop", 953 gn->name); 954 return(FALSE); 955 } 956 } 957 } 958 return (TRUE); 959 } 960 #ifdef RMT_WILL_WATCH 961 /*- 962 *----------------------------------------------------------------------- 963 * JobLocalInput -- 964 * Handle a pipe becoming readable. Callback function for Rmt_Watch 965 * 966 * Results: 967 * None 968 * 969 * Side Effects: 970 * JobDoOutput is called. 971 * 972 *----------------------------------------------------------------------- 973 */ 974 /*ARGSUSED*/ 975 static void 976 JobLocalInput(stream, job) 977 int stream; /* Stream that's ready (ignored) */ 978 Job *job; /* Job to which the stream belongs */ 979 { 980 JobDoOutput(job, FALSE); 981 } 982 #endif /* RMT_WILL_WATCH */ 983 984 /*- 985 *----------------------------------------------------------------------- 986 * JobExec -- 987 * Execute the shell for the given job. Called from JobStart and 988 * JobRestart. 989 * 990 * Results: 991 * None. 992 * 993 * Side Effects: 994 * A shell is executed, outputs is altered and the Job structure added 995 * to the job table. 996 * 997 *----------------------------------------------------------------------- 998 */ 999 static void 1000 JobExec(job, argv) 1001 Job *job; /* Job to execute */ 1002 char **argv; 1003 { 1004 int cpid; /* ID of new child */ 1005 1006 if (DEBUG(JOB)) { 1007 int i; 1008 1009 printf("Running %s %sly\n", job->node->name, 1010 job->flags&JOB_REMOTE?"remote":"local"); 1011 printf("\tCommand: "); 1012 for (i = 0; argv[i] != (char *)NULL; i++) { 1013 printf("%s ", argv[i]); 1014 } 1015 printf("\n"); 1016 } 1017 1018 /* 1019 * Some jobs produce no output and it's disconcerting to have 1020 * no feedback of their running (since they produce no output, the 1021 * banner with their name in it never appears). This is an attempt to 1022 * provide that feedback, even if nothing follows it. 1023 */ 1024 if ((lastNode != job->node) && (job->flags & JOB_FIRST) && 1025 !(job->flags & JOB_SILENT)) 1026 { 1027 printf(targFmt, job->node->name); 1028 lastNode = job->node; 1029 } 1030 1031 #ifdef RMT_NO_EXEC 1032 if (job->flags & JOB_REMOTE) { 1033 goto jobExecFinish; 1034 } 1035 #endif /* RMT_NO_EXEC */ 1036 1037 if ((cpid = vfork()) == -1) { 1038 Punt ("Cannot fork"); 1039 } else if (cpid == 0) { 1040 1041 /* 1042 * Must duplicate the input stream down to the child's input and 1043 * reset it to the beginning (again). Since the stream was marked 1044 * close-on-exec, we must clear that bit in the new input. 1045 */ 1046 (void) dup2(fileno(job->cmdFILE), 0); 1047 fcntl(0, F_SETFD, 0); 1048 lseek(0, 0, L_SET); 1049 1050 if (usePipes) { 1051 /* 1052 * Set up the child's output to be routed through the pipe 1053 * we've created for it. 1054 */ 1055 (void) dup2 (job->outPipe, 1); 1056 } else { 1057 /* 1058 * We're capturing output in a file, so we duplicate the 1059 * descriptor to the temporary file into the standard 1060 * output. 1061 */ 1062 (void) dup2 (job->outFd, 1); 1063 } 1064 /* 1065 * The output channels are marked close on exec. This bit was 1066 * duplicated by the dup2 (on some systems), so we have to clear 1067 * it before routing the shell's error output to the same place as 1068 * its standard output. 1069 */ 1070 fcntl(1, F_SETFD, 0); 1071 (void) dup2 (1, 2); 1072 1073 #ifdef USE_PGRP 1074 /* 1075 * We want to switch the child into a different process family so 1076 * we can kill it and all its descendants in one fell swoop, 1077 * by killing its process family, but not commit suicide. 1078 */ 1079 1080 (void) setpgrp(0, getpid()); 1081 #endif USE_PGRP 1082 1083 (void) execv (shellPath, argv); 1084 (void) write (2, "Could not execute shell\n", 1085 sizeof ("Could not execute shell")); 1086 _exit (1); 1087 } else { 1088 job->pid = cpid; 1089 1090 if (usePipes && (job->flags & JOB_FIRST) ) { 1091 /* 1092 * The first time a job is run for a node, we set the current 1093 * position in the buffer to the beginning and mark another 1094 * stream to watch in the outputs mask 1095 */ 1096 job->curPos = 0; 1097 1098 #ifdef RMT_WILL_WATCH 1099 Rmt_Watch(job->inPipe, JobLocalInput, job); 1100 #else 1101 FD_SET(job->inPipe, &outputs); 1102 #endif /* RMT_WILL_WATCH */ 1103 } 1104 1105 if (job->flags & JOB_REMOTE) { 1106 job->rmtID = 0; 1107 } else { 1108 nLocal += 1; 1109 /* 1110 * XXX: Used to not happen if CUSTOMS. Why? 1111 */ 1112 if (job->cmdFILE != stdout) { 1113 fclose(job->cmdFILE); 1114 job->cmdFILE = NULL; 1115 } 1116 } 1117 } 1118 1119 #ifdef RMT_NO_EXEC 1120 jobExecFinish: 1121 #endif 1122 /* 1123 * Now the job is actually running, add it to the table. 1124 */ 1125 nJobs += 1; 1126 (void)Lst_AtEnd (jobs, (ClientData)job); 1127 if (nJobs == maxJobs) { 1128 jobFull = TRUE; 1129 } 1130 } 1131 1132 /*- 1133 *----------------------------------------------------------------------- 1134 * JobMakeArgv -- 1135 * Create the argv needed to execute the shell for a given job. 1136 * 1137 * 1138 * Results: 1139 * 1140 * Side Effects: 1141 * 1142 *----------------------------------------------------------------------- 1143 */ 1144 static void 1145 JobMakeArgv(job, argv) 1146 Job *job; 1147 char **argv; 1148 { 1149 int argc; 1150 static char args[10]; /* For merged arguments */ 1151 1152 argv[0] = shellName; 1153 argc = 1; 1154 1155 if ((commandShell->exit && (*commandShell->exit != '-')) || 1156 (commandShell->echo && (*commandShell->echo != '-'))) 1157 { 1158 /* 1159 * At least one of the flags doesn't have a minus before it, so 1160 * merge them together. Have to do this because the *(&(@*#*&#$# 1161 * Bourne shell thinks its second argument is a file to source. 1162 * Grrrr. Note the ten-character limitation on the combined arguments. 1163 */ 1164 (void)sprintf(args, "-%s%s", 1165 ((job->flags & JOB_IGNERR) ? "" : 1166 (commandShell->exit ? commandShell->exit : "")), 1167 ((job->flags & JOB_SILENT) ? "" : 1168 (commandShell->echo ? commandShell->echo : ""))); 1169 1170 if (args[1]) { 1171 argv[argc] = args; 1172 argc++; 1173 } 1174 } else { 1175 if (!(job->flags & JOB_IGNERR) && commandShell->exit) { 1176 argv[argc] = commandShell->exit; 1177 argc++; 1178 } 1179 if (!(job->flags & JOB_SILENT) && commandShell->echo) { 1180 argv[argc] = commandShell->echo; 1181 argc++; 1182 } 1183 } 1184 argv[argc] = (char *)NULL; 1185 } 1186 1187 /*- 1188 *----------------------------------------------------------------------- 1189 * JobRestart -- 1190 * Restart a job that stopped for some reason. 1191 * 1192 * Results: 1193 * None. 1194 * 1195 * Side Effects: 1196 * jobFull will be set if the job couldn't be run. 1197 * 1198 *----------------------------------------------------------------------- 1199 */ 1200 static void 1201 JobRestart(job) 1202 Job *job; /* Job to restart */ 1203 { 1204 if (job->flags & JOB_REMIGRATE) { 1205 if (DEBUG(JOB)) { 1206 printf("Remigrating %x\n", job->pid); 1207 } 1208 if (nLocal != maxLocal) { 1209 /* 1210 * Job cannot be remigrated, but there's room on the local 1211 * machine, so resume the job and note that another 1212 * local job has started. 1213 */ 1214 if (DEBUG(JOB)) { 1215 printf("resuming on local machine\n"); 1216 } 1217 KILL(job->pid, SIGCONT); 1218 nLocal +=1; 1219 job->flags &= ~(JOB_REMIGRATE|JOB_RESUME); 1220 } else { 1221 /* 1222 * Job cannot be restarted. Mark the table as full and 1223 * place the job back on the list of stopped jobs. 1224 */ 1225 if (DEBUG(JOB)) { 1226 printf("holding\n"); 1227 } 1228 (void)Lst_AtFront(stoppedJobs, (ClientData)job); 1229 jobFull = TRUE; 1230 if (DEBUG(JOB)) { 1231 printf("Job queue is full.\n"); 1232 } 1233 return; 1234 } 1235 1236 (void)Lst_AtEnd(jobs, (ClientData)job); 1237 nJobs += 1; 1238 if (nJobs == maxJobs) { 1239 jobFull = TRUE; 1240 if (DEBUG(JOB)) { 1241 printf("Job queue is full.\n"); 1242 } 1243 } 1244 } else if (job->flags & JOB_RESTART) { 1245 /* 1246 * Set up the control arguments to the shell. This is based on the 1247 * flags set earlier for this job. If the JOB_IGNERR flag is clear, 1248 * the 'exit' flag of the commandShell is used to cause it to exit 1249 * upon receiving an error. If the JOB_SILENT flag is clear, the 1250 * 'echo' flag of the commandShell is used to get it to start echoing 1251 * as soon as it starts processing commands. 1252 */ 1253 char *argv[4]; 1254 1255 JobMakeArgv(job, argv); 1256 1257 if (DEBUG(JOB)) { 1258 printf("Restarting %s...", job->node->name); 1259 } 1260 if (((nLocal >= maxLocal) && ! (job->flags & JOB_SPECIAL))) { 1261 /* 1262 * Can't be exported and not allowed to run locally -- put it 1263 * back on the hold queue and mark the table full 1264 */ 1265 if (DEBUG(JOB)) { 1266 printf("holding\n"); 1267 } 1268 (void)Lst_AtFront(stoppedJobs, (ClientData)job); 1269 jobFull = TRUE; 1270 if (DEBUG(JOB)) { 1271 printf("Job queue is full.\n"); 1272 } 1273 return; 1274 } else { 1275 /* 1276 * Job may be run locally. 1277 */ 1278 if (DEBUG(JOB)) { 1279 printf("running locally\n"); 1280 } 1281 job->flags &= ~JOB_REMOTE; 1282 } 1283 JobExec(job, argv); 1284 } else { 1285 /* 1286 * The job has stopped and needs to be restarted. Why it stopped, 1287 * we don't know... 1288 */ 1289 if (DEBUG(JOB)) { 1290 printf("Resuming %s...", job->node->name); 1291 } 1292 if (((job->flags & JOB_REMOTE) || 1293 (nLocal < maxLocal) || 1294 (((job->flags & JOB_SPECIAL)) && 1295 (maxLocal == 0))) && 1296 (nJobs != maxJobs)) 1297 { 1298 /* 1299 * If the job is remote, it's ok to resume it as long as the 1300 * maximum concurrency won't be exceeded. If it's local and 1301 * we haven't reached the local concurrency limit already (or the 1302 * job must be run locally and maxLocal is 0), it's also ok to 1303 * resume it. 1304 */ 1305 Boolean error; 1306 extern int errno; 1307 union wait status; 1308 1309 #ifdef RMT_WANTS_SIGNALS 1310 if (job->flags & JOB_REMOTE) { 1311 error = !Rmt_Signal(job, SIGCONT); 1312 } else 1313 #endif /* RMT_WANTS_SIGNALS */ 1314 error = (KILL(job->pid, SIGCONT) != 0); 1315 1316 if (!error) { 1317 /* 1318 * Make sure the user knows we've continued the beast and 1319 * actually put the thing in the job table. 1320 */ 1321 job->flags |= JOB_CONTINUING; 1322 status.w_termsig = SIGCONT; 1323 JobFinish(job, status); 1324 1325 job->flags &= ~(JOB_RESUME|JOB_CONTINUING); 1326 if (DEBUG(JOB)) { 1327 printf("done\n"); 1328 } 1329 } else { 1330 Error("couldn't resume %s: %s", 1331 job->node->name, strerror(errno)); 1332 status.w_status = 0; 1333 status.w_retcode = 1; 1334 JobFinish(job, status); 1335 } 1336 } else { 1337 /* 1338 * Job cannot be restarted. Mark the table as full and 1339 * place the job back on the list of stopped jobs. 1340 */ 1341 if (DEBUG(JOB)) { 1342 printf("table full\n"); 1343 } 1344 (void)Lst_AtFront(stoppedJobs, (ClientData)job); 1345 jobFull = TRUE; 1346 if (DEBUG(JOB)) { 1347 printf("Job queue is full.\n"); 1348 } 1349 } 1350 } 1351 } 1352 1353 /*- 1354 *----------------------------------------------------------------------- 1355 * JobStart -- 1356 * Start a target-creation process going for the target described 1357 * by the graph node gn. 1358 * 1359 * Results: 1360 * JOB_ERROR if there was an error in the commands, JOB_FINISHED 1361 * if there isn't actually anything left to do for the job and 1362 * JOB_RUNNING if the job has been started. 1363 * 1364 * Side Effects: 1365 * A new Job node is created and added to the list of running 1366 * jobs. PMake is forked and a child shell created. 1367 *----------------------------------------------------------------------- 1368 */ 1369 static int 1370 JobStart (gn, flags, previous) 1371 GNode *gn; /* target to create */ 1372 int flags; /* flags for the job to override normal ones. 1373 * e.g. JOB_SPECIAL or JOB_IGNDOTS */ 1374 Job *previous; /* The previous Job structure for this node, 1375 * if any. */ 1376 { 1377 register Job *job; /* new job descriptor */ 1378 char *argv[4]; /* Argument vector to shell */ 1379 static int jobno = 0; /* job number of catching output in a file */ 1380 Boolean cmdsOK; /* true if the nodes commands were all right */ 1381 Boolean local; /* Set true if the job was run locally */ 1382 Boolean noExec; /* Set true if we decide not to run the job */ 1383 1384 if (previous != (Job *)NULL) { 1385 previous->flags &= ~ (JOB_FIRST|JOB_IGNERR|JOB_SILENT|JOB_REMOTE); 1386 job = previous; 1387 } else { 1388 job = (Job *) emalloc (sizeof (Job)); 1389 if (job == (Job *)NULL) { 1390 Punt("JobStart out of memory"); 1391 } 1392 flags |= JOB_FIRST; 1393 } 1394 1395 job->node = gn; 1396 job->tailCmds = NILLNODE; 1397 1398 /* 1399 * Set the initial value of the flags for this job based on the global 1400 * ones and the node's attributes... Any flags supplied by the caller 1401 * are also added to the field. 1402 */ 1403 job->flags = 0; 1404 if (Targ_Ignore (gn)) { 1405 job->flags |= JOB_IGNERR; 1406 } 1407 if (Targ_Silent (gn)) { 1408 job->flags |= JOB_SILENT; 1409 } 1410 job->flags |= flags; 1411 1412 /* 1413 * Check the commands now so any attributes from .DEFAULT have a chance 1414 * to migrate to the node 1415 */ 1416 if (job->flags & JOB_FIRST) { 1417 cmdsOK = Job_CheckCommands(gn, Error); 1418 } else { 1419 cmdsOK = TRUE; 1420 } 1421 1422 /* 1423 * If the -n flag wasn't given, we open up OUR (not the child's) 1424 * temporary file to stuff commands in it. The thing is rd/wr so we don't 1425 * need to reopen it to feed it to the shell. If the -n flag *was* given, 1426 * we just set the file to be stdout. Cute, huh? 1427 */ 1428 if ((gn->type & OP_MAKE) || (!noExecute && !touchFlag)) { 1429 /* 1430 * We're serious here, but if the commands were bogus, we're 1431 * also dead... 1432 */ 1433 if (!cmdsOK) { 1434 DieHorribly(); 1435 } 1436 1437 job->cmdFILE = fopen (tfile, "w+"); 1438 if (job->cmdFILE == (FILE *) NULL) { 1439 Punt ("Could not open %s", tfile); 1440 } 1441 fcntl(fileno(job->cmdFILE), F_SETFD, 1); 1442 /* 1443 * Send the commands to the command file, flush all its buffers then 1444 * rewind and remove the thing. 1445 */ 1446 noExec = FALSE; 1447 1448 /* 1449 * used to be backwards; replace when start doing multiple commands 1450 * per shell. 1451 */ 1452 if (compatMake) { 1453 /* 1454 * Be compatible: If this is the first time for this node, 1455 * verify its commands are ok and open the commands list for 1456 * sequential access by later invocations of JobStart. 1457 * Once that is done, we take the next command off the list 1458 * and print it to the command file. If the command was an 1459 * ellipsis, note that there's nothing more to execute. 1460 */ 1461 if ((job->flags&JOB_FIRST) && (Lst_Open(gn->commands) != SUCCESS)){ 1462 cmdsOK = FALSE; 1463 } else { 1464 LstNode ln = Lst_Next (gn->commands); 1465 1466 if ((ln == NILLNODE) || 1467 JobPrintCommand ((char *)Lst_Datum (ln), job)) 1468 { 1469 noExec = TRUE; 1470 Lst_Close (gn->commands); 1471 } 1472 if (noExec && !(job->flags & JOB_FIRST)) { 1473 /* 1474 * If we're not going to execute anything, the job 1475 * is done and we need to close down the various 1476 * file descriptors we've opened for output, then 1477 * call JobDoOutput to catch the final characters or 1478 * send the file to the screen... Note that the i/o streams 1479 * are only open if this isn't the first job. 1480 * Note also that this could not be done in 1481 * Job_CatchChildren b/c it wasn't clear if there were 1482 * more commands to execute or not... 1483 */ 1484 if (usePipes) { 1485 #ifdef RMT_WILL_WATCH 1486 Rmt_Ignore(job->inPipe); 1487 #else 1488 FD_CLR(job->inPipe, &outputs); 1489 #endif 1490 if (job->outPipe != job->inPipe) { 1491 (void)close (job->outPipe); 1492 } 1493 JobDoOutput (job, TRUE); 1494 (void)close (job->inPipe); 1495 } else { 1496 (void)close (job->outFd); 1497 JobDoOutput (job, TRUE); 1498 } 1499 } 1500 } 1501 } else { 1502 /* 1503 * We can do all the commands at once. hooray for sanity 1504 */ 1505 numCommands = 0; 1506 Lst_ForEach (gn->commands, JobPrintCommand, (ClientData)job); 1507 1508 /* 1509 * If we didn't print out any commands to the shell script, 1510 * there's not much point in executing the shell, is there? 1511 */ 1512 if (numCommands == 0) { 1513 noExec = TRUE; 1514 } 1515 } 1516 } else if (noExecute) { 1517 /* 1518 * Not executing anything -- just print all the commands to stdout 1519 * in one fell swoop. This will still set up job->tailCmds correctly. 1520 */ 1521 if (lastNode != gn) { 1522 printf (targFmt, gn->name); 1523 lastNode = gn; 1524 } 1525 job->cmdFILE = stdout; 1526 /* 1527 * Only print the commands if they're ok, but don't die if they're 1528 * not -- just let the user know they're bad and keep going. It 1529 * doesn't do any harm in this case and may do some good. 1530 */ 1531 if (cmdsOK) { 1532 Lst_ForEach(gn->commands, JobPrintCommand, (ClientData)job); 1533 } 1534 /* 1535 * Don't execute the shell, thank you. 1536 */ 1537 noExec = TRUE; 1538 } else { 1539 /* 1540 * Just touch the target and note that no shell should be executed. 1541 * Set cmdFILE to stdout to make life easier. Check the commands, too, 1542 * but don't die if they're no good -- it does no harm to keep working 1543 * up the graph. 1544 */ 1545 job->cmdFILE = stdout; 1546 Job_Touch (gn, job->flags&JOB_SILENT); 1547 noExec = TRUE; 1548 } 1549 1550 /* 1551 * If we're not supposed to execute a shell, don't. 1552 */ 1553 if (noExec) { 1554 /* 1555 * Unlink and close the command file if we opened one 1556 */ 1557 if (job->cmdFILE != stdout) { 1558 (void) unlink (tfile); 1559 fclose(job->cmdFILE); 1560 } else { 1561 fflush (stdout); 1562 } 1563 1564 /* 1565 * We only want to work our way up the graph if we aren't here because 1566 * the commands for the job were no good. 1567 */ 1568 if (cmdsOK) { 1569 if (aborting == 0) { 1570 if (job->tailCmds != NILLNODE) { 1571 Lst_ForEachFrom(job->node->commands, job->tailCmds, 1572 JobSaveCommand, 1573 (ClientData)job->node); 1574 } 1575 Make_Update(job->node); 1576 } 1577 free((Address)job); 1578 return(JOB_FINISHED); 1579 } else { 1580 free((Address)job); 1581 return(JOB_ERROR); 1582 } 1583 } else { 1584 fflush (job->cmdFILE); 1585 (void) unlink (tfile); 1586 } 1587 1588 /* 1589 * Set up the control arguments to the shell. This is based on the flags 1590 * set earlier for this job. 1591 */ 1592 JobMakeArgv(job, argv); 1593 1594 /* 1595 * If we're using pipes to catch output, create the pipe by which we'll 1596 * get the shell's output. If we're using files, print out that we're 1597 * starting a job and then set up its temporary-file name. This is just 1598 * tfile with two extra digits tacked on -- jobno. 1599 */ 1600 if (job->flags & JOB_FIRST) { 1601 if (usePipes) { 1602 int fd[2]; 1603 (void) pipe(fd); 1604 job->inPipe = fd[0]; 1605 job->outPipe = fd[1]; 1606 (void)fcntl (job->inPipe, F_SETFD, 1); 1607 (void)fcntl (job->outPipe, F_SETFD, 1); 1608 } else { 1609 printf ("Remaking `%s'\n", gn->name); 1610 fflush (stdout); 1611 sprintf (job->outFile, "%s%02d", tfile, jobno); 1612 jobno = (jobno + 1) % 100; 1613 job->outFd = open(job->outFile,O_WRONLY|O_CREAT|O_APPEND,0600); 1614 (void)fcntl (job->outFd, F_SETFD, 1); 1615 } 1616 } 1617 1618 local = TRUE; 1619 1620 if (local && (((nLocal >= maxLocal) && 1621 !(job->flags & JOB_SPECIAL) && 1622 (maxLocal != 0)))) 1623 { 1624 /* 1625 * The job can only be run locally, but we've hit the limit of 1626 * local concurrency, so put the job on hold until some other job 1627 * finishes. Note that the special jobs (.BEGIN, .INTERRUPT and .END) 1628 * may be run locally even when the local limit has been reached 1629 * (e.g. when maxLocal == 0), though they will be exported if at 1630 * all possible. 1631 */ 1632 jobFull = TRUE; 1633 1634 if (DEBUG(JOB)) { 1635 printf("Can only run job locally.\n"); 1636 } 1637 job->flags |= JOB_RESTART; 1638 (void)Lst_AtEnd(stoppedJobs, (ClientData)job); 1639 } else { 1640 if ((nLocal >= maxLocal) && local) { 1641 /* 1642 * If we're running this job locally as a special case (see above), 1643 * at least say the table is full. 1644 */ 1645 jobFull = TRUE; 1646 if (DEBUG(JOB)) { 1647 printf("Local job queue is full.\n"); 1648 } 1649 } 1650 JobExec(job, argv); 1651 } 1652 return(JOB_RUNNING); 1653 } 1654 1655 /*- 1656 *----------------------------------------------------------------------- 1657 * JobDoOutput -- 1658 * This function is called at different times depending on 1659 * whether the user has specified that output is to be collected 1660 * via pipes or temporary files. In the former case, we are called 1661 * whenever there is something to read on the pipe. We collect more 1662 * output from the given job and store it in the job's outBuf. If 1663 * this makes up a line, we print it tagged by the job's identifier, 1664 * as necessary. 1665 * If output has been collected in a temporary file, we open the 1666 * file and read it line by line, transfering it to our own 1667 * output channel until the file is empty. At which point we 1668 * remove the temporary file. 1669 * In both cases, however, we keep our figurative eye out for the 1670 * 'noPrint' line for the shell from which the output came. If 1671 * we recognize a line, we don't print it. If the command is not 1672 * alone on the line (the character after it is not \0 or \n), we 1673 * do print whatever follows it. 1674 * 1675 * Results: 1676 * None 1677 * 1678 * Side Effects: 1679 * curPos may be shifted as may the contents of outBuf. 1680 *----------------------------------------------------------------------- 1681 */ 1682 static void 1683 JobDoOutput (job, finish) 1684 register Job *job; /* the job whose output needs printing */ 1685 Boolean finish; /* TRUE if this is the last time we'll be 1686 * called for this job */ 1687 { 1688 Boolean gotNL = FALSE; /* true if got a newline */ 1689 register int nr; /* number of bytes read */ 1690 register int i; /* auxiliary index into outBuf */ 1691 register int max; /* limit for i (end of current data) */ 1692 int nRead; /* (Temporary) number of bytes read */ 1693 1694 FILE *oFILE; /* Stream pointer to shell's output file */ 1695 char inLine[132]; 1696 1697 1698 if (usePipes) { 1699 /* 1700 * Read as many bytes as will fit in the buffer. 1701 */ 1702 end_loop: 1703 1704 nRead = read (job->inPipe, &job->outBuf[job->curPos], 1705 JOB_BUFSIZE - job->curPos); 1706 if (nRead < 0) { 1707 if (DEBUG(JOB)) { 1708 perror("JobDoOutput(piperead)"); 1709 } 1710 nr = 0; 1711 } else { 1712 nr = nRead; 1713 } 1714 1715 /* 1716 * If we hit the end-of-file (the job is dead), we must flush its 1717 * remaining output, so pretend we read a newline if there's any 1718 * output remaining in the buffer. 1719 * Also clear the 'finish' flag so we stop looping. 1720 */ 1721 if ((nr == 0) && (job->curPos != 0)) { 1722 job->outBuf[job->curPos] = '\n'; 1723 nr = 1; 1724 finish = FALSE; 1725 } else if (nr == 0) { 1726 finish = FALSE; 1727 } 1728 1729 /* 1730 * Look for the last newline in the bytes we just got. If there is 1731 * one, break out of the loop with 'i' as its index and gotNL set 1732 * TRUE. 1733 */ 1734 max = job->curPos + nr; 1735 for (i = job->curPos + nr - 1; i >= job->curPos; i--) { 1736 if (job->outBuf[i] == '\n') { 1737 gotNL = TRUE; 1738 break; 1739 } else if (job->outBuf[i] == '\0') { 1740 /* 1741 * Why? 1742 */ 1743 job->outBuf[i] = ' '; 1744 } 1745 } 1746 1747 if (!gotNL) { 1748 job->curPos += nr; 1749 if (job->curPos == JOB_BUFSIZE) { 1750 /* 1751 * If we've run out of buffer space, we have no choice 1752 * but to print the stuff. sigh. 1753 */ 1754 gotNL = TRUE; 1755 i = job->curPos; 1756 } 1757 } 1758 if (gotNL) { 1759 /* 1760 * Need to send the output to the screen. Null terminate it 1761 * first, overwriting the newline character if there was one. 1762 * So long as the line isn't one we should filter (according 1763 * to the shell description), we print the line, preceeded 1764 * by a target banner if this target isn't the same as the 1765 * one for which we last printed something. 1766 * The rest of the data in the buffer are then shifted down 1767 * to the start of the buffer and curPos is set accordingly. 1768 */ 1769 job->outBuf[i] = '\0'; 1770 if (i >= job->curPos) { 1771 register char *cp, *ecp; 1772 1773 cp = job->outBuf; 1774 if (commandShell->noPrint) { 1775 ecp = Str_FindSubstring(job->outBuf, 1776 commandShell->noPrint); 1777 while (ecp != (char *)NULL) { 1778 if (cp != ecp) { 1779 *ecp = '\0'; 1780 if (job->node != lastNode) { 1781 printf (targFmt, job->node->name); 1782 lastNode = job->node; 1783 } 1784 /* 1785 * The only way there wouldn't be a newline after 1786 * this line is if it were the last in the buffer. 1787 * however, since the non-printable comes after it, 1788 * there must be a newline, so we don't print one. 1789 */ 1790 printf ("%s", cp); 1791 } 1792 cp = ecp + commandShell->noPLen; 1793 if (cp != &job->outBuf[i]) { 1794 /* 1795 * Still more to print, look again after skipping 1796 * the whitespace following the non-printable 1797 * command.... 1798 */ 1799 cp++; 1800 while (*cp == ' ' || *cp == '\t' || *cp == '\n') { 1801 cp++; 1802 } 1803 ecp = Str_FindSubstring (cp, 1804 commandShell->noPrint); 1805 } else { 1806 break; 1807 } 1808 } 1809 } 1810 1811 /* 1812 * There's still more in that thar buffer. This time, though, 1813 * we know there's no newline at the end, so we add one of 1814 * our own free will. 1815 */ 1816 if (*cp != '\0') { 1817 if (job->node != lastNode) { 1818 printf (targFmt, job->node->name); 1819 lastNode = job->node; 1820 } 1821 printf ("%s\n", cp); 1822 } 1823 1824 fflush (stdout); 1825 } 1826 if (i < max - 1) { 1827 /* shift the remaining characters down */ 1828 memcpy ( job->outBuf, &job->outBuf[i + 1], max - (i + 1)); 1829 job->curPos = max - (i + 1); 1830 1831 } else { 1832 /* 1833 * We have written everything out, so we just start over 1834 * from the start of the buffer. No copying. No nothing. 1835 */ 1836 job->curPos = 0; 1837 } 1838 } 1839 if (finish) { 1840 /* 1841 * If the finish flag is true, we must loop until we hit 1842 * end-of-file on the pipe. This is guaranteed to happen eventually 1843 * since the other end of the pipe is now closed (we closed it 1844 * explicitly and the child has exited). When we do get an EOF, 1845 * finish will be set FALSE and we'll fall through and out. 1846 */ 1847 goto end_loop; 1848 } 1849 } else { 1850 /* 1851 * We've been called to retrieve the output of the job from the 1852 * temporary file where it's been squirreled away. This consists of 1853 * opening the file, reading the output line by line, being sure not 1854 * to print the noPrint line for the shell we used, then close and 1855 * remove the temporary file. Very simple. 1856 * 1857 * Change to read in blocks and do FindSubString type things as for 1858 * pipes? That would allow for "@echo -n..." 1859 */ 1860 oFILE = fopen (job->outFile, "r"); 1861 if (oFILE != (FILE *) NULL) { 1862 printf ("Results of making %s:\n", job->node->name); 1863 while (fgets (inLine, sizeof(inLine), oFILE) != NULL) { 1864 register char *cp, *ecp, *endp; 1865 1866 cp = inLine; 1867 endp = inLine + strlen(inLine); 1868 if (endp[-1] == '\n') { 1869 *--endp = '\0'; 1870 } 1871 if (commandShell->noPrint) { 1872 ecp = Str_FindSubstring(cp, commandShell->noPrint); 1873 while (ecp != (char *)NULL) { 1874 if (cp != ecp) { 1875 *ecp = '\0'; 1876 /* 1877 * The only way there wouldn't be a newline after 1878 * this line is if it were the last in the buffer. 1879 * however, since the non-printable comes after it, 1880 * there must be a newline, so we don't print one. 1881 */ 1882 printf ("%s", cp); 1883 } 1884 cp = ecp + commandShell->noPLen; 1885 if (cp != endp) { 1886 /* 1887 * Still more to print, look again after skipping 1888 * the whitespace following the non-printable 1889 * command.... 1890 */ 1891 cp++; 1892 while (*cp == ' ' || *cp == '\t' || *cp == '\n') { 1893 cp++; 1894 } 1895 ecp = Str_FindSubstring(cp, commandShell->noPrint); 1896 } else { 1897 break; 1898 } 1899 } 1900 } 1901 1902 /* 1903 * There's still more in that thar buffer. This time, though, 1904 * we know there's no newline at the end, so we add one of 1905 * our own free will. 1906 */ 1907 if (*cp != '\0') { 1908 printf ("%s\n", cp); 1909 } 1910 } 1911 fclose (oFILE); 1912 (void) unlink (job->outFile); 1913 } 1914 } 1915 fflush(stdout); 1916 } 1917 1918 /*- 1919 *----------------------------------------------------------------------- 1920 * Job_CatchChildren -- 1921 * Handle the exit of a child. Called from Make_Make. 1922 * 1923 * Results: 1924 * none. 1925 * 1926 * Side Effects: 1927 * The job descriptor is removed from the list of children. 1928 * 1929 * Notes: 1930 * We do waits, blocking or not, according to the wisdom of our 1931 * caller, until there are no more children to report. For each 1932 * job, call JobFinish to finish things off. This will take care of 1933 * putting jobs on the stoppedJobs queue. 1934 * 1935 *----------------------------------------------------------------------- 1936 */ 1937 void 1938 Job_CatchChildren (block) 1939 Boolean block; /* TRUE if should block on the wait. */ 1940 { 1941 int pid; /* pid of dead child */ 1942 register Job *job; /* job descriptor for dead child */ 1943 LstNode jnode; /* list element for finding job */ 1944 union wait status; /* Exit/termination status */ 1945 1946 /* 1947 * Don't even bother if we know there's no one around. 1948 */ 1949 if (nLocal == 0) { 1950 return; 1951 } 1952 1953 while ((pid = wait3((int *)&status, (block?0:WNOHANG)|WUNTRACED, 1954 (struct rusage *)0)) > 0) 1955 { 1956 if (DEBUG(JOB)) 1957 printf("Process %d exited or stopped.\n", pid); 1958 1959 1960 jnode = Lst_Find (jobs, (ClientData)&pid, JobCmpPid); 1961 1962 if (jnode == NILLNODE) { 1963 if (WIFSIGNALED(status) && (status.w_termsig == SIGCONT)) { 1964 jnode = Lst_Find(stoppedJobs, (ClientData) &pid, JobCmpPid); 1965 if (jnode == NILLNODE) { 1966 Error("Resumed child (%d) not in table", pid); 1967 continue; 1968 } 1969 job = (Job *)Lst_Datum(jnode); 1970 (void)Lst_Remove(stoppedJobs, jnode); 1971 } else { 1972 Error ("Child (%d) not in table?", pid); 1973 continue; 1974 } 1975 } else { 1976 job = (Job *) Lst_Datum (jnode); 1977 (void)Lst_Remove (jobs, jnode); 1978 nJobs -= 1; 1979 if (jobFull && DEBUG(JOB)) { 1980 printf("Job queue is no longer full.\n"); 1981 } 1982 jobFull = FALSE; 1983 nLocal -= 1; 1984 } 1985 1986 JobFinish (job, status); 1987 } 1988 } 1989 1990 /*- 1991 *----------------------------------------------------------------------- 1992 * Job_CatchOutput -- 1993 * Catch the output from our children, if we're using 1994 * pipes do so. Otherwise just block time until we get a 1995 * signal (most likely a SIGCHLD) since there's no point in 1996 * just spinning when there's nothing to do and the reaping 1997 * of a child can wait for a while. 1998 * 1999 * Results: 2000 * None 2001 * 2002 * Side Effects: 2003 * Output is read from pipes if we're piping. 2004 * ----------------------------------------------------------------------- 2005 */ 2006 void 2007 Job_CatchOutput () 2008 { 2009 int nfds; 2010 struct timeval timeout; 2011 fd_set readfds; 2012 register LstNode ln; 2013 register Job *job; 2014 #ifdef RMT_WILL_WATCH 2015 int pnJobs; /* Previous nJobs */ 2016 #endif 2017 2018 fflush(stdout); 2019 #ifdef RMT_WILL_WATCH 2020 pnJobs = nJobs; 2021 2022 /* 2023 * It is possible for us to be called with nJobs equal to 0. This happens 2024 * if all the jobs finish and a job that is stopped cannot be run 2025 * locally (eg if maxLocal is 0) and cannot be exported. The job will 2026 * be placed back on the stoppedJobs queue, Job_Empty() will return false, 2027 * Make_Run will call us again when there's nothing for which to wait. 2028 * nJobs never changes, so we loop forever. Hence the check. It could 2029 * be argued that we should sleep for a bit so as not to swamp the 2030 * exportation system with requests. Perhaps we should. 2031 * 2032 * NOTE: IT IS THE RESPONSIBILITY OF Rmt_Wait TO CALL Job_CatchChildren 2033 * IN A TIMELY FASHION TO CATCH ANY LOCALLY RUNNING JOBS THAT EXIT. 2034 * It may use the variable nLocal to determine if it needs to call 2035 * Job_CatchChildren (if nLocal is 0, there's nothing for which to 2036 * wait...) 2037 */ 2038 while (nJobs != 0 && pnJobs == nJobs) { 2039 Rmt_Wait(); 2040 } 2041 #else 2042 if (usePipes) { 2043 readfds = outputs; 2044 timeout.tv_sec = SEL_SEC; 2045 timeout.tv_usec = SEL_USEC; 2046 2047 if ((nfds = select (FD_SETSIZE, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout)) < 0) 2048 { 2049 return; 2050 } else { 2051 if (Lst_Open (jobs) == FAILURE) { 2052 Punt ("Cannot open job table"); 2053 } 2054 while (nfds && (ln = Lst_Next (jobs)) != NILLNODE) { 2055 job = (Job *) Lst_Datum (ln); 2056 if (FD_ISSET(job->inPipe, &readfds)) { 2057 JobDoOutput (job, FALSE); 2058 nfds -= 1; 2059 } 2060 } 2061 Lst_Close (jobs); 2062 } 2063 } 2064 #endif /* RMT_WILL_WATCH */ 2065 } 2066 2067 /*- 2068 *----------------------------------------------------------------------- 2069 * Job_Make -- 2070 * Start the creation of a target. Basically a front-end for 2071 * JobStart used by the Make module. 2072 * 2073 * Results: 2074 * None. 2075 * 2076 * Side Effects: 2077 * Another job is started. 2078 * 2079 *----------------------------------------------------------------------- 2080 */ 2081 void 2082 Job_Make (gn) 2083 GNode *gn; 2084 { 2085 (void)JobStart (gn, 0, (Job *)NULL); 2086 } 2087 2088 /*- 2089 *----------------------------------------------------------------------- 2090 * Job_Init -- 2091 * Initialize the process module 2092 * 2093 * Results: 2094 * none 2095 * 2096 * Side Effects: 2097 * lists and counters are initialized 2098 *----------------------------------------------------------------------- 2099 */ 2100 void 2101 Job_Init (maxproc, maxlocal) 2102 int maxproc; /* the greatest number of jobs which may be 2103 * running at one time */ 2104 int maxlocal; /* the greatest number of local jobs which may 2105 * be running at once. */ 2106 { 2107 GNode *begin; /* node for commands to do at the very start */ 2108 2109 sprintf (tfile, "/tmp/make%05d", getpid()); 2110 2111 jobs = Lst_Init (FALSE); 2112 stoppedJobs = Lst_Init(FALSE); 2113 maxJobs = maxproc; 2114 maxLocal = maxlocal; 2115 nJobs = 0; 2116 nLocal = 0; 2117 jobFull = FALSE; 2118 2119 aborting = 0; 2120 errors = 0; 2121 2122 lastNode = NILGNODE; 2123 2124 if (maxJobs == 1) { 2125 /* 2126 * If only one job can run at a time, there's no need for a banner, 2127 * no is there? 2128 */ 2129 targFmt = ""; 2130 } else { 2131 targFmt = TARG_FMT; 2132 } 2133 2134 if (shellPath == (char *) NULL) { 2135 /* 2136 * The user didn't specify a shell to use, so we are using the 2137 * default one... Both the absolute path and the last component 2138 * must be set. The last component is taken from the 'name' field 2139 * of the default shell description pointed-to by commandShell. 2140 * All default shells are located in _PATH_DEFSHELLDIR. 2141 */ 2142 shellName = commandShell->name; 2143 shellPath = str_concat (_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH); 2144 } 2145 2146 if (commandShell->exit == (char *)NULL) { 2147 commandShell->exit = ""; 2148 } 2149 if (commandShell->echo == (char *)NULL) { 2150 commandShell->echo = ""; 2151 } 2152 2153 /* 2154 * Catch the four signals that POSIX specifies if they aren't ignored. 2155 * JobPassSig will take care of calling JobInterrupt if appropriate. 2156 */ 2157 if (signal (SIGINT, SIG_IGN) != SIG_IGN) { 2158 signal (SIGINT, JobPassSig); 2159 } 2160 if (signal (SIGHUP, SIG_IGN) != SIG_IGN) { 2161 signal (SIGHUP, JobPassSig); 2162 } 2163 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN) { 2164 signal (SIGQUIT, JobPassSig); 2165 } 2166 if (signal (SIGTERM, SIG_IGN) != SIG_IGN) { 2167 signal (SIGTERM, JobPassSig); 2168 } 2169 /* 2170 * There are additional signals that need to be caught and passed if 2171 * either the export system wants to be told directly of signals or if 2172 * we're giving each job its own process group (since then it won't get 2173 * signals from the terminal driver as we own the terminal) 2174 */ 2175 #if defined(RMT_WANTS_SIGNALS) || defined(USE_PGRP) 2176 if (signal (SIGTSTP, SIG_IGN) != SIG_IGN) { 2177 signal (SIGTSTP, JobPassSig); 2178 } 2179 if (signal (SIGTTOU, SIG_IGN) != SIG_IGN) { 2180 signal (SIGTTOU, JobPassSig); 2181 } 2182 if (signal (SIGTTIN, SIG_IGN) != SIG_IGN) { 2183 signal (SIGTTIN, JobPassSig); 2184 } 2185 if (signal (SIGWINCH, SIG_IGN) != SIG_IGN) { 2186 signal (SIGWINCH, JobPassSig); 2187 } 2188 #endif 2189 2190 begin = Targ_FindNode (".BEGIN", TARG_NOCREATE); 2191 2192 if (begin != NILGNODE) { 2193 JobStart (begin, JOB_SPECIAL, (Job *)0); 2194 while (nJobs) { 2195 Job_CatchOutput(); 2196 #ifndef RMT_WILL_WATCH 2197 Job_CatchChildren (!usePipes); 2198 #endif /* RMT_WILL_WATCH */ 2199 } 2200 } 2201 postCommands = Targ_FindNode (".END", TARG_CREATE); 2202 } 2203 2204 /*- 2205 *----------------------------------------------------------------------- 2206 * Job_Full -- 2207 * See if the job table is full. It is considered full if it is OR 2208 * if we are in the process of aborting OR if we have 2209 * reached/exceeded our local quota. This prevents any more jobs 2210 * from starting up. 2211 * 2212 * Results: 2213 * TRUE if the job table is full, FALSE otherwise 2214 * Side Effects: 2215 * None. 2216 *----------------------------------------------------------------------- 2217 */ 2218 Boolean 2219 Job_Full () 2220 { 2221 return (aborting || jobFull); 2222 } 2223 2224 /*- 2225 *----------------------------------------------------------------------- 2226 * Job_Empty -- 2227 * See if the job table is empty. Because the local concurrency may 2228 * be set to 0, it is possible for the job table to become empty, 2229 * while the list of stoppedJobs remains non-empty. In such a case, 2230 * we want to restart as many jobs as we can. 2231 * 2232 * Results: 2233 * TRUE if it is. FALSE if it ain't. 2234 * 2235 * Side Effects: 2236 * None. 2237 * 2238 * ----------------------------------------------------------------------- 2239 */ 2240 Boolean 2241 Job_Empty () 2242 { 2243 if (nJobs == 0) { 2244 if (!Lst_IsEmpty(stoppedJobs) && !aborting) { 2245 /* 2246 * The job table is obviously not full if it has no jobs in 2247 * it...Try and restart the stopped jobs. 2248 */ 2249 jobFull = FALSE; 2250 while (!jobFull && !Lst_IsEmpty(stoppedJobs)) { 2251 JobRestart((Job *)Lst_DeQueue(stoppedJobs)); 2252 } 2253 return(FALSE); 2254 } else { 2255 return(TRUE); 2256 } 2257 } else { 2258 return(FALSE); 2259 } 2260 } 2261 2262 /*- 2263 *----------------------------------------------------------------------- 2264 * JobMatchShell -- 2265 * Find a matching shell in 'shells' given its final component. 2266 * 2267 * Results: 2268 * A pointer to the Shell structure. 2269 * 2270 * Side Effects: 2271 * None. 2272 * 2273 *----------------------------------------------------------------------- 2274 */ 2275 static Shell * 2276 JobMatchShell (name) 2277 char *name; /* Final component of shell path */ 2278 { 2279 register Shell *sh; /* Pointer into shells table */ 2280 Shell *match; /* Longest-matching shell */ 2281 register char *cp1, 2282 *cp2; 2283 char *eoname; 2284 2285 eoname = name + strlen (name); 2286 2287 match = (Shell *) NULL; 2288 2289 for (sh = shells; sh->name != NULL; sh++) { 2290 for (cp1 = eoname - strlen (sh->name), cp2 = sh->name; 2291 *cp1 != '\0' && *cp1 == *cp2; 2292 cp1++, cp2++) { 2293 continue; 2294 } 2295 if (*cp1 != *cp2) { 2296 continue; 2297 } else if (match == (Shell *) NULL || 2298 strlen (match->name) < strlen (sh->name)) { 2299 match = sh; 2300 } 2301 } 2302 return (match == (Shell *) NULL ? sh : match); 2303 } 2304 2305 /*- 2306 *----------------------------------------------------------------------- 2307 * Job_ParseShell -- 2308 * Parse a shell specification and set up commandShell, shellPath 2309 * and shellName appropriately. 2310 * 2311 * Results: 2312 * FAILURE if the specification was incorrect. 2313 * 2314 * Side Effects: 2315 * commandShell points to a Shell structure (either predefined or 2316 * created from the shell spec), shellPath is the full path of the 2317 * shell described by commandShell, while shellName is just the 2318 * final component of shellPath. 2319 * 2320 * Notes: 2321 * A shell specification consists of a .SHELL target, with dependency 2322 * operator, followed by a series of blank-separated words. Double 2323 * quotes can be used to use blanks in words. A backslash escapes 2324 * anything (most notably a double-quote and a space) and 2325 * provides the functionality it does in C. Each word consists of 2326 * keyword and value separated by an equal sign. There should be no 2327 * unnecessary spaces in the word. The keywords are as follows: 2328 * name Name of shell. 2329 * path Location of shell. Overrides "name" if given 2330 * quiet Command to turn off echoing. 2331 * echo Command to turn echoing on 2332 * filter Result of turning off echoing that shouldn't be 2333 * printed. 2334 * echoFlag Flag to turn echoing on at the start 2335 * errFlag Flag to turn error checking on at the start 2336 * hasErrCtl True if shell has error checking control 2337 * check Command to turn on error checking if hasErrCtl 2338 * is TRUE or template of command to echo a command 2339 * for which error checking is off if hasErrCtl is 2340 * FALSE. 2341 * ignore Command to turn off error checking if hasErrCtl 2342 * is TRUE or template of command to execute a 2343 * command so as to ignore any errors it returns if 2344 * hasErrCtl is FALSE. 2345 * 2346 *----------------------------------------------------------------------- 2347 */ 2348 ReturnStatus 2349 Job_ParseShell (line) 2350 char *line; /* The shell spec */ 2351 { 2352 char **words; 2353 int wordCount; 2354 register char **argv; 2355 register int argc; 2356 char *path; 2357 Shell newShell; 2358 Boolean fullSpec = FALSE; 2359 2360 while (isspace (*line)) { 2361 line++; 2362 } 2363 words = brk_string (line, &wordCount, TRUE); 2364 2365 memset ((Address)&newShell, 0, sizeof(newShell)); 2366 2367 /* 2368 * Parse the specification by keyword 2369 */ 2370 for (path = (char *)NULL, argc = wordCount - 1, argv = words + 1; 2371 argc != 0; 2372 argc--, argv++) { 2373 if (strncmp (*argv, "path=", 5) == 0) { 2374 path = &argv[0][5]; 2375 } else if (strncmp (*argv, "name=", 5) == 0) { 2376 newShell.name = &argv[0][5]; 2377 } else { 2378 if (strncmp (*argv, "quiet=", 6) == 0) { 2379 newShell.echoOff = &argv[0][6]; 2380 } else if (strncmp (*argv, "echo=", 5) == 0) { 2381 newShell.echoOn = &argv[0][5]; 2382 } else if (strncmp (*argv, "filter=", 7) == 0) { 2383 newShell.noPrint = &argv[0][7]; 2384 newShell.noPLen = strlen(newShell.noPrint); 2385 } else if (strncmp (*argv, "echoFlag=", 9) == 0) { 2386 newShell.echo = &argv[0][9]; 2387 } else if (strncmp (*argv, "errFlag=", 8) == 0) { 2388 newShell.exit = &argv[0][8]; 2389 } else if (strncmp (*argv, "hasErrCtl=", 10) == 0) { 2390 char c = argv[0][10]; 2391 newShell.hasErrCtl = !((c != 'Y') && (c != 'y') && 2392 (c != 'T') && (c != 't')); 2393 } else if (strncmp (*argv, "check=", 6) == 0) { 2394 newShell.errCheck = &argv[0][6]; 2395 } else if (strncmp (*argv, "ignore=", 7) == 0) { 2396 newShell.ignErr = &argv[0][7]; 2397 } else { 2398 Parse_Error (PARSE_FATAL, "Unknown keyword \"%s\"", 2399 *argv); 2400 return (FAILURE); 2401 } 2402 fullSpec = TRUE; 2403 } 2404 } 2405 2406 if (path == (char *)NULL) { 2407 /* 2408 * If no path was given, the user wants one of the pre-defined shells, 2409 * yes? So we find the one s/he wants with the help of JobMatchShell 2410 * and set things up the right way. shellPath will be set up by 2411 * Job_Init. 2412 */ 2413 if (newShell.name == (char *)NULL) { 2414 Parse_Error (PARSE_FATAL, "Neither path nor name specified"); 2415 return (FAILURE); 2416 } else { 2417 commandShell = JobMatchShell (newShell.name); 2418 shellName = newShell.name; 2419 } 2420 } else { 2421 /* 2422 * The user provided a path. If s/he gave nothing else (fullSpec is 2423 * FALSE), try and find a matching shell in the ones we know of. 2424 * Else we just take the specification at its word and copy it 2425 * to a new location. In either case, we need to record the 2426 * path the user gave for the shell. 2427 */ 2428 shellPath = path; 2429 path = strrchr (path, '/'); 2430 if (path == (char *)NULL) { 2431 path = shellPath; 2432 } else { 2433 path += 1; 2434 } 2435 if (newShell.name != (char *)NULL) { 2436 shellName = newShell.name; 2437 } else { 2438 shellName = path; 2439 } 2440 if (!fullSpec) { 2441 commandShell = JobMatchShell (shellName); 2442 } else { 2443 commandShell = (Shell *) emalloc(sizeof(Shell)); 2444 *commandShell = newShell; 2445 } 2446 } 2447 2448 if (commandShell->echoOn && commandShell->echoOff) { 2449 commandShell->hasEchoCtl = TRUE; 2450 } 2451 2452 if (!commandShell->hasErrCtl) { 2453 if (commandShell->errCheck == (char *)NULL) { 2454 commandShell->errCheck = ""; 2455 } 2456 if (commandShell->ignErr == (char *)NULL) { 2457 commandShell->ignErr = "%s\n"; 2458 } 2459 } 2460 2461 /* 2462 * Do not free up the words themselves, since they might be in use by the 2463 * shell specification... 2464 */ 2465 free (words); 2466 return SUCCESS; 2467 } 2468 2469 /*- 2470 *----------------------------------------------------------------------- 2471 * JobInterrupt -- 2472 * Handle the receipt of an interrupt. 2473 * 2474 * Results: 2475 * None 2476 * 2477 * Side Effects: 2478 * All children are killed. Another job will be started if the 2479 * .INTERRUPT target was given. 2480 *----------------------------------------------------------------------- 2481 */ 2482 static void 2483 JobInterrupt (runINTERRUPT) 2484 int runINTERRUPT; /* Non-zero if commands for the .INTERRUPT 2485 * target should be executed */ 2486 { 2487 LstNode ln; /* element in job table */ 2488 Job *job; /* job descriptor in that element */ 2489 GNode *interrupt; /* the node describing the .INTERRUPT target */ 2490 2491 aborting = ABORT_INTERRUPT; 2492 2493 (void)Lst_Open (jobs); 2494 while ((ln = Lst_Next (jobs)) != NILLNODE) { 2495 job = (Job *) Lst_Datum (ln); 2496 2497 if (!Targ_Precious (job->node)) { 2498 char *file = (job->node->path == (char *)NULL ? 2499 job->node->name : 2500 job->node->path); 2501 struct stat st; 2502 if (!noExecute && lstat(file, &st) != -1 && !S_ISDIR(st.st_mode) && 2503 unlink(file) != -1) { 2504 Error ("*** %s removed", file); 2505 } 2506 } 2507 #ifdef RMT_WANTS_SIGNALS 2508 if (job->flags & JOB_REMOTE) { 2509 /* 2510 * If job is remote, let the Rmt module do the killing. 2511 */ 2512 if (!Rmt_Signal(job, SIGINT)) { 2513 /* 2514 * If couldn't kill the thing, finish it out now with an 2515 * error code, since no exit report will come in likely. 2516 */ 2517 union wait status; 2518 2519 status.w_status = 0; 2520 status.w_retcode = 1; 2521 JobFinish(job, status); 2522 } 2523 } else if (job->pid) { 2524 KILL(job->pid, SIGINT); 2525 } 2526 #else 2527 if (job->pid) { 2528 KILL(job->pid, SIGINT); 2529 } 2530 #endif /* RMT_WANTS_SIGNALS */ 2531 } 2532 Lst_Close (jobs); 2533 2534 if (runINTERRUPT && !touchFlag) { 2535 interrupt = Targ_FindNode (".INTERRUPT", TARG_NOCREATE); 2536 if (interrupt != NILGNODE) { 2537 ignoreErrors = FALSE; 2538 2539 JobStart (interrupt, JOB_IGNDOTS, (Job *)0); 2540 while (nJobs) { 2541 Job_CatchOutput(); 2542 #ifndef RMT_WILL_WATCH 2543 Job_CatchChildren (!usePipes); 2544 #endif /* RMT_WILL_WATCH */ 2545 } 2546 } 2547 } 2548 (void) unlink (tfile); 2549 exit (0); 2550 } 2551 2552 /* 2553 *----------------------------------------------------------------------- 2554 * Job_End -- 2555 * Do final processing such as the running of the commands 2556 * attached to the .END target. 2557 * 2558 * Results: 2559 * Number of errors reported. 2560 * 2561 * Side Effects: 2562 * The process' temporary file (tfile) is removed if it still 2563 * existed. 2564 *----------------------------------------------------------------------- 2565 */ 2566 int 2567 Job_End () 2568 { 2569 if (postCommands != NILGNODE && !Lst_IsEmpty (postCommands->commands)) { 2570 if (errors) { 2571 Error ("Errors reported so .END ignored"); 2572 } else { 2573 JobStart (postCommands, JOB_SPECIAL | JOB_IGNDOTS, 2574 (Job *)0); 2575 2576 while (nJobs) { 2577 Job_CatchOutput(); 2578 #ifndef RMT_WILL_WATCH 2579 Job_CatchChildren (!usePipes); 2580 #endif /* RMT_WILL_WATCH */ 2581 } 2582 } 2583 } 2584 (void) unlink (tfile); 2585 return(errors); 2586 } 2587 2588 /*- 2589 *----------------------------------------------------------------------- 2590 * Job_Wait -- 2591 * Waits for all running jobs to finish and returns. Sets 'aborting' 2592 * to ABORT_WAIT to prevent other jobs from starting. 2593 * 2594 * Results: 2595 * None. 2596 * 2597 * Side Effects: 2598 * Currently running jobs finish. 2599 * 2600 *----------------------------------------------------------------------- 2601 */ 2602 void 2603 Job_Wait() 2604 { 2605 aborting = ABORT_WAIT; 2606 while (nJobs != 0) { 2607 Job_CatchOutput(); 2608 #ifndef RMT_WILL_WATCH 2609 Job_CatchChildren(!usePipes); 2610 #endif /* RMT_WILL_WATCH */ 2611 } 2612 aborting = 0; 2613 } 2614 2615 /*- 2616 *----------------------------------------------------------------------- 2617 * Job_AbortAll -- 2618 * Abort all currently running jobs without handling output or anything. 2619 * This function is to be called only in the event of a major 2620 * error. Most definitely NOT to be called from JobInterrupt. 2621 * 2622 * Results: 2623 * None 2624 * 2625 * Side Effects: 2626 * All children are killed, not just the firstborn 2627 *----------------------------------------------------------------------- 2628 */ 2629 void 2630 Job_AbortAll () 2631 { 2632 LstNode ln; /* element in job table */ 2633 Job *job; /* the job descriptor in that element */ 2634 int foo; 2635 2636 aborting = ABORT_ERROR; 2637 2638 if (nJobs) { 2639 2640 (void)Lst_Open (jobs); 2641 while ((ln = Lst_Next (jobs)) != NILLNODE) { 2642 job = (Job *) Lst_Datum (ln); 2643 2644 /* 2645 * kill the child process with increasingly drastic signals to make 2646 * darn sure it's dead. 2647 */ 2648 #ifdef RMT_WANTS_SIGNALS 2649 if (job->flags & JOB_REMOTE) { 2650 Rmt_Signal(job, SIGINT); 2651 Rmt_Signal(job, SIGKILL); 2652 } else { 2653 KILL(job->pid, SIGINT); 2654 KILL(job->pid, SIGKILL); 2655 } 2656 #else 2657 KILL(job->pid, SIGINT); 2658 KILL(job->pid, SIGKILL); 2659 #endif /* RMT_WANTS_SIGNALS */ 2660 } 2661 } 2662 2663 /* 2664 * Catch as many children as want to report in at first, then give up 2665 */ 2666 while (wait3(&foo, WNOHANG, (struct rusage *)0) > 0) 2667 continue; 2668 (void) unlink (tfile); 2669 } 2670