Lines Matching refs:job

1 /*	$NetBSD: job.c,v 1.471 2024/05/07 18:26:22 sjg Exp $	*/
90 * a decent clip, since job table entries aren't
109 * job table is empty.
152 #include "job.h"
156 /* "@(#)job.c 8.2 (Berkeley) 3/19/94" */
157 MAKE_RCSID("$NetBSD: job.c,v 1.471 2024/05/07 18:26:22 sjg Exp $");
291 JOB_ERROR, /* Error in starting the job */
292 JOB_FINISHED /* The job is already finished */
454 static char *targPrefix = NULL; /* To identify a job change in the output. */
455 static Job tokenWaitJob; /* token wait pseudo-job */
457 static Job childExitJob; /* child exit pseudo-job */
498 Job_FlagsToString(const Job *job, char *buf, size_t bufsize)
501 job->ignerr ? 'i' : '-',
502 !job->echo ? 's' : '-',
503 job->special ? 'S' : '-');
509 Job *job;
512 debug_printf("job table @ %s\n", where);
513 for (job = job_table; job < job_table_end; job++) {
514 Job_FlagsToString(job, flags, sizeof flags);
515 debug_printf("job %d, status %d, flags %s, pid %d\n",
516 (int)(job - job_table), job->status, flags, job->pid);
522 * unsuccessful job unless inhibited by .PRECIOUS.
565 JobCreatePipe(Job *job, int minfd)
582 job->inPipe = pipe_fds[0];
583 job->outPipe = pipe_fds[1];
585 if (fcntl(job->inPipe, F_SETFD, FD_CLOEXEC) == -1)
587 if (fcntl(job->outPipe, F_SETFD, FD_CLOEXEC) == -1)
592 * pipe when we're waiting for a job token, but we might lose the
596 flags = fcntl(job->inPipe, F_GETFL, 0);
600 if (fcntl(job->inPipe, F_SETFL, flags) == -1)
604 /* Pass the signal to each running job. */
608 Job *job;
612 for (job = job_table; job < job_table_end; job++) {
613 if (job->status != JOB_ST_RUNNING)
616 signo, job->pid);
617 KILLPG(job->pid, signo);
679 /* Suppress job started/continued messages */
682 /* Pass the signal onto every job */
731 Job *job;
733 for (job = job_table; job < job_table_end; job++) {
734 if (job->status == status && job->pid == pid)
735 return job;
859 JobWriteSpecialsEchoCtl(Job *job, ShellWriter *wr, CommandFlags *inout_cmdFlags,
862 /* XXX: Why is the whole job modified at this point? */
863 job->ignerr = true;
865 if (job->echo && inout_cmdFlags->echo) {
886 JobWriteSpecials(Job *job, ShellWriter *wr, const char *escCmd, bool run,
892 ShellWriter_ErrOff(wr, job->echo && inout_cmdFlags->echo);
894 JobWriteSpecialsEchoCtl(job, wr, inout_cmdFlags, escCmd,
901 * Write a shell command to the job's commands file, to be run later.
907 * of the predefined shells has that), ignore errors for the entire job.
909 * XXX: Why ignore errors for the entire job? This is even documented in the
912 * XXX: The manual page says the '-' "affects the entire job", but that's not
915 * If the command is just "...", skip all further commands of this job. These
920 JobWriteCommand(Job *job, ShellWriter *wr, StringListNode *ln, const char *ucmd)
931 run = GNode_ShouldExecute(job->node);
933 EvalStack_Push(job->node->name, NULL, NULL);
934 xcmd = Var_Subst(ucmd, job->node, VARE_WANTRES);
949 (void)Compat_RunCommand(ucmd, job->node, ln);
962 if (job->echo && run && shell->hasEchoCtl)
969 JobWriteSpecials(job, wr, escCmd, run, &cmdFlags, &cmdTemplate);
980 if (job->echo && cmdFlags.echo) {
1005 ShellWriter_ErrOn(wr, cmdFlags.echo && job->echo);
1020 JobWriteCommands(Job *job)
1026 wr.f = job->cmdFILE;
1029 for (ln = job->node->commands.first; ln != NULL; ln = ln->next) {
1033 job->node->type |= OP_SAVE_CMDS;
1034 job->tailCmds = ln->next;
1038 JobWriteCommand(job, &wr, ln, ln->datum);
1050 JobSaveCommands(Job *job)
1054 for (ln = job->tailCmds; ln != NULL; ln = ln->next) {
1062 EvalStack_Push(job->node->name, NULL, NULL);
1063 expanded_cmd = Var_Subst(cmd, job->node, VARE_WANTRES);
1071 /* Called to close both input and output pipes when a job is finished. */
1073 JobClosePipes(Job *job)
1075 clearfd(job);
1076 (void)close(job->outPipe);
1077 job->outPipe = -1;
1079 CollectOutput(job, true);
1080 (void)close(job->inPipe);
1081 job->inPipe = -1;
1085 DebugFailedJob(const Job *job)
1093 debug_printf("*** Failed target: %s\n", job->node->name);
1096 for (ln = job->node->commands.first; ln != NULL; ln = ln->next) {
1101 char *xcmd = Var_Subst(cmd, job->node, VARE_WANTRES);
1109 JobFinishDoneExitedError(Job *job, WAIT_T *inout_status)
1111 SwitchOutputTo(job->node);
1114 meta_job_error(job, job->node,
1115 job->ignerr, WEXITSTATUS(*inout_status));
1118 if (!shouldDieQuietly(job->node, -1)) {
1119 DebugFailedJob(job);
1121 job->node->name, WEXITSTATUS(*inout_status),
1122 job->ignerr ? " (ignored)" : "");
1125 if (job->ignerr)
1129 JobDeleteTarget(job->node);
1130 PrintOnError(job->node, "\n");
1135 JobFinishDoneExited(Job *job, WAIT_T *inout_status)
1137 DEBUG2(JOB, "Process %d [%s] exited.\n", job->pid, job->node->name);
1140 JobFinishDoneExitedError(job, inout_status);
1142 SwitchOutputTo(job->node);
1144 job->node->name);
1149 JobFinishDoneSignaled(Job *job, WAIT_T status)
1151 SwitchOutputTo(job->node);
1152 DebugFailedJob(job);
1153 (void)printf("*** [%s] Signal %d\n", job->node->name, WTERMSIG(status));
1155 JobDeleteTarget(job->node);
1159 JobFinishDone(Job *job, WAIT_T *inout_status)
1162 JobFinishDoneExited(job, inout_status);
1164 JobFinishDoneSignaled(job, *inout_status);
1170 * Do final processing for the given job including updating parent nodes and
1173 * Deferred commands for the job are placed on the .END node.
1179 * job job to finish
1180 * status sub-why job went away
1183 JobFinish (Job *job, WAIT_T status)
1188 job->pid, job->node->name, status);
1191 ((WEXITSTATUS(status) != 0 && !job->ignerr))) ||
1195 JobClosePipes(job);
1196 if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
1197 if (fclose(job->cmdFILE) != 0)
1199 job->node->name, strerror(errno));
1200 job->cmdFILE = NULL;
1212 JobClosePipes(job);
1220 JobFinishDone(job, &status);
1224 int meta_status = meta_job_finish(job);
1232 Trace_Log(JOBEND, job);
1233 if (!job->special) {
1242 * As long as we aren't aborting and the job didn't return a
1246 JobSaveCommands(job);
1247 job->node->made = MADE;
1248 if (!job->special)
1250 Make_Update(job->node);
1251 job->status = JOB_ST_FREE;
1254 job->status = JOB_ST_FREE;
1421 * Execute the shell for the given job.
1426 JobExec(Job *job, char **argv)
1434 debug_printf("Running %s\n", job->node->name);
1448 if (job->echo)
1449 SwitchOutputTo(job->node);
1451 /* No interruptions until this job is on the `jobs' list */
1454 /* Pre-emptively mark job running, pid still zero though */
1455 job->status = JOB_ST_RUNNING;
1457 Var_ReexportVars(job->node);
1469 meta_job_child(job);
1487 if (dup2(fileno(job->cmdFILE), 0) == -1)
1488 execDie("dup2", "job->cmdFILE");
1495 (job->node->type & (OP_MAKE | OP_SUBMAKE))) {
1496 /* Pass job token pipe to submakes. */
1509 if (dup2(job->outPipe, 1) == -1)
1510 execDie("dup2", "job->outPipe");
1545 job->pid = cpid;
1547 Trace_Log(JOBSTART, job);
1551 meta_job_parent(job, cpid);
1558 job->curPos = 0;
1560 watchfd(job);
1562 if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
1563 if (fclose(job->cmdFILE) != 0)
1565 job->node->name, strerror(errno));
1566 job->cmdFILE = NULL;
1569 /* Now that the job is actually running, add it to the table. */
1572 job->node->name, job->pid);
1573 DumpJobs("job started");
1578 /* Create the argv needed to execute the shell for a given job. */
1580 JobMakeArgv(Job *job, char **argv)
1601 (job->ignerr ? "" :
1603 (!job->echo ? "" :
1611 if (!job->ignerr && shell->errFlag != NULL) {
1615 if (job->echo && shell->echoFlag != NULL) {
1624 JobWriteShellCommands(Job *job, GNode *gn, bool *out_run)
1636 job->cmdFILE = fdopen(tfd, "w+");
1637 if (job->cmdFILE == NULL)
1640 (void)fcntl(fileno(job->cmdFILE), F_SETFD, FD_CLOEXEC);
1644 meta_job_start(job, gn);
1646 job->echo = false;
1650 *out_run = JobWriteCommands(job);
1658 * if there isn't actually anything left to do for the job and
1659 * JOB_RUNNING if the job has been started.
1670 Job *job; /* new job descriptor */
1675 for (job = job_table; job < job_table_end; job++) {
1676 if (job->status == JOB_ST_FREE)
1679 if (job >= job_table_end)
1680 Punt("JobStart no job slots vacant");
1682 memset(job, 0, sizeof *job);
1683 job->node = gn;
1684 job->tailCmds = NULL;
1685 job->status = JOB_ST_SET_UP;
1687 job->special = special || gn->type & OP_SPECIAL;
1688 job->ignerr = opts.ignoreErrors || gn->type & OP_IGNORE;
1689 job->echo = !(opts.silent || gn->type & OP_SILENT);
1697 job->inPollfd = NULL;
1700 job->cmdFILE = stdout;
1729 JobWriteShellCommands(job, gn, &run);
1730 (void)fflush(job->cmdFILE);
1734 * This still sets up job->tailCmds correctly.
1737 job->cmdFILE = stdout;
1739 JobWriteCommands(job);
1741 (void)fflush(job->cmdFILE);
1743 Job_Touch(gn, job->echo);
1749 if (!job->special)
1752 if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
1753 (void)fclose(job->cmdFILE);
1754 job->cmdFILE = NULL;
1759 * here because the commands for the job were no good.
1762 JobSaveCommands(job);
1763 job->node->made = MADE;
1764 Make_Update(job->node);
1766 job->status = JOB_ST_FREE;
1772 * flags set earlier for this job.
1774 JobMakeArgv(job, argv);
1777 JobCreatePipe(job, 3);
1779 JobExec(job, argv);
1829 * We collect more output from the given job and store it in the job's
1830 * outBuf. If this makes up a line, we print it tagged by the job's
1838 * job the job whose output needs printing
1840 * for this job
1843 CollectOutput(Job *job, bool finish)
1857 nRead = read(job->inPipe, &job->outBuf[job->curPos],
1858 JOB_BUFSIZE - job->curPos);
1872 * If we hit the end-of-file (the job is dead), we must flush its
1876 if (nr == 0 && job->curPos != 0) {
1877 job->outBuf[job->curPos] = '\n';
1881 max = job->curPos + nr;
1882 for (i = job->curPos; i < max; i++)
1883 if (job->outBuf[i] == '\0')
1884 job->outBuf[i] = ' ';
1887 for (i = job->curPos + nr - 1;
1888 i >= job->curPos && i != (size_t)-1; i--) {
1889 if (job->outBuf[i] == '\n') {
1896 job->curPos += nr;
1897 if (job->curPos == JOB_BUFSIZE) {
1903 i = job->curPos;
1917 job->outBuf[i] = '\0';
1918 if (i >= job->curPos) {
1927 p = PrintFilteredOutput(job->outBuf, &job->outBuf[i]);
1936 SwitchOutputTo(job->node);
1939 meta_job_output(job, p,
1954 (void)memmove(job->outBuf, &job->outBuf[i + 1],
1956 job->curPos = max - (i + 1);
1959 job->curPos = 0;
1981 * .INTERRUPT job in the parallel job module. As of 2020-09-25,
2008 * The job descriptor is removed from the list of children.
2013 * job, call JobFinish to finish things off.
2044 Job *job; /* job descriptor for dead child */
2050 job = JobFindPid(pid, JOB_ST_RUNNING, isJobs);
2051 if (job == NULL) {
2061 job->pid, job->node->name);
2066 job->node->name);
2070 job->node->name);
2074 job->node->name, WSTOPSIG(status));
2076 job->suspended = true;
2082 job->status = JOB_ST_FINISHED;
2083 job->exit_status = WAIT_STATUS(status);
2085 job->node->exit_status = WEXITSTATUS(status);
2087 JobFinish(job, status);
2100 Job *job;
2105 /* The first fd in the list is the job token pipe */
2139 job = jobByFdIndex[i];
2140 if (job->status == JOB_ST_RUNNING)
2141 CollectOutput(job, false);
2144 * With meta mode, we may have activity on the job's filemon
2146 * than job->inPollfd.
2148 if (useMeta && job->inPollfd != &fds[i]) {
2149 if (meta_job_event(job) <= 0)
2250 /* Allocate space for all the job info */
2318 * we're giving each job its own process group (since then it won't get
2568 * All children are killed. Another job will be started if the .INTERRUPT
2579 Job *job; /* job descriptor in that element */
2588 for (job = job_table; job < job_table_end; job++) {
2589 if (job->status != JOB_ST_RUNNING)
2592 gn = job->node;
2595 if (job->pid != 0) {
2598 signo, job->pid);
2599 KILLPG(job->pid, signo);
2668 Job *job; /* the job descriptor in that element */
2674 for (job = job_table; job < job_table_end; job++) {
2675 if (job->status != JOB_ST_RUNNING)
2681 KILLPG(job->pid, SIGINT);
2682 KILLPG(job->pid, SIGKILL);
2700 Job *job;
2702 for (job = job_table; job < job_table_end; job++) {
2703 if (job->status == JOB_ST_RUNNING &&
2704 (make_suspended || job->suspended)) {
2705 DEBUG1(JOB, "Restarting stopped job pid %d.\n",
2706 job->pid);
2707 if (job->suspended) {
2709 job->node->name);
2712 job->suspended = false;
2713 if (KILLPG(job->pid, SIGCONT) != 0 && DEBUG(JOB)) {
2715 job->pid);
2718 if (job->status == JOB_ST_FINISHED) {
2723 JobFinish(job, job->exit_status);
2730 watchfd(Job *job)
2732 if (job->inPollfd != NULL)
2733 Punt("Watching watched job");
2735 fds[fdsLen].fd = job->inPipe;
2737 jobByFdIndex[fdsLen] = job;
2738 job->inPollfd = &fds[fdsLen];
2742 fds[fdsLen].fd = meta_job_fd(job);
2744 jobByFdIndex[fdsLen] = job;
2751 clearfd(Job *job)
2754 if (job->inPollfd == NULL)
2755 Punt("Unwatching unwatched job");
2756 i = (size_t)(job->inPollfd - fds);
2761 * Sanity check: there should be two fds per job, so the job's
2770 /* Move last job in table into hole made by dead job. */
2782 job->inPollfd = NULL;
2786 readyfd(Job *job)
2788 if (job->inPollfd == NULL)
2789 Punt("Polling unwatched job");
2790 return (job->inPollfd->revents & POLLIN) != 0;
2794 * Put a token (back) into the job pipe.
2795 * This allows a make process to start a build job.
2834 /* Prep the job token pipe in the root make process. */
2859 * Preload the job pipe with one token per job, save the one
2860 * "extra" token for the primary job.
2905 Fatal("eof on job pipe!");
2908 Fatal("job pipe read: %s", strerror(errno));
2915 /* make being aborted - remove any other job tokens */