Deleted Added
full compact
job.c (138232) job.c (138264)
1/*
2 * Copyright (c) 1988, 1989, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1988, 1989 by Adam de Boor
5 * Copyright (c) 1989 by Berkeley Softworks
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by

--- 26 unchanged lines hidden (view full) ---

35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * @(#)job.c 8.2 (Berkeley) 3/19/94
40 */
41
42#include <sys/cdefs.h>
1/*
2 * Copyright (c) 1988, 1989, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1988, 1989 by Adam de Boor
5 * Copyright (c) 1989 by Berkeley Softworks
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by

--- 26 unchanged lines hidden (view full) ---

35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * @(#)job.c 8.2 (Berkeley) 3/19/94
40 */
41
42#include <sys/cdefs.h>
43__FBSDID("$FreeBSD: head/usr.bin/make/job.c 138232 2004-11-30 17:46:29Z harti $");
43__FBSDID("$FreeBSD: head/usr.bin/make/job.c 138264 2004-12-01 10:29:20Z harti $");
44
45#ifndef OLD_JOKE
46#define OLD_JOKE 0
47#endif /* OLD_JOKE */
48
49/*-
50 * job.c --
51 * handle the creation etc. of our child processes.

--- 271 unchanged lines hidden (view full) ---

323 * Side Effects:
324 * None, except the job may bite it.
325 *
326 *-----------------------------------------------------------------------
327 */
328static int
329JobCondPassSig(void *jobp, void *signop)
330{
44
45#ifndef OLD_JOKE
46#define OLD_JOKE 0
47#endif /* OLD_JOKE */
48
49/*-
50 * job.c --
51 * handle the creation etc. of our child processes.

--- 271 unchanged lines hidden (view full) ---

323 * Side Effects:
324 * None, except the job may bite it.
325 *
326 *-----------------------------------------------------------------------
327 */
328static int
329JobCondPassSig(void *jobp, void *signop)
330{
331 Job *job = (Job *)jobp;
331 Job *job = jobp;
332 int signo = *(int *)signop;
333
334 DEBUGF(JOB, ("JobCondPassSig passing signal %d to child %d.\n",
335 signo, job->pid));
336 KILL(job->pid, signo);
337 return (0);
338}
339

--- 17 unchanged lines hidden (view full) ---

357 sigset_t nmask, omask;
358 struct sigaction act;
359
360 sigemptyset(&nmask);
361 sigaddset(&nmask, signo);
362 sigprocmask(SIG_SETMASK, &nmask, &omask);
363
364 DEBUGF(JOB, ("JobPassSig(%d) called.\n", signo));
332 int signo = *(int *)signop;
333
334 DEBUGF(JOB, ("JobCondPassSig passing signal %d to child %d.\n",
335 signo, job->pid));
336 KILL(job->pid, signo);
337 return (0);
338}
339

--- 17 unchanged lines hidden (view full) ---

357 sigset_t nmask, omask;
358 struct sigaction act;
359
360 sigemptyset(&nmask);
361 sigaddset(&nmask, signo);
362 sigprocmask(SIG_SETMASK, &nmask, &omask);
363
364 DEBUGF(JOB, ("JobPassSig(%d) called.\n", signo));
365 Lst_ForEach(jobs, JobCondPassSig, (void *)&signo);
365 Lst_ForEach(jobs, JobCondPassSig, &signo);
366
367 /*
368 * Deal with proper cleanup based on the signal received. We only run
369 * the .INTERRUPT target if the signal was in fact an interrupt. The other
370 * three termination signals are more of a "get out *now*" command.
371 */
372 if (signo == SIGINT) {
373 JobInterrupt(TRUE, signo);

--- 22 unchanged lines hidden (view full) ---

396
397 DEBUGF(JOB, ("JobPassSig passing signal to self, mask = %x.\n",
398 ~0 & ~(1 << (signo - 1))));
399 signal(signo, SIG_DFL);
400
401 KILL(getpid(), signo);
402
403 signo = SIGCONT;
366
367 /*
368 * Deal with proper cleanup based on the signal received. We only run
369 * the .INTERRUPT target if the signal was in fact an interrupt. The other
370 * three termination signals are more of a "get out *now*" command.
371 */
372 if (signo == SIGINT) {
373 JobInterrupt(TRUE, signo);

--- 22 unchanged lines hidden (view full) ---

396
397 DEBUGF(JOB, ("JobPassSig passing signal to self, mask = %x.\n",
398 ~0 & ~(1 << (signo - 1))));
399 signal(signo, SIG_DFL);
400
401 KILL(getpid(), signo);
402
403 signo = SIGCONT;
404 Lst_ForEach(jobs, JobCondPassSig, (void *)&signo);
404 Lst_ForEach(jobs, JobCondPassSig, &signo);
405
406 sigprocmask(SIG_SETMASK, &omask, NULL);
407 sigprocmask(SIG_SETMASK, &omask, NULL);
408 act.sa_handler = JobPassSig;
409 sigaction(signo, &act, NULL);
410}
411
412/*-

--- 8 unchanged lines hidden (view full) ---

421 *
422 * Side Effects:
423 * None
424 *-----------------------------------------------------------------------
425 */
426static int
427JobCmpPid(void *job, void *pid)
428{
405
406 sigprocmask(SIG_SETMASK, &omask, NULL);
407 sigprocmask(SIG_SETMASK, &omask, NULL);
408 act.sa_handler = JobPassSig;
409 sigaction(signo, &act, NULL);
410}
411
412/*-

--- 8 unchanged lines hidden (view full) ---

421 *
422 * Side Effects:
423 * None
424 *-----------------------------------------------------------------------
425 */
426static int
427JobCmpPid(void *job, void *pid)
428{
429
429 return (*(int *)pid - ((Job *)job)->pid);
430}
431
432/*-
433 *-----------------------------------------------------------------------
434 * JobPrintCommand --
435 * Put out another command for the given job. If the command starts
436 * with an @ or a - we process it specially. In the former case,

--- 29 unchanged lines hidden (view full) ---

466 * into the command file */
467 Boolean errOff = FALSE; /* true if we turned error checking
468 * off before printing the command
469 * and need to turn it back on */
470 char *cmdTemplate; /* Template to use when printing the
471 * command */
472 char *cmdStart; /* Start of expanded command */
473 LstNode cmdNode; /* Node for replacing the command */
430 return (*(int *)pid - ((Job *)job)->pid);
431}
432
433/*-
434 *-----------------------------------------------------------------------
435 * JobPrintCommand --
436 * Put out another command for the given job. If the command starts
437 * with an @ or a - we process it specially. In the former case,

--- 29 unchanged lines hidden (view full) ---

467 * into the command file */
468 Boolean errOff = FALSE; /* true if we turned error checking
469 * off before printing the command
470 * and need to turn it back on */
471 char *cmdTemplate; /* Template to use when printing the
472 * command */
473 char *cmdStart; /* Start of expanded command */
474 LstNode cmdNode; /* Node for replacing the command */
474 char *cmd = (char *)cmdp;
475 Job *job = (Job *)jobp;
475 char *cmd = cmdp;
476 Job *job = jobp;
476
477 noSpecials = (noExecute && !(job->node->type & OP_MAKE));
478
479 if (strcmp(cmd, "...") == 0) {
480 job->node->type |= OP_SAVE_CMDS;
481 if ((job->flags & JOB_IGNDOTS) == 0) {
477
478 noSpecials = (noExecute && !(job->node->type & OP_MAKE));
479
480 if (strcmp(cmd, "...") == 0) {
481 job->node->type |= OP_SAVE_CMDS;
482 if ((job->flags & JOB_IGNDOTS) == 0) {
482 job->tailCmds = Lst_Succ(Lst_Member(job->node->commands,
483 (void *)cmd));
483 job->tailCmds = Lst_Succ(Lst_Member(job->node->commands, cmd));
484 return (1);
485 }
486 return (0);
487 }
488
489#define DBPRINTF(fmt, arg) \
490 DEBUGF(JOB, (fmt, arg)); \
491 fprintf(job->cmdFILE, fmt, arg); \
492 fflush(job->cmdFILE);
493
494 numCommands += 1;
495
496 /*
497 * For debugging, we replace each command with the result of expanding
498 * the variables in the command.
499 */
484 return (1);
485 }
486 return (0);
487 }
488
489#define DBPRINTF(fmt, arg) \
490 DEBUGF(JOB, (fmt, arg)); \
491 fprintf(job->cmdFILE, fmt, arg); \
492 fflush(job->cmdFILE);
493
494 numCommands += 1;
495
496 /*
497 * For debugging, we replace each command with the result of expanding
498 * the variables in the command.
499 */
500 cmdNode = Lst_Member(job->node->commands, (void *)cmd);
500 cmdNode = Lst_Member(job->node->commands, cmd);
501 cmdStart = cmd = Var_Subst(NULL, cmd, job->node, FALSE);
501 cmdStart = cmd = Var_Subst(NULL, cmd, job->node, FALSE);
502 Lst_Replace(cmdNode, (void *)cmdStart);
502 Lst_Replace(cmdNode, cmdStart);
503
504 cmdTemplate = "%s\n";
505
506 /*
507 * Check for leading @', -' or +'s to control echoing, error checking,
508 * and execution on -n.
509 */
510 while (*cmd == '@' || *cmd == '-' || *cmd == '+') {

--- 88 unchanged lines hidden (view full) ---

599 DBPRINTF(cmdTemplate, cmd);
600
601 if (errOff) {
602 /*
603 * If echoing is already off, there's no point in issuing the
604 * echoOff command. Otherwise we issue it and pretend it was on
605 * for the whole command...
606 */
503
504 cmdTemplate = "%s\n";
505
506 /*
507 * Check for leading @', -' or +'s to control echoing, error checking,
508 * and execution on -n.
509 */
510 while (*cmd == '@' || *cmd == '-' || *cmd == '+') {

--- 88 unchanged lines hidden (view full) ---

599 DBPRINTF(cmdTemplate, cmd);
600
601 if (errOff) {
602 /*
603 * If echoing is already off, there's no point in issuing the
604 * echoOff command. Otherwise we issue it and pretend it was on
605 * for the whole command...
606 */
607 if (!shutUp && !(job->flags & JOB_SILENT) && commandShell->hasEchoCtl){
607 if (!shutUp && !(job->flags & JOB_SILENT) && commandShell->hasEchoCtl) {
608 DBPRINTF("%s\n", commandShell->echoOff);
609 shutUp = TRUE;
610 }
611 DBPRINTF("%s\n", commandShell->errCheck);
612 }
613 if (shutUp) {
614 DBPRINTF("%s\n", commandShell->echoOn);
615 }

--- 13 unchanged lines hidden (view full) ---

629 * The command is tacked onto the end of postCommands's commands list.
630 *
631 *-----------------------------------------------------------------------
632 */
633static int
634JobSaveCommand(void *cmd, void *gn)
635{
636
608 DBPRINTF("%s\n", commandShell->echoOff);
609 shutUp = TRUE;
610 }
611 DBPRINTF("%s\n", commandShell->errCheck);
612 }
613 if (shutUp) {
614 DBPRINTF("%s\n", commandShell->echoOn);
615 }

--- 13 unchanged lines hidden (view full) ---

629 * The command is tacked onto the end of postCommands's commands list.
630 *
631 *-----------------------------------------------------------------------
632 */
633static int
634JobSaveCommand(void *cmd, void *gn)
635{
636
637 cmd = (void *)Var_Subst(NULL, (char *)cmd, (GNode *)gn, FALSE);
637 cmd = Var_Subst(NULL, cmd, gn, FALSE);
638 Lst_AtEnd(postCommands->commands, cmd);
639 return (0);
640}
641
642
643/*-
644 *-----------------------------------------------------------------------
645 * JobClose --

--- 140 unchanged lines hidden (view full) ---

786 DEBUGF(JOB, ("Process %d stopped.\n", job->pid));
787 if (usePipes && job->node != lastNode) {
788 MESSAGE(out, job->node);
789 lastNode = job->node;
790 }
791 fprintf(out, "*** Stopped -- signal %d\n",
792 WSTOPSIG(*status));
793 job->flags |= JOB_RESUME;
638 Lst_AtEnd(postCommands->commands, cmd);
639 return (0);
640}
641
642
643/*-
644 *-----------------------------------------------------------------------
645 * JobClose --

--- 140 unchanged lines hidden (view full) ---

786 DEBUGF(JOB, ("Process %d stopped.\n", job->pid));
787 if (usePipes && job->node != lastNode) {
788 MESSAGE(out, job->node);
789 lastNode = job->node;
790 }
791 fprintf(out, "*** Stopped -- signal %d\n",
792 WSTOPSIG(*status));
793 job->flags |= JOB_RESUME;
794 Lst_AtEnd(stoppedJobs, (void *)job);
794 Lst_AtEnd(stoppedJobs, job);
795 fflush(out);
796 return;
797 } else if (WTERMSIG(*status) == SIGCONT) {
798 /*
799 * If the beastie has continued, shift the Job from the stopped
800 * list to the running one (or re-stop it if concurrency is
801 * exceeded) and go and get another child.
802 */

--- 12 unchanged lines hidden (view full) ---

815 * because it continued, especially not without killing the
816 * continuing process! That's why this is ifdef'ed out.
817 * FD - 9/17/90
818 */
819 JobRestart(job);
820#endif
821 }
822 job->flags &= ~JOB_CONTINUING;
795 fflush(out);
796 return;
797 } else if (WTERMSIG(*status) == SIGCONT) {
798 /*
799 * If the beastie has continued, shift the Job from the stopped
800 * list to the running one (or re-stop it if concurrency is
801 * exceeded) and go and get another child.
802 */

--- 12 unchanged lines hidden (view full) ---

815 * because it continued, especially not without killing the
816 * continuing process! That's why this is ifdef'ed out.
817 * FD - 9/17/90
818 */
819 JobRestart(job);
820#endif
821 }
822 job->flags &= ~JOB_CONTINUING;
823 Lst_AtEnd(jobs, (void *)job);
823 Lst_AtEnd(jobs, job);
824 nJobs += 1;
825 DEBUGF(JOB, ("Process %d is continuing locally.\n", job->pid));
826 if (nJobs == maxJobs) {
827 jobFull = TRUE;
828 DEBUGF(JOB, ("Job queue is full.\n"));
829 }
830 fflush(out);
831 return;

--- 49 unchanged lines hidden (view full) ---

881 /*
882 * As long as we aren't aborting and the job didn't return a non-zero
883 * status that we shouldn't ignore, we call Make_Update to update
884 * the parents. In addition, any saved commands for the node are placed
885 * on the .END target.
886 */
887 if (job->tailCmds != NULL) {
888 Lst_ForEachFrom(job->node->commands, job->tailCmds,
824 nJobs += 1;
825 DEBUGF(JOB, ("Process %d is continuing locally.\n", job->pid));
826 if (nJobs == maxJobs) {
827 jobFull = TRUE;
828 DEBUGF(JOB, ("Job queue is full.\n"));
829 }
830 fflush(out);
831 return;

--- 49 unchanged lines hidden (view full) ---

881 /*
882 * As long as we aren't aborting and the job didn't return a non-zero
883 * status that we shouldn't ignore, we call Make_Update to update
884 * the parents. In addition, any saved commands for the node are placed
885 * on the .END target.
886 */
887 if (job->tailCmds != NULL) {
888 Lst_ForEachFrom(job->node->commands, job->tailCmds,
889 JobSaveCommand,
890 (void *)job->node);
889 JobSaveCommand, job->node);
891 }
892 job->node->made = MADE;
893 Make_Update(job->node);
894 free(job);
895 } else if (*status != 0) {
896 errors += 1;
897 free(job);
898 }

--- 34 unchanged lines hidden (view full) ---

933 *-----------------------------------------------------------------------
934 */
935void
936Job_Touch(GNode *gn, Boolean silent)
937{
938 int streamID; /* ID of stream opened to do the touch */
939 struct utimbuf times; /* Times for utime() call */
940
890 }
891 job->node->made = MADE;
892 Make_Update(job->node);
893 free(job);
894 } else if (*status != 0) {
895 errors += 1;
896 free(job);
897 }

--- 34 unchanged lines hidden (view full) ---

932 *-----------------------------------------------------------------------
933 */
934void
935Job_Touch(GNode *gn, Boolean silent)
936{
937 int streamID; /* ID of stream opened to do the touch */
938 struct utimbuf times; /* Times for utime() call */
939
941 if (gn->type & (OP_JOIN|OP_USE|OP_EXEC|OP_OPTIONAL)) {
940 if (gn->type & (OP_JOIN | OP_USE | OP_EXEC | OP_OPTIONAL)) {
942 /*
943 * .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual" targets
944 * and, as such, shouldn't really be created.
945 */
946 return;
947 }
948
949 if (!silent) {

--- 242 unchanged lines hidden (view full) ---

1192 job->cmdFILE = NULL;
1193 }
1194 }
1195
1196 /*
1197 * Now the job is actually running, add it to the table.
1198 */
1199 nJobs += 1;
941 /*
942 * .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual" targets
943 * and, as such, shouldn't really be created.
944 */
945 return;
946 }
947
948 if (!silent) {

--- 242 unchanged lines hidden (view full) ---

1191 job->cmdFILE = NULL;
1192 }
1193 }
1194
1195 /*
1196 * Now the job is actually running, add it to the table.
1197 */
1198 nJobs += 1;
1200 Lst_AtEnd(jobs, (void *)job);
1199 Lst_AtEnd(jobs, job);
1201 if (nJobs == maxJobs) {
1202 jobFull = TRUE;
1203 }
1204}
1205
1206/*-
1207 *-----------------------------------------------------------------------
1208 * JobMakeArgv --

--- 174 unchanged lines hidden (view full) ---

1383 if (interrupted) {
1384 JobPassSig(interrupted);
1385 return (JOB_ERROR);
1386 }
1387 if (previous != NULL) {
1388 previous->flags &= ~(JOB_FIRST|JOB_IGNERR|JOB_SILENT);
1389 job = previous;
1390 } else {
1200 if (nJobs == maxJobs) {
1201 jobFull = TRUE;
1202 }
1203}
1204
1205/*-
1206 *-----------------------------------------------------------------------
1207 * JobMakeArgv --

--- 174 unchanged lines hidden (view full) ---

1382 if (interrupted) {
1383 JobPassSig(interrupted);
1384 return (JOB_ERROR);
1385 }
1386 if (previous != NULL) {
1387 previous->flags &= ~(JOB_FIRST|JOB_IGNERR|JOB_SILENT);
1388 job = previous;
1389 } else {
1391 job = (Job *)emalloc(sizeof(Job));
1390 job = emalloc(sizeof(Job));
1392 flags |= JOB_FIRST;
1393 }
1394
1395 job->node = gn;
1396 job->tailCmds = NULL;
1397
1398 /*
1399 * Set the initial value of the flags for this job based on the global

--- 64 unchanged lines hidden (view full) ---

1464 * ellipsis, note that there's nothing more to execute.
1465 */
1466 if ((job->flags&JOB_FIRST) && (Lst_Open(gn->commands) != SUCCESS)){
1467 cmdsOK = FALSE;
1468 } else {
1469 LstNode ln = Lst_Next(gn->commands);
1470
1471 if ((ln == NULL) ||
1391 flags |= JOB_FIRST;
1392 }
1393
1394 job->node = gn;
1395 job->tailCmds = NULL;
1396
1397 /*
1398 * Set the initial value of the flags for this job based on the global

--- 64 unchanged lines hidden (view full) ---

1463 * ellipsis, note that there's nothing more to execute.
1464 */
1465 if ((job->flags&JOB_FIRST) && (Lst_Open(gn->commands) != SUCCESS)){
1466 cmdsOK = FALSE;
1467 } else {
1468 LstNode ln = Lst_Next(gn->commands);
1469
1470 if ((ln == NULL) ||
1472 JobPrintCommand((void *)Lst_Datum(ln),
1473 (void *)job))
1471 JobPrintCommand(Lst_Datum(ln), job))
1474 {
1475 noExec = TRUE;
1476 Lst_Close(gn->commands);
1477 }
1478 if (noExec && !(job->flags & JOB_FIRST)) {
1479 /*
1480 * If we're not going to execute anything, the job
1481 * is done and we need to close down the various

--- 8 unchanged lines hidden (view full) ---

1490 JobClose(job);
1491 }
1492 }
1493 } else {
1494 /*
1495 * We can do all the commands at once. hooray for sanity
1496 */
1497 numCommands = 0;
1472 {
1473 noExec = TRUE;
1474 Lst_Close(gn->commands);
1475 }
1476 if (noExec && !(job->flags & JOB_FIRST)) {
1477 /*
1478 * If we're not going to execute anything, the job
1479 * is done and we need to close down the various

--- 8 unchanged lines hidden (view full) ---

1488 JobClose(job);
1489 }
1490 }
1491 } else {
1492 /*
1493 * We can do all the commands at once. hooray for sanity
1494 */
1495 numCommands = 0;
1498 Lst_ForEach(gn->commands, JobPrintCommand, (void *)job);
1496 Lst_ForEach(gn->commands, JobPrintCommand, job);
1499
1500 /*
1501 * If we didn't print out any commands to the shell script,
1502 * there's not much point in executing the shell, is there?
1503 */
1504 if (numCommands == 0) {
1505 noExec = TRUE;
1506 }

--- 9 unchanged lines hidden (view full) ---

1516 }
1517 job->cmdFILE = stdout;
1518 /*
1519 * Only print the commands if they're ok, but don't die if they're
1520 * not -- just let the user know they're bad and keep going. It
1521 * doesn't do any harm in this case and may do some good.
1522 */
1523 if (cmdsOK) {
1497
1498 /*
1499 * If we didn't print out any commands to the shell script,
1500 * there's not much point in executing the shell, is there?
1501 */
1502 if (numCommands == 0) {
1503 noExec = TRUE;
1504 }

--- 9 unchanged lines hidden (view full) ---

1514 }
1515 job->cmdFILE = stdout;
1516 /*
1517 * Only print the commands if they're ok, but don't die if they're
1518 * not -- just let the user know they're bad and keep going. It
1519 * doesn't do any harm in this case and may do some good.
1520 */
1521 if (cmdsOK) {
1524 Lst_ForEach(gn->commands, JobPrintCommand, (void *)job);
1522 Lst_ForEach(gn->commands, JobPrintCommand, job);
1525 }
1526 /*
1527 * Don't execute the shell, thank you.
1528 */
1529 noExec = TRUE;
1530 } else {
1531 /*
1532 * Just touch the target and note that no shell should be executed.
1533 * Set cmdFILE to stdout to make life easier. Check the commands, too,
1534 * but don't die if they're no good -- it does no harm to keep working
1535 * up the graph.
1536 */
1537 job->cmdFILE = stdout;
1523 }
1524 /*
1525 * Don't execute the shell, thank you.
1526 */
1527 noExec = TRUE;
1528 } else {
1529 /*
1530 * Just touch the target and note that no shell should be executed.
1531 * Set cmdFILE to stdout to make life easier. Check the commands, too,
1532 * but don't die if they're no good -- it does no harm to keep working
1533 * up the graph.
1534 */
1535 job->cmdFILE = stdout;
1538 Job_Touch(gn, job->flags&JOB_SILENT);
1536 Job_Touch(gn, job->flags & JOB_SILENT);
1539 noExec = TRUE;
1540 }
1541
1542 /*
1543 * If we're not supposed to execute a shell, don't.
1544 */
1545 if (noExec) {
1546 /*

--- 9 unchanged lines hidden (view full) ---

1556 /*
1557 * We only want to work our way up the graph if we aren't here because
1558 * the commands for the job were no good.
1559 */
1560 if (cmdsOK) {
1561 if (aborting == 0) {
1562 if (job->tailCmds != NULL) {
1563 Lst_ForEachFrom(job->node->commands, job->tailCmds,
1537 noExec = TRUE;
1538 }
1539
1540 /*
1541 * If we're not supposed to execute a shell, don't.
1542 */
1543 if (noExec) {
1544 /*

--- 9 unchanged lines hidden (view full) ---

1554 /*
1555 * We only want to work our way up the graph if we aren't here because
1556 * the commands for the job were no good.
1557 */
1558 if (cmdsOK) {
1559 if (aborting == 0) {
1560 if (job->tailCmds != NULL) {
1561 Lst_ForEachFrom(job->node->commands, job->tailCmds,
1564 JobSaveCommand,
1565 (void *)job->node);
1562 JobSaveCommand, job->node);
1566 }
1567 job->node->made = MADE;
1568 Make_Update(job->node);
1569 }
1570 free(job);
1571 return(JOB_FINISHED);
1572 } else {
1573 free(job);

--- 40 unchanged lines hidden (view full) ---

1614 * some other job finishes. Note that the special jobs (.BEGIN,
1615 * .INTERRUPT and .END) may be run even when the limit has been reached
1616 * (e.g. when maxJobs == 0).
1617 */
1618 jobFull = TRUE;
1619
1620 DEBUGF(JOB, ("Can only run job locally.\n"));
1621 job->flags |= JOB_RESTART;
1563 }
1564 job->node->made = MADE;
1565 Make_Update(job->node);
1566 }
1567 free(job);
1568 return(JOB_FINISHED);
1569 } else {
1570 free(job);

--- 40 unchanged lines hidden (view full) ---

1611 * some other job finishes. Note that the special jobs (.BEGIN,
1612 * .INTERRUPT and .END) may be run even when the limit has been reached
1613 * (e.g. when maxJobs == 0).
1614 */
1615 jobFull = TRUE;
1616
1617 DEBUGF(JOB, ("Can only run job locally.\n"));
1618 job->flags |= JOB_RESTART;
1622 Lst_AtEnd(stoppedJobs, (void *)job);
1619 Lst_AtEnd(stoppedJobs, job);
1623 } else {
1624 if (nJobs >= maxJobs) {
1625 /*
1626 * If we're running this job locally as a special case (see above),
1627 * at least say the table is full.
1628 */
1629 jobFull = TRUE;
1630 DEBUGF(JOB, ("Local job queue is full.\n"));

--- 81 unchanged lines hidden (view full) ---

1712 int nr; /* number of bytes read */
1713 int i; /* auxiliary index into outBuf */
1714 int max; /* limit for i (end of current data) */
1715 int nRead; /* (Temporary) number of bytes read */
1716
1717 FILE *oFILE; /* Stream pointer to shell's output file */
1718 char inLine[132];
1719
1620 } else {
1621 if (nJobs >= maxJobs) {
1622 /*
1623 * If we're running this job locally as a special case (see above),
1624 * at least say the table is full.
1625 */
1626 jobFull = TRUE;
1627 DEBUGF(JOB, ("Local job queue is full.\n"));

--- 81 unchanged lines hidden (view full) ---

1709 int nr; /* number of bytes read */
1710 int i; /* auxiliary index into outBuf */
1711 int max; /* limit for i (end of current data) */
1712 int nRead; /* (Temporary) number of bytes read */
1713
1714 FILE *oFILE; /* Stream pointer to shell's output file */
1715 char inLine[132];
1716
1720
1721 if (usePipes) {
1722 /*
1723 * Read as many bytes as will fit in the buffer.
1724 */
1725end_loop:
1726 gotNL = FALSE;
1727 fbuf = FALSE;
1728

--- 120 unchanged lines hidden (view full) ---

1849 * to print the noPrint line for the shell we used, then close and
1850 * remove the temporary file. Very simple.
1851 *
1852 * Change to read in blocks and do FindSubString type things as for
1853 * pipes? That would allow for "@echo -n..."
1854 */
1855 oFILE = fopen(job->outFile, "r");
1856 if (oFILE != NULL) {
1717 if (usePipes) {
1718 /*
1719 * Read as many bytes as will fit in the buffer.
1720 */
1721end_loop:
1722 gotNL = FALSE;
1723 fbuf = FALSE;
1724

--- 120 unchanged lines hidden (view full) ---

1845 * to print the noPrint line for the shell we used, then close and
1846 * remove the temporary file. Very simple.
1847 *
1848 * Change to read in blocks and do FindSubString type things as for
1849 * pipes? That would allow for "@echo -n..."
1850 */
1851 oFILE = fopen(job->outFile, "r");
1852 if (oFILE != NULL) {
1857 fprintf(stdout, "Results of making %s:\n", job->node->name);
1858 fflush(stdout);
1853 fprintf(stdout, "Results of making %s:\n", job->node->name);
1854 fflush(stdout);
1859 while (fgets(inLine, sizeof(inLine), oFILE) != NULL) {
1860 char *cp, *endp, *oendp;
1861
1862 cp = inLine;
1863 oendp = endp = inLine + strlen(inLine);
1864 if (endp[-1] == '\n') {
1865 *--endp = '\0';
1866 }

--- 6 unchanged lines hidden (view full) ---

1873 */
1874 fprintf(stdout, "%s", cp);
1875 fflush(stdout);
1876 if (endp != oendp) {
1877 fprintf(stdout, "\n");
1878 fflush(stdout);
1879 }
1880 }
1855 while (fgets(inLine, sizeof(inLine), oFILE) != NULL) {
1856 char *cp, *endp, *oendp;
1857
1858 cp = inLine;
1859 oendp = endp = inLine + strlen(inLine);
1860 if (endp[-1] == '\n') {
1861 *--endp = '\0';
1862 }

--- 6 unchanged lines hidden (view full) ---

1869 */
1870 fprintf(stdout, "%s", cp);
1871 fflush(stdout);
1872 if (endp != oendp) {
1873 fprintf(stdout, "\n");
1874 fflush(stdout);
1875 }
1876 }
1881 fclose(oFILE);
1882 eunlink(job->outFile);
1877 fclose(oFILE);
1878 eunlink(job->outFile);
1883 }
1884 }
1885}
1886
1887/*-
1888 *-----------------------------------------------------------------------
1889 * Job_CatchChildren --
1890 * Handle the exit of a child. Called from Make_Make.

--- 28 unchanged lines hidden (view full) ---

1919 }
1920
1921 for (;;) {
1922 pid = waitpid((pid_t)-1, &status, (block ? 0 : WNOHANG) | WUNTRACED);
1923 if (pid <= 0)
1924 break;
1925 DEBUGF(JOB, ("Process %d exited or stopped.\n", pid));
1926
1879 }
1880 }
1881}
1882
1883/*-
1884 *-----------------------------------------------------------------------
1885 * Job_CatchChildren --
1886 * Handle the exit of a child. Called from Make_Make.

--- 28 unchanged lines hidden (view full) ---

1915 }
1916
1917 for (;;) {
1918 pid = waitpid((pid_t)-1, &status, (block ? 0 : WNOHANG) | WUNTRACED);
1919 if (pid <= 0)
1920 break;
1921 DEBUGF(JOB, ("Process %d exited or stopped.\n", pid));
1922
1927 jnode = Lst_Find(jobs, (void *)&pid, JobCmpPid);
1923 jnode = Lst_Find(jobs, &pid, JobCmpPid);
1928
1929 if (jnode == NULL) {
1930 if (WIFSIGNALED(status) && (WTERMSIG(status) == SIGCONT)) {
1924
1925 if (jnode == NULL) {
1926 if (WIFSIGNALED(status) && (WTERMSIG(status) == SIGCONT)) {
1931 jnode = Lst_Find(stoppedJobs, (void *)&pid, JobCmpPid);
1927 jnode = Lst_Find(stoppedJobs, &pid, JobCmpPid);
1932 if (jnode == NULL) {
1933 Error("Resumed child (%d) not in table", pid);
1934 continue;
1935 }
1928 if (jnode == NULL) {
1929 Error("Resumed child (%d) not in table", pid);
1930 continue;
1931 }
1936 job = (Job *)Lst_Datum(jnode);
1932 job = Lst_Datum(jnode);
1937 Lst_Remove(stoppedJobs, jnode);
1938 } else {
1939 Error("Child (%d) not in table?", pid);
1940 continue;
1941 }
1942 } else {
1933 Lst_Remove(stoppedJobs, jnode);
1934 } else {
1935 Error("Child (%d) not in table?", pid);
1936 continue;
1937 }
1938 } else {
1943 job = (Job *)Lst_Datum(jnode);
1939 job = Lst_Datum(jnode);
1944 Lst_Remove(jobs, jnode);
1945 nJobs -= 1;
1946 if (fifoFd >= 0 && maxJobs > 1) {
1947 write(fifoFd, "+", 1);
1948 maxJobs--;
1949 if (nJobs >= maxJobs)
1950 jobFull = TRUE;
1951 else

--- 69 unchanged lines hidden (view full) ---

2021 }
2022#else
2023 readfds = outputs;
2024 timeout.tv_sec = SEL_SEC;
2025 timeout.tv_usec = SEL_USEC;
2026 if (flag && jobFull && fifoFd >= 0)
2027 FD_SET(fifoFd, &readfds);
2028
1940 Lst_Remove(jobs, jnode);
1941 nJobs -= 1;
1942 if (fifoFd >= 0 && maxJobs > 1) {
1943 write(fifoFd, "+", 1);
1944 maxJobs--;
1945 if (nJobs >= maxJobs)
1946 jobFull = TRUE;
1947 else

--- 69 unchanged lines hidden (view full) ---

2017 }
2018#else
2019 readfds = outputs;
2020 timeout.tv_sec = SEL_SEC;
2021 timeout.tv_usec = SEL_USEC;
2022 if (flag && jobFull && fifoFd >= 0)
2023 FD_SET(fifoFd, &readfds);
2024
2029 nfds = select(FD_SETSIZE, &readfds, (fd_set *) 0,
2030 (fd_set *) 0, &timeout);
2025 nfds = select(FD_SETSIZE, &readfds, (fd_set *)NULL,
2026 (fd_set *)NULL, &timeout);
2031 if (nfds <= 0) {
2032 if (interrupted)
2033 JobPassSig(interrupted);
2034 return;
2035 }
2036 if (fifoFd >= 0 && FD_ISSET(fifoFd, &readfds)) {
2037 if (--nfds <= 0)
2038 return;
2039 }
2040 if (Lst_Open(jobs) == FAILURE) {
2041 Punt("Cannot open job table");
2042 }
2043 while (nfds && (ln = Lst_Next(jobs)) != NULL) {
2027 if (nfds <= 0) {
2028 if (interrupted)
2029 JobPassSig(interrupted);
2030 return;
2031 }
2032 if (fifoFd >= 0 && FD_ISSET(fifoFd, &readfds)) {
2033 if (--nfds <= 0)
2034 return;
2035 }
2036 if (Lst_Open(jobs) == FAILURE) {
2037 Punt("Cannot open job table");
2038 }
2039 while (nfds && (ln = Lst_Next(jobs)) != NULL) {
2044 job = (Job *)Lst_Datum(ln);
2040 job = Lst_Datum(ln);
2045 if (FD_ISSET(job->inPipe, &readfds)) {
2046 JobDoOutput(job, FALSE);
2047 nfds -= 1;
2048 }
2049 }
2050 Lst_Close(jobs);
2051#endif /* !USE_KQUEUE */
2052 }

--- 153 unchanged lines hidden (view full) ---

2206 if (fifoFd >= 0) {
2207 fifoMaster = 1;
2208 fcntl(fifoFd, F_SETFL, O_NONBLOCK);
2209 env = fifoName;
2210 setenv("MAKE_JOBS_FIFO", env, 1);
2211 while (maxproc-- > 0) {
2212 write(fifoFd, "+", 1);
2213 }
2041 if (FD_ISSET(job->inPipe, &readfds)) {
2042 JobDoOutput(job, FALSE);
2043 nfds -= 1;
2044 }
2045 }
2046 Lst_Close(jobs);
2047#endif /* !USE_KQUEUE */
2048 }

--- 153 unchanged lines hidden (view full) ---

2202 if (fifoFd >= 0) {
2203 fifoMaster = 1;
2204 fcntl(fifoFd, F_SETFL, O_NONBLOCK);
2205 env = fifoName;
2206 setenv("MAKE_JOBS_FIFO", env, 1);
2207 while (maxproc-- > 0) {
2208 write(fifoFd, "+", 1);
2209 }
2214 /*The master make does not get a magic token */
2210 /* The master make does not get a magic token */
2215 jobFull = TRUE;
2216 maxJobs = 0;
2217 } else {
2218 unlink(fifoName);
2219 env = NULL;
2220 }
2221 }
2222 } else if (env != NULL) {

--- 82 unchanged lines hidden (view full) ---

2305 if ((kqfd = kqueue()) == -1) {
2306 Punt("kqueue: %s", strerror(errno));
2307 }
2308#endif
2309
2310 begin = Targ_FindNode(".BEGIN", TARG_NOCREATE);
2311
2312 if (begin != NULL) {
2211 jobFull = TRUE;
2212 maxJobs = 0;
2213 } else {
2214 unlink(fifoName);
2215 env = NULL;
2216 }
2217 }
2218 } else if (env != NULL) {

--- 82 unchanged lines hidden (view full) ---

2301 if ((kqfd = kqueue()) == -1) {
2302 Punt("kqueue: %s", strerror(errno));
2303 }
2304#endif
2305
2306 begin = Targ_FindNode(".BEGIN", TARG_NOCREATE);
2307
2308 if (begin != NULL) {
2313 JobStart(begin, JOB_SPECIAL, (Job *)0);
2309 JobStart(begin, JOB_SPECIAL, (Job *)NULL);
2314 while (nJobs) {
2315 Job_CatchOutput(0);
2316 Job_CatchChildren(!usePipes);
2317 }
2318 }
2319 postCommands = Targ_FindNode(".END", TARG_CREATE);
2320}
2321

--- 316 unchanged lines hidden (view full) ---

2638 LstNode ln; /* element in job table */
2639 Job *job = NULL; /* job descriptor in that element */
2640 GNode *interrupt; /* the node describing the .INTERRUPT target */
2641
2642 aborting = ABORT_INTERRUPT;
2643
2644 Lst_Open(jobs);
2645 while ((ln = Lst_Next(jobs)) != NULL) {
2310 while (nJobs) {
2311 Job_CatchOutput(0);
2312 Job_CatchChildren(!usePipes);
2313 }
2314 }
2315 postCommands = Targ_FindNode(".END", TARG_CREATE);
2316}
2317

--- 316 unchanged lines hidden (view full) ---

2634 LstNode ln; /* element in job table */
2635 Job *job = NULL; /* job descriptor in that element */
2636 GNode *interrupt; /* the node describing the .INTERRUPT target */
2637
2638 aborting = ABORT_INTERRUPT;
2639
2640 Lst_Open(jobs);
2641 while ((ln = Lst_Next(jobs)) != NULL) {
2646 job = (Job *)Lst_Datum(ln);
2642 job = Lst_Datum(ln);
2647
2648 if (!Targ_Precious(job->node)) {
2649 char *file = (job->node->path == NULL ?
2650 job->node->name :
2651 job->node->path);
2652 if (!noExecute && eunlink(file) != -1) {
2653 Error("*** %s removed", file);
2654 }

--- 9 unchanged lines hidden (view full) ---

2664 /* clear the interrupted flag because we would get an
2665 * infinite loop otherwise */
2666 interrupted = 0;
2667
2668 interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE);
2669 if (interrupt != NULL) {
2670 ignoreErrors = FALSE;
2671
2643
2644 if (!Targ_Precious(job->node)) {
2645 char *file = (job->node->path == NULL ?
2646 job->node->name :
2647 job->node->path);
2648 if (!noExecute && eunlink(file) != -1) {
2649 Error("*** %s removed", file);
2650 }

--- 9 unchanged lines hidden (view full) ---

2660 /* clear the interrupted flag because we would get an
2661 * infinite loop otherwise */
2662 interrupted = 0;
2663
2664 interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE);
2665 if (interrupt != NULL) {
2666 ignoreErrors = FALSE;
2667
2672 JobStart(interrupt, JOB_IGNDOTS, (Job *)0);
2668 JobStart(interrupt, JOB_IGNDOTS, (Job *)NULL);
2673 while (nJobs) {
2674 Job_CatchOutput(0);
2675 Job_CatchChildren(!usePipes);
2676 }
2677 }
2678 }
2679}
2680

--- 77 unchanged lines hidden (view full) ---

2758{
2759 LstNode ln; /* element in job table */
2760 Job *job; /* the job descriptor in that element */
2761 int foo;
2762
2763 aborting = ABORT_ERROR;
2764
2765 if (nJobs) {
2669 while (nJobs) {
2670 Job_CatchOutput(0);
2671 Job_CatchChildren(!usePipes);
2672 }
2673 }
2674 }
2675}
2676

--- 77 unchanged lines hidden (view full) ---

2754{
2755 LstNode ln; /* element in job table */
2756 Job *job; /* the job descriptor in that element */
2757 int foo;
2758
2759 aborting = ABORT_ERROR;
2760
2761 if (nJobs) {
2766
2767 Lst_Open(jobs);
2768 while ((ln = Lst_Next(jobs)) != NULL) {
2762 Lst_Open(jobs);
2763 while ((ln = Lst_Next(jobs)) != NULL) {
2769 job = (Job *)Lst_Datum(ln);
2764 job = Lst_Datum(ln);
2770
2771 /*
2772 * kill the child process with increasingly drastic signals to make
2773 * darn sure it's dead.
2774 */
2775 KILL(job->pid, SIGINT);
2776 KILL(job->pid, SIGKILL);
2777 }

--- 21 unchanged lines hidden (view full) ---

2799 *
2800 *-----------------------------------------------------------------------
2801 */
2802static void
2803JobRestartJobs(void)
2804{
2805 while (!jobFull && !Lst_IsEmpty(stoppedJobs)) {
2806 DEBUGF(JOB, ("Job queue is not full. Restarting a stopped job.\n"));
2765
2766 /*
2767 * kill the child process with increasingly drastic signals to make
2768 * darn sure it's dead.
2769 */
2770 KILL(job->pid, SIGINT);
2771 KILL(job->pid, SIGKILL);
2772 }

--- 21 unchanged lines hidden (view full) ---

2794 *
2795 *-----------------------------------------------------------------------
2796 */
2797static void
2798JobRestartJobs(void)
2799{
2800 while (!jobFull && !Lst_IsEmpty(stoppedJobs)) {
2801 DEBUGF(JOB, ("Job queue is not full. Restarting a stopped job.\n"));
2807 JobRestart((Job *)Lst_DeQueue(stoppedJobs));
2802 JobRestart(Lst_DeQueue(stoppedJobs));
2808 }
2809}
2803 }
2804}