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