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