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