1 /* $NetBSD: job.c,v 1.76 2003/04/08 17:46:59 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 5 * Copyright (c) 1988, 1989 by Adam de Boor 6 * Copyright (c) 1989 by Berkeley Softworks 7 * All rights reserved. 8 * 9 * This code is derived from software contributed to Berkeley by 10 * Adam de Boor. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the University of 23 * California, Berkeley and its contributors. 24 * 4. Neither the name of the University nor the names of its contributors 25 * may be used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 */ 40 41 #ifdef MAKE_BOOTSTRAP 42 static char rcsid[] = "$NetBSD: job.c,v 1.76 2003/04/08 17:46:59 christos 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.76 2003/04/08 17:46:59 christos 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 || Lst_IsEmpty(gn->children))) { 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 sigemptyset(&mask); 1375 JobSigUnlock(&mask); 1376 1377 /* 1378 * Must duplicate the input stream down to the child's input and 1379 * reset it to the beginning (again). Since the stream was marked 1380 * close-on-exec, we must clear that bit in the new input. 1381 */ 1382 if (dup2(FILENO(job->cmdFILE), 0) == -1) { 1383 execError("dup2", "job->cmdFILE"); 1384 _exit(1); 1385 } 1386 (void) fcntl(0, F_SETFD, 0); 1387 (void) lseek(0, (off_t)0, SEEK_SET); 1388 1389 if (job->node->type & OP_MAKE) { 1390 /* 1391 * Pass job token pipe to submakes. 1392 */ 1393 fcntl(job_pipe[0], F_SETFD, 0); 1394 fcntl(job_pipe[1], F_SETFD, 0); 1395 } 1396 1397 if (usePipes) { 1398 /* 1399 * Set up the child's output to be routed through the pipe 1400 * we've created for it. 1401 */ 1402 if (dup2(job->outPipe, 1) == -1) { 1403 execError("dup2", "job->outPipe"); 1404 _exit(1); 1405 } 1406 } else { 1407 /* 1408 * We're capturing output in a file, so we duplicate the 1409 * descriptor to the temporary file into the standard 1410 * output. 1411 */ 1412 if (dup2(job->outFd, 1) == -1) { 1413 execError("dup2", "job->outFd"); 1414 _exit(1); 1415 } 1416 } 1417 /* 1418 * The output channels are marked close on exec. This bit was 1419 * duplicated by the dup2 (on some systems), so we have to clear 1420 * it before routing the shell's error output to the same place as 1421 * its standard output. 1422 */ 1423 (void) fcntl(1, F_SETFD, 0); 1424 if (dup2(1, 2) == -1) { 1425 execError("dup2", "1, 2"); 1426 _exit(1); 1427 } 1428 1429 #ifdef USE_PGRP 1430 /* 1431 * We want to switch the child into a different process family so 1432 * we can kill it and all its descendants in one fell swoop, 1433 * by killing its process family, but not commit suicide. 1434 */ 1435 # if defined(SYSV) 1436 (void) setsid(); 1437 # else 1438 (void) setpgid(0, getpid()); 1439 # endif 1440 #endif /* USE_PGRP */ 1441 1442 #ifdef REMOTE 1443 if (job->flags & JOB_REMOTE) { 1444 Rmt_Exec(shellPath, argv, FALSE); 1445 } else 1446 #endif /* REMOTE */ 1447 { 1448 (void) execv(shellPath, argv); 1449 execError("exec", shellPath); 1450 } 1451 _exit(1); 1452 } else { 1453 job->pid = cpid; 1454 1455 Trace_Log(JOBSTART, job); 1456 1457 if (usePipes && (job->flags & JOB_FIRST)) { 1458 /* 1459 * The first time a job is run for a node, we set the current 1460 * position in the buffer to the beginning and mark another 1461 * stream to watch in the outputs mask 1462 */ 1463 job->curPos = 0; 1464 1465 #ifdef RMT_WILL_WATCH 1466 Rmt_Watch(job->inPipe, JobLocalInput, job); 1467 #else 1468 watchfd(job); 1469 #endif /* RMT_WILL_WATCH */ 1470 } 1471 1472 if (job->flags & JOB_REMOTE) { 1473 #ifndef REMOTE 1474 job->rmtID = 0; 1475 #else 1476 job->rmtID = Rmt_LastID(job->pid); 1477 #endif /* REMOTE */ 1478 } else { 1479 nLocal += 1; 1480 /* 1481 * XXX: Used to not happen if REMOTE. Why? 1482 */ 1483 if (job->cmdFILE != NULL && job->cmdFILE != stdout) { 1484 (void) fclose(job->cmdFILE); 1485 job->cmdFILE = NULL; 1486 } 1487 } 1488 } 1489 1490 #ifdef RMT_NO_EXEC 1491 jobExecFinish: 1492 #endif 1493 /* 1494 * Now the job is actually running, add it to the table. 1495 */ 1496 if (DEBUG(JOB)) { 1497 printf("JobExec(%s): pid %d added to jobs table\n", 1498 job->node->name, job->pid); 1499 } 1500 nJobs += 1; 1501 (void) Lst_AtEnd(jobs, (ClientData)job); 1502 JobSigUnlock(&mask); 1503 } 1504 1505 /*- 1506 *----------------------------------------------------------------------- 1507 * JobMakeArgv -- 1508 * Create the argv needed to execute the shell for a given job. 1509 * 1510 * 1511 * Results: 1512 * 1513 * Side Effects: 1514 * 1515 *----------------------------------------------------------------------- 1516 */ 1517 static void 1518 JobMakeArgv(Job *job, char **argv) 1519 { 1520 int argc; 1521 static char args[10]; /* For merged arguments */ 1522 1523 argv[0] = shellName; 1524 argc = 1; 1525 1526 if ((commandShell->exit && (*commandShell->exit != '-')) || 1527 (commandShell->echo && (*commandShell->echo != '-'))) 1528 { 1529 /* 1530 * At least one of the flags doesn't have a minus before it, so 1531 * merge them together. Have to do this because the *(&(@*#*&#$# 1532 * Bourne shell thinks its second argument is a file to source. 1533 * Grrrr. Note the ten-character limitation on the combined arguments. 1534 */ 1535 (void)snprintf(args, sizeof(args), "-%s%s", 1536 ((job->flags & JOB_IGNERR) ? "" : 1537 (commandShell->exit ? commandShell->exit : "")), 1538 ((job->flags & JOB_SILENT) ? "" : 1539 (commandShell->echo ? commandShell->echo : ""))); 1540 1541 if (args[1]) { 1542 argv[argc] = args; 1543 argc++; 1544 } 1545 } else { 1546 if (!(job->flags & JOB_IGNERR) && commandShell->exit) { 1547 argv[argc] = commandShell->exit; 1548 argc++; 1549 } 1550 if (!(job->flags & JOB_SILENT) && commandShell->echo) { 1551 argv[argc] = commandShell->echo; 1552 argc++; 1553 } 1554 } 1555 argv[argc] = NULL; 1556 } 1557 1558 /*- 1559 *----------------------------------------------------------------------- 1560 * JobRestart -- 1561 * Restart a job that stopped for some reason. 1562 * 1563 * Input: 1564 * job Job to restart 1565 * 1566 * Results: 1567 * 1 if max number of running jobs has been reached, 0 otherwise. 1568 * 1569 *----------------------------------------------------------------------- 1570 */ 1571 static int 1572 JobRestart(Job *job) 1573 { 1574 #ifdef REMOTE 1575 int host; 1576 #endif 1577 1578 if (job->flags & JOB_REMIGRATE) { 1579 if ( 1580 #ifdef REMOTE 1581 verboseRemigrates || 1582 #endif 1583 DEBUG(JOB)) { 1584 (void) fprintf(stdout, "*** remigrating %x(%s)\n", 1585 job->pid, job->node->name); 1586 (void) fflush(stdout); 1587 } 1588 1589 #ifdef REMOTE 1590 if (!Rmt_ReExport(job->pid, job->node, &host)) { 1591 if (verboseRemigrates || DEBUG(JOB)) { 1592 (void) fprintf(stdout, "*** couldn't migrate...\n"); 1593 (void) fflush(stdout); 1594 } 1595 #endif 1596 if (nLocal != maxLocal) { 1597 /* 1598 * Job cannot be remigrated, but there's room on the local 1599 * machine, so resume the job and note that another 1600 * local job has started. 1601 */ 1602 if ( 1603 #ifdef REMOTE 1604 verboseRemigrates || 1605 #endif 1606 DEBUG(JOB)) { 1607 (void) fprintf(stdout, "*** resuming on local machine\n"); 1608 (void) fflush(stdout); 1609 } 1610 KILL(job->pid, SIGCONT); 1611 nLocal +=1; 1612 #ifdef REMOTE 1613 job->flags &= ~(JOB_REMIGRATE|JOB_RESUME|JOB_REMOTE); 1614 job->flags |= JOB_CONTINUING; 1615 #else 1616 job->flags &= ~(JOB_REMIGRATE|JOB_RESUME); 1617 #endif 1618 } else { 1619 /* 1620 * Job cannot be restarted. Mark the table as full and 1621 * place the job back on the list of stopped jobs. 1622 */ 1623 if ( 1624 #ifdef REMOTE 1625 verboseRemigrates || 1626 #endif 1627 DEBUG(JOB)) { 1628 (void) fprintf(stdout, "*** holding\n"); 1629 (void) fflush(stdout); 1630 } 1631 (void)Lst_AtFront(stoppedJobs, (ClientData)job); 1632 return 1; 1633 } 1634 #ifdef REMOTE 1635 } else { 1636 /* 1637 * Clear out the remigrate and resume flags. Set the continuing 1638 * flag so we know later on that the process isn't exiting just 1639 * because of a signal. 1640 */ 1641 job->flags &= ~(JOB_REMIGRATE|JOB_RESUME); 1642 job->flags |= JOB_CONTINUING; 1643 job->rmtID = host; 1644 } 1645 #endif 1646 1647 (void)Lst_AtEnd(jobs, (ClientData)job); 1648 nJobs += 1; 1649 } else if (job->flags & JOB_RESTART) { 1650 /* 1651 * Set up the control arguments to the shell. This is based on the 1652 * flags set earlier for this job. If the JOB_IGNERR flag is clear, 1653 * the 'exit' flag of the commandShell is used to cause it to exit 1654 * upon receiving an error. If the JOB_SILENT flag is clear, the 1655 * 'echo' flag of the commandShell is used to get it to start echoing 1656 * as soon as it starts processing commands. 1657 */ 1658 char *argv[10]; 1659 1660 JobMakeArgv(job, argv); 1661 1662 if (DEBUG(JOB)) { 1663 (void) fprintf(stdout, "Restarting %s...", job->node->name); 1664 (void) fflush(stdout); 1665 } 1666 #ifdef REMOTE 1667 if ((job->node->type & OP_NOEXPORT) || 1668 (nLocal < maxLocal && runLocalFirst) 1669 # ifdef RMT_NO_EXEC 1670 || !Rmt_Export(shellPath, argv, job) 1671 # else 1672 || !Rmt_Begin(shellPath, argv, job->node) 1673 # endif 1674 ) 1675 #endif 1676 { 1677 if (((nLocal >= maxLocal) && !(job->flags & JOB_SPECIAL))) { 1678 /* 1679 * Can't be exported and not allowed to run locally -- put it 1680 * back on the hold queue and mark the table full 1681 */ 1682 if (DEBUG(JOB)) { 1683 (void) fprintf(stdout, "holding\n"); 1684 (void) fflush(stdout); 1685 } 1686 (void)Lst_AtFront(stoppedJobs, (ClientData)job); 1687 return 1; 1688 } else { 1689 /* 1690 * Job may be run locally. 1691 */ 1692 if (DEBUG(JOB)) { 1693 (void) fprintf(stdout, "running locally\n"); 1694 (void) fflush(stdout); 1695 } 1696 job->flags &= ~JOB_REMOTE; 1697 } 1698 } 1699 #ifdef REMOTE 1700 else { 1701 /* 1702 * Can be exported. Hooray! 1703 */ 1704 if (DEBUG(JOB)) { 1705 (void) fprintf(stdout, "exporting\n"); 1706 (void) fflush(stdout); 1707 } 1708 job->flags |= JOB_REMOTE; 1709 } 1710 #endif 1711 JobExec(job, argv); 1712 } else { 1713 /* 1714 * The job has stopped and needs to be restarted. Why it stopped, 1715 * we don't know... 1716 */ 1717 if (DEBUG(JOB)) { 1718 (void) fprintf(stdout, "Resuming %s...", job->node->name); 1719 (void) fflush(stdout); 1720 } 1721 if ((nJobs != maxJobs) && 1722 ((job->flags & JOB_REMOTE) || 1723 (nLocal < maxLocal) || 1724 ((maxLocal == 0) && 1725 ((job->flags & JOB_SPECIAL) 1726 #ifdef REMOTE 1727 && (job->node->type & OP_NOEXPORT) 1728 #endif 1729 )))) 1730 { 1731 /* 1732 * If the job is remote, it's ok to resume it as long as the 1733 * maximum concurrency won't be exceeded. If it's local and 1734 * we haven't reached the local concurrency limit already (or the 1735 * job must be run locally and maxLocal is 0), it's also ok to 1736 * resume it. 1737 */ 1738 Boolean error; 1739 int status; 1740 1741 #ifdef RMT_WANTS_SIGNALS 1742 if (job->flags & JOB_REMOTE) { 1743 error = !Rmt_Signal(job, SIGCONT); 1744 } else 1745 #endif /* RMT_WANTS_SIGNALS */ 1746 error = (KILL(job->pid, SIGCONT) != 0); 1747 1748 if (!error) { 1749 /* 1750 * Make sure the user knows we've continued the beast and 1751 * actually put the thing in the job table. 1752 */ 1753 job->flags |= JOB_CONTINUING; 1754 status = W_STOPCODE(SIGCONT); 1755 JobFinish(job, &status); 1756 1757 job->flags &= ~(JOB_RESUME|JOB_CONTINUING); 1758 if (DEBUG(JOB)) { 1759 (void) fprintf(stdout, "done\n"); 1760 (void) fflush(stdout); 1761 } 1762 } else { 1763 Error("couldn't resume %s: %s", 1764 job->node->name, strerror(errno)); 1765 status = W_EXITCODE(1, 0); 1766 JobFinish(job, &status); 1767 } 1768 } else { 1769 /* 1770 * Job cannot be restarted. Mark the table as full and 1771 * place the job back on the list of stopped jobs. 1772 */ 1773 if (DEBUG(JOB)) { 1774 (void) fprintf(stdout, "table full\n"); 1775 (void) fflush(stdout); 1776 } 1777 (void) Lst_AtFront(stoppedJobs, (ClientData)job); 1778 return 1; 1779 } 1780 } 1781 return 0; 1782 } 1783 1784 /*- 1785 *----------------------------------------------------------------------- 1786 * JobStart -- 1787 * Start a target-creation process going for the target described 1788 * by the graph node gn. 1789 * 1790 * Input: 1791 * gn target to create 1792 * flags flags for the job to override normal ones. 1793 * e.g. JOB_SPECIAL or JOB_IGNDOTS 1794 * previous The previous Job structure for this node, if any. 1795 * 1796 * Results: 1797 * JOB_ERROR if there was an error in the commands, JOB_FINISHED 1798 * if there isn't actually anything left to do for the job and 1799 * JOB_RUNNING if the job has been started. 1800 * 1801 * Side Effects: 1802 * A new Job node is created and added to the list of running 1803 * jobs. PMake is forked and a child shell created. 1804 *----------------------------------------------------------------------- 1805 */ 1806 static int 1807 JobStart(GNode *gn, int flags, Job *previous) 1808 { 1809 Job *job; /* new job descriptor */ 1810 char *argv[10]; /* Argument vector to shell */ 1811 Boolean cmdsOK; /* true if the nodes commands were all right */ 1812 Boolean local; /* Set true if the job was run locally */ 1813 Boolean noExec; /* Set true if we decide not to run the job */ 1814 int tfd; /* File descriptor to the temp file */ 1815 1816 if (previous != NULL) { 1817 previous->flags &= ~(JOB_FIRST|JOB_IGNERR|JOB_SILENT|JOB_REMOTE); 1818 job = previous; 1819 } else { 1820 job = (Job *) emalloc(sizeof(Job)); 1821 if (job == NULL) { 1822 Punt("JobStart out of memory"); 1823 } 1824 flags |= JOB_FIRST; 1825 } 1826 1827 job->node = gn; 1828 job->tailCmds = NILLNODE; 1829 1830 /* 1831 * Set the initial value of the flags for this job based on the global 1832 * ones and the node's attributes... Any flags supplied by the caller 1833 * are also added to the field. 1834 */ 1835 job->flags = 0; 1836 if (Targ_Ignore(gn)) { 1837 job->flags |= JOB_IGNERR; 1838 } 1839 if (Targ_Silent(gn)) { 1840 job->flags |= JOB_SILENT; 1841 } 1842 job->flags |= flags; 1843 1844 /* 1845 * Check the commands now so any attributes from .DEFAULT have a chance 1846 * to migrate to the node 1847 */ 1848 if (!compatMake && job->flags & JOB_FIRST) { 1849 cmdsOK = Job_CheckCommands(gn, Error); 1850 } else { 1851 cmdsOK = TRUE; 1852 } 1853 1854 #ifndef RMT_WILL_WATCH 1855 job->inPollfd = NULL; 1856 #endif 1857 /* 1858 * If the -n flag wasn't given, we open up OUR (not the child's) 1859 * temporary file to stuff commands in it. The thing is rd/wr so we don't 1860 * need to reopen it to feed it to the shell. If the -n flag *was* given, 1861 * we just set the file to be stdout. Cute, huh? 1862 */ 1863 if (((gn->type & OP_MAKE) && !(noRecursiveExecute)) || 1864 (!noExecute && !touchFlag)) { 1865 /* 1866 * tfile is the name of a file into which all shell commands are 1867 * put. It is used over by removing it before the child shell is 1868 * executed. The XXXXXX in the string are replaced by the pid of 1869 * the make process in a 6-character field with leading zeroes. 1870 */ 1871 char tfile[sizeof(TMPPAT)]; 1872 sigset_t mask; 1873 /* 1874 * We're serious here, but if the commands were bogus, we're 1875 * also dead... 1876 */ 1877 if (!cmdsOK) { 1878 DieHorribly(); 1879 } 1880 1881 JobSigLock(&mask); 1882 (void)strcpy(tfile, TMPPAT); 1883 if ((tfd = mkstemp(tfile)) == -1) 1884 Punt("Could not create temporary file %s", strerror(errno)); 1885 (void) eunlink(tfile); 1886 JobSigUnlock(&mask); 1887 1888 job->cmdFILE = fdopen(tfd, "w+"); 1889 if (job->cmdFILE == NULL) { 1890 Punt("Could not fdopen %s", tfile); 1891 } 1892 (void) fcntl(FILENO(job->cmdFILE), F_SETFD, 1); 1893 /* 1894 * Send the commands to the command file, flush all its buffers then 1895 * rewind and remove the thing. 1896 */ 1897 noExec = FALSE; 1898 1899 /* 1900 * used to be backwards; replace when start doing multiple commands 1901 * per shell. 1902 */ 1903 if (compatMake) { 1904 /* 1905 * Be compatible: If this is the first time for this node, 1906 * verify its commands are ok and open the commands list for 1907 * sequential access by later invocations of JobStart. 1908 * Once that is done, we take the next command off the list 1909 * and print it to the command file. If the command was an 1910 * ellipsis, note that there's nothing more to execute. 1911 */ 1912 if ((job->flags&JOB_FIRST) && (Lst_Open(gn->commands) != SUCCESS)){ 1913 cmdsOK = FALSE; 1914 } else { 1915 LstNode ln = Lst_Next(gn->commands); 1916 1917 if ((ln == NILLNODE) || 1918 JobPrintCommand((ClientData) Lst_Datum(ln), 1919 (ClientData) job)) 1920 { 1921 noExec = TRUE; 1922 Lst_Close(gn->commands); 1923 } 1924 if (noExec && !(job->flags & JOB_FIRST)) { 1925 /* 1926 * If we're not going to execute anything, the job 1927 * is done and we need to close down the various 1928 * file descriptors we've opened for output, then 1929 * call JobDoOutput to catch the final characters or 1930 * send the file to the screen... Note that the i/o streams 1931 * are only open if this isn't the first job. 1932 * Note also that this could not be done in 1933 * Job_CatchChildren b/c it wasn't clear if there were 1934 * more commands to execute or not... 1935 */ 1936 JobClose(job); 1937 } 1938 } 1939 } else { 1940 /* 1941 * We can do all the commands at once. hooray for sanity 1942 */ 1943 numCommands = 0; 1944 Lst_ForEach(gn->commands, JobPrintCommand, (ClientData)job); 1945 1946 /* 1947 * If we didn't print out any commands to the shell script, 1948 * there's not much point in executing the shell, is there? 1949 */ 1950 if (numCommands == 0) { 1951 noExec = TRUE; 1952 } 1953 } 1954 } else if (NoExecute(gn)) { 1955 /* 1956 * Not executing anything -- just print all the commands to stdout 1957 * in one fell swoop. This will still set up job->tailCmds correctly. 1958 */ 1959 if (lastNode != gn) { 1960 MESSAGE(stdout, gn); 1961 lastNode = gn; 1962 } 1963 job->cmdFILE = stdout; 1964 /* 1965 * Only print the commands if they're ok, but don't die if they're 1966 * not -- just let the user know they're bad and keep going. It 1967 * doesn't do any harm in this case and may do some good. 1968 */ 1969 if (cmdsOK) { 1970 Lst_ForEach(gn->commands, JobPrintCommand, (ClientData)job); 1971 } 1972 /* 1973 * Don't execute the shell, thank you. 1974 */ 1975 noExec = TRUE; 1976 } else { 1977 /* 1978 * Just touch the target and note that no shell should be executed. 1979 * Set cmdFILE to stdout to make life easier. Check the commands, too, 1980 * but don't die if they're no good -- it does no harm to keep working 1981 * up the graph. 1982 */ 1983 job->cmdFILE = stdout; 1984 Job_Touch(gn, job->flags&JOB_SILENT); 1985 noExec = TRUE; 1986 } 1987 1988 /* 1989 * If we're not supposed to execute a shell, don't. 1990 */ 1991 if (noExec) { 1992 /* 1993 * Unlink and close the command file if we opened one 1994 */ 1995 if (job->cmdFILE != stdout) { 1996 if (job->cmdFILE != NULL) { 1997 (void) fclose(job->cmdFILE); 1998 job->cmdFILE = NULL; 1999 } 2000 } else { 2001 (void) fflush(stdout); 2002 } 2003 2004 /* 2005 * We only want to work our way up the graph if we aren't here because 2006 * the commands for the job were no good. 2007 */ 2008 if (cmdsOK) { 2009 if (aborting == 0) { 2010 if (job->tailCmds != NILLNODE) { 2011 Lst_ForEachFrom(job->node->commands, job->tailCmds, 2012 JobSaveCommand, 2013 (ClientData)job->node); 2014 } 2015 if (!(job->flags & JOB_SPECIAL)) 2016 Job_TokenReturn(); 2017 job->node->made = MADE; 2018 Make_Update(job->node); 2019 } 2020 free((Address)job); 2021 return(JOB_FINISHED); 2022 } else { 2023 free((Address)job); 2024 return(JOB_ERROR); 2025 } 2026 } else { 2027 (void) fflush(job->cmdFILE); 2028 } 2029 2030 /* 2031 * Set up the control arguments to the shell. This is based on the flags 2032 * set earlier for this job. 2033 */ 2034 JobMakeArgv(job, argv); 2035 2036 /* 2037 * If we're using pipes to catch output, create the pipe by which we'll 2038 * get the shell's output. If we're using files, print out that we're 2039 * starting a job and then set up its temporary-file name. 2040 */ 2041 if (!compatMake || (job->flags & JOB_FIRST)) { 2042 if (usePipes) { 2043 int fd[2]; 2044 if (pipe(fd) == -1) 2045 Punt("Cannot create pipe: %s", strerror(errno)); 2046 job->inPipe = fd[0]; 2047 job->outPipe = fd[1]; 2048 (void) fcntl(job->inPipe, F_SETFD, 1); 2049 (void) fcntl(job->outPipe, F_SETFD, 1); 2050 } else { 2051 (void) fprintf(stdout, "Remaking `%s'\n", gn->name); 2052 (void) fflush(stdout); 2053 (void) strcpy(job->outFile, TMPPAT); 2054 job->outFd = mkstemp(job->outFile); 2055 (void) fcntl(job->outFd, F_SETFD, 1); 2056 } 2057 } 2058 2059 #ifdef REMOTE 2060 if (!(gn->type & OP_NOEXPORT) && !(runLocalFirst && nLocal < maxLocal)) { 2061 #ifdef RMT_NO_EXEC 2062 local = !Rmt_Export(shellPath, argv, job); 2063 #else 2064 local = !Rmt_Begin(shellPath, argv, job->node); 2065 #endif /* RMT_NO_EXEC */ 2066 if (!local) { 2067 job->flags |= JOB_REMOTE; 2068 } 2069 } else 2070 #endif 2071 local = TRUE; 2072 2073 if (local && (((nLocal >= maxLocal) && 2074 !(job->flags & JOB_SPECIAL) && 2075 #ifdef REMOTE 2076 (!(gn->type & OP_NOEXPORT) || (maxLocal != 0)) 2077 #else 2078 (maxLocal != 0) 2079 #endif 2080 ))) 2081 { 2082 /* 2083 * The job can only be run locally, but we've hit the limit of 2084 * local concurrency, so put the job on hold until some other job 2085 * finishes. Note that the special jobs (.BEGIN, .INTERRUPT and .END) 2086 * may be run locally even when the local limit has been reached 2087 * (e.g. when maxLocal == 0), though they will be exported if at 2088 * all possible. In addition, any target marked with .NOEXPORT will 2089 * be run locally if maxLocal is 0. 2090 */ 2091 job->flags |= JOB_RESTART; 2092 (void) Lst_AtEnd(stoppedJobs, (ClientData)job); 2093 } else { 2094 JobExec(job, argv); 2095 } 2096 return(JOB_RUNNING); 2097 } 2098 2099 static char * 2100 JobOutput(Job *job, char *cp, char *endp, int msg) 2101 { 2102 char *ecp; 2103 2104 if (commandShell->noPrint) { 2105 ecp = Str_FindSubstring(cp, commandShell->noPrint); 2106 while (ecp != NULL) { 2107 if (cp != ecp) { 2108 *ecp = '\0'; 2109 if (msg && job->node != lastNode) { 2110 MESSAGE(stdout, job->node); 2111 lastNode = job->node; 2112 } 2113 /* 2114 * The only way there wouldn't be a newline after 2115 * this line is if it were the last in the buffer. 2116 * however, since the non-printable comes after it, 2117 * there must be a newline, so we don't print one. 2118 */ 2119 (void) fprintf(stdout, "%s", cp); 2120 (void) fflush(stdout); 2121 } 2122 cp = ecp + commandShell->noPLen; 2123 if (cp != endp) { 2124 /* 2125 * Still more to print, look again after skipping 2126 * the whitespace following the non-printable 2127 * command.... 2128 */ 2129 cp++; 2130 while (*cp == ' ' || *cp == '\t' || *cp == '\n') { 2131 cp++; 2132 } 2133 ecp = Str_FindSubstring(cp, commandShell->noPrint); 2134 } else { 2135 return cp; 2136 } 2137 } 2138 } 2139 return cp; 2140 } 2141 2142 /*- 2143 *----------------------------------------------------------------------- 2144 * JobDoOutput -- 2145 * This function is called at different times depending on 2146 * whether the user has specified that output is to be collected 2147 * via pipes or temporary files. In the former case, we are called 2148 * whenever there is something to read on the pipe. We collect more 2149 * output from the given job and store it in the job's outBuf. If 2150 * this makes up a line, we print it tagged by the job's identifier, 2151 * as necessary. 2152 * If output has been collected in a temporary file, we open the 2153 * file and read it line by line, transfering it to our own 2154 * output channel until the file is empty. At which point we 2155 * remove the temporary file. 2156 * In both cases, however, we keep our figurative eye out for the 2157 * 'noPrint' line for the shell from which the output came. If 2158 * we recognize a line, we don't print it. If the command is not 2159 * alone on the line (the character after it is not \0 or \n), we 2160 * do print whatever follows it. 2161 * 2162 * Input: 2163 * job the job whose output needs printing 2164 * finish TRUE if this is the last time we'll be called 2165 * for this job 2166 * 2167 * Results: 2168 * None 2169 * 2170 * Side Effects: 2171 * curPos may be shifted as may the contents of outBuf. 2172 *----------------------------------------------------------------------- 2173 */ 2174 STATIC void 2175 JobDoOutput(Job *job, Boolean finish) 2176 { 2177 Boolean gotNL = FALSE; /* true if got a newline */ 2178 Boolean fbuf; /* true if our buffer filled up */ 2179 int nr; /* number of bytes read */ 2180 int i; /* auxiliary index into outBuf */ 2181 int max; /* limit for i (end of current data) */ 2182 int nRead; /* (Temporary) number of bytes read */ 2183 2184 FILE *oFILE; /* Stream pointer to shell's output file */ 2185 char inLine[132]; 2186 2187 2188 if (usePipes) { 2189 /* 2190 * Read as many bytes as will fit in the buffer. 2191 */ 2192 end_loop: 2193 gotNL = FALSE; 2194 fbuf = FALSE; 2195 2196 nRead = read(job->inPipe, &job->outBuf[job->curPos], 2197 JOB_BUFSIZE - job->curPos); 2198 if (nRead < 0) { 2199 if (DEBUG(JOB)) { 2200 perror("JobDoOutput(piperead)"); 2201 } 2202 nr = 0; 2203 } else { 2204 nr = nRead; 2205 } 2206 2207 /* 2208 * If we hit the end-of-file (the job is dead), we must flush its 2209 * remaining output, so pretend we read a newline if there's any 2210 * output remaining in the buffer. 2211 * Also clear the 'finish' flag so we stop looping. 2212 */ 2213 if ((nr == 0) && (job->curPos != 0)) { 2214 job->outBuf[job->curPos] = '\n'; 2215 nr = 1; 2216 finish = FALSE; 2217 } else if (nr == 0) { 2218 finish = FALSE; 2219 } 2220 2221 /* 2222 * Look for the last newline in the bytes we just got. If there is 2223 * one, break out of the loop with 'i' as its index and gotNL set 2224 * TRUE. 2225 */ 2226 max = job->curPos + nr; 2227 for (i = job->curPos + nr - 1; i >= job->curPos; i--) { 2228 if (job->outBuf[i] == '\n') { 2229 gotNL = TRUE; 2230 break; 2231 } else if (job->outBuf[i] == '\0') { 2232 /* 2233 * Why? 2234 */ 2235 job->outBuf[i] = ' '; 2236 } 2237 } 2238 2239 if (!gotNL) { 2240 job->curPos += nr; 2241 if (job->curPos == JOB_BUFSIZE) { 2242 /* 2243 * If we've run out of buffer space, we have no choice 2244 * but to print the stuff. sigh. 2245 */ 2246 fbuf = TRUE; 2247 i = job->curPos; 2248 } 2249 } 2250 if (gotNL || fbuf) { 2251 /* 2252 * Need to send the output to the screen. Null terminate it 2253 * first, overwriting the newline character if there was one. 2254 * So long as the line isn't one we should filter (according 2255 * to the shell description), we print the line, preceded 2256 * by a target banner if this target isn't the same as the 2257 * one for which we last printed something. 2258 * The rest of the data in the buffer are then shifted down 2259 * to the start of the buffer and curPos is set accordingly. 2260 */ 2261 job->outBuf[i] = '\0'; 2262 if (i >= job->curPos) { 2263 char *cp; 2264 2265 cp = JobOutput(job, job->outBuf, &job->outBuf[i], FALSE); 2266 2267 /* 2268 * There's still more in that thar buffer. This time, though, 2269 * we know there's no newline at the end, so we add one of 2270 * our own free will. 2271 */ 2272 if (*cp != '\0') { 2273 if (job->node != lastNode) { 2274 MESSAGE(stdout, job->node); 2275 lastNode = job->node; 2276 } 2277 (void) fprintf(stdout, "%s%s", cp, gotNL ? "\n" : ""); 2278 (void) fflush(stdout); 2279 } 2280 } 2281 if (i < max - 1) { 2282 /* shift the remaining characters down */ 2283 (void) memcpy(job->outBuf, &job->outBuf[i + 1], max - (i + 1)); 2284 job->curPos = max - (i + 1); 2285 2286 } else { 2287 /* 2288 * We have written everything out, so we just start over 2289 * from the start of the buffer. No copying. No nothing. 2290 */ 2291 job->curPos = 0; 2292 } 2293 } 2294 if (finish) { 2295 /* 2296 * If the finish flag is true, we must loop until we hit 2297 * end-of-file on the pipe. This is guaranteed to happen 2298 * eventually since the other end of the pipe is now closed 2299 * (we closed it explicitly and the child has exited). When 2300 * we do get an EOF, finish will be set FALSE and we'll fall 2301 * through and out. 2302 */ 2303 goto end_loop; 2304 } 2305 } else { 2306 /* 2307 * We've been called to retrieve the output of the job from the 2308 * temporary file where it's been squirreled away. This consists of 2309 * opening the file, reading the output line by line, being sure not 2310 * to print the noPrint line for the shell we used, then close and 2311 * remove the temporary file. Very simple. 2312 * 2313 * Change to read in blocks and do FindSubString type things as for 2314 * pipes? That would allow for "@echo -n..." 2315 */ 2316 oFILE = fopen(job->outFile, "r"); 2317 if (oFILE != NULL) { 2318 (void) fprintf(stdout, "Results of making %s:\n", job->node->name); 2319 (void) fflush(stdout); 2320 while (fgets(inLine, sizeof(inLine), oFILE) != NULL) { 2321 char *cp, *endp, *oendp; 2322 2323 cp = inLine; 2324 oendp = endp = inLine + strlen(inLine); 2325 if (endp[-1] == '\n') { 2326 *--endp = '\0'; 2327 } 2328 cp = JobOutput(job, inLine, endp, FALSE); 2329 2330 /* 2331 * There's still more in that thar buffer. This time, though, 2332 * we know there's no newline at the end, so we add one of 2333 * our own free will. 2334 */ 2335 (void) fprintf(stdout, "%s", cp); 2336 (void) fflush(stdout); 2337 if (endp != oendp) { 2338 (void) fprintf(stdout, "\n"); 2339 (void) fflush(stdout); 2340 } 2341 } 2342 (void) fclose(oFILE); 2343 (void) eunlink(job->outFile); 2344 } else { 2345 Punt("Cannot open `%s'", job->outFile); 2346 } 2347 } 2348 } 2349 2350 /*- 2351 *----------------------------------------------------------------------- 2352 * Job_CatchChildren -- 2353 * Handle the exit of a child. Called from Make_Make. 2354 * 2355 * Input: 2356 * block TRUE if should block on the wait 2357 * 2358 * Results: 2359 * none. 2360 * 2361 * Side Effects: 2362 * The job descriptor is removed from the list of children. 2363 * 2364 * Notes: 2365 * We do waits, blocking or not, according to the wisdom of our 2366 * caller, until there are no more children to report. For each 2367 * job, call JobFinish to finish things off. This will take care of 2368 * putting jobs on the stoppedJobs queue. 2369 * 2370 *----------------------------------------------------------------------- 2371 */ 2372 void 2373 Job_CatchChildren(Boolean block) 2374 { 2375 int pid; /* pid of dead child */ 2376 Job *job; /* job descriptor for dead child */ 2377 LstNode jnode; /* list element for finding job */ 2378 int status; /* Exit/termination status */ 2379 2380 /* 2381 * Don't even bother if we know there's no one around. 2382 */ 2383 if (nLocal == 0) { 2384 return; 2385 } 2386 2387 while ((pid = waitpid((pid_t) -1, &status, 2388 (block?0:WNOHANG)|WUNTRACED)) > 0) 2389 { 2390 if (DEBUG(JOB)) { 2391 (void) fprintf(stdout, "Process %d exited or stopped %x.\n", pid, 2392 status); 2393 (void) fflush(stdout); 2394 } 2395 2396 jnode = Lst_Find(jobs, (ClientData)&pid, JobCmpPid); 2397 if (jnode == NILLNODE) { 2398 if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGCONT)) { 2399 jnode = Lst_Find(stoppedJobs, (ClientData) &pid, JobCmpPid); 2400 if (jnode == NILLNODE) { 2401 Error("Resumed child (%d) not in table", pid); 2402 continue; 2403 } 2404 job = (Job *)Lst_Datum(jnode); 2405 (void) Lst_Remove(stoppedJobs, jnode); 2406 } else { 2407 Error("Child (%d) not in table?", pid); 2408 continue; 2409 } 2410 } else { 2411 job = (Job *) Lst_Datum(jnode); 2412 (void) Lst_Remove(jobs, jnode); 2413 nJobs -= 1; 2414 #ifdef REMOTE 2415 if (!(job->flags & JOB_REMOTE)) { 2416 if (DEBUG(JOB)) { 2417 (void) fprintf(stdout, 2418 "Job queue has one fewer local process.\n"); 2419 (void) fflush(stdout); 2420 } 2421 nLocal -= 1; 2422 } 2423 #else 2424 nLocal -= 1; 2425 #endif 2426 } 2427 2428 JobFinish(job, &status); 2429 } 2430 } 2431 2432 /*- 2433 *----------------------------------------------------------------------- 2434 * Job_CatchOutput -- 2435 * Catch the output from our children, if we're using 2436 * pipes do so. Otherwise just block time until we get a 2437 * signal (most likely a SIGCHLD) since there's no point in 2438 * just spinning when there's nothing to do and the reaping 2439 * of a child can wait for a while. 2440 * 2441 * Results: 2442 * None 2443 * 2444 * Side Effects: 2445 * Output is read from pipes if we're piping. 2446 * ----------------------------------------------------------------------- 2447 */ 2448 void 2449 Job_CatchOutput(void) 2450 { 2451 int nready; 2452 LstNode ln; 2453 Job *job; 2454 #ifdef RMT_WILL_WATCH 2455 int pnJobs; /* Previous nJobs */ 2456 #endif 2457 2458 (void) fflush(stdout); 2459 Job_TokenFlush(); 2460 #ifdef RMT_WILL_WATCH 2461 pnJobs = nJobs; 2462 2463 /* 2464 * It is possible for us to be called with nJobs equal to 0. This happens 2465 * if all the jobs finish and a job that is stopped cannot be run 2466 * locally (eg if maxLocal is 0) and cannot be exported. The job will 2467 * be placed back on the stoppedJobs queue, Job_Empty() will return false, 2468 * Make_Run will call us again when there's nothing for which to wait. 2469 * nJobs never changes, so we loop forever. Hence the check. It could 2470 * be argued that we should sleep for a bit so as not to swamp the 2471 * exportation system with requests. Perhaps we should. 2472 * 2473 * NOTE: IT IS THE RESPONSIBILITY OF Rmt_Wait TO CALL Job_CatchChildren 2474 * IN A TIMELY FASHION TO CATCH ANY LOCALLY RUNNING JOBS THAT EXIT. 2475 * It may use the variable nLocal to determine if it needs to call 2476 * Job_CatchChildren (if nLocal is 0, there's nothing for which to 2477 * wait...) 2478 */ 2479 while (nJobs != 0 && pnJobs == nJobs) { 2480 Rmt_Wait(); 2481 } 2482 #else 2483 if (usePipes) { 2484 if ((nready = poll((wantToken ? fds : (fds + 1)), 2485 (wantToken ? nfds : (nfds - 1)), POLL_MSEC)) <= 0) { 2486 return; 2487 } else { 2488 sigset_t mask; 2489 JobSigLock(&mask); 2490 if (Lst_Open(jobs) == FAILURE) { 2491 Punt("Cannot open job table"); 2492 } 2493 2494 if (readyfd(&childExitJob)) { 2495 char token; 2496 (void) read(childExitJob.inPipe, &token, 1); 2497 nready -= 1; 2498 } 2499 2500 while (nready && (ln = Lst_Next(jobs)) != NILLNODE) { 2501 job = (Job *) Lst_Datum(ln); 2502 if (readyfd(job)) { 2503 JobDoOutput(job, FALSE); 2504 nready -= 1; 2505 } 2506 } 2507 Lst_Close(jobs); 2508 JobSigUnlock(&mask); 2509 } 2510 } 2511 #endif /* RMT_WILL_WATCH */ 2512 } 2513 2514 /*- 2515 *----------------------------------------------------------------------- 2516 * Job_Make -- 2517 * Start the creation of a target. Basically a front-end for 2518 * JobStart used by the Make module. 2519 * 2520 * Results: 2521 * None. 2522 * 2523 * Side Effects: 2524 * Another job is started. 2525 * 2526 *----------------------------------------------------------------------- 2527 */ 2528 void 2529 Job_Make(GNode *gn) 2530 { 2531 (void) JobStart(gn, 0, NULL); 2532 } 2533 2534 /*- 2535 *----------------------------------------------------------------------- 2536 * Job_Init -- 2537 * Initialize the process module 2538 * 2539 * Input: 2540 * maxproc the greatest number of jobs which may be running 2541 * at one time 2542 * maxlocal the greatest number of jobs which may be running 2543 * at once 2544 * 2545 * Results: 2546 * none 2547 * 2548 * Side Effects: 2549 * lists and counters are initialized 2550 *----------------------------------------------------------------------- 2551 */ 2552 void 2553 Job_Init(int maxproc, int maxlocal) 2554 { 2555 GNode *begin; /* node for commands to do at the very start */ 2556 2557 jobs = Lst_Init(FALSE); 2558 stoppedJobs = Lst_Init(FALSE); 2559 maxJobs = maxproc; 2560 maxLocal = maxlocal; 2561 nJobs = 0; 2562 nLocal = 0; 2563 wantToken = FALSE; 2564 2565 aborting = 0; 2566 errors = 0; 2567 2568 lastNode = NILGNODE; 2569 2570 if (maxJobs == 1 2571 #ifdef REMOTE 2572 || noMessages 2573 #endif 2574 ) { 2575 /* 2576 * If only one job can run at a time, there's no need for a banner, 2577 * is there? 2578 */ 2579 targFmt = ""; 2580 } else { 2581 targFmt = TARG_FMT; 2582 } 2583 2584 if (shellPath == NULL) { 2585 /* 2586 * The user didn't specify a shell to use, so we are using the 2587 * default one... Both the absolute path and the last component 2588 * must be set. The last component is taken from the 'name' field 2589 * of the default shell description pointed-to by commandShell. 2590 * All default shells are located in _PATH_DEFSHELLDIR. 2591 */ 2592 shellName = commandShell->name; 2593 shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH); 2594 } 2595 2596 if (commandShell->exit == NULL) { 2597 commandShell->exit = ""; 2598 } 2599 if (commandShell->echo == NULL) { 2600 commandShell->echo = ""; 2601 } 2602 2603 if (pipe(exit_pipe) < 0) 2604 Fatal("error in pipe: %s", strerror(errno)); 2605 fcntl(exit_pipe[0], F_SETFD, 1); 2606 fcntl(exit_pipe[1], F_SETFD, 1); 2607 2608 childExitJob.inPipe = exit_pipe[0]; 2609 2610 sigemptyset(&caught_signals); 2611 /* 2612 * Install a SIGCHLD handler. 2613 */ 2614 (void)signal(SIGCHLD, JobChildSig); 2615 sigaddset(&caught_signals, SIGCHLD); 2616 2617 #define ADDSIG(s,h) \ 2618 if (signal(s, SIG_IGN) != SIG_IGN) { \ 2619 sigaddset(&caught_signals, s); \ 2620 (void) signal(s, h); \ 2621 } 2622 2623 /* 2624 * Catch the four signals that POSIX specifies if they aren't ignored. 2625 * JobPassSig will take care of calling JobInterrupt if appropriate. 2626 */ 2627 ADDSIG(SIGINT, JobPassSig) 2628 ADDSIG(SIGHUP, JobPassSig) 2629 ADDSIG(SIGTERM, JobPassSig) 2630 ADDSIG(SIGQUIT, JobPassSig) 2631 2632 /* 2633 * There are additional signals that need to be caught and passed if 2634 * either the export system wants to be told directly of signals or if 2635 * we're giving each job its own process group (since then it won't get 2636 * signals from the terminal driver as we own the terminal) 2637 */ 2638 #if defined(RMT_WANTS_SIGNALS) || defined(USE_PGRP) 2639 ADDSIG(SIGTSTP, JobPassSig) 2640 ADDSIG(SIGTTOU, JobPassSig) 2641 ADDSIG(SIGTTIN, JobPassSig) 2642 ADDSIG(SIGWINCH, JobPassSig) 2643 ADDSIG(SIGCONT, JobContinueSig) 2644 #endif 2645 #undef ADDSIG 2646 2647 begin = Targ_FindNode(".BEGIN", TARG_NOCREATE); 2648 2649 if (begin != NILGNODE) { 2650 JobStart(begin, JOB_SPECIAL, (Job *)0); 2651 while (nJobs) { 2652 Job_CatchOutput(); 2653 #ifndef RMT_WILL_WATCH 2654 Job_CatchChildren(!usePipes); 2655 #endif /* RMT_WILL_WATCH */ 2656 } 2657 } 2658 postCommands = Targ_FindNode(".END", TARG_CREATE); 2659 } 2660 2661 static void JobSigReset(void) 2662 { 2663 #define DELSIG(s) \ 2664 if (sigismember(&caught_signals, s)) { \ 2665 (void) signal(SIGINT, SIG_DFL); \ 2666 } 2667 2668 DELSIG(SIGINT) 2669 DELSIG(SIGHUP) 2670 DELSIG(SIGQUIT) 2671 DELSIG(SIGTERM) 2672 #if defined(RMT_WANTS_SIGNALS) || defined(USE_PGRP) 2673 DELSIG(SIGTSTP) 2674 DELSIG(SIGTTOU) 2675 DELSIG(SIGTTIN) 2676 DELSIG(SIGWINCH) 2677 DELSIG(SIGCONT) 2678 #endif 2679 #undef DELSIG 2680 (void)signal(SIGCHLD, SIG_DFL); 2681 } 2682 2683 /*- 2684 *----------------------------------------------------------------------- 2685 * Job_Empty -- 2686 * See if the job table is empty. Because the local concurrency may 2687 * be set to 0, it is possible for the job table to become empty, 2688 * while the list of stoppedJobs remains non-empty. In such a case, 2689 * we want to restart as many jobs as we can. 2690 * 2691 * Results: 2692 * TRUE if it is. FALSE if it ain't. 2693 * 2694 * Side Effects: 2695 * None. 2696 * 2697 * ----------------------------------------------------------------------- 2698 */ 2699 Boolean 2700 Job_Empty(void) 2701 { 2702 if (nJobs == 0) { 2703 if (!Lst_IsEmpty(stoppedJobs) && !aborting) { 2704 /* 2705 * The job table is obviously not full if it has no jobs in 2706 * it...Try and restart the stopped jobs. 2707 */ 2708 JobRestartJobs(); 2709 return(FALSE); 2710 } else { 2711 return(TRUE); 2712 } 2713 } else { 2714 return(FALSE); 2715 } 2716 } 2717 2718 /*- 2719 *----------------------------------------------------------------------- 2720 * JobMatchShell -- 2721 * Find a shell in 'shells' given its name. 2722 * 2723 * Results: 2724 * A pointer to the Shell structure. 2725 * 2726 * Side Effects: 2727 * None. 2728 * 2729 *----------------------------------------------------------------------- 2730 */ 2731 static Shell * 2732 JobMatchShell(char *name) 2733 { 2734 Shell *sh; 2735 2736 for (sh = shells; sh->name != NULL; sh++) { 2737 if (strcmp(name, sh->name) == 0) 2738 return (sh); 2739 } 2740 return (NULL); 2741 } 2742 2743 /*- 2744 *----------------------------------------------------------------------- 2745 * Job_ParseShell -- 2746 * Parse a shell specification and set up commandShell, shellPath 2747 * and shellName appropriately. 2748 * 2749 * Input: 2750 * line The shell spec 2751 * 2752 * Results: 2753 * FAILURE if the specification was incorrect. 2754 * 2755 * Side Effects: 2756 * commandShell points to a Shell structure (either predefined or 2757 * created from the shell spec), shellPath is the full path of the 2758 * shell described by commandShell, while shellName is just the 2759 * final component of shellPath. 2760 * 2761 * Notes: 2762 * A shell specification consists of a .SHELL target, with dependency 2763 * operator, followed by a series of blank-separated words. Double 2764 * quotes can be used to use blanks in words. A backslash escapes 2765 * anything (most notably a double-quote and a space) and 2766 * provides the functionality it does in C. Each word consists of 2767 * keyword and value separated by an equal sign. There should be no 2768 * unnecessary spaces in the word. The keywords are as follows: 2769 * name Name of shell. 2770 * path Location of shell. 2771 * quiet Command to turn off echoing. 2772 * echo Command to turn echoing on 2773 * filter Result of turning off echoing that shouldn't be 2774 * printed. 2775 * echoFlag Flag to turn echoing on at the start 2776 * errFlag Flag to turn error checking on at the start 2777 * hasErrCtl True if shell has error checking control 2778 * check Command to turn on error checking if hasErrCtl 2779 * is TRUE or template of command to echo a command 2780 * for which error checking is off if hasErrCtl is 2781 * FALSE. 2782 * ignore Command to turn off error checking if hasErrCtl 2783 * is TRUE or template of command to execute a 2784 * command so as to ignore any errors it returns if 2785 * hasErrCtl is FALSE. 2786 * 2787 *----------------------------------------------------------------------- 2788 */ 2789 ReturnStatus 2790 Job_ParseShell(char *line) 2791 { 2792 char **words; 2793 char **argv; 2794 int argc; 2795 char *path; 2796 Shell newShell; 2797 Boolean fullSpec = FALSE; 2798 Shell *sh; 2799 2800 while (isspace((unsigned char)*line)) { 2801 line++; 2802 } 2803 2804 if (shellArgv) 2805 free(shellArgv); 2806 2807 memset((Address)&newShell, 0, sizeof(newShell)); 2808 2809 /* 2810 * Parse the specification by keyword 2811 */ 2812 words = brk_string(line, &argc, TRUE, &shellArgv); 2813 2814 for (path = NULL, argv = words; argc != 0; argc--, argv++) { 2815 if (strncmp(*argv, "path=", 5) == 0) { 2816 path = &argv[0][5]; 2817 } else if (strncmp(*argv, "name=", 5) == 0) { 2818 newShell.name = &argv[0][5]; 2819 } else { 2820 if (strncmp(*argv, "quiet=", 6) == 0) { 2821 newShell.echoOff = &argv[0][6]; 2822 } else if (strncmp(*argv, "echo=", 5) == 0) { 2823 newShell.echoOn = &argv[0][5]; 2824 } else if (strncmp(*argv, "filter=", 7) == 0) { 2825 newShell.noPrint = &argv[0][7]; 2826 newShell.noPLen = strlen(newShell.noPrint); 2827 } else if (strncmp(*argv, "echoFlag=", 9) == 0) { 2828 newShell.echo = &argv[0][9]; 2829 } else if (strncmp(*argv, "errFlag=", 8) == 0) { 2830 newShell.exit = &argv[0][8]; 2831 } else if (strncmp(*argv, "hasErrCtl=", 10) == 0) { 2832 char c = argv[0][10]; 2833 newShell.hasErrCtl = !((c != 'Y') && (c != 'y') && 2834 (c != 'T') && (c != 't')); 2835 } else if (strncmp(*argv, "check=", 6) == 0) { 2836 newShell.errCheck = &argv[0][6]; 2837 } else if (strncmp(*argv, "ignore=", 7) == 0) { 2838 newShell.ignErr = &argv[0][7]; 2839 } else { 2840 Parse_Error(PARSE_FATAL, "Unknown keyword \"%s\"", 2841 *argv); 2842 free(words); 2843 return(FAILURE); 2844 } 2845 fullSpec = TRUE; 2846 } 2847 } 2848 2849 if (path == NULL) { 2850 /* 2851 * If no path was given, the user wants one of the pre-defined shells, 2852 * yes? So we find the one s/he wants with the help of JobMatchShell 2853 * and set things up the right way. shellPath will be set up by 2854 * Job_Init. 2855 */ 2856 if (newShell.name == NULL) { 2857 Parse_Error(PARSE_FATAL, "Neither path nor name specified"); 2858 free(words); 2859 return(FAILURE); 2860 } else { 2861 if ((sh = JobMatchShell(newShell.name)) == NULL) { 2862 Parse_Error(PARSE_WARNING, "%s: No matching shell", 2863 newShell.name); 2864 free(words); 2865 return(FAILURE); 2866 } 2867 commandShell = sh; 2868 shellName = newShell.name; 2869 } 2870 } else { 2871 /* 2872 * The user provided a path. If s/he gave nothing else (fullSpec is 2873 * FALSE), try and find a matching shell in the ones we know of. 2874 * Else we just take the specification at its word and copy it 2875 * to a new location. In either case, we need to record the 2876 * path the user gave for the shell. 2877 */ 2878 shellPath = path; 2879 path = strrchr(path, '/'); 2880 if (path == NULL) { 2881 path = shellPath; 2882 } else { 2883 path += 1; 2884 } 2885 if (newShell.name != NULL) { 2886 shellName = newShell.name; 2887 } else { 2888 shellName = path; 2889 } 2890 if (!fullSpec) { 2891 if ((sh = JobMatchShell(shellName)) == NULL) { 2892 Parse_Error(PARSE_WARNING, "%s: No matching shell", 2893 shellName); 2894 free(words); 2895 return(FAILURE); 2896 } 2897 commandShell = sh; 2898 } else { 2899 commandShell = (Shell *) emalloc(sizeof(Shell)); 2900 *commandShell = newShell; 2901 } 2902 } 2903 2904 if (commandShell->echoOn && commandShell->echoOff) { 2905 commandShell->hasEchoCtl = TRUE; 2906 } 2907 2908 if (!commandShell->hasErrCtl) { 2909 if (commandShell->errCheck == NULL) { 2910 commandShell->errCheck = ""; 2911 } 2912 if (commandShell->ignErr == NULL) { 2913 commandShell->ignErr = "%s\n"; 2914 } 2915 } 2916 2917 /* 2918 * Do not free up the words themselves, since they might be in use by the 2919 * shell specification. 2920 */ 2921 free(words); 2922 return SUCCESS; 2923 } 2924 2925 /*- 2926 *----------------------------------------------------------------------- 2927 * JobInterrupt -- 2928 * Handle the receipt of an interrupt. 2929 * 2930 * Input: 2931 * runINTERRUPT Non-zero if commands for the .INTERRUPT target 2932 * should be executed 2933 * signo signal received 2934 * 2935 * Results: 2936 * None 2937 * 2938 * Side Effects: 2939 * All children are killed. Another job will be started if the 2940 * .INTERRUPT target was given. 2941 *----------------------------------------------------------------------- 2942 */ 2943 static void 2944 JobInterrupt(int runINTERRUPT, int signo) 2945 { 2946 LstNode ln; /* element in job table */ 2947 Job *job; /* job descriptor in that element */ 2948 GNode *interrupt; /* the node describing the .INTERRUPT target */ 2949 sigset_t mask; 2950 2951 aborting = ABORT_INTERRUPT; 2952 2953 JobSigLock(&mask); 2954 2955 (void) Lst_Open(jobs); 2956 while ((ln = Lst_Next(jobs)) != NILLNODE) { 2957 GNode *gn; 2958 2959 job = (Job *) Lst_Datum(ln); 2960 gn = job->node; 2961 2962 if ((gn->type & (OP_JOIN|OP_PHONY)) == 0 && !Targ_Precious(gn)) { 2963 char *file = (gn->path == NULL ? gn->name : gn->path); 2964 if (!noExecute && eunlink(file) != -1) { 2965 Error("*** %s removed", file); 2966 } 2967 } 2968 #ifdef RMT_WANTS_SIGNALS 2969 if (job->flags & JOB_REMOTE) { 2970 /* 2971 * If job is remote, let the Rmt module do the killing. 2972 */ 2973 if (!Rmt_Signal(job, signo)) { 2974 /* 2975 * If couldn't kill the thing, finish it out now with an 2976 * error code, since no exit report will come in likely. 2977 */ 2978 int status; 2979 2980 status.w_status = 0; 2981 status.w_retcode = 1; 2982 JobFinish(job, &status); 2983 } 2984 } else if (job->pid) { 2985 KILL(job->pid, signo); 2986 } 2987 #else 2988 if (job->pid) { 2989 if (DEBUG(JOB)) { 2990 (void) fprintf(stdout, 2991 "JobInterrupt passing signal %d to child %d.\n", 2992 signo, job->pid); 2993 (void) fflush(stdout); 2994 } 2995 KILL(job->pid, signo); 2996 } 2997 #endif /* RMT_WANTS_SIGNALS */ 2998 } 2999 Lst_Close(jobs); 3000 3001 #ifdef REMOTE 3002 (void)Lst_Open(stoppedJobs); 3003 while ((ln = Lst_Next(stoppedJobs)) != NILLNODE) { 3004 GNode *gn; 3005 3006 job = (Job *) Lst_Datum(ln); 3007 gn = job->node; 3008 3009 if (job->flags & JOB_RESTART) { 3010 if (DEBUG(JOB)) { 3011 (void) fprintf(stdout, "%s%s", 3012 "JobInterrupt skipping job on stopped queue", 3013 "-- it was waiting to be restarted.\n"); 3014 (void) fflush(stdout); 3015 } 3016 continue; 3017 } 3018 if ((gn->type & (OP_JOIN|OP_PHONY)) == 0 && !Targ_Precious(gn)) { 3019 char *file = (gn->path == NULL ? gn->name : gn->path); 3020 if (eunlink(file) == 0) { 3021 Error("*** %s removed", file); 3022 } 3023 } 3024 /* 3025 * Resume the thing so it will take the signal. 3026 */ 3027 if (DEBUG(JOB)) { 3028 (void) fprintf(stdout, 3029 "JobInterrupt passing CONT to stopped child %d.\n", 3030 job->pid); 3031 (void) fflush(stdout); 3032 } 3033 KILL(job->pid, SIGCONT); 3034 #ifdef RMT_WANTS_SIGNALS 3035 if (job->flags & JOB_REMOTE) { 3036 /* 3037 * If job is remote, let the Rmt module do the killing. 3038 */ 3039 if (!Rmt_Signal(job, SIGINT)) { 3040 /* 3041 * If couldn't kill the thing, finish it out now with an 3042 * error code, since no exit report will come in likely. 3043 */ 3044 int status; 3045 status.w_status = 0; 3046 status.w_retcode = 1; 3047 JobFinish(job, &status); 3048 } 3049 } else if (job->pid) { 3050 if (DEBUG(JOB)) { 3051 (void) fprintf(stdout, 3052 "JobInterrupt passing interrupt to stopped child %d.\n", 3053 job->pid); 3054 (void) fflush(stdout); 3055 } 3056 KILL(job->pid, SIGINT); 3057 } 3058 #endif /* RMT_WANTS_SIGNALS */ 3059 } 3060 Lst_Close(stoppedJobs); 3061 #endif /* REMOTE */ 3062 3063 JobSigUnlock(&mask); 3064 3065 if (runINTERRUPT && !touchFlag) { 3066 interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE); 3067 if (interrupt != NILGNODE) { 3068 ignoreErrors = FALSE; 3069 3070 JobStart(interrupt, JOB_IGNDOTS, (Job *)0); 3071 while (nJobs) { 3072 Job_CatchOutput(); 3073 #ifndef RMT_WILL_WATCH 3074 Job_CatchChildren(!usePipes); 3075 #endif /* RMT_WILL_WATCH */ 3076 } 3077 } 3078 } 3079 Trace_Log(MAKEINTR, 0); 3080 exit(signo); 3081 } 3082 3083 /* 3084 *----------------------------------------------------------------------- 3085 * Job_Finish -- 3086 * Do final processing such as the running of the commands 3087 * attached to the .END target. 3088 * 3089 * Results: 3090 * Number of errors reported. 3091 * 3092 * Side Effects: 3093 * None. 3094 *----------------------------------------------------------------------- 3095 */ 3096 int 3097 Job_Finish(void) 3098 { 3099 if (postCommands != NILGNODE && !Lst_IsEmpty(postCommands->commands)) { 3100 if (errors) { 3101 Error("Errors reported so .END ignored"); 3102 } else { 3103 JobStart(postCommands, JOB_SPECIAL | JOB_IGNDOTS, NULL); 3104 3105 while (nJobs) { 3106 Job_CatchOutput(); 3107 #ifndef RMT_WILL_WATCH 3108 Job_CatchChildren(!usePipes); 3109 #endif /* RMT_WILL_WATCH */ 3110 } 3111 } 3112 } 3113 Job_TokenFlush(); 3114 return(errors); 3115 } 3116 3117 /*- 3118 *----------------------------------------------------------------------- 3119 * Job_End -- 3120 * Cleanup any memory used by the jobs module 3121 * 3122 * Results: 3123 * None. 3124 * 3125 * Side Effects: 3126 * Memory is freed 3127 *----------------------------------------------------------------------- 3128 */ 3129 void 3130 Job_End(void) 3131 { 3132 #ifdef CLEANUP 3133 if (shellArgv) 3134 free(shellArgv); 3135 #endif 3136 } 3137 3138 /*- 3139 *----------------------------------------------------------------------- 3140 * Job_Wait -- 3141 * Waits for all running jobs to finish and returns. Sets 'aborting' 3142 * to ABORT_WAIT to prevent other jobs from starting. 3143 * 3144 * Results: 3145 * None. 3146 * 3147 * Side Effects: 3148 * Currently running jobs finish. 3149 * 3150 *----------------------------------------------------------------------- 3151 */ 3152 void 3153 Job_Wait(void) 3154 { 3155 aborting = ABORT_WAIT; 3156 while (nJobs != 0) { 3157 Job_CatchOutput(); 3158 #ifndef RMT_WILL_WATCH 3159 Job_CatchChildren(!usePipes); 3160 #endif /* RMT_WILL_WATCH */ 3161 } 3162 Job_TokenFlush(); 3163 aborting = 0; 3164 } 3165 3166 /*- 3167 *----------------------------------------------------------------------- 3168 * Job_AbortAll -- 3169 * Abort all currently running jobs without handling output or anything. 3170 * This function is to be called only in the event of a major 3171 * error. Most definitely NOT to be called from JobInterrupt. 3172 * 3173 * Results: 3174 * None 3175 * 3176 * Side Effects: 3177 * All children are killed, not just the firstborn 3178 *----------------------------------------------------------------------- 3179 */ 3180 void 3181 Job_AbortAll(void) 3182 { 3183 LstNode ln; /* element in job table */ 3184 Job *job; /* the job descriptor in that element */ 3185 int foo; 3186 sigset_t mask; 3187 3188 aborting = ABORT_ERROR; 3189 3190 if (nJobs) { 3191 3192 JobSigLock(&mask); 3193 (void) Lst_Open(jobs); 3194 while ((ln = Lst_Next(jobs)) != NILLNODE) { 3195 job = (Job *) Lst_Datum(ln); 3196 3197 /* 3198 * kill the child process with increasingly drastic signals to make 3199 * darn sure it's dead. 3200 */ 3201 #ifdef RMT_WANTS_SIGNALS 3202 if (job->flags & JOB_REMOTE) { 3203 Rmt_Signal(job, SIGINT); 3204 Rmt_Signal(job, SIGKILL); 3205 } else { 3206 KILL(job->pid, SIGINT); 3207 KILL(job->pid, SIGKILL); 3208 } 3209 #else 3210 KILL(job->pid, SIGINT); 3211 KILL(job->pid, SIGKILL); 3212 #endif /* RMT_WANTS_SIGNALS */ 3213 } 3214 Lst_Close(jobs); 3215 JobSigUnlock(&mask); 3216 } 3217 3218 /* 3219 * Catch as many children as want to report in at first, then give up 3220 */ 3221 while (waitpid((pid_t) -1, &foo, WNOHANG) > 0) 3222 continue; 3223 } 3224 3225 #ifdef REMOTE 3226 /*- 3227 *----------------------------------------------------------------------- 3228 * JobFlagForMigration -- 3229 * Handle the eviction of a child. Called from RmtStatusChange. 3230 * Flags the child as remigratable and then suspends it. 3231 * 3232 * Input: 3233 * hostID ID of host we used, for matching children 3234 * 3235 * Results: 3236 * none. 3237 * 3238 * Side Effects: 3239 * The job descriptor is flagged for remigration. 3240 * 3241 *----------------------------------------------------------------------- 3242 */ 3243 void 3244 JobFlagForMigration(int hostID) 3245 { 3246 Job *job; /* job descriptor for dead child */ 3247 LstNode jnode; /* list element for finding job */ 3248 3249 if (DEBUG(JOB)) { 3250 (void) fprintf(stdout, "JobFlagForMigration(%d) called.\n", hostID); 3251 (void) fflush(stdout); 3252 } 3253 jnode = Lst_Find(jobs, (ClientData)&hostID, JobCmpRmtID); 3254 3255 if (jnode == NILLNODE) { 3256 jnode = Lst_Find(stoppedJobs, (ClientData)hostID, JobCmpRmtID); 3257 if (jnode == NILLNODE) { 3258 if (DEBUG(JOB)) { 3259 Error("Evicting host(%d) not in table", hostID); 3260 } 3261 return; 3262 } 3263 } 3264 job = (Job *) Lst_Datum(jnode); 3265 3266 if (DEBUG(JOB)) { 3267 (void) fprintf(stdout, 3268 "JobFlagForMigration(%d) found job '%s'.\n", hostID, 3269 job->node->name); 3270 (void) fflush(stdout); 3271 } 3272 3273 KILL(job->pid, SIGSTOP); 3274 3275 job->flags |= JOB_REMIGRATE; 3276 } 3277 3278 #endif 3279 3280 /*- 3281 *----------------------------------------------------------------------- 3282 * JobRestartJobs -- 3283 * Tries to restart stopped jobs if there are slots available. 3284 * Note that this tries to restart them regardless of pending errors. 3285 * It's not good to leave stopped jobs lying around! 3286 * 3287 * Results: 3288 * None. 3289 * 3290 * Side Effects: 3291 * Resumes(and possibly migrates) jobs. 3292 * 3293 *----------------------------------------------------------------------- 3294 */ 3295 static void 3296 JobRestartJobs(void) 3297 { 3298 sigset_t mask; 3299 3300 JobSigLock(&mask); 3301 while (!Lst_IsEmpty(stoppedJobs)) { 3302 if (DEBUG(JOB)) { 3303 (void) fprintf(stdout, "Restarting a stopped job.\n"); 3304 (void) fflush(stdout); 3305 } 3306 if (JobRestart((Job *)Lst_DeQueue(stoppedJobs)) != 0) 3307 break; 3308 } 3309 JobSigUnlock(&mask); 3310 } 3311 3312 #ifndef RMT_WILL_WATCH 3313 static void 3314 watchfd(Job *job) 3315 { 3316 int i; 3317 if (job->inPollfd != NULL) 3318 Punt("Watching watched job"); 3319 if (fds == NULL) { 3320 maxfds = JBSTART; 3321 fds = emalloc(sizeof(struct pollfd) * maxfds); 3322 jobfds = emalloc(sizeof(Job **) * maxfds); 3323 3324 fds[0].fd = job_pipe[0]; 3325 fds[0].events = POLLIN; 3326 jobfds[0] = &tokenWaitJob; 3327 tokenWaitJob.inPollfd = &fds[0]; 3328 nfds++; 3329 3330 fds[1].fd = exit_pipe[0]; 3331 fds[1].events = POLLIN; 3332 jobfds[1] = &childExitJob; 3333 childExitJob.inPollfd = &fds[1]; 3334 nfds++; 3335 } else if (nfds == maxfds) { 3336 maxfds *= JBFACTOR; 3337 fds = erealloc(fds, sizeof(struct pollfd) * maxfds); 3338 jobfds = erealloc(jobfds, sizeof(Job **) * maxfds); 3339 for (i = 0; i < nfds; i++) 3340 jobfds[i]->inPollfd = &fds[i]; 3341 } 3342 3343 fds[nfds].fd = job->inPipe; 3344 fds[nfds].events = POLLIN; 3345 jobfds[nfds] = job; 3346 job->inPollfd = &fds[nfds]; 3347 nfds++; 3348 } 3349 3350 static void 3351 clearfd(Job *job) 3352 { 3353 int i; 3354 if (job->inPollfd == NULL) 3355 Punt("Unwatching unwatched job"); 3356 i = job->inPollfd - fds; 3357 nfds--; 3358 /* 3359 * Move last job in table into hole made by dead job. 3360 */ 3361 if (nfds != i) { 3362 fds[i] = fds[nfds]; 3363 jobfds[i] = jobfds[nfds]; 3364 jobfds[i]->inPollfd = &fds[i]; 3365 } 3366 job->inPollfd = NULL; 3367 } 3368 3369 static int 3370 readyfd(Job *job) 3371 { 3372 if (job->inPollfd == NULL) 3373 Punt("Polling unwatched job"); 3374 return (job->inPollfd->revents & POLLIN) != 0; 3375 } 3376 #endif 3377 3378 /*- 3379 *----------------------------------------------------------------------- 3380 * JobTokenAdd -- 3381 * Put a token into the job pipe so that some make process can start 3382 * another job. 3383 * 3384 * Side Effects: 3385 * Allows more build jobs to be spawned somewhere. 3386 * 3387 *----------------------------------------------------------------------- 3388 */ 3389 3390 static void 3391 JobTokenAdd(void) 3392 { 3393 3394 if (DEBUG(JOB)) 3395 printf("deposit token\n"); 3396 write(job_pipe[1], "+", 1); 3397 } 3398 3399 /*- 3400 *----------------------------------------------------------------------- 3401 * Job_ServerStartTokenAdd -- 3402 * Prep the job token pipe in the root make process. 3403 * 3404 *----------------------------------------------------------------------- 3405 */ 3406 3407 void 3408 Job_ServerStart(int maxproc) 3409 { 3410 int i, flags; 3411 char jobarg[64]; 3412 3413 if (pipe(job_pipe) < 0) 3414 Fatal ("error in pipe: %s", strerror(errno)); 3415 3416 /* 3417 * We mark the input side of the pipe non-blocking; we poll(2) the 3418 * pipe when we're waiting for a job token, but we might lose the 3419 * race for the token when a new one becomes available, so the read 3420 * from the pipe should not block. 3421 */ 3422 flags = fcntl(job_pipe[0], F_GETFL, 0); 3423 flags |= O_NONBLOCK; 3424 fcntl(job_pipe[0], F_SETFL, flags); 3425 3426 /* 3427 * Mark job pipes as close-on-exec. 3428 * Note that we will clear this when executing submakes. 3429 */ 3430 fcntl(job_pipe[0], F_SETFD, 1); 3431 fcntl(job_pipe[1], F_SETFD, 1); 3432 3433 snprintf(jobarg, sizeof(jobarg), "%d,%d", job_pipe[0], job_pipe[1]); 3434 3435 Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL); 3436 Var_Append(MAKEFLAGS, jobarg, VAR_GLOBAL); 3437 3438 /* 3439 * Preload job_pipe with one token per job, save the one 3440 * "extra" token for the primary job. 3441 * 3442 * XXX should clip maxJobs against PIPE_BUF -- if maxJobs is 3443 * larger than the write buffer size of the pipe, we will 3444 * deadlock here. 3445 */ 3446 for (i=1; i < maxproc; i++) 3447 JobTokenAdd(); 3448 } 3449 3450 /* 3451 * this tracks the number of tokens currently "out" to build jobs. 3452 */ 3453 int jobTokensRunning = 0; 3454 int jobTokensFree = 0; 3455 /*- 3456 *----------------------------------------------------------------------- 3457 * Job_TokenReturn -- 3458 * Return a withdrawn token to the pool. 3459 * 3460 *----------------------------------------------------------------------- 3461 */ 3462 3463 void 3464 Job_TokenReturn(void) 3465 { 3466 jobTokensRunning--; 3467 if (jobTokensRunning < 0) 3468 Punt("token botch"); 3469 if (jobTokensRunning) 3470 jobTokensFree++; 3471 } 3472 3473 /*- 3474 *----------------------------------------------------------------------- 3475 * Job_TokenWithdraw -- 3476 * Attempt to withdraw a token from the pool. 3477 * 3478 * Results: 3479 * Returns TRUE if a token was withdrawn, and FALSE if the pool 3480 * is currently empty. 3481 * 3482 * Side Effects: 3483 * If pool is empty, set wantToken so that we wake up 3484 * when a token is released. 3485 * 3486 *----------------------------------------------------------------------- 3487 */ 3488 3489 3490 Boolean 3491 Job_TokenWithdraw(void) 3492 { 3493 char tok; 3494 int count; 3495 3496 wantToken = FALSE; 3497 3498 if (aborting) 3499 return FALSE; 3500 3501 if (jobTokensRunning == 0) { 3502 if (DEBUG(JOB)) 3503 printf("first one's free\n"); 3504 jobTokensRunning++; 3505 return TRUE; 3506 } 3507 if (jobTokensFree > 0) { 3508 jobTokensFree--; 3509 jobTokensRunning++; 3510 return TRUE; 3511 } 3512 count = read(job_pipe[0], &tok, 1); 3513 if (count == 0) 3514 Fatal("eof on job pipe!"); 3515 else if (count < 0) { 3516 if (errno != EAGAIN) { 3517 Fatal("job pipe read: %s", strerror(errno)); 3518 } 3519 if (DEBUG(JOB)) 3520 printf("blocked for token\n"); 3521 wantToken = TRUE; 3522 return FALSE; 3523 } 3524 jobTokensRunning++; 3525 if (DEBUG(JOB)) 3526 printf("withdrew token\n"); 3527 return TRUE; 3528 } 3529 3530 /*- 3531 *----------------------------------------------------------------------- 3532 * Job_TokenFlush -- 3533 * Return free tokens to the pool. 3534 * 3535 *----------------------------------------------------------------------- 3536 */ 3537 3538 void 3539 Job_TokenFlush(void) 3540 { 3541 if (compatMake) return; 3542 3543 while (jobTokensFree > 0) { 3544 JobTokenAdd(); 3545 jobTokensFree--; 3546 } 3547 } 3548 3549 #ifdef USE_SELECT 3550 int 3551 emul_poll(struct pollfd *fd, int nfd, int timeout) 3552 { 3553 fd_set rfds, wfds; 3554 int i, maxfd, nselect, npoll; 3555 struct timeval tv, *tvp; 3556 long usecs; 3557 3558 FD_ZERO(&rfds); 3559 FD_ZERO(&wfds); 3560 3561 maxfd = -1; 3562 for (i = 0; i < nfd; i++) { 3563 fd[i].revents = 0; 3564 3565 if (fd[i].events & POLLIN) 3566 FD_SET(fd[i].fd, &rfds); 3567 3568 if (fd[i].events & POLLOUT) 3569 FD_SET(fd[i].fd, &wfds); 3570 3571 if (fd[i].fd > maxfd) 3572 maxfd = fd[i].fd; 3573 } 3574 3575 if (maxfd >= FD_SETSIZE) { 3576 Punt("Ran out of fd_set slots; " 3577 "recompile with a larger FD_SETSIZE."); 3578 } 3579 3580 if (timeout < 0) { 3581 tvp = NULL; 3582 } else { 3583 usecs = timeout * 1000; 3584 tv.tv_sec = usecs / 1000000; 3585 tv.tv_usec = usecs % 1000000; 3586 tvp = &tv; 3587 } 3588 3589 nselect = select(maxfd + 1, &rfds, &wfds, 0, tvp); 3590 3591 if (nselect <= 0) 3592 return nselect; 3593 3594 npoll = 0; 3595 for (i = 0; i < nfd; i++) { 3596 if (FD_ISSET(fd[i].fd, &rfds)) 3597 fd[i].revents |= POLLIN; 3598 3599 if (FD_ISSET(fd[i].fd, &wfds)) 3600 fd[i].revents |= POLLOUT; 3601 3602 if (fd[i].revents) 3603 npoll++; 3604 } 3605 3606 return npoll; 3607 } 3608 #endif /* USE_SELECT */ 3609