xref: /openbsd-src/usr.bin/make/job.c (revision 99fd087599a8791921855f21bd7e36130f39aadc)
1 /*	$OpenBSD: job.c,v 1.160 2020/01/29 17:06:51 espie Exp $	*/
2 /*	$NetBSD: job.c,v 1.16 1996/11/06 17:59:08 christos Exp $	*/
3 
4 /*
5  * Copyright (c) 2012 Marc Espie.
6  *
7  * Extensive code modifications for the OpenBSD project.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OPENBSD
22  * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 /*
31  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
32  * Copyright (c) 1988, 1989 by Adam de Boor
33  * Copyright (c) 1989 by Berkeley Softworks
34  * All rights reserved.
35  *
36  * This code is derived from software contributed to Berkeley by
37  * Adam de Boor.
38  *
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions
41  * are met:
42  * 1. Redistributions of source code must retain the above copyright
43  *    notice, this list of conditions and the following disclaimer.
44  * 2. Redistributions in binary form must reproduce the above copyright
45  *    notice, this list of conditions and the following disclaimer in the
46  *    documentation and/or other materials provided with the distribution.
47  * 3. Neither the name of the University nor the names of its contributors
48  *    may be used to endorse or promote products derived from this software
49  *    without specific prior written permission.
50  *
51  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
52  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
55  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61  * SUCH DAMAGE.
62  */
63 
64 /*-
65  * job.c --
66  *	handle the creation etc. of our child processes.
67  *
68  * Interface:
69  *	Job_Make		Start the creation of the given target.
70  *
71  *	Job_Init		Called to initialize this module.
72  *
73  *	can_start_job		Return true if we can start job
74  *
75  *	Job_Empty		Return true if the job table is completely
76  *				empty.
77  *
78  *	Job_AbortAll		Abort all current jobs. It doesn't
79  *				handle output or do anything for the jobs,
80  *				just kills them.
81  *
82  *	Job_Wait		Wait for all running jobs to finish.
83  */
84 
85 #include <sys/types.h>
86 #include <sys/wait.h>
87 #include <ctype.h>
88 #include <errno.h>
89 #include <fcntl.h>
90 #include <signal.h>
91 #include <stdarg.h>
92 #include <stdio.h>
93 #include <stdlib.h>
94 #include <string.h>
95 #include <unistd.h>
96 #include "config.h"
97 #include "defines.h"
98 #include "job.h"
99 #include "engine.h"
100 #include "pathnames.h"
101 #include "var.h"
102 #include "targ.h"
103 #include "error.h"
104 #include "extern.h"
105 #include "lst.h"
106 #include "gnode.h"
107 #include "memory.h"
108 #include "buf.h"
109 #include "enginechoice.h"
110 
111 static int	aborting = 0;	    /* why is the make aborting? */
112 #define ABORT_ERROR	1	    /* Because of an error */
113 #define ABORT_INTERRUPT 2	    /* Because it was interrupted */
114 #define ABORT_WAIT	3	    /* Waiting for jobs to finish */
115 
116 static bool	no_new_jobs;	/* Mark recursive shit so we shouldn't start
117 				 * something else at the same time
118 				 */
119 bool sequential;
120 Job *runningJobs;		/* Jobs currently running a process */
121 Job *errorJobs;			/* Jobs in error at end */
122 Job *availableJobs;		/* Pool of available jobs */
123 static Job *heldJobs;		/* Jobs not running yet because of expensive */
124 static pid_t mypid;		/* Used for printing debugging messages */
125 static Job *extra_job;		/* Needed for .INTERRUPT */
126 
127 static volatile sig_atomic_t got_fatal;
128 
129 static volatile sig_atomic_t got_SIGINT, got_SIGHUP, got_SIGQUIT, got_SIGTERM,
130     got_SIGINFO;
131 
132 static sigset_t sigset, emptyset, origset;
133 
134 static void handle_fatal_signal(int);
135 static void handle_siginfo(void);
136 static void postprocess_job(Job *);
137 static void determine_job_next_step(Job *);
138 static void may_continue_job(Job *);
139 static Job *reap_finished_job(pid_t);
140 static bool reap_jobs(void);
141 static void may_continue_heldback_jobs(void);
142 
143 static bool expensive_job(Job *);
144 static bool expensive_command(const char *);
145 static void setup_signal(int);
146 static void notice_signal(int);
147 static void setup_all_signals(void);
148 static const char *really_kill(Job *, int);
149 static void debug_kill_printf(const char *, ...);
150 static void debug_vprintf(const char *, va_list);
151 static void may_remove_target(Job *);
152 static void print_error(Job *);
153 static void internal_print_errors(void);
154 
155 static int dying_signal = 0;
156 
157 const char *	basedirectory = NULL;
158 
159 static const char *
160 really_kill(Job *job, int signo)
161 {
162 	pid_t pid = job->pid;
163 	if (getpgid(pid) != getpgrp()) {
164 		if (killpg(pid, signo) == 0)
165 			return "group got signal";
166 		pid = -pid;
167 	} else {
168 		if (kill(pid, signo) == 0)
169 			return "process got signal";
170 	}
171 	if (errno == ESRCH)
172 		job->flags |= JOB_LOST;
173 	return strerror(errno);
174 }
175 
176 static void
177 may_remove_target(Job *j)
178 {
179 	int dying = check_dying_signal();
180 
181 	if (dying && !noExecute && !Targ_Precious(j->node)) {
182 		const char *file = Var(TARGET_INDEX, j->node);
183 		int r = eunlink(file);
184 
185 		if (DEBUG(JOB) && r == -1)
186 			fprintf(stderr, " *** would unlink %s\n", file);
187 		if (r != -1)
188 			fprintf(stderr, " *** %s removed\n", file);
189 	}
190 }
191 
192 static void
193 buf_addcurdir(BUFFER *buf)
194 {
195 	const char *v = Var_Value(".CURDIR");
196 	if (basedirectory != NULL) {
197 		size_t len = strlen(basedirectory);
198 		if (strncmp(basedirectory, v, len) == 0 &&
199 		    v[len] == '/') {
200 			v += len+1;
201 		} else if (strcmp(basedirectory, v) == 0) {
202 			Buf_AddString(buf, ".");
203 			return;
204 		}
205 	}
206 	Buf_AddString(buf, v);
207 }
208 
209 static const char *
210 shortened_curdir(void)
211 {
212 	static BUFFER buf;
213 	static bool first = true;
214 	if (first) {
215 		Buf_Init(&buf, 0);
216 		buf_addcurdir(&buf);
217 		first = false;
218 	}
219 	return Buf_Retrieve(&buf);
220 }
221 
222 static void
223 quick_error(Job *j, int signo, bool first)
224 {
225 	if (first) {
226 		fprintf(stderr, "*** Signal SIG%s", sys_signame[signo]);
227 		fprintf(stderr, " in %s (", shortened_curdir());
228 	} else
229 		fprintf(stderr, " ");
230 
231 	fprintf(stderr, "%s", j->node->name);
232 	free(j->cmd);
233 }
234 
235 static void
236 print_error(Job *j)
237 {
238 	static bool first = true;
239 	BUFFER buf;
240 
241 	Buf_Init(&buf, 0);
242 
243 	if (j->exit_type == JOB_EXIT_BAD)
244 		Buf_printf(&buf, "*** Error %d", j->code);
245 	else if (j->exit_type == JOB_SIGNALED) {
246 		if (j->code < NSIG)
247 			Buf_printf(&buf, "*** Signal SIG%s",
248 			    sys_signame[j->code]);
249 		else
250 			Buf_printf(&buf, "*** unknown signal %d", j->code);
251 	} else
252 		Buf_printf(&buf, "*** Should not happen %d/%d",
253 		    j->exit_type, j->code);
254 	if (DEBUG(KILL) && (j->flags & JOB_LOST))
255 		Buf_AddChar(&buf, '!');
256 	if (first) {
257 		Buf_AddString(&buf, " in ");
258 		buf_addcurdir(&buf);
259 		first = false;
260 	}
261 	Buf_printf(&buf, " (%s:%lu", j->location->fname, j->location->lineno);
262 	Buf_printf(&buf, " '%s'", j->node->name);
263 	if ((j->flags & (JOB_SILENT | JOB_IS_EXPENSIVE)) == JOB_SILENT
264 	    && Buf_Size(&buf) < 140-2) {
265 		size_t len = strlen(j->cmd);
266 		Buf_AddString(&buf, ": ");
267 		if (len + Buf_Size(&buf) < 140)
268 			Buf_AddString(&buf, j->cmd);
269 		else {
270 			Buf_AddChars(&buf, 140 - Buf_Size(&buf), j->cmd);
271 			Buf_AddString(&buf, "...");
272 		}
273 	}
274 	fprintf(stderr, "%s)\n", Buf_Retrieve(&buf));
275 	Buf_Destroy(&buf);
276 	free(j->cmd);
277 }
278 static void
279 quick_summary(int signo)
280 {
281 	Job *j, *k, *jnext;
282 	bool first = true;
283 
284 	k = errorJobs;
285 	errorJobs = NULL;
286 	for (j = k; j != NULL; j = jnext) {
287 		jnext = j->next;
288 		if ((j->exit_type == JOB_EXIT_BAD && j->code == signo+128) ||
289 		    (j->exit_type == JOB_SIGNALED && j->code == signo)) {
290 			quick_error(j, signo, first);
291 			first = false;
292 		} else {
293 			j->next = errorJobs;
294 			errorJobs = j;
295 		}
296 	}
297 	if (!first)
298 		fprintf(stderr, ")\n");
299 }
300 
301 static void
302 internal_print_errors()
303 {
304 	Job *j, *k, *jnext;
305 	int dying;
306 
307 	if (!errorJobs)
308 		fprintf(stderr, "Stop in %s\n", shortened_curdir());
309 
310 	for (j = errorJobs; j != NULL; j = j->next)
311 		may_remove_target(j);
312 	dying = check_dying_signal();
313 	if (dying)
314 		quick_summary(dying);
315 	/* Print errors grouped by file name. */
316 	while (errorJobs != NULL) {
317 		/* Select the first job. */
318 		k = errorJobs;
319 		errorJobs = NULL;
320 		for (j = k; j != NULL; j = jnext) {
321 			jnext = j->next;
322 			if (j->location->fname == k->location->fname)
323 				/* Print errors with the same filename. */
324 				print_error(j);
325 			else {
326 				/* Keep others for the next iteration. */
327 				j->next = errorJobs;
328 				errorJobs = j;
329 			}
330 		}
331 	}
332 }
333 
334 void
335 print_errors(void)
336 {
337 	handle_all_signals();
338 	internal_print_errors();
339 }
340 
341 static void
342 setup_signal(int sig)
343 {
344 	if (signal(sig, SIG_IGN) != SIG_IGN) {
345 		(void)signal(sig, notice_signal);
346 		sigaddset(&sigset, sig);
347 	}
348 }
349 
350 static void
351 notice_signal(int sig)
352 {
353 
354 	switch(sig) {
355 	case SIGINT:
356 		got_SIGINT++;
357 		got_fatal = 1;
358 		break;
359 	case SIGHUP:
360 		got_SIGHUP++;
361 		got_fatal = 1;
362 		break;
363 	case SIGQUIT:
364 		got_SIGQUIT++;
365 		got_fatal = 1;
366 		break;
367 	case SIGTERM:
368 		got_SIGTERM++;
369 		got_fatal = 1;
370 		break;
371 	case SIGINFO:
372 		got_SIGINFO++;
373 		break;
374 	case SIGCHLD:
375 		break;
376 	}
377 }
378 
379 void
380 Sigset_Init()
381 {
382 	sigemptyset(&emptyset);
383 	sigprocmask(SIG_BLOCK, &emptyset, &origset);
384 }
385 
386 static void
387 setup_all_signals(void)
388 {
389 	sigemptyset(&sigset);
390 	/*
391 	 * Catch the four signals that POSIX specifies if they aren't ignored.
392 	 * handle_signal will take care of calling JobInterrupt if appropriate.
393 	 */
394 	setup_signal(SIGINT);
395 	setup_signal(SIGHUP);
396 	setup_signal(SIGQUIT);
397 	setup_signal(SIGTERM);
398 	/* Display running jobs on SIGINFO */
399 	setup_signal(SIGINFO);
400 	/* Have to see SIGCHLD */
401 	setup_signal(SIGCHLD);
402 	got_fatal = 0;
403 }
404 
405 static void
406 handle_siginfo(void)
407 {
408 	static BUFFER buf;
409 	static size_t length = 0;
410 
411 	Job *job;
412 	bool first = true;
413 
414 	got_SIGINFO = 0;
415 	/* we have to store the info in a buffer, because status from all
416 	 * makes running would get intermixed otherwise
417 	 */
418 
419 	if (length == 0) {
420 		Buf_Init(&buf, 0);
421 		Buf_printf(&buf, "%s in ", Var_Value("MAKE"));
422 		buf_addcurdir(&buf);
423 		Buf_AddString(&buf, ": ");
424 		length = Buf_Size(&buf);
425 	} else
426 		Buf_Truncate(&buf, length);
427 
428 	for (job = runningJobs; job != NULL ; job = job->next) {
429 		if (!first)
430 			Buf_puts(&buf, ", ");
431 		first = false;
432 		Buf_puts(&buf, job->node->name);
433 	}
434 	Buf_puts(&buf, first ? "nothing running\n" : "\n");
435 
436 	fputs(Buf_Retrieve(&buf), stderr);
437 }
438 
439 int
440 check_dying_signal(void)
441 {
442 	sigset_t set;
443 	if (dying_signal)
444 		return dying_signal;
445 	sigpending(&set);
446 	if (got_SIGINT || sigismember(&set, SIGINT))
447 		return dying_signal = SIGINT;
448 	if (got_SIGHUP || sigismember(&set, SIGHUP))
449 		return dying_signal = SIGHUP;
450 	if (got_SIGQUIT || sigismember(&set, SIGQUIT))
451 		return dying_signal = SIGQUIT;
452 	if (got_SIGTERM || sigismember(&set, SIGTERM))
453 		return dying_signal = SIGTERM;
454 	return 0;
455 }
456 
457 void
458 handle_all_signals(void)
459 {
460 	if (got_SIGINFO)
461 		handle_siginfo();
462 	while (got_fatal) {
463 		got_fatal = 0;
464 		aborting = ABORT_INTERRUPT;
465 
466 		if (got_SIGINT) {
467 			got_SIGINT=0;
468 			handle_fatal_signal(SIGINT);
469 		}
470 		if (got_SIGHUP) {
471 			got_SIGHUP=0;
472 			handle_fatal_signal(SIGHUP);
473 		}
474 		if (got_SIGQUIT) {
475 			got_SIGQUIT=0;
476 			handle_fatal_signal(SIGQUIT);
477 		}
478 		if (got_SIGTERM) {
479 			got_SIGTERM=0;
480 			handle_fatal_signal(SIGTERM);
481 		}
482 	}
483 }
484 
485 static void
486 debug_vprintf(const char *fmt, va_list va)
487 {
488 	(void)printf("[%ld] ", (long)mypid);
489 	(void)vprintf(fmt, va);
490 	fflush(stdout);
491 }
492 
493 void
494 debug_job_printf(const char *fmt, ...)
495 {
496 	if (DEBUG(JOB)) {
497 		va_list va;
498 		va_start(va, fmt);
499 		debug_vprintf(fmt, va);
500 		va_end(va);
501 	}
502 }
503 
504 static void
505 debug_kill_printf(const char *fmt, ...)
506 {
507 	if (DEBUG(KILL)) {
508 		va_list va;
509 		va_start(va, fmt);
510 		debug_vprintf(fmt, va);
511 		va_end(va);
512 	}
513 }
514 
515 /*-
516  *-----------------------------------------------------------------------
517  * postprocess_job  --
518  *	Do final processing for the given job including updating
519  *	parents and starting new jobs as available/necessary.
520  *
521  * Side Effects:
522  *	If we got an error and are aborting (aborting == ABORT_ERROR) and
523  *	the job list is now empty, we are done for the day.
524  *	If we recognized an error we set the aborting flag
525  *	to ABORT_ERROR so no more jobs will be started.
526  *-----------------------------------------------------------------------
527  */
528 /*ARGSUSED*/
529 
530 static void
531 postprocess_job(Job *job)
532 {
533 	if (job->exit_type == JOB_EXIT_OKAY &&
534 	    aborting != ABORT_ERROR &&
535 	    aborting != ABORT_INTERRUPT) {
536 		/* As long as we aren't aborting and the job didn't return a
537 		 * non-zero status that we shouldn't ignore, we call
538 		 * Make_Update to update the parents. */
539 		job->node->built_status = REBUILT;
540 		engine_node_updated(job->node);
541 	}
542 	if (job->flags & JOB_KEEPERROR) {
543 		job->next = errorJobs;
544 		errorJobs = job;
545 	} else {
546 		job->next = availableJobs;
547 		availableJobs = job;
548 	}
549 
550 	if (errorJobs != NULL && aborting != ABORT_INTERRUPT)
551 		aborting = ABORT_ERROR;
552 
553 	if (aborting == ABORT_ERROR && DEBUG(QUICKDEATH))
554 		handle_fatal_signal(SIGINT);
555 	if (aborting == ABORT_ERROR && Job_Empty())
556 		Finish();
557 }
558 
559 /* expensive jobs handling: in order to avoid forking an exponential number
560  * of jobs, make tries to figure out "recursive make" configurations.
561  * It may err on the side of caution.
562  * Basically, a command is "expensive" if it's likely to fork an extra
563  * level of make: either by looking at the command proper, or if it has
564  * some specific qualities ('+cmd' are likely to be recursive, as are
565  * .MAKE: commands).  It's possible to explicitly say some targets are
566  * expensive or cheap with .EXPENSIVE or .CHEAP.
567  *
568  * While an expensive command is running, no_new_jobs
569  * is set, so jobs that would fork new processes are accumulated in the
570  * heldJobs list instead.
571  *
572  * XXX This heuristics is also used on error exit: we display silent commands
573  * that failed, unless those ARE expensive commands: expensive commands are
574  * likely to not be failing by themselves, but to be the result of a cascade of
575  * failures in descendant makes.
576  */
577 void
578 determine_expensive_job(Job *job)
579 {
580 	if (expensive_job(job)) {
581 		job->flags |= JOB_IS_EXPENSIVE;
582 		no_new_jobs = true;
583 	} else
584 		job->flags &= ~JOB_IS_EXPENSIVE;
585 	if (DEBUG(EXPENSIVE))
586 		fprintf(stderr, "[%ld] Target %s running %.50s: %s\n",
587 		    (long)mypid, job->node->name, job->cmd,
588 		    job->flags & JOB_IS_EXPENSIVE ? "expensive" : "cheap");
589 }
590 
591 static bool
592 expensive_job(Job *job)
593 {
594 	if (job->node->type & OP_CHEAP)
595 		return false;
596 	if (job->node->type & (OP_EXPENSIVE | OP_MAKE))
597 		return true;
598 	return expensive_command(job->cmd);
599 }
600 
601 static bool
602 expensive_command(const char *s)
603 {
604 	const char *p;
605 	bool include = false;
606 	bool expensive = false;
607 
608 	/* okay, comments are cheap, always */
609 	if (*s == '#')
610 		return false;
611 	/* and commands we always execute are expensive */
612 	if (*s == '+')
613 		return true;
614 
615 	for (p = s; *p != '\0'; p++) {
616 		if (*p == ' ' || *p == '\t') {
617 			include = false;
618 			if (p[1] == '-' && p[2] == 'I')
619 				include = true;
620 		}
621 		if (include)
622 			continue;
623 		/* KMP variant, avoid looking twice at the same
624 		 * letter.
625 		 */
626 		if (*p != 'm')
627 			continue;
628 		if (p[1] != 'a')
629 			continue;
630 		p++;
631 		if (p[1] != 'k')
632 			continue;
633 		p++;
634 		if (p[1] != 'e')
635 			continue;
636 		p++;
637 		expensive = true;
638 		while (p[1] != '\0' && p[1] != ' ' && p[1] != '\t') {
639 			if (p[1] == '.' || p[1] == '/') {
640 				expensive = false;
641 				break;
642 			}
643 		    	p++;
644 		}
645 		if (expensive)
646 			return true;
647 	}
648 	return false;
649 }
650 
651 static void
652 may_continue_job(Job *job)
653 {
654 	if (no_new_jobs) {
655 		if (DEBUG(EXPENSIVE))
656 			fprintf(stderr, "[%ld] expensive -> hold %s\n",
657 			    (long)mypid, job->node->name);
658 		job->next = heldJobs;
659 		heldJobs = job;
660 	} else {
661 		bool finished = job_run_next(job);
662 		if (finished)
663 			postprocess_job(job);
664 		else if (!sequential)
665 			determine_expensive_job(job);
666 	}
667 }
668 
669 static void
670 may_continue_heldback_jobs()
671 {
672 	while (!no_new_jobs) {
673 		if (heldJobs != NULL) {
674 			Job *job = heldJobs;
675 			heldJobs = heldJobs->next;
676 			if (DEBUG(EXPENSIVE))
677 				fprintf(stderr, "[%ld] cheap -> release %s\n",
678 				    (long)mypid, job->node->name);
679 			may_continue_job(job);
680 		} else
681 			break;
682 	}
683 }
684 
685 /*-
686  *-----------------------------------------------------------------------
687  * Job_Make  --
688  *	Start a target-creation process going for the target described
689  *	by the graph node gn.
690  *
691  * Side Effects:
692  *	A new Job node is created and  its commands continued, which
693  *	may fork the first command of that job.
694  *-----------------------------------------------------------------------
695  */
696 void
697 Job_Make(GNode *gn)
698 {
699 	Job *job = availableJobs;
700 
701 	assert(job != NULL);
702 	availableJobs = availableJobs->next;
703 	job_attach_node(job, gn);
704 	may_continue_job(job);
705 }
706 
707 static void
708 determine_job_next_step(Job *job)
709 {
710 	if (job->flags & JOB_IS_EXPENSIVE) {
711 		no_new_jobs = false;
712 		if (DEBUG(EXPENSIVE))
713 			fprintf(stderr, "[%ld] "
714 			    "Returning from expensive target %s, "
715 			    "allowing new jobs\n", (long)mypid,
716 			    job->node->name);
717 	}
718 
719 	if (job->exit_type != JOB_EXIT_OKAY || job->next_cmd == NULL)
720 		postprocess_job(job);
721 	else
722 		may_continue_job(job);
723 }
724 
725 /*
726  * job = reap_finished_job(pid):
727  * 	retrieve and remove a job from runningJobs, based on its pid
728  *
729  *	Note that we remove it right away, so that handle_signals()
730  *	is accurate.
731  */
732 static Job *
733 reap_finished_job(pid_t pid)
734 {
735 	Job **j, *job;
736 
737 	for (j = &runningJobs; *j != NULL; j = &((*j)->next))
738 		if ((*j)->pid == pid) {
739 			job = *j;
740 			*j = job->next;
741 			return job;
742 		}
743 
744 	return NULL;
745 }
746 
747 /*
748  * classic waitpid handler: retrieve as many dead children as possible.
749  * returns true if succesful
750  */
751 static bool
752 reap_jobs(void)
753 {
754  	pid_t pid;	/* pid of dead child */
755  	int status;	/* Exit/termination status */
756 	bool reaped = false;
757 	Job *job;
758 
759 	while ((pid = waitpid(WAIT_ANY, &status, WNOHANG)) > 0) {
760 		if (WIFSTOPPED(status))
761 			continue;
762 		reaped = true;
763 		job = reap_finished_job(pid);
764 
765 		if (job == NULL) {
766 			Punt("Child (%ld) with status %d not in table?",
767 			    (long)pid, status);
768 		} else {
769 			handle_job_status(job, status);
770 			determine_job_next_step(job);
771 		}
772 		may_continue_heldback_jobs();
773 	}
774 	/* sanity check, should not happen */
775 	if (pid == -1 && errno == ECHILD && runningJobs != NULL)
776 		Punt("Process has no children, but runningJobs is not empty ?");
777 	return reaped;
778 }
779 
780 void
781 reset_signal_mask()
782 {
783 	sigprocmask(SIG_SETMASK, &origset, NULL);
784 }
785 
786 void
787 handle_running_jobs(void)
788 {
789 	/* reaping children in the presence of caught signals */
790 
791 	/* first, we make sure to hold on new signals, to synchronize
792 	 * reception of new stuff on sigsuspend
793 	 */
794 	sigprocmask(SIG_BLOCK, &sigset, NULL);
795 	/* note this will NOT loop until runningJobs == NULL.
796 	 * It's merely an optimisation, namely that we don't need to go
797 	 * through the logic if no job is present. As soon as a job
798 	 * gets reaped, we WILL exit the loop through the break.
799 	 */
800 	while (runningJobs != NULL) {
801 		/* did we already have pending stuff that advances things ?
802 		 * then handle_all_signals() will not return
803 		 * or reap_jobs() will reap_jobs()
804 		 */
805 		handle_all_signals();
806 		if (reap_jobs())
807 			break;
808 		/* okay, so it's safe to suspend, we have nothing to do but
809 		 * wait...
810 		 */
811 		sigsuspend(&emptyset);
812 	}
813 	reset_signal_mask();
814 }
815 
816 void
817 loop_handle_running_jobs()
818 {
819 	while (runningJobs != NULL)
820 		handle_running_jobs();
821 }
822 
823 void
824 Job_Init(int maxJobs)
825 {
826 	Job *j;
827 	int i;
828 
829 	runningJobs = NULL;
830 	heldJobs = NULL;
831 	errorJobs = NULL;
832 	availableJobs = NULL;
833 	sequential = maxJobs == 1;
834 
835 	/* we allocate n+1 jobs, since we may need an extra job for
836 	 * running .INTERRUPT.  */
837 	j = ereallocarray(NULL, sizeof(Job), maxJobs+1);
838 	for (i = 0; i != maxJobs; i++) {
839 		j[i].next = availableJobs;
840 		availableJobs = &j[i];
841 	}
842 	extra_job = &j[maxJobs];
843 	mypid = getpid();
844 
845 	aborting = 0;
846 	setup_all_signals();
847 }
848 
849 bool
850 can_start_job(void)
851 {
852 	if (aborting || availableJobs == NULL)
853 		return false;
854 	else
855 		return true;
856 }
857 
858 bool
859 Job_Empty(void)
860 {
861 	return runningJobs == NULL;
862 }
863 
864 /*-
865  *-----------------------------------------------------------------------
866  * handle_fatal_signal --
867  *	Handle the receipt of a fatal interrupt
868  *
869  * Side Effects:
870  *	All children are killed. Another job may be started if there
871  *	is an interrupt target and the signal was SIGINT.
872  *-----------------------------------------------------------------------
873  */
874 static void
875 handle_fatal_signal(int signo)
876 {
877 	Job *job;
878 
879 	debug_kill_printf("handle_fatal_signal(%d) called.\n", signo);
880 
881 	dying_signal = signo;
882 	for (job = runningJobs; job != NULL; job = job->next) {
883 		debug_kill_printf("passing to "
884 		    "child %ld running %s: %s\n", (long)job->pid,
885 		    job->node->name, really_kill(job, signo));
886 		may_remove_target(job);
887 	}
888 
889 	if (signo == SIGINT && !touchFlag) {
890 		if ((interrupt_node->type & OP_DUMMY) == 0) {
891 			ignoreErrors = false;
892 			extra_job->next = availableJobs;
893 			availableJobs = extra_job;
894 			Job_Make(interrupt_node);
895 		}
896 	}
897 	loop_handle_running_jobs();
898 	internal_print_errors();
899 
900 	/* die by that signal */
901 	sigprocmask(SIG_BLOCK, &sigset, NULL);
902 	signal(signo, SIG_DFL);
903 	kill(getpid(), signo);
904 	sigprocmask(SIG_SETMASK, &emptyset, NULL);
905 	/*NOTREACHED*/
906 	fprintf(stderr, "This should never happen\n");
907 	exit(1);
908 }
909 
910 /*-
911  *-----------------------------------------------------------------------
912  * Job_Wait --
913  *	Waits for all running jobs to finish and returns. Sets 'aborting'
914  *	to ABORT_WAIT to prevent other jobs from starting.
915  *
916  * Side Effects:
917  *	Currently running jobs finish.
918  *
919  *-----------------------------------------------------------------------
920  */
921 void
922 Job_Wait(void)
923 {
924 	aborting = ABORT_WAIT;
925 	loop_handle_running_jobs();
926 	aborting = 0;
927 }
928 
929 /*-
930  *-----------------------------------------------------------------------
931  * Job_AbortAll --
932  *	Abort all currently running jobs without handling output or anything.
933  *	This function is to be called only in the event of a major
934  *	error.
935  *
936  * Side Effects:
937  *	All children are killed
938  *-----------------------------------------------------------------------
939  */
940 void
941 Job_AbortAll(void)
942 {
943 	Job *job;	/* the job descriptor in that element */
944 	int foo;
945 
946 	aborting = ABORT_ERROR;
947 
948 	for (job = runningJobs; job != NULL; job = job->next) {
949 		killpg(job->pid, SIGINT);
950 		killpg(job->pid, SIGKILL);
951 	}
952 
953 	/*
954 	 * Catch as many children as want to report in at first, then give up
955 	 */
956 	while (waitpid(WAIT_ANY, &foo, WNOHANG) > 0)
957 		continue;
958 }
959