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