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