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