Changeset 24 for branches/FREEBSD/src/kmk/job.c
- Timestamp:
- Nov 26, 2002, 10:24:54 PM (23 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/FREEBSD/src/kmk/job.c
r10 r24 1 1 /* 2 * Copyright (c) 1988, 1989, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 2 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 4 3 * Copyright (c) 1988, 1989 by Adam de Boor 5 4 * Copyright (c) 1989 by Berkeley Softworks … … 36 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 36 * SUCH DAMAGE. 38 * 39 * @(#)job.c 8.2 (Berkeley) 3/19/94 40 */ 41 42 #include <sys/cdefs.h> 43 __FBSDID("$FreeBSD: src/usr.bin/make/job.c,v 1.45 2002/10/09 03:42:10 jmallett Exp $"); 37 */ 38 39 #ifndef lint 40 #if 0 41 static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94"; 42 #else 43 static const char rcsid[] = 44 "$FreeBSD: src/usr.bin/make/job.c,v 1.17.2.2 2001/02/13 03:13:57 will Exp $"; 45 #endif 46 #endif /* not lint */ 44 47 45 48 #ifndef OLD_JOKE 46 #define 49 #define OLD_JOKE 0 47 50 #endif /* OLD_JOKE */ 48 51 … … 84 87 * FAILURE if the spec was incorrect. 85 88 * 86 * Job_ FinishPerform any final processing which needs doing.89 * Job_End Perform any final processing which needs doing. 87 90 * This includes the execution of any commands 88 91 * which have been/were attached to the .END … … 107 110 #include <sys/file.h> 108 111 #include <sys/time.h> 109 #include <sys/event.h>110 112 #include <sys/wait.h> 111 #include < err.h>113 #include <fcntl.h> 112 114 #include <errno.h> 113 #include < fcntl.h>115 #include <utime.h> 114 116 #include <stdio.h> 115 117 #include <string.h> 116 118 #include <signal.h> 117 #include <unistd.h>118 #include <utime.h>119 119 #include "make.h" 120 120 #include "hash.h" … … 134 134 static int errors = 0; /* number of errors reported */ 135 135 static int aborting = 0; /* why is the make aborting? */ 136 #define 137 #define 138 #define 136 #define ABORT_ERROR 1 /* Because of an error */ 137 #define ABORT_INTERRUPT 2 /* Because it was interrupted */ 138 #define ABORT_WAIT 3 /* Waiting for jobs to finish */ 139 139 140 140 /* … … 142 142 * is a char! So when we go above 127 we turn negative! 143 143 */ 144 #define 144 #define FILENO(a) ((unsigned) fileno(a)) 145 145 146 146 /* … … 158 158 * Return values from JobStart. 159 159 */ 160 #define 161 #define 162 #define 163 #define 160 #define JOB_RUNNING 0 /* Job is running */ 161 #define JOB_ERROR 1 /* Error in starting the job */ 162 #define JOB_FINISHED 2 /* The job is already finished */ 163 #define JOB_STOPPED 3 /* The job is stopped */ 164 164 165 165 /* … … 196 196 FALSE, "echo \"%s\"\n", "sh -c '%s || exit 0'\n", 197 197 #endif 198 "v", "e",199 },200 /*201 * KSH description. The Korn shell has a superset of202 * the Bourne shell's functionality.203 */204 {205 "ksh",206 TRUE, "set -", "set -v", "set -", 5,207 TRUE, "set -e", "set +e",208 198 "v", "e", 209 199 }, … … 239 229 * nLocal equals maxLocal */ 240 230 #ifndef RMT_WILL_WATCH 241 #ifdef USE_KQUEUE242 static int kqfd; /* File descriptor obtained by kqueue() */243 #else244 231 static fd_set outputs; /* Set of descriptors of pipes connected to 245 232 * the output channels of children */ 246 #endif247 233 #endif 248 234 … … 290 276 * really ugly, use dramamine sparingly. You have been warned. 291 277 */ 292 #define 278 #define W_SETMASKED(st, val, fun) \ 293 279 { \ 294 280 int sh = (int) ~0; \ … … 300 286 } 301 287 302 #define 303 #define 304 305 306 static int JobCondPassSig (void *, void *);307 static void JobPassSig (int);308 static int JobCmpPid (void *, void *);309 static int JobPrintCommand (void *, void *);310 static int JobSaveCommand (void *, void *);311 static void JobClose (Job *);288 #define W_SETTERMSIG(st, val) W_SETMASKED(st, val, WTERMSIG) 289 #define W_SETEXITSTATUS(st, val) W_SETMASKED(st, val, WEXITSTATUS) 290 291 292 static int JobCondPassSig __P((ClientData, ClientData)); 293 static void JobPassSig __P((int)); 294 static int JobCmpPid __P((ClientData, ClientData)); 295 static int JobPrintCommand __P((ClientData, ClientData)); 296 static int JobSaveCommand __P((ClientData, ClientData)); 297 static void JobClose __P((Job *)); 312 298 #ifdef REMOTE 313 static int JobCmpRmtID (Job *, int);299 static int JobCmpRmtID __P((Job *, int)); 314 300 # ifdef RMT_WILL_WATCH 315 static void JobLocalInput (int, Job *);301 static void JobLocalInput __P((int, Job *)); 316 302 # endif 317 303 #else 318 static void JobFinish (Job *, int *);319 static void JobExec (Job *, char **);320 #endif 321 static void JobMakeArgv (Job *, char **);322 static void JobRestart (Job *);323 static int JobStart (GNode *, int, Job *);324 static char *JobOutput (Job *, char *, char *, int);325 static void JobDoOutput (Job *, Boolean);326 static Shell *JobMatchShell (char *);327 static void JobInterrupt (int, int);328 static void JobRestartJobs (void);304 static void JobFinish __P((Job *, int *)); 305 static void JobExec __P((Job *, char **)); 306 #endif 307 static void JobMakeArgv __P((Job *, char **)); 308 static void JobRestart __P((Job *)); 309 static int JobStart __P((GNode *, int, Job *)); 310 static char *JobOutput __P((Job *, char *, char *, int)); 311 static void JobDoOutput __P((Job *, Boolean)); 312 static Shell *JobMatchShell __P((char *)); 313 static void JobInterrupt __P((int, int)); 314 static void JobRestartJobs __P((void)); 329 315 330 316 /*- … … 343 329 */ 344 330 static int 345 JobCondPassSig(void *jobp, void *signop) 331 JobCondPassSig(jobp, signop) 332 ClientData jobp; /* Job to biff */ 333 ClientData signop; /* Signal to send it */ 346 334 { 347 335 Job *job = (Job *) jobp; … … 358 346 * job as well. 359 347 */ 360 DEBUGF(JOB, ("JobCondPassSig passing signal %d to child %d.\n", signo, job->pid)); 348 if (DEBUG(JOB)) { 349 (void) fprintf(stdout, 350 "JobCondPassSig passing signal %d to child %d.\n", 351 signo, job->pid); 352 (void) fflush(stdout); 353 } 361 354 KILL(job->pid, signo); 362 355 #endif … … 379 372 */ 380 373 static void 381 JobPassSig(int signo) 374 JobPassSig(signo) 375 int signo; /* The signal number we've received */ 382 376 { 383 377 sigset_t nmask, omask; 384 378 struct sigaction act; 385 379 386 DEBUGF(JOB, ("JobPassSig(%d) called.\n", signo)); 387 Lst_ForEach(jobs, JobCondPassSig, (void *) &signo); 380 if (DEBUG(JOB)) { 381 (void) fprintf(stdout, "JobPassSig(%d) called.\n", signo); 382 (void) fflush(stdout); 383 } 384 Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo); 388 385 389 386 /* … … 419 416 sigaction(signo, &act, NULL); 420 417 421 DEBUGF(JOB, ("JobPassSig passing signal to self, mask = %x.\n", ~0 & ~(1 << (signo-1)))); 418 if (DEBUG(JOB)) { 419 (void) fprintf(stdout, 420 "JobPassSig passing signal to self, mask = %x.\n", 421 ~0 & ~(1 << (signo-1))); 422 (void) fflush(stdout); 423 } 422 424 (void) signal(signo, SIG_DFL); 423 425 … … 425 427 426 428 signo = SIGCONT; 427 Lst_ForEach(jobs, JobCondPassSig, ( void *) &signo);429 Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo); 428 430 429 431 (void) sigprocmask(SIG_SETMASK, &omask, NULL); … … 448 450 */ 449 451 static int 450 JobCmpPid(void *job, void *pid) 452 JobCmpPid(job, pid) 453 ClientData job; /* job to examine */ 454 ClientData pid; /* process id desired */ 451 455 { 452 456 return *(int *) pid - ((Job *) job)->pid; … … 468 472 */ 469 473 static int 470 JobCmpRmtID(void *job, void *rmtID) 474 JobCmpRmtID(job, rmtID) 475 ClientData job; /* job to examine */ 476 ClientData rmtID; /* remote id desired */ 471 477 { 472 478 return(*(int *) rmtID - *(int *) job->rmtID); … … 487 493 * made and return non-zero to signal that the end of the commands 488 494 * was reached. These commands are later attached to the postCommands 489 * node and executed by Job_ Finishwhen all things are done.495 * node and executed by Job_End when all things are done. 490 496 * This function is called from JobStart via Lst_ForEach. 491 497 * … … 502 508 */ 503 509 static int 504 JobPrintCommand(void *cmdp, void *jobp) 510 JobPrintCommand(cmdp, jobp) 511 ClientData cmdp; /* command string to print */ 512 ClientData jobp; /* job for which to print it */ 505 513 { 506 514 Boolean noSpecials; /* true if we shouldn't worry about … … 525 533 if ((job->flags & JOB_IGNDOTS) == 0) { 526 534 job->tailCmds = Lst_Succ(Lst_Member(job->node->commands, 527 ( void *)cmd));535 (ClientData)cmd)); 528 536 return 1; 529 537 } … … 531 539 } 532 540 533 #define DBPRINTF(fmt, arg) \ 534 DEBUGF(JOB, (fmt, arg)); \ 541 #define DBPRINTF(fmt, arg) if (DEBUG(JOB)) { \ 542 (void) fprintf(stdout, fmt, arg); \ 543 (void) fflush(stdout); \ 544 } \ 535 545 (void) fprintf(job->cmdFILE, fmt, arg); \ 536 546 (void) fflush(job->cmdFILE); … … 542 552 * the variables in the command. 543 553 */ 544 cmdNode = Lst_Member(job->node->commands, ( void *)cmd);554 cmdNode = Lst_Member(job->node->commands, (ClientData)cmd); 545 555 cmdStart = cmd = Var_Subst(NULL, cmd, job->node, FALSE); 546 Lst_Replace(cmdNode, ( void *)cmdStart);556 Lst_Replace(cmdNode, (ClientData)cmdStart); 547 557 548 558 cmdTemplate = "%s\n"; … … 659 669 */ 660 670 static int 661 JobSaveCommand(void *cmd, void *gn) 662 { 663 cmd = (void *) Var_Subst(NULL, (char *) cmd, (GNode *) gn, FALSE); 671 JobSaveCommand(cmd, gn) 672 ClientData cmd; 673 ClientData gn; 674 { 675 cmd = (ClientData) Var_Subst(NULL, (char *) cmd, (GNode *) gn, FALSE); 664 676 (void) Lst_AtEnd(postCommands->commands, cmd); 665 677 return(0); … … 681 693 */ 682 694 static void 683 JobClose(Job *job) 695 JobClose(job) 696 Job *job; 684 697 { 685 698 if (usePipes) { 686 699 #ifdef RMT_WILL_WATCH 687 700 Rmt_Ignore(job->inPipe); 688 #el if !defined(USE_KQUEUE)701 #else 689 702 FD_CLR(job->inPipe, &outputs); 690 703 #endif … … 725 738 /*ARGSUSED*/ 726 739 static void 727 JobFinish(Job *job, int *status) 740 JobFinish(job, status) 741 Job *job; /* job to finish */ 742 int *status; /* sub-why job went away */ 728 743 { 729 744 Boolean done; … … 794 809 */ 795 810 out = fdopen(job->outFd, "w"); 796 if (out == NULL)797 Punt("Cannot fdopen");798 811 } else { 799 812 out = stdout; … … 801 814 802 815 if (WIFEXITED(*status)) { 803 DEBUGF(JOB, ("Process %d exited.\n", job->pid)); 816 if (DEBUG(JOB)) { 817 (void) fprintf(stdout, "Process %d exited.\n", job->pid); 818 (void) fflush(stdout); 819 } 804 820 if (WEXITSTATUS(*status) != 0) { 805 821 if (usePipes && job->node != lastNode) { … … 822 838 } 823 839 } else if (WIFSTOPPED(*status)) { 824 DEBUGF(JOB, ("Process %d stopped.\n", job->pid)); 840 if (DEBUG(JOB)) { 841 (void) fprintf(stdout, "Process %d stopped.\n", job->pid); 842 (void) fflush(stdout); 843 } 825 844 if (usePipes && job->node != lastNode) { 826 845 MESSAGE(out, job->node); … … 832 851 } 833 852 job->flags |= JOB_RESUME; 834 (void)Lst_AtEnd(stoppedJobs, ( void *)job);853 (void)Lst_AtEnd(stoppedJobs, (ClientData)job); 835 854 #ifdef REMOTE 836 855 if (job->flags & JOB_REMIGRATE) … … 853 872 } 854 873 if (!(job->flags & JOB_CONTINUING)) { 855 DEBUGF(JOB, ("Warning: process %d was not continuing.\n", job->pid)); 874 if (DEBUG(JOB)) { 875 (void) fprintf(stdout, 876 "Warning: process %d was not continuing.\n", 877 job->pid); 878 (void) fflush(stdout); 879 } 856 880 #ifdef notdef 857 881 /* … … 865 889 } 866 890 job->flags &= ~JOB_CONTINUING; 867 Lst_AtEnd(jobs, ( void *)job);891 Lst_AtEnd(jobs, (ClientData)job); 868 892 nJobs += 1; 869 893 if (!(job->flags & JOB_REMOTE)) { 870 DEBUGF(JOB, ("Process %d is continuing locally.\n", job->pid)); 894 if (DEBUG(JOB)) { 895 (void) fprintf(stdout, 896 "Process %d is continuing locally.\n", 897 job->pid); 898 (void) fflush(stdout); 899 } 871 900 nLocal += 1; 872 901 } 873 902 if (nJobs == maxJobs) { 874 903 jobFull = TRUE; 875 DEBUGF(JOB, ("Job queue is full.\n")); 904 if (DEBUG(JOB)) { 905 (void) fprintf(stdout, "Job queue is full.\n"); 906 (void) fflush(stdout); 907 } 876 908 } 877 909 (void) fflush(out); … … 913 945 done = FALSE; 914 946 break; 915 default:916 break;917 947 } 918 948 } else { … … 932 962 * on the .END target. 933 963 */ 934 if (job->tailCmds != N ULL) {964 if (job->tailCmds != NILLNODE) { 935 965 Lst_ForEachFrom(job->node->commands, job->tailCmds, 936 966 JobSaveCommand, 937 ( void *)job->node);967 (ClientData)job->node); 938 968 } 939 969 job->node->made = MADE; 940 970 Make_Update(job->node); 941 free( job);971 free((Address)job); 942 972 } else if (*status != 0) { 943 973 errors += 1; 944 free( job);974 free((Address)job); 945 975 } 946 976 … … 970 1000 * Job_Touch -- 971 1001 * Touch the given target. Called by JobStart when the -t flag was 972 * given . Prints messages unless told to be silent.1002 * given 973 1003 * 974 1004 * Results: … … 981 1011 */ 982 1012 void 983 Job_Touch(GNode *gn, Boolean silent) 1013 Job_Touch(gn, silent) 1014 GNode *gn; /* the node of the file to touch */ 1015 Boolean silent; /* TRUE if should not print messages */ 984 1016 { 985 1017 int streamID; /* ID of stream opened to do the touch */ … … 1022 1054 */ 1023 1055 if (read(streamID, &c, 1) == 1) { 1024 (void) lseek(streamID, (off_t)0, SEEK_SET);1056 (void) lseek(streamID, 0L, SEEK_SET); 1025 1057 (void) write(streamID, &c, 1); 1026 1058 } … … 1050 1082 */ 1051 1083 Boolean 1052 Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...)) 1084 Job_CheckCommands(gn, abortProc) 1085 GNode *gn; /* The target whose commands need 1086 * verifying */ 1087 void (*abortProc) __P((char *, ...)); 1088 /* Function to abort with message */ 1053 1089 { 1054 1090 if (OP_NOP(gn->type) && Lst_IsEmpty(gn->commands) && … … 1058 1094 * commands 1059 1095 */ 1060 if ((DEFAULT != N ULL) && !Lst_IsEmpty(DEFAULT->commands)) {1096 if ((DEFAULT != NILGNODE) && !Lst_IsEmpty(DEFAULT->commands)) { 1061 1097 char *p1; 1062 1098 /* … … 1118 1154 /*ARGSUSED*/ 1119 1155 static void 1120 JobLocalInput(int stream, Job *job) 1156 JobLocalInput(stream, job) 1157 int stream; /* Stream that's ready (ignored) */ 1158 Job *job; /* Job to which the stream belongs */ 1121 1159 { 1122 1160 JobDoOutput(job, FALSE); … … 1140 1178 */ 1141 1179 static void 1142 JobExec(Job *job, char **argv) 1180 JobExec(job, argv) 1181 Job *job; /* Job to execute */ 1182 char **argv; 1143 1183 { 1144 1184 int cpid; /* ID of new child */ … … 1147 1187 int i; 1148 1188 1149 DEBUGF(JOB, ("Running %s %sly\n", job->node->name,1150 job->flags&JOB_REMOTE?"remote":"local"));1151 DEBUGF(JOB, ("\tCommand: "));1189 (void) fprintf(stdout, "Running %s %sly\n", job->node->name, 1190 job->flags&JOB_REMOTE?"remote":"local"); 1191 (void) fprintf(stdout, "\tCommand: "); 1152 1192 for (i = 0; argv[i] != NULL; i++) { 1153 DEBUGF(JOB, ("%s ", argv[i])); 1154 } 1155 DEBUGF(JOB, ("\n")); 1193 (void) fprintf(stdout, "%s ", argv[i]); 1194 } 1195 (void) fprintf(stdout, "\n"); 1196 (void) fflush(stdout); 1156 1197 } 1157 1198 … … 1186 1227 Punt("Cannot dup2: %s", strerror(errno)); 1187 1228 (void) fcntl(0, F_SETFD, 0); 1188 (void) lseek(0, (off_t)0, SEEK_SET);1229 (void) lseek(0, 0, SEEK_SET); 1189 1230 1190 1231 if (usePipes) { … … 1234 1275 (void) execv(shellPath, argv); 1235 1276 1236 (void) write( STDERR_FILENO, "Could not execute shell\n",1277 (void) write(2, "Could not execute shell\n", 1237 1278 sizeof("Could not execute shell")); 1238 1279 _exit(1); … … 1249 1290 * stream to watch in the outputs mask 1250 1291 */ 1251 #ifdef USE_KQUEUE1252 struct kevent kev[2];1253 #endif1254 1292 job->curPos = 0; 1255 1293 1256 1294 #ifdef RMT_WILL_WATCH 1257 1295 Rmt_Watch(job->inPipe, JobLocalInput, job); 1258 #elif defined(USE_KQUEUE)1259 EV_SET(&kev[0], job->inPipe, EVFILT_READ, EV_ADD, 0, 0, job);1260 EV_SET(&kev[1], job->pid, EVFILT_PROC, EV_ADD | EV_ONESHOT,1261 NOTE_EXIT, 0, NULL);1262 if (kevent(kqfd, kev, 2, NULL, 0, NULL) != 0) {1263 /* kevent() will fail if the job is already finished */1264 if (errno != EBADF && errno != ESRCH)1265 Punt("kevent: %s", strerror(errno));1266 }1267 1296 #else 1268 1297 FD_SET(job->inPipe, &outputs); … … 1298 1327 */ 1299 1328 nJobs += 1; 1300 (void) Lst_AtEnd(jobs, ( void *)job);1329 (void) Lst_AtEnd(jobs, (ClientData)job); 1301 1330 if (nJobs == maxJobs) { 1302 1331 jobFull = TRUE; … … 1317 1346 */ 1318 1347 static void 1319 JobMakeArgv(Job *job, char **argv) 1348 JobMakeArgv(job, argv) 1349 Job *job; 1350 char **argv; 1320 1351 { 1321 1352 int argc; … … 1371 1402 */ 1372 1403 static void 1373 JobRestart(Job *job) 1404 JobRestart(job) 1405 Job *job; /* Job to restart */ 1374 1406 { 1375 1407 #ifdef REMOTE … … 1430 1462 (void) fflush(stdout); 1431 1463 } 1432 (void)Lst_AtFront(stoppedJobs, ( void *)job);1464 (void)Lst_AtFront(stoppedJobs, (ClientData)job); 1433 1465 jobFull = TRUE; 1434 DEBUGF(JOB, ("Job queue is full.\n")); 1466 if (DEBUG(JOB)) { 1467 (void) fprintf(stdout, "Job queue is full.\n"); 1468 (void) fflush(stdout); 1469 } 1435 1470 return; 1436 1471 } … … 1448 1483 #endif 1449 1484 1450 (void)Lst_AtEnd(jobs, ( void *)job);1485 (void)Lst_AtEnd(jobs, (ClientData)job); 1451 1486 nJobs += 1; 1452 1487 if (nJobs == maxJobs) { 1453 1488 jobFull = TRUE; 1454 DEBUGF(JOB, ("Job queue is full.\n")); 1489 if (DEBUG(JOB)) { 1490 (void) fprintf(stdout, "Job queue is full.\n"); 1491 (void) fflush(stdout); 1492 } 1455 1493 } 1456 1494 } else if (job->flags & JOB_RESTART) { … … 1467 1505 JobMakeArgv(job, argv); 1468 1506 1469 DEBUGF(JOB, ("Restarting %s...", job->node->name)); 1507 if (DEBUG(JOB)) { 1508 (void) fprintf(stdout, "Restarting %s...", job->node->name); 1509 (void) fflush(stdout); 1510 } 1470 1511 #ifdef REMOTE 1471 1512 if ((job->node->type&OP_NOEXPORT) || … … 1483 1524 * back on the hold queue and mark the table full 1484 1525 */ 1485 DEBUGF(JOB, ("holding\n")); 1486 (void)Lst_AtFront(stoppedJobs, (void *)job); 1526 if (DEBUG(JOB)) { 1527 (void) fprintf(stdout, "holding\n"); 1528 (void) fflush(stdout); 1529 } 1530 (void)Lst_AtFront(stoppedJobs, (ClientData)job); 1487 1531 jobFull = TRUE; 1488 DEBUGF(JOB, ("Job queue is full.\n")); 1532 if (DEBUG(JOB)) { 1533 (void) fprintf(stdout, "Job queue is full.\n"); 1534 (void) fflush(stdout); 1535 } 1489 1536 return; 1490 1537 } else { … … 1492 1539 * Job may be run locally. 1493 1540 */ 1494 DEBUGF(JOB, ("running locally\n")); 1541 if (DEBUG(JOB)) { 1542 (void) fprintf(stdout, "running locally\n"); 1543 (void) fflush(stdout); 1544 } 1495 1545 job->flags &= ~JOB_REMOTE; 1496 1546 } … … 1501 1551 * Can be exported. Hooray! 1502 1552 */ 1503 DEBUGF(JOB, ("exporting\n")); 1553 if (DEBUG(JOB)) { 1554 (void) fprintf(stdout, "exporting\n"); 1555 (void) fflush(stdout); 1556 } 1504 1557 job->flags |= JOB_REMOTE; 1505 1558 } … … 1511 1564 * we don't know... 1512 1565 */ 1513 DEBUGF(JOB, ("Resuming %s...", job->node->name)); 1566 if (DEBUG(JOB)) { 1567 (void) fprintf(stdout, "Resuming %s...", job->node->name); 1568 (void) fflush(stdout); 1569 } 1514 1570 if (((job->flags & JOB_REMOTE) || 1515 1571 (nLocal < maxLocal) || … … 1551 1607 1552 1608 job->flags &= ~(JOB_RESUME|JOB_CONTINUING); 1553 DEBUGF(JOB, ("done\n")); 1609 if (DEBUG(JOB)) { 1610 (void) fprintf(stdout, "done\n"); 1611 (void) fflush(stdout); 1612 } 1554 1613 } else { 1555 1614 Error("couldn't resume %s: %s", … … 1564 1623 * place the job back on the list of stopped jobs. 1565 1624 */ 1566 DEBUGF(JOB, ("table full\n")); 1567 (void) Lst_AtFront(stoppedJobs, (void *)job); 1625 if (DEBUG(JOB)) { 1626 (void) fprintf(stdout, "table full\n"); 1627 (void) fflush(stdout); 1628 } 1629 (void) Lst_AtFront(stoppedJobs, (ClientData)job); 1568 1630 jobFull = TRUE; 1569 DEBUGF(JOB, ("Job queue is full.\n")); 1631 if (DEBUG(JOB)) { 1632 (void) fprintf(stdout, "Job queue is full.\n"); 1633 (void) fflush(stdout); 1634 } 1570 1635 } 1571 1636 } … … 1589 1654 */ 1590 1655 static int 1591 JobStart(GNode *gn, int flags, Job *previous) 1592 { 1593 Job *job; /* new job descriptor */ 1656 JobStart(gn, flags, previous) 1657 GNode *gn; /* target to create */ 1658 int flags; /* flags for the job to override normal ones. 1659 * e.g. JOB_SPECIAL or JOB_IGNDOTS */ 1660 Job *previous; /* The previous Job structure for this node, 1661 * if any. */ 1662 { 1663 register Job *job; /* new job descriptor */ 1594 1664 char *argv[4]; /* Argument vector to shell */ 1595 1665 Boolean cmdsOK; /* true if the nodes commands were all right */ … … 1603 1673 } else { 1604 1674 job = (Job *) emalloc(sizeof(Job)); 1675 if (job == NULL) { 1676 Punt("JobStart out of memory"); 1677 } 1605 1678 flags |= JOB_FIRST; 1606 1679 } 1607 1680 1608 1681 job->node = gn; 1609 job->tailCmds = N ULL;1682 job->tailCmds = NILLNODE; 1610 1683 1611 1684 /* … … 1682 1755 LstNode ln = Lst_Next(gn->commands); 1683 1756 1684 if ((ln == N ULL) ||1685 JobPrintCommand(( void *) Lst_Datum(ln),1686 ( void *) job))1757 if ((ln == NILLNODE) || 1758 JobPrintCommand((ClientData) Lst_Datum(ln), 1759 (ClientData) job)) 1687 1760 { 1688 1761 noExec = TRUE; … … 1709 1782 */ 1710 1783 numCommands = 0; 1711 Lst_ForEach(gn->commands, JobPrintCommand, ( void *)job);1784 Lst_ForEach(gn->commands, JobPrintCommand, (ClientData)job); 1712 1785 1713 1786 /* … … 1735 1808 */ 1736 1809 if (cmdsOK) { 1737 Lst_ForEach(gn->commands, JobPrintCommand, ( void *)job);1810 Lst_ForEach(gn->commands, JobPrintCommand, (ClientData)job); 1738 1811 } 1739 1812 /* … … 1773 1846 if (cmdsOK) { 1774 1847 if (aborting == 0) { 1775 if (job->tailCmds != N ULL) {1848 if (job->tailCmds != NILLNODE) { 1776 1849 Lst_ForEachFrom(job->node->commands, job->tailCmds, 1777 1850 JobSaveCommand, 1778 ( void *)job->node);1851 (ClientData)job->node); 1779 1852 } 1780 1853 job->node->made = MADE; 1781 1854 Make_Update(job->node); 1782 1855 } 1783 free( job);1856 free((Address)job); 1784 1857 return(JOB_FINISHED); 1785 1858 } else { 1786 free( job);1859 free((Address)job); 1787 1860 return(JOB_ERROR); 1788 1861 } … … 1855 1928 jobFull = TRUE; 1856 1929 1857 DEBUGF(JOB, ("Can only run job locally.\n")); 1930 if (DEBUG(JOB)) { 1931 (void) fprintf(stdout, "Can only run job locally.\n"); 1932 (void) fflush(stdout); 1933 } 1858 1934 job->flags |= JOB_RESTART; 1859 (void) Lst_AtEnd(stoppedJobs, ( void *)job);1935 (void) Lst_AtEnd(stoppedJobs, (ClientData)job); 1860 1936 } else { 1861 1937 if ((nLocal >= maxLocal) && local) { … … 1865 1941 */ 1866 1942 jobFull = TRUE; 1867 DEBUGF(JOB, ("Local job queue is full.\n")); 1943 if (DEBUG(JOB)) { 1944 (void) fprintf(stdout, "Local job queue is full.\n"); 1945 (void) fflush(stdout); 1946 } 1868 1947 } 1869 1948 JobExec(job, argv); … … 1873 1952 1874 1953 static char * 1875 JobOutput(Job *job, char *cp, char *endp, int msg) 1876 { 1877 char *ecp; 1954 JobOutput(job, cp, endp, msg) 1955 register Job *job; 1956 register char *cp, *endp; 1957 int msg; 1958 { 1959 register char *ecp; 1878 1960 1879 1961 if (commandShell->noPrint) { … … 1943 2025 */ 1944 2026 STATIC void 1945 JobDoOutput(Job *job, Boolean finish) 2027 JobDoOutput(job, finish) 2028 register Job *job; /* the job whose output needs printing */ 2029 Boolean finish; /* TRUE if this is the last time we'll be 2030 * called for this job */ 1946 2031 { 1947 2032 Boolean gotNL = FALSE; /* true if got a newline */ 1948 2033 Boolean fbuf; /* true if our buffer filled up */ 1949 intnr; /* number of bytes read */1950 inti; /* auxiliary index into outBuf */1951 intmax; /* limit for i (end of current data) */2034 register int nr; /* number of bytes read */ 2035 register int i; /* auxiliary index into outBuf */ 2036 register int max; /* limit for i (end of current data) */ 1952 2037 int nRead; /* (Temporary) number of bytes read */ 1953 2038 … … 1967 2052 JOB_BUFSIZE - job->curPos); 1968 2053 if (nRead < 0) { 1969 DEBUGF(JOB, ("JobDoOutput(piperead)")); 2054 if (DEBUG(JOB)) { 2055 perror("JobDoOutput(piperead)"); 2056 } 1970 2057 nr = 0; 1971 2058 } else { … … 2021 2108 * first, overwriting the newline character if there was one. 2022 2109 * So long as the line isn't one we should filter (according 2023 * to the shell description), we print the line, prece ded2110 * to the shell description), we print the line, preceeded 2024 2111 * by a target banner if this target isn't the same as the 2025 2112 * one for which we last printed something. … … 2087 2174 (void) fflush(stdout); 2088 2175 while (fgets(inLine, sizeof(inLine), oFILE) != NULL) { 2089 char *cp, *endp, *oendp;2176 register char *cp, *endp, *oendp; 2090 2177 2091 2178 cp = inLine; … … 2134 2221 */ 2135 2222 void 2136 Job_CatchChildren(Boolean block) 2223 Job_CatchChildren(block) 2224 Boolean block; /* TRUE if should block on the wait. */ 2137 2225 { 2138 2226 int pid; /* pid of dead child */ 2139 Job*job; /* job descriptor for dead child */2227 register Job *job; /* job descriptor for dead child */ 2140 2228 LstNode jnode; /* list element for finding job */ 2141 2229 int status; /* Exit/termination status */ … … 2151 2239 (block?0:WNOHANG)|WUNTRACED)) > 0) 2152 2240 { 2153 DEBUGF(JOB, ("Process %d exited or stopped.\n", pid)); 2154 2155 jnode = Lst_Find(jobs, (void *)&pid, JobCmpPid); 2156 2157 if (jnode == NULL) { 2241 if (DEBUG(JOB)) { 2242 (void) fprintf(stdout, "Process %d exited or stopped.\n", pid); 2243 (void) fflush(stdout); 2244 } 2245 2246 2247 jnode = Lst_Find(jobs, (ClientData)&pid, JobCmpPid); 2248 2249 if (jnode == NILLNODE) { 2158 2250 if (WIFSIGNALED(status) && (WTERMSIG(status) == SIGCONT)) { 2159 jnode = Lst_Find(stoppedJobs, ( void *) &pid, JobCmpPid);2160 if (jnode == N ULL) {2251 jnode = Lst_Find(stoppedJobs, (ClientData) &pid, JobCmpPid); 2252 if (jnode == NILLNODE) { 2161 2253 Error("Resumed child (%d) not in table", pid); 2162 2254 continue; … … 2172 2264 (void) Lst_Remove(jobs, jnode); 2173 2265 nJobs -= 1; 2174 DEBUGF(JOB, ("Job queue is no longer full.\n")); 2266 if (jobFull && DEBUG(JOB)) { 2267 (void) fprintf(stdout, "Job queue is no longer full.\n"); 2268 (void) fflush(stdout); 2269 } 2175 2270 jobFull = FALSE; 2176 2271 #ifdef REMOTE 2177 2272 if (!(job->flags & JOB_REMOTE)) { 2178 DEBUGF(JOB, ("Job queue has one fewer local process.\n")); 2273 if (DEBUG(JOB)) { 2274 (void) fprintf(stdout, 2275 "Job queue has one fewer local process.\n"); 2276 (void) fflush(stdout); 2277 } 2179 2278 nLocal -= 1; 2180 2279 } … … 2205 2304 */ 2206 2305 void 2207 Job_CatchOutput( void)2306 Job_CatchOutput() 2208 2307 { 2209 2308 int nfds; 2210 #ifdef USE_KQUEUE2211 #define KEV_SIZE 42212 struct kevent kev[KEV_SIZE];2213 int i;2214 #else2215 2309 struct timeval timeout; 2216 2310 fd_set readfds; 2217 LstNode ln; 2218 Job *job; 2219 #endif 2311 register LstNode ln; 2312 register Job *job; 2220 2313 #ifdef RMT_WILL_WATCH 2221 2314 int pnJobs; /* Previous nJobs */ … … 2247 2340 #else 2248 2341 if (usePipes) { 2249 #ifdef USE_KQUEUE2250 if ((nfds = kevent(kqfd, NULL, 0, kev, KEV_SIZE, NULL)) == -1) {2251 Punt("kevent: %s", strerror(errno));2252 } else {2253 for (i = 0; i < nfds; i++) {2254 if (kev[i].flags & EV_ERROR) {2255 warnc(kev[i].data, "kevent");2256 continue;2257 }2258 switch (kev[i].filter) {2259 case EVFILT_READ:2260 JobDoOutput(kev[i].udata, FALSE);2261 break;2262 case EVFILT_PROC:2263 /* Just wake up and let Job_CatchChildren() collect the2264 * terminated job. */2265 break;2266 }2267 }2268 }2269 #else2270 2342 readfds = outputs; 2271 2343 timeout.tv_sec = SEL_SEC; … … 2279 2351 Punt("Cannot open job table"); 2280 2352 } 2281 while (nfds && (ln = Lst_Next(jobs)) != N ULL) {2353 while (nfds && (ln = Lst_Next(jobs)) != NILLNODE) { 2282 2354 job = (Job *) Lst_Datum(ln); 2283 2355 if (FD_ISSET(job->inPipe, &readfds)) { … … 2288 2360 Lst_Close(jobs); 2289 2361 } 2290 #endif /* !USE_KQUEUE */2291 2362 } 2292 2363 #endif /* RMT_WILL_WATCH */ … … 2308 2379 */ 2309 2380 void 2310 Job_Make(GNode *gn) 2381 Job_Make(gn) 2382 GNode *gn; 2311 2383 { 2312 2384 (void) JobStart(gn, 0, NULL); … … 2316 2388 *----------------------------------------------------------------------- 2317 2389 * Job_Init -- 2318 * Initialize the process module, given a maximum number of jobs, and 2319 * a maximum number of local jobs. 2390 * Initialize the process module 2320 2391 * 2321 2392 * Results: … … 2327 2398 */ 2328 2399 void 2329 Job_Init(int maxproc, int maxlocal) 2400 Job_Init(maxproc, maxlocal) 2401 int maxproc; /* the greatest number of jobs which may be 2402 * running at one time */ 2403 int maxlocal; /* the greatest number of local jobs which may 2404 * be running at once. */ 2330 2405 { 2331 2406 GNode *begin; /* node for commands to do at the very start */ … … 2342 2417 errors = 0; 2343 2418 2344 lastNode = N ULL;2419 lastNode = NILGNODE; 2345 2420 2346 2421 if (maxJobs == 1 || beVerbose == 0 … … 2414 2489 #endif 2415 2490 2416 #ifdef USE_KQUEUE2417 if ((kqfd = kqueue()) == -1) {2418 Punt("kqueue: %s", strerror(errno));2419 }2420 #endif2421 2422 2491 begin = Targ_FindNode(".BEGIN", TARG_NOCREATE); 2423 2492 2424 if (begin != N ULL) {2493 if (begin != NILGNODE) { 2425 2494 JobStart(begin, JOB_SPECIAL, (Job *)0); 2426 2495 while (nJobs) { … … 2449 2518 */ 2450 2519 Boolean 2451 Job_Full( void)2520 Job_Full() 2452 2521 { 2453 2522 return(aborting || jobFull); … … 2471 2540 */ 2472 2541 Boolean 2473 Job_Empty( void)2542 Job_Empty() 2474 2543 { 2475 2544 if (nJobs == 0) { … … 2504 2573 */ 2505 2574 static Shell * 2506 JobMatchShell(char *name) 2507 { 2508 Shell *sh; /* Pointer into shells table */ 2509 Shell *match; /* Longest-matching shell */ 2510 char *cp1, 2575 JobMatchShell(name) 2576 char *name; /* Final component of shell path */ 2577 { 2578 register Shell *sh; /* Pointer into shells table */ 2579 Shell *match; /* Longest-matching shell */ 2580 register char *cp1, 2511 2581 *cp2; 2512 2582 char *eoname; … … 2575 2645 */ 2576 2646 ReturnStatus 2577 Job_ParseShell(char *line) 2647 Job_ParseShell(line) 2648 char *line; /* The shell spec */ 2578 2649 { 2579 2650 char **words; 2580 2651 int wordCount; 2581 char**argv;2582 intargc;2652 register char **argv; 2653 register int argc; 2583 2654 char *path; 2584 2655 Shell newShell; 2585 2656 Boolean fullSpec = FALSE; 2586 2657 2587 while (isspace( (unsigned char)*line)) {2658 while (isspace(*line)) { 2588 2659 line++; 2589 2660 } 2590 2661 words = brk_string(line, &wordCount, TRUE); 2591 2662 2592 memset( &newShell, 0, sizeof(newShell));2663 memset((Address)&newShell, 0, sizeof(newShell)); 2593 2664 2594 2665 /* … … 2686 2757 } 2687 2758 2759 /* 2760 * Do not free up the words themselves, since they might be in use by the 2761 * shell specification... 2762 */ 2763 free(words); 2688 2764 return SUCCESS; 2689 2765 } … … 2703 2779 */ 2704 2780 static void 2705 JobInterrupt(int runINTERRUPT, int signo) 2781 JobInterrupt(runINTERRUPT, signo) 2782 int runINTERRUPT; /* Non-zero if commands for the .INTERRUPT 2783 * target should be executed */ 2784 int signo; /* signal received */ 2706 2785 { 2707 2786 LstNode ln; /* element in job table */ … … 2711 2790 aborting = ABORT_INTERRUPT; 2712 2791 2713 2714 while ((ln = Lst_Next(jobs)) != N ULL) {2792 (void) Lst_Open(jobs); 2793 while ((ln = Lst_Next(jobs)) != NILLNODE) { 2715 2794 job = (Job *) Lst_Datum(ln); 2716 2795 … … 2744 2823 #else 2745 2824 if (job->pid) { 2746 DEBUGF(JOB, ("JobInterrupt passing signal to child %d.\n", 2747 job->pid)); 2825 if (DEBUG(JOB)) { 2826 (void) fprintf(stdout, 2827 "JobInterrupt passing signal to child %d.\n", 2828 job->pid); 2829 (void) fflush(stdout); 2830 } 2748 2831 KILL(job->pid, signo); 2749 2832 } … … 2752 2835 2753 2836 #ifdef REMOTE 2754 2755 while ((ln = Lst_Next(stoppedJobs)) != N ULL) {2837 (void)Lst_Open(stoppedJobs); 2838 while ((ln = Lst_Next(stoppedJobs)) != NILLNODE) { 2756 2839 job = (Job *) Lst_Datum(ln); 2757 2840 2758 2841 if (job->flags & JOB_RESTART) { 2759 DEBUGF(JOB, "JobInterrupt skipping job on stopped queue" 2760 "-- it was waiting to be restarted.\n"); 2842 if (DEBUG(JOB)) { 2843 (void) fprintf(stdout, "%s%s", 2844 "JobInterrupt skipping job on stopped queue", 2845 "-- it was waiting to be restarted.\n"); 2846 (void) fflush(stdout); 2847 } 2761 2848 continue; 2762 2849 } … … 2772 2859 * Resume the thing so it will take the signal. 2773 2860 */ 2774 DEBUGF(JOB, ("JobInterrupt passing CONT to stopped child %d.\n", job->pid)); 2861 if (DEBUG(JOB)) { 2862 (void) fprintf(stdout, 2863 "JobInterrupt passing CONT to stopped child %d.\n", 2864 job->pid); 2865 (void) fflush(stdout); 2866 } 2775 2867 KILL(job->pid, SIGCONT); 2776 2868 #ifdef RMT_WANTS_SIGNALS … … 2790 2882 } 2791 2883 } else if (job->pid) { 2792 DEBUGF(JOB, "JobInterrupt passing interrupt to stopped child %d.\n", 2793 job->pid); 2884 if (DEBUG(JOB)) { 2885 (void) fprintf(stdout, 2886 "JobInterrupt passing interrupt to stopped child %d.\n", 2887 job->pid); 2888 (void) fflush(stdout); 2889 } 2794 2890 KILL(job->pid, SIGINT); 2795 2891 } … … 2801 2897 if (runINTERRUPT && !touchFlag) { 2802 2898 interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE); 2803 if (interrupt != N ULL) {2899 if (interrupt != NILGNODE) { 2804 2900 ignoreErrors = FALSE; 2805 2901 … … 2817 2913 /* 2818 2914 *----------------------------------------------------------------------- 2819 * Job_ Finish--2915 * Job_End -- 2820 2916 * Do final processing such as the running of the commands 2821 2917 * attached to the .END target. … … 2826 2922 */ 2827 2923 int 2828 Job_ Finish(void)2829 { 2830 if (postCommands != N ULL&& !Lst_IsEmpty(postCommands->commands)) {2924 Job_End() 2925 { 2926 if (postCommands != NILGNODE && !Lst_IsEmpty(postCommands->commands)) { 2831 2927 if (errors) { 2832 2928 Error("Errors reported so .END ignored"); … … 2860 2956 */ 2861 2957 void 2862 Job_Wait( void)2958 Job_Wait() 2863 2959 { 2864 2960 aborting = ABORT_WAIT; … … 2887 2983 */ 2888 2984 void 2889 Job_AbortAll( void)2985 Job_AbortAll() 2890 2986 { 2891 2987 LstNode ln; /* element in job table */ … … 2898 2994 2899 2995 (void) Lst_Open(jobs); 2900 while ((ln = Lst_Next(jobs)) != N ULL) {2996 while ((ln = Lst_Next(jobs)) != NILLNODE) { 2901 2997 job = (Job *) Lst_Datum(ln); 2902 2998 … … 2932 3028 * JobFlagForMigration -- 2933 3029 * Handle the eviction of a child. Called from RmtStatusChange. 2934 * Flags the child as remigratable and then suspends it. Takes 2935 * the ID of the host we used, for matching children. 3030 * Flags the child as remigratable and then suspends it. 2936 3031 * 2937 3032 * Results: … … 2944 3039 */ 2945 3040 void 2946 JobFlagForMigration(int hostID) 2947 { 2948 Job *job; /* job descriptor for dead child */ 3041 JobFlagForMigration(hostID) 3042 int hostID; /* ID of host we used, for matching children. */ 3043 { 3044 register Job *job; /* job descriptor for dead child */ 2949 3045 LstNode jnode; /* list element for finding job */ 2950 3046 2951 DEBUGF(JOB, ("JobFlagForMigration(%d) called.\n", hostID)); 2952 jnode = Lst_Find(jobs, (void *)hostID, JobCmpRmtID); 2953 2954 if (jnode == NULL) { 2955 jnode = Lst_Find(stoppedJobs, (void *)hostID, JobCmpRmtID); 2956 if (jnode == NULL) { 3047 if (DEBUG(JOB)) { 3048 (void) fprintf(stdout, "JobFlagForMigration(%d) called.\n", hostID); 3049 (void) fflush(stdout); 3050 } 3051 jnode = Lst_Find(jobs, (ClientData)hostID, JobCmpRmtID); 3052 3053 if (jnode == NILLNODE) { 3054 jnode = Lst_Find(stoppedJobs, (ClientData)hostID, JobCmpRmtID); 3055 if (jnode == NILLNODE) { 2957 3056 if (DEBUG(JOB)) { 2958 3057 Error("Evicting host(%d) not in table", hostID); … … 2963 3062 job = (Job *) Lst_Datum(jnode); 2964 3063 2965 DEBUGF(JOB, ("JobFlagForMigration(%d) found job '%s'.\n", hostID, job->node->name)); 3064 if (DEBUG(JOB)) { 3065 (void) fprintf(stdout, 3066 "JobFlagForMigration(%d) found job '%s'.\n", hostID, 3067 job->node->name); 3068 (void) fflush(stdout); 3069 } 2966 3070 2967 3071 KILL(job->pid, SIGSTOP); … … 2989 3093 */ 2990 3094 static void 2991 JobRestartJobs( void)3095 JobRestartJobs() 2992 3096 { 2993 3097 while (!jobFull && !Lst_IsEmpty(stoppedJobs)) { 2994 DEBUGF(JOB, ("Job queue is not full. Restarting a stopped job.\n")); 3098 if (DEBUG(JOB)) { 3099 (void) fprintf(stdout, 3100 "Job queue is not full. Restarting a stopped job.\n"); 3101 (void) fflush(stdout); 3102 } 2995 3103 JobRestart((Job *)Lst_DeQueue(stoppedJobs)); 2996 3104 }
Note:
See TracChangeset
for help on using the changeset viewer.