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