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} |