Lines Matching refs:job

1 /*	$NetBSD: job.c,v 1.176 2013/08/04 16:48:15 sjg Exp $	*/
73 static char rcsid[] = "$NetBSD: job.c,v 1.176 2013/08/04 16:48:15 sjg Exp $";
78 static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94";
80 __RCSID("$NetBSD: job.c,v 1.176 2013/08/04 16:48:15 sjg Exp $");
86 * job.c --
95 * a decent clip, since job table entries aren't
121 * job table is empty.
169 #include "job.h"
228 #define JOB_ERROR 1 /* Error in starting the job */
229 #define JOB_FINISHED 2 /* The job is already finished */
356 static Job tokenWaitJob; /* token wait pseudo-job */
358 static Job childExitJob; /* child exit pseudo-job */
398 Job *job;
400 fprintf(debug_file, "job table @ %s\n", where);
401 for (job = job_table; job < job_table_end; job++) {
402 fprintf(debug_file, "job %d, status %d, flags %d, pid %d\n",
403 (int)(job - job_table), job->job_state, job->flags, job->pid);
427 JobCreatePipe(Job *job, int minfd)
431 if (pipe(job->jobPipe) == -1)
436 fd = fcntl(job->jobPipe[i], F_DUPFD, minfd);
438 close(job->jobPipe[i]);
439 job->jobPipe[i] = fd;
444 (void)fcntl(job->jobPipe[0], F_SETFD, 1);
445 (void)fcntl(job->jobPipe[1], F_SETFD, 1);
449 * pipe when we're waiting for a job token, but we might lose the
453 fcntl(job->jobPipe[0], F_SETFL,
454 fcntl(job->jobPipe[0], F_GETFL, 0) | O_NONBLOCK);
460 * Pass a signal to a job
466 * None, except the job may bite it.
473 Job *job;
479 for (job = job_table; job < job_table_end; job++) {
480 if (job->job_state != JOB_ST_RUNNING)
485 signo, job->pid);
487 KILLPG(job->pid, signo);
580 /* Suppress job started/continued messages */
583 /* Pass the signal onto every job */
635 * Compare the pid of the job with the given pid and return 0 if they
637 * to find the job descriptor of the finished job.
640 * job job to examine
653 Job *job;
655 for (job = job_table; job < job_table_end; job++) {
656 if ((job->job_state == status) && job->pid == pid)
657 return job;
667 * Put out another command for the given job. If the command starts
671 * we ignore errors for the entire job, unless the shell has error
674 * job to be commands to be executed once the entire graph has been
682 * jobp job for which to print it
689 * the JOB_IGNERR flag is set in the job descriptor.
711 Job *job = (Job *)jobp;
714 noSpecials = NoExecute(job->node);
717 job->node->type |= OP_SAVE_CMDS;
718 if ((job->flags & JOB_IGNDOTS) == 0) {
719 job->tailCmds = Lst_Succ(Lst_Member(job->node->commands,
729 (void)fprintf(job->cmdFILE, fmt, arg); \
730 (void)fflush(job->cmdFILE);
734 cmdStart = cmd = Var_Subst(NULL, cmd, job->node, FALSE);
747 job->flags |= JOB_IGNERR;
756 CompatRunCommand(cmdp, job->node);
786 if (!(job->flags & JOB_SILENT) && !noSpecials &&
806 if (!(job->flags & JOB_SILENT) && !shutUp &&
826 if (!(job->flags & JOB_SILENT) && !shutUp) {
860 if (!(job->flags & JOB_SILENT) && !shutUp) {
878 (job->flags & JOB_TRACED) == 0) {
880 job->flags |= JOB_TRACED;
893 if (!shutUp && !(job->flags & JOB_SILENT) && commandShell->hasEchoCtl){
931 * Called to close both input and output pipes when a job is finished.
937 * The file descriptors associated with the job are closed.
942 JobClose(Job *job)
944 clearfd(job);
945 (void)close(job->outPipe);
946 job->outPipe = -1;
948 JobDoOutput(job, TRUE);
949 (void)close(job->inPipe);
950 job->inPipe = -1;
956 * Do final processing for the given job including updating
964 * job job to finish
965 * status sub-why job went away
971 * Final commands for the job are placed on postCommands.
974 * the job list is now empty, we are done for the day.
981 JobFinish (Job *job, WAIT_T status)
987 job->pid, job->node->name, status);
991 (((WEXITSTATUS(status) != 0) && !(job->flags & JOB_IGNERR)))) ||
996 * way or we're not ignoring errors, the job is finished.
998 * the job is also finished. In these
999 * cases, finish out the job's output before printing the exit
1002 JobClose(job);
1003 if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
1004 (void)fclose(job->cmdFILE);
1005 job->cmdFILE = NULL;
1013 * TRUE if in -B mode and the job exited non-zero.
1023 JobClose(job);
1035 job->pid, job->node->name);
1038 if (job->node != lastNode) {
1039 MESSAGE(stdout, job->node);
1040 lastNode = job->node;
1044 meta_job_error(job, job->node, job->flags, WEXITSTATUS(status));
1048 job->node->name,
1050 (job->flags & JOB_IGNERR) ? " (ignored)" : "");
1051 if (job->flags & JOB_IGNERR) {
1054 PrintOnError(job->node, NULL);
1057 if (job->node != lastNode) {
1058 MESSAGE(stdout, job->node);
1059 lastNode = job->node;
1062 job->node->name);
1065 if (job->node != lastNode) {
1066 MESSAGE(stdout, job->node);
1067 lastNode = job->node;
1070 job->node->name, WTERMSIG(status));
1077 meta_job_finish(job);
1083 Trace_Log(JOBEND, job);
1084 if (!(job->flags & JOB_SPECIAL)) {
1094 * As long as we aren't aborting and the job didn't return a non-zero
1099 if (job->tailCmds != NULL) {
1100 Lst_ForEachFrom(job->node->commands, job->tailCmds,
1102 job->node);
1104 job->node->made = MADE;
1105 if (!(job->flags & JOB_SPECIAL))
1107 Make_Update(job->node);
1108 job->job_state = JOB_ST_FREE;
1111 job->job_state = JOB_ST_FREE;
1131 * If we are aborting and the job table is now empty, we finish.
1294 * Execute the shell for the given job. Called from JobStart
1297 * job Job to execute
1304 * to the job table.
1309 JobExec(Job *job, char **argv)
1314 job->flags &= ~JOB_TRACED;
1319 (void)fprintf(debug_file, "Running %s %sly\n", job->node->name, "local");
1333 if ((lastNode != job->node) && !(job->flags & JOB_SILENT)) {
1334 MESSAGE(stdout, job->node);
1335 lastNode = job->node;
1338 /* No interruptions until this job is on the `jobs' list */
1341 /* Pre-emptively mark job running, pid still zero though */
1342 job->job_state = JOB_ST_RUNNING;
1354 meta_job_child(job);
1372 if (dup2(FILENO(job->cmdFILE), 0) == -1) {
1373 execError("dup2", "job->cmdFILE");
1379 if (Always_pass_job_queue || (job->node->type & OP_MAKE)) {
1381 * Pass job token pipe to submakes.
1391 if (dup2(job->outPipe, 1) == -1) {
1392 execError("dup2", "job->outPipe");
1431 job->pid = cpid;
1433 Trace_Log(JOBSTART, job);
1439 job->curPos = 0;
1441 watchfd(job);
1443 if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
1444 (void)fclose(job->cmdFILE);
1445 job->cmdFILE = NULL;
1449 * Now the job is actually running, add it to the table.
1453 job->node->name, job->pid);
1454 job_table_dump("job started");
1462 * Create the argv needed to execute the shell for a given job.
1472 JobMakeArgv(Job *job, char **argv)
1490 ((job->flags & JOB_IGNERR) ? "" :
1492 ((job->flags & JOB_SILENT) ? "" :
1500 if (!(job->flags & JOB_IGNERR) && commandShell->exit) {
1504 if (!(job->flags & JOB_SILENT) && commandShell->echo) {
1520 * flags flags for the job to override normal ones.
1526 * if there isn't actually anything left to do for the job and
1527 * JOB_RUNNING if the job has been started.
1541 Job *job; /* new job descriptor */
1544 Boolean noExec; /* Set true if we decide not to run the job */
1547 for (job = job_table; job < job_table_end; job++) {
1548 if (job->job_state == JOB_ST_FREE)
1551 if (job >= job_table_end)
1552 Punt("JobStart no job slots vacant");
1554 memset(job, 0, sizeof *job);
1555 job->job_state = JOB_ST_SETUP;
1559 job->node = gn;
1560 job->tailCmds = NULL;
1563 * Set the initial value of the flags for this job based on the global
1567 job->flags = 0;
1569 job->flags |= JOB_IGNERR;
1572 job->flags |= JOB_SILENT;
1574 job->flags |= flags;
1582 job->inPollfd = NULL;
1613 job->cmdFILE = fdopen(tfd, "w+");
1614 if (job->cmdFILE == NULL) {
1617 (void)fcntl(FILENO(job->cmdFILE), F_SETFD, 1);
1626 meta_job_start(job, gn);
1628 job->flags |= JOB_SILENT;
1636 Lst_ForEach(gn->commands, JobPrintCommand, job);
1650 * in one fell swoop. This will still set up job->tailCmds correctly.
1656 job->cmdFILE = stdout;
1663 Lst_ForEach(gn->commands, JobPrintCommand, job);
1676 job->cmdFILE = stdout;
1677 Job_Touch(gn, job->flags&JOB_SILENT);
1681 (void)fflush(job->cmdFILE);
1687 if (!(job->flags & JOB_SPECIAL))
1692 if (job->cmdFILE != stdout) {
1693 if (job->cmdFILE != NULL) {
1694 (void)fclose(job->cmdFILE);
1695 job->cmdFILE = NULL;
1701 * the commands for the job were no good.
1704 if (job->tailCmds != NULL) {
1705 Lst_ForEachFrom(job->node->commands, job->tailCmds,
1707 job->node);
1709 job->node->made = MADE;
1710 Make_Update(job->node);
1712 job->job_state = JOB_ST_FREE;
1718 * set earlier for this job.
1720 JobMakeArgv(job, argv);
1723 JobCreatePipe(job, 3);
1725 JobExec(job, argv);
1730 JobOutput(Job *job, char *cp, char *endp, int msg)
1739 if (!beSilent && msg && job->node != lastNode) {
1740 MESSAGE(stdout, job->node);
1741 lastNode = job->node;
1779 * output from the given job and store it in the job's outBuf. If
1780 * this makes up a line, we print it tagged by the job's identifier,
1793 * job the job whose output needs printing
1795 * for this job
1805 JobDoOutput(Job *job, Boolean finish)
1821 nRead = read(job->inPipe, &job->outBuf[job->curPos],
1822 JOB_BUFSIZE - job->curPos);
1835 * If we hit the end-of-file (the job is dead), we must flush its
1840 if ((nr == 0) && (job->curPos != 0)) {
1841 job->outBuf[job->curPos] = '\n';
1853 max = job->curPos + nr;
1854 for (i = job->curPos + nr - 1; i >= job->curPos; i--) {
1855 if (job->outBuf[i] == '\n') {
1858 } else if (job->outBuf[i] == '\0') {
1862 job->outBuf[i] = ' ';
1867 job->curPos += nr;
1868 if (job->curPos == JOB_BUFSIZE) {
1874 i = job->curPos;
1888 job->outBuf[i] = '\0';
1889 if (i >= job->curPos) {
1892 cp = JobOutput(job, job->outBuf, &job->outBuf[i], FALSE);
1900 if (!beSilent && job->node != lastNode) {
1901 MESSAGE(stdout, job->node);
1902 lastNode = job->node;
1906 meta_job_output(job, cp, gotNL ? "\n" : "");
1915 (void)memcpy(job->outBuf, &job->outBuf[i + 1], max - (i + 1));
1916 job->curPos = max - (i + 1);
1923 job->curPos = 0;
1945 * and .INTERRUPT job in the parallel job module. This has
1977 * The job descriptor is removed from the list of children.
1982 * job, call JobFinish to finish things off.
2015 Job *job; /* job descriptor for dead child */
2023 job = JobFindPid(pid, JOB_ST_RUNNING, isJobs);
2024 if (job == NULL) {
2034 job->pid, job->node->name);
2039 (void)printf("*** [%s] Suspended\n", job->node->name);
2042 (void)printf("*** [%s] Stopped\n", job->node->name);
2046 job->node->name, WSTOPSIG(status));
2048 job->job_suspended = 1;
2054 job->job_state = JOB_ST_FINISHED;
2055 job->exit_status = WAIT_STATUS(status);
2057 JobFinish(job, status);
2080 Job *job;
2085 /* The first fd in the list is the job token pipe */
2120 job = jobfds[i];
2121 if (job->job_state == JOB_ST_RUNNING)
2122 JobDoOutput(job, FALSE);
2138 * Another job is started.
2234 /* Allocate space for all the job info */
2272 /* We can only need to wait for tokens, children and output from each job */
2305 * we're giving each job its own process group (since then it won't get
2580 * All children are killed. Another job will be started if the
2587 Job *job; /* job descriptor in that element */
2596 for (job = job_table; job < job_table_end; job++) {
2597 if (job->job_state != JOB_ST_RUNNING)
2600 gn = job->node;
2608 if (job->pid) {
2612 signo, job->pid);
2614 KILLPG(job->pid, signo);
2721 Job *job; /* the job descriptor in that element */
2727 for (job = job_table; job < job_table_end; job++) {
2728 if (job->job_state != JOB_ST_RUNNING)
2734 KILLPG(job->pid, SIGINT);
2735 KILLPG(job->pid, SIGKILL);
2765 Job *job;
2767 for (job = job_table; job < job_table_end; job++) {
2768 if (job->job_state == JOB_ST_RUNNING &&
2769 (make_suspended || job->job_suspended)) {
2771 (void)fprintf(debug_file, "Restarting stopped job pid %d.\n",
2772 job->pid);
2774 if (job->job_suspended) {
2775 (void)printf("*** [%s] Continued\n", job->node->name);
2778 job->job_suspended = 0;
2779 if (KILLPG(job->pid, SIGCONT) != 0 && DEBUG(JOB)) {
2780 fprintf(debug_file, "Failed to send SIGCONT to %d\n", job->pid);
2783 if (job->job_state == JOB_ST_FINISHED)
2785 JobFinish(job, job->exit_status);
2791 watchfd(Job *job)
2793 if (job->inPollfd != NULL)
2794 Punt("Watching watched job");
2796 fds[nfds].fd = job->inPipe;
2798 jobfds[nfds] = job;
2799 job->inPollfd = &fds[nfds];
2804 clearfd(Job *job)
2807 if (job->inPollfd == NULL)
2808 Punt("Unwatching unwatched job");
2809 i = job->inPollfd - fds;
2812 * Move last job in table into hole made by dead job.
2819 job->inPollfd = NULL;
2823 readyfd(Job *job)
2825 if (job->inPollfd == NULL)
2826 Punt("Polling unwatched job");
2827 return (job->inPollfd->revents & POLLIN) != 0;
2833 * Put a token into the job pipe so that some make process can start
2834 * another job.
2867 * Prep the job token pipe in the root make process.
2896 * Preload the job pipe with one token per job, save the one
2897 * "extra" token for the primary job.
2958 Fatal("eof on job pipe!");
2961 Fatal("job pipe read: %s", strerror(errno));
2970 /* make being abvorted - remove any other job tokens */