dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / make / bin / parallel.cc
blob109c43cffd8444792a11831ff41ac7df6aaa90bd
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
28 * parallel.cc
30 * Deal with the parallel processing
34 * Included files
36 #include <errno.h> /* errno */
37 #include <fcntl.h>
38 #include <mk/defs.h>
39 #include <mksh/dosys.h> /* redirect_io() */
40 #include <mksh/macro.h> /* expand_value() */
41 #include <mksh/misc.h> /* getmem() */
42 #include <sys/signal.h>
43 #include <sys/stat.h>
44 #include <sys/types.h>
45 #include <sys/utsname.h>
46 #include <sys/wait.h>
47 #include <unistd.h>
48 #include <netdb.h>
49 #include <libintl.h>
54 * Defined macros
56 #define MAXRULES 100
59 * This const should be in avo_dms/include/AvoDmakeCommand.h
61 const int local_host_mask = 0x20;
65 * typedefs & structs
70 * Static variables
72 static Boolean just_did_subtree = false;
73 static char local_host[MAXNAMELEN] = "";
74 static char user_name[MAXNAMELEN] = "";
75 static int pmake_max_jobs = 0;
76 static pid_t process_running = -1;
77 static Running *running_tail = &running_list;
78 static Name subtree_conflict;
79 static Name subtree_conflict2;
83 * File table of contents
85 static void delete_running_struct(Running rp);
86 static Boolean dependency_conflict(Name target);
87 static Doname distribute_process(char **commands, Property line);
88 static void doname_subtree(Name target, Boolean do_get, Boolean implicit);
89 static void dump_out_file(char *filename, Boolean err);
90 static void finish_doname(Running rp);
91 static void maybe_reread_make_state(void);
92 static void process_next(void);
93 static void reset_conditionals(int cnt, Name *targets, Property *locals);
94 static pid_t run_rule_commands(char *host, char **commands);
95 static Property *set_conditionals(int cnt, Name *targets);
96 static void store_conditionals(Running rp);
100 * execute_parallel(line, waitflg)
102 * DMake 2.x:
103 * parallel mode: spawns a parallel process to execute the command group.
105 * Return value:
106 * The result of the execution
108 * Parameters:
109 * line The command group to execute
111 Doname
112 execute_parallel(Property line, Boolean waitflg, Boolean local)
114 int argcnt;
115 int cmd_options = 0;
116 char *commands[MAXRULES + 5];
117 char *cp;
118 Name dmake_name;
119 Name dmake_value;
120 int ignore;
121 Name make_machines_name;
122 char **p;
123 Property prop;
124 Doname result = build_ok;
125 Cmd_line rule;
126 Boolean silent_flag;
127 Name target = line->body.line.target;
128 Boolean wrote_state_file = false;
130 if ((pmake_max_jobs == 0) &&
131 (dmake_mode_type == parallel_mode)) {
132 if (local_host[0] == '\0') {
133 (void) gethostname(local_host, MAXNAMELEN);
135 MBSTOWCS(wcs_buffer, "DMAKE_MAX_JOBS");
136 dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
137 if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
138 ((dmake_value = prop->body.macro.value) != NULL)) {
139 pmake_max_jobs = atoi(dmake_value->string_mb);
140 if (pmake_max_jobs <= 0) {
141 warning(gettext("DMAKE_MAX_JOBS cannot be less than or equal to zero."));
142 warning(gettext("setting DMAKE_MAX_JOBS to %d."), PMAKE_DEF_MAX_JOBS);
143 pmake_max_jobs = PMAKE_DEF_MAX_JOBS;
145 } else {
147 * For backwards compatibility w/ PMake 1.x, when
148 * DMake 2.x is being run in parallel mode, DMake
149 * should parse the PMake startup file
150 * $(HOME)/.make.machines to get the pmake_max_jobs.
152 MBSTOWCS(wcs_buffer, "PMAKE_MACHINESFILE");
153 dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
154 if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
155 ((dmake_value = prop->body.macro.value) != NULL)) {
156 make_machines_name = dmake_value;
157 } else {
158 make_machines_name = NULL;
160 if ((pmake_max_jobs = read_make_machines(make_machines_name)) <= 0) {
161 pmake_max_jobs = PMAKE_DEF_MAX_JOBS;
166 if ((dmake_mode_type == serial_mode) ||
167 ((dmake_mode_type == parallel_mode) && (waitflg))) {
168 return (execute_serial(line));
172 p = commands;
175 argcnt = 0;
176 for (rule = line->body.line.command_used;
177 rule != NULL;
178 rule = rule->next) {
179 if (posix && (touch || quest) && !rule->always_exec) {
180 continue;
182 if (vpath_defined) {
183 rule->command_line =
184 vpath_translation(rule->command_line);
187 silent_flag = false;
188 ignore = 0;
190 if (rule->command_line->hash.length > 0) {
191 if (++argcnt == MAXRULES) {
192 return build_serial;
195 if (rule->silent && !silent) {
196 silent_flag = true;
198 if (rule->ignore_error) {
199 ignore++;
201 /* XXX - need to add support for + prefix */
202 if (silent_flag || ignore) {
203 *p = getmem((silent_flag ? 1 : 0) +
204 ignore +
205 (strlen(rule->
206 command_line->
207 string_mb)) +
209 cp = *p++;
210 if (silent_flag) {
211 *cp++ = (int) at_char;
213 if (ignore) {
214 *cp++ = (int) hyphen_char;
216 (void) strcpy(cp, rule->command_line->string_mb);
217 } else {
218 *p++ = rule->command_line->string_mb;
223 if ((argcnt == 0) ||
224 (report_dependencies_level > 0)) {
225 return build_ok;
228 *p = NULL;
230 Doname res = distribute_process(commands, line);
231 if (res == build_running) {
232 parallel_process_cnt++;
236 * Return only those memory that were specially allocated
237 * for part of commands.
239 for (int i = 0; commands[i] != NULL; i++) {
240 if ((commands[i][0] == (int) at_char) ||
241 (commands[i][0] == (int) hyphen_char)) {
242 retmem_mb(commands[i]);
245 return res;
251 #include <unistd.h> /* sysconf(_SC_NPROCESSORS_ONLN) */
252 #include <sys/ipc.h> /* ftok() */
253 #include <sys/shm.h> /* shmget(), shmat(), shmdt(), shmctl() */
254 #include <semaphore.h> /* sem_init(), sem_trywait(), sem_post(), sem_destroy() */
255 #include <sys/loadavg.h> /* getloadavg() */
258 * adjust_pmake_max_jobs (int pmake_max_jobs)
260 * Parameters:
261 * pmake_max_jobs - max jobs limit set by user
263 * External functions used:
264 * sysconf()
265 * getloadavg()
267 static int
268 adjust_pmake_max_jobs (int pmake_max_jobs)
270 static int ncpu = 0;
271 double loadavg[3];
272 int adjustment;
273 int adjusted_max_jobs;
275 if (ncpu <= 0) {
276 if ((ncpu = sysconf(_SC_NPROCESSORS_ONLN)) <= 0) {
277 ncpu = 1;
280 if (getloadavg(loadavg, 3) != 3) return(pmake_max_jobs);
281 adjustment = ((int)loadavg[LOADAVG_1MIN]);
282 if (adjustment < 2) return(pmake_max_jobs);
283 if (ncpu > 1) {
284 adjustment = adjustment / ncpu;
286 adjusted_max_jobs = pmake_max_jobs - adjustment;
287 if (adjusted_max_jobs < 1) adjusted_max_jobs = 1;
288 return(adjusted_max_jobs);
292 * M2 adjust mode data and functions
294 * m2_init() - initializes M2 shared semaphore
295 * m2_acquire_job() - decrements M2 semaphore counter
296 * m2_release_job() - increments M2 semaphore counter
297 * m2_fini() - destroys M2 semaphore and shared memory*
299 * Environment variables:
300 * __DMAKE_M2_FILE__
302 * External functions:
303 * ftok(), shmget(), shmat(), shmdt(), shmctl()
304 * sem_init(), sem_trywait(), sem_post(), sem_destroy()
305 * creat(), close(), unlink()
306 * getenv(), putenv()
308 * Static variables:
309 * m2_file - tmp file name to create ipc key for shared memory
310 * m2_shm_id - shared memory id
311 * m2_shm_sem - shared memory semaphore
314 static char m2_file[MAXPATHLEN];
315 static int m2_shm_id = -1;
316 static sem_t* m2_shm_sem = 0;
318 static int
319 m2_init() {
320 char *var;
321 key_t key;
323 if ((var = getenv("__DMAKE_M2_FILE__")) == 0) {
324 /* compose tmp file name */
325 sprintf(m2_file, "%s/dmake.m2.%d.XXXXXX", tmpdir, getpid());
327 /* create tmp file */
328 int fd = mkstemp(m2_file);
329 if (fd < 0) {
330 return -1;
331 } else {
332 close(fd);
334 } else {
335 /* using existing semaphore */
336 strcpy(m2_file, var);
339 /* combine IPC key */
340 if ((key = ftok(m2_file, 38)) == (key_t) -1) {
341 return -1;
344 /* create shared memory */
345 if ((m2_shm_id = shmget(key, sizeof(*m2_shm_sem), 0666 | (var ? 0 : IPC_CREAT|IPC_EXCL))) == -1) {
346 return -1;
349 /* attach shared memory */
350 if ((m2_shm_sem = (sem_t*) shmat(m2_shm_id, 0, 0666)) == (sem_t*)-1) {
351 return -1;
354 /* root process */
355 if (var == 0) {
356 /* initialize semaphore */
357 if (sem_init(m2_shm_sem, 1, pmake_max_jobs)) {
358 return -1;
361 /* alloc memory for env variable */
362 if ((var = (char*) malloc(MAXPATHLEN)) == 0) {
363 return -1;
366 /* put key to env */
367 sprintf(var, "__DMAKE_M2_FILE__=%s", m2_file);
368 if (putenv(var)) {
369 return -1;
372 return 0;
375 static void
376 m2_fini() {
377 if (m2_shm_id >= 0) {
378 struct shmid_ds stat;
380 /* determine the number of attached processes */
381 if (shmctl(m2_shm_id, IPC_STAT, &stat) == 0) {
382 if (stat.shm_nattch <= 1) {
383 /* destroy semaphore */
384 if (m2_shm_sem != 0) {
385 (void) sem_destroy(m2_shm_sem);
388 /* destroy shared memory */
389 (void) shmctl(m2_shm_id, IPC_RMID, &stat);
391 /* remove tmp file created for the key */
392 (void) unlink(m2_file);
393 } else {
394 /* detach shared memory */
395 if (m2_shm_sem != 0) {
396 (void) shmdt((char*) m2_shm_sem);
401 m2_shm_id = -1;
402 m2_shm_sem = 0;
406 static int
407 m2_acquire_job() {
408 if ((m2_shm_id >= 0) && (m2_shm_sem != 0)) {
409 if (sem_trywait(m2_shm_sem) == 0) {
410 return 1;
412 if (errno == EAGAIN) {
413 return 0;
416 return -1;
419 static int
420 m2_release_job() {
421 if ((m2_shm_id >= 0) && (m2_shm_sem != 0)) {
422 if (sem_post(m2_shm_sem) == 0) {
423 return 0;
426 return -1;
430 * job adjust mode
432 * Possible values:
433 * ADJUST_M1 - adjustment by system load (default)
434 * ADJUST_M2 - fixed limit of jobs for the group of nested dmakes
435 * ADJUST_NONE - no adjustment - fixed limit of jobs for the current dmake
437 static enum {
438 ADJUST_UNKNOWN,
439 ADJUST_M1,
440 ADJUST_M2,
441 ADJUST_NONE
442 } job_adjust_mode = ADJUST_UNKNOWN;
445 * void job_adjust_fini()
447 * Description:
448 * Cleans up job adjust data.
450 * Static variables:
451 * job_adjust_mode Current job adjust mode
453 void
454 job_adjust_fini() {
455 if (job_adjust_mode == ADJUST_M2) {
456 m2_fini();
461 * void job_adjust_error()
463 * Description:
464 * Prints warning message, cleans up job adjust data, and disables job adjustment
466 * Environment:
467 * DMAKE_ADJUST_MAX_JOBS
469 * External functions:
470 * putenv()
472 * Static variables:
473 * job_adjust_mode Current job adjust mode
475 static void
476 job_adjust_error() {
477 if (job_adjust_mode != ADJUST_NONE) {
478 /* cleanup internals */
479 job_adjust_fini();
481 /* warning message for the user */
482 warning(gettext("Encountered max jobs auto adjustment error - disabling auto adjustment."));
484 /* switch off job adjustment for the children */
485 putenv(strdup("DMAKE_ADJUST_MAX_JOBS=NO"));
487 /* and for this dmake */
488 job_adjust_mode = ADJUST_NONE;
493 * void job_adjust_init()
495 * Description:
496 * Parses DMAKE_ADJUST_MAX_JOBS env variable
497 * and performs appropriate initializations.
499 * Environment:
500 * DMAKE_ADJUST_MAX_JOBS
501 * DMAKE_ADJUST_MAX_JOBS == "NO" - no adjustment
502 * DMAKE_ADJUST_MAX_JOBS == "M2" - M2 adjust mode
503 * other - M1 adjust mode
505 * External functions:
506 * getenv()
508 * Static variables:
509 * job_adjust_mode Current job adjust mode
511 static void
512 job_adjust_init() {
513 if (job_adjust_mode == ADJUST_UNKNOWN) {
514 /* default mode */
515 job_adjust_mode = ADJUST_M1;
517 /* determine adjust mode */
518 if (char *var = getenv("DMAKE_ADJUST_MAX_JOBS")) {
519 if (strcasecmp(var, "NO") == 0) {
520 job_adjust_mode = ADJUST_NONE;
521 } else if (strcasecmp(var, "M2") == 0) {
522 job_adjust_mode = ADJUST_M2;
526 /* M2 specific initialization */
527 if (job_adjust_mode == ADJUST_M2) {
528 if (m2_init()) {
529 job_adjust_error();
537 * distribute_process(char **commands, Property line)
539 * Parameters:
540 * commands argv vector of commands to execute
542 * Return value:
543 * The result of the execution
545 * Static variables used:
546 * process_running Set to the pid of the process set running
547 * job_adjust_mode Current job adjust mode
549 static Doname
550 distribute_process(char **commands, Property line)
552 static unsigned file_number = 0;
553 wchar_t string[MAXPATHLEN];
554 char mbstring[MAXPATHLEN];
555 int filed;
556 int res;
557 int tmp_index;
558 char *tmp_index_str_ptr;
560 /* initialize adjust mode, if not initialized */
561 if (job_adjust_mode == ADJUST_UNKNOWN) {
562 job_adjust_init();
565 /* actions depend on adjust mode */
566 switch (job_adjust_mode) {
567 case ADJUST_M1:
568 while (parallel_process_cnt >= adjust_pmake_max_jobs (pmake_max_jobs)) {
569 await_parallel(false);
570 finish_children(true);
572 break;
573 case ADJUST_M2:
574 if ((res = m2_acquire_job()) == 0) {
575 if (parallel_process_cnt > 0) {
576 await_parallel(false);
577 finish_children(true);
579 if ((res = m2_acquire_job()) == 0) {
580 return build_serial;
582 } else {
583 return build_serial;
586 if (res < 0) {
587 /* job adjustment error */
588 job_adjust_error();
590 /* no adjustment */
591 while (parallel_process_cnt >= pmake_max_jobs) {
592 await_parallel(false);
593 finish_children(true);
596 break;
597 default:
598 while (parallel_process_cnt >= pmake_max_jobs) {
599 await_parallel(false);
600 finish_children(true);
604 setvar_envvar();
606 * Tell the user what DMake is doing.
608 if (!silent && output_mode != txt2_mode) {
610 * Print local_host --> x job(s).
612 (void) fprintf(stdout,
613 gettext("%s --> %d %s\n"),
614 local_host,
615 parallel_process_cnt + 1,
616 (parallel_process_cnt == 0) ? gettext("job") : gettext("jobs"));
618 /* Print command line(s). */
619 tmp_index = 0;
620 while (commands[tmp_index] != NULL) {
621 /* No @ char. */
622 /* XXX - need to add [2] when + prefix is added */
623 if ((commands[tmp_index][0] != (int) at_char) &&
624 (commands[tmp_index][1] != (int) at_char)) {
625 tmp_index_str_ptr = commands[tmp_index];
626 if (*tmp_index_str_ptr == (int) hyphen_char) {
627 tmp_index_str_ptr++;
629 (void) fprintf(stdout, "%s\n", tmp_index_str_ptr);
631 tmp_index++;
633 (void) fflush(stdout);
636 (void) sprintf(mbstring,
637 "%s/dmake.stdout.%d.%d.XXXXXX",
638 tmpdir,
639 getpid(),
640 file_number++);
642 mktemp(mbstring);
644 stdout_file = strdup(mbstring);
645 stderr_file = NULL;
647 if (!out_err_same) {
648 (void) sprintf(mbstring,
649 "%s/dmake.stderr.%d.%d.XXXXXX",
650 tmpdir,
651 getpid(),
652 file_number++);
654 mktemp(mbstring);
656 stderr_file = strdup(mbstring);
659 process_running = run_rule_commands(local_host, commands);
661 return build_running;
665 * doname_parallel(target, do_get, implicit)
667 * Processes the given target and finishes up any parallel
668 * processes left running.
670 * Return value:
671 * Result of target build
673 * Parameters:
674 * target Target to build
675 * do_get True if sccs get to be done
676 * implicit True if this is an implicit target
678 Doname
679 doname_parallel(Name target, Boolean do_get, Boolean implicit)
681 Doname result;
683 result = doname_check(target, do_get, implicit, false);
684 if (result == build_ok || result == build_failed) {
685 return result;
687 finish_running();
688 return (Doname) target->state;
692 * doname_subtree(target, do_get, implicit)
694 * Completely computes an object and its dependents for a
695 * serial subtree build.
697 * Parameters:
698 * target Target to build
699 * do_get True if sccs get to be done
700 * implicit True if this is an implicit target
702 * Static variables used:
703 * running_tail Tail of the list of running processes
705 * Global variables used:
706 * running_list The list of running processes
708 static void
709 doname_subtree(Name target, Boolean do_get, Boolean implicit)
711 Running save_running_list;
712 Running *save_running_tail;
714 save_running_list = running_list;
715 save_running_tail = running_tail;
716 running_list = NULL;
717 running_tail = &running_list;
718 target->state = build_subtree;
719 target->checking_subtree = true;
720 while(doname_check(target, do_get, implicit, false) == build_running) {
721 target->checking_subtree = false;
722 finish_running();
723 target->state = build_subtree;
725 target->checking_subtree = false;
726 running_list = save_running_list;
727 running_tail = save_running_tail;
731 * finish_running()
733 * Keeps processing until the running_list is emptied out.
735 * Parameters:
737 * Global variables used:
738 * running_list The list of running processes
740 void
741 finish_running(void)
743 while (running_list != NULL) {
745 await_parallel(false);
746 finish_children(true);
748 if (running_list != NULL) {
749 process_next();
755 * process_next()
757 * Searches the running list for any targets which can start processing.
758 * This can be a pending target, a serial target, or a subtree target.
760 * Parameters:
762 * Static variables used:
763 * running_tail The end of the list of running procs
764 * subtree_conflict A target which conflicts with a subtree
765 * subtree_conflict2 The other target which conflicts
767 * Global variables used:
768 * commands_done True if commands executed
769 * debug_level Controls debug output
770 * parallel_process_cnt Number of parallel process running
771 * recursion_level Indentation for debug output
772 * running_list List of running processes
774 static void
775 process_next(void)
777 Running rp;
778 Running *rp_prev;
779 Property line;
780 Chain target_group;
781 Dependency dep;
782 Boolean quiescent = true;
783 Running *subtree_target;
784 Boolean saved_commands_done;
785 Property *conditionals;
787 subtree_target = NULL;
788 subtree_conflict = NULL;
789 subtree_conflict2 = NULL;
791 * If nothing currently running, build a serial target, if any.
793 start_loop_1:
794 for (rp_prev = &running_list, rp = running_list;
795 rp != NULL && parallel_process_cnt == 0;
796 rp = rp->next) {
797 if (rp->state == build_serial) {
798 *rp_prev = rp->next;
799 if (rp->next == NULL) {
800 running_tail = rp_prev;
802 recursion_level = rp->recursion_level;
803 rp->target->state = build_pending;
804 (void) doname_check(rp->target,
805 rp->do_get,
806 rp->implicit,
807 false);
808 quiescent = false;
809 delete_running_struct(rp);
810 goto start_loop_1;
811 } else {
812 rp_prev = &rp->next;
816 * Find a target to build. The target must be pending, have all
817 * its dependencies built, and not be in a target group with a target
818 * currently building.
820 start_loop_2:
821 for (rp_prev = &running_list, rp = running_list;
822 rp != NULL;
823 rp = rp->next) {
824 if (!(rp->state == build_pending ||
825 rp->state == build_subtree)) {
826 quiescent = false;
827 rp_prev = &rp->next;
828 } else if (rp->state == build_pending) {
829 line = get_prop(rp->target->prop, line_prop);
830 for (dep = line->body.line.dependencies;
831 dep != NULL;
832 dep = dep->next) {
833 if (dep->name->state == build_running ||
834 dep->name->state == build_pending ||
835 dep->name->state == build_serial) {
836 break;
839 if (dep == NULL) {
840 for (target_group = line->body.line.target_group;
841 target_group != NULL;
842 target_group = target_group->next) {
843 if (is_running(target_group->name)) {
844 break;
847 if (target_group == NULL) {
848 *rp_prev = rp->next;
849 if (rp->next == NULL) {
850 running_tail = rp_prev;
852 recursion_level = rp->recursion_level;
853 rp->target->state = rp->redo ?
854 build_dont_know : build_pending;
855 saved_commands_done = commands_done;
856 conditionals =
857 set_conditionals
858 (rp->conditional_cnt,
859 rp->conditional_targets);
860 rp->target->dont_activate_cond_values = true;
861 if ((doname_check(rp->target,
862 rp->do_get,
863 rp->implicit,
864 rp->target->has_target_prop ? true : false) !=
865 build_running) &&
866 !commands_done) {
867 commands_done =
868 saved_commands_done;
870 rp->target->dont_activate_cond_values = false;
871 reset_conditionals
872 (rp->conditional_cnt,
873 rp->conditional_targets,
874 conditionals);
875 quiescent = false;
876 delete_running_struct(rp);
877 goto start_loop_2;
878 } else {
879 rp_prev = &rp->next;
881 } else {
882 rp_prev = &rp->next;
884 } else {
885 rp_prev = &rp->next;
889 * If nothing has been found to build and there exists a subtree
890 * target with no dependency conflicts, build it.
892 if (quiescent) {
893 start_loop_3:
894 for (rp_prev = &running_list, rp = running_list;
895 rp != NULL;
896 rp = rp->next) {
897 if (rp->state == build_subtree) {
898 if (!dependency_conflict(rp->target)) {
899 *rp_prev = rp->next;
900 if (rp->next == NULL) {
901 running_tail = rp_prev;
903 recursion_level = rp->recursion_level;
904 doname_subtree(rp->target,
905 rp->do_get,
906 rp->implicit);
907 quiescent = false;
908 delete_running_struct(rp);
909 goto start_loop_3;
910 } else {
911 subtree_target = rp_prev;
912 rp_prev = &rp->next;
914 } else {
915 rp_prev = &rp->next;
920 * If still nothing found to build, we either have a deadlock
921 * or a subtree with a dependency conflict with something waiting
922 * to build.
924 if (quiescent) {
925 if (subtree_target == NULL) {
926 fatal(gettext("Internal error: deadlock detected in process_next"));
927 } else {
928 rp = *subtree_target;
929 if (debug_level > 0) {
930 warning(gettext("Conditional macro conflict encountered for %s between %s and %s"),
931 subtree_conflict2->string_mb,
932 rp->target->string_mb,
933 subtree_conflict->string_mb);
935 *subtree_target = (*subtree_target)->next;
936 if (rp->next == NULL) {
937 running_tail = subtree_target;
939 recursion_level = rp->recursion_level;
940 doname_subtree(rp->target, rp->do_get, rp->implicit);
941 delete_running_struct(rp);
947 * set_conditionals(cnt, targets)
949 * Sets the conditional macros for the targets given in the array of
950 * targets. The old macro values are returned in an array of
951 * Properties for later resetting.
953 * Return value:
954 * Array of conditional macro settings
956 * Parameters:
957 * cnt Number of targets
958 * targets Array of targets
960 static Property *
961 set_conditionals(int cnt, Name *targets)
963 Property *locals, *lp;
964 Name *tp;
966 locals = (Property *) getmem(cnt * sizeof(Property));
967 for (lp = locals, tp = targets;
968 cnt > 0;
969 cnt--, lp++, tp++) {
970 *lp = (Property) getmem((*tp)->conditional_cnt *
971 sizeof(struct _Property));
972 set_locals(*tp, *lp);
974 return locals;
978 * reset_conditionals(cnt, targets, locals)
980 * Resets the conditional macros as saved in the given array of
981 * Properties. The resets are done in reverse order. Afterwards the
982 * data structures are freed.
984 * Parameters:
985 * cnt Number of targets
986 * targets Array of targets
987 * locals Array of dependency macro settings
989 static void
990 reset_conditionals(int cnt, Name *targets, Property *locals)
992 Name *tp;
993 Property *lp;
995 for (tp = targets + (cnt - 1), lp = locals + (cnt - 1);
996 cnt > 0;
997 cnt--, tp--, lp--) {
998 reset_locals(*tp,
999 *lp,
1000 get_prop((*tp)->prop, conditional_prop),
1002 retmem_mb((caddr_t) *lp);
1004 retmem_mb((caddr_t) locals);
1008 * dependency_conflict(target)
1010 * Returns true if there is an intersection between
1011 * the subtree of the target and any dependents of the pending targets.
1013 * Return value:
1014 * True if conflict found
1016 * Parameters:
1017 * target Subtree target to check
1019 * Static variables used:
1020 * subtree_conflict Target conflict found
1021 * subtree_conflict2 Second conflict found
1023 * Global variables used:
1024 * running_list List of running processes
1025 * wait_name .WAIT, not a real dependency
1027 static Boolean
1028 dependency_conflict(Name target)
1030 Property line;
1031 Property pending_line;
1032 Dependency dp;
1033 Dependency pending_dp;
1034 Running rp;
1036 /* Return if we are already checking this target */
1037 if (target->checking_subtree) {
1038 return false;
1040 target->checking_subtree = true;
1041 line = get_prop(target->prop, line_prop);
1042 if (line == NULL) {
1043 target->checking_subtree = false;
1044 return false;
1046 /* Check each dependency of the target for conflicts */
1047 for (dp = line->body.line.dependencies; dp != NULL; dp = dp->next) {
1048 /* Ignore .WAIT dependency */
1049 if (dp->name == wait_name) {
1050 continue;
1053 * For each pending target, look for a dependency which
1054 * is the same as a dependency of the subtree target. Since
1055 * we can't build the subtree until all pending targets have
1056 * finished which depend on the same dependency, this is
1057 * a conflict.
1059 for (rp = running_list; rp != NULL; rp = rp->next) {
1060 if (rp->state == build_pending) {
1061 pending_line = get_prop(rp->target->prop,
1062 line_prop);
1063 if (pending_line == NULL) {
1064 continue;
1066 for(pending_dp = pending_line->
1067 body.line.dependencies;
1068 pending_dp != NULL;
1069 pending_dp = pending_dp->next) {
1070 if (dp->name == pending_dp->name) {
1071 target->checking_subtree
1072 = false;
1073 subtree_conflict = rp->target;
1074 subtree_conflict2 = dp->name;
1075 return true;
1080 if (dependency_conflict(dp->name)) {
1081 target->checking_subtree = false;
1082 return true;
1085 target->checking_subtree = false;
1086 return false;
1090 * await_parallel(waitflg)
1092 * Waits for parallel children to exit and finishes their processing.
1093 * If waitflg is false, the function returns after update_delay.
1095 * Parameters:
1096 * waitflg dwight
1098 void
1099 await_parallel(Boolean waitflg)
1101 Boolean nohang;
1102 pid_t pid;
1103 int status;
1104 Running rp;
1105 int waiterr;
1107 nohang = false;
1108 for ( ; ; ) {
1109 if (!nohang) {
1110 (void) alarm((int) update_delay);
1112 pid = waitpid((pid_t)-1,
1113 &status,
1114 nohang ? WNOHANG : 0);
1115 waiterr = errno;
1116 if (!nohang) {
1117 (void) alarm(0);
1119 if (pid <= 0) {
1120 if (waiterr == EINTR) {
1121 if (waitflg) {
1122 continue;
1123 } else {
1124 return;
1126 } else {
1127 return;
1130 for (rp = running_list;
1131 (rp != NULL) && (rp->pid != pid);
1132 rp = rp->next) {
1135 if (rp == NULL) {
1136 fatal(gettext("Internal error: returned child pid not in running_list"));
1137 } else {
1138 rp->state = (WIFEXITED(status) && WEXITSTATUS(status) == 0) ? build_ok : build_failed;
1140 nohang = true;
1141 parallel_process_cnt--;
1143 if (job_adjust_mode == ADJUST_M2) {
1144 if (m2_release_job()) {
1145 job_adjust_error();
1152 * finish_children(docheck)
1154 * Finishes the processing for all targets which were running
1155 * and have now completed.
1157 * Parameters:
1158 * docheck Completely check the finished target
1160 * Static variables used:
1161 * running_tail The tail of the running list
1163 * Global variables used:
1164 * continue_after_error -k flag
1165 * fatal_in_progress True if we are finishing up after fatal err
1166 * running_list List of running processes
1168 void
1169 finish_children(Boolean docheck)
1171 int cmds_length;
1172 Property line;
1173 Property line2;
1174 struct stat out_buf;
1175 Running rp;
1176 Running *rp_prev;
1177 Cmd_line rule;
1178 Boolean silent_flag;
1180 for (rp_prev = &running_list, rp = running_list;
1181 rp != NULL;
1182 rp = rp->next) {
1183 bypass_for_loop_inc_4:
1185 * If the state is ok or failed, then this target has
1186 * finished building.
1187 * In parallel_mode, output the accumulated stdout/stderr.
1188 * Read the auto dependency stuff, handle a failed build,
1189 * update the target, then finish the doname process for
1190 * that target.
1192 if (rp->state == build_ok || rp->state == build_failed) {
1193 *rp_prev = rp->next;
1194 if (rp->next == NULL) {
1195 running_tail = rp_prev;
1197 if ((line2 = rp->command) == NULL) {
1198 line2 = get_prop(rp->target->prop, line_prop);
1203 * Check if there were any job output
1204 * from the parallel build.
1206 if (rp->stdout_file != NULL) {
1207 if (stat(rp->stdout_file, &out_buf) < 0) {
1208 fatal(gettext("stat of %s failed: %s"),
1209 rp->stdout_file,
1210 errmsg(errno));
1213 if ((line2 != NULL) &&
1214 (out_buf.st_size > 0)) {
1215 cmds_length = 0;
1216 for (rule = line2->body.line.command_used,
1217 silent_flag = silent;
1218 rule != NULL;
1219 rule = rule->next) {
1220 cmds_length += rule->command_line->hash.length + 1;
1221 silent_flag = BOOLEAN(silent_flag || rule->silent);
1223 if (out_buf.st_size != cmds_length || silent_flag ||
1224 output_mode == txt2_mode) {
1225 dump_out_file(rp->stdout_file, false);
1228 (void) unlink(rp->stdout_file);
1229 retmem_mb(rp->stdout_file);
1230 rp->stdout_file = NULL;
1233 if (!out_err_same && (rp->stderr_file != NULL)) {
1234 if (stat(rp->stderr_file, &out_buf) < 0) {
1235 fatal(gettext("stat of %s failed: %s"),
1236 rp->stderr_file,
1237 errmsg(errno));
1239 if ((line2 != NULL) &&
1240 (out_buf.st_size > 0)) {
1241 dump_out_file(rp->stderr_file, true);
1243 (void) unlink(rp->stderr_file);
1244 retmem_mb(rp->stderr_file);
1245 rp->stderr_file = NULL;
1248 check_state(rp->temp_file);
1249 if (rp->temp_file != NULL) {
1250 free_name(rp->temp_file);
1252 rp->temp_file = NULL;
1253 if (rp->state == build_failed) {
1254 line = get_prop(rp->target->prop, line_prop);
1255 if (line != NULL) {
1256 line->body.line.command_used = NULL;
1258 if (continue_after_error ||
1259 fatal_in_progress ||
1260 !docheck) {
1261 warning(gettext("Command failed for target `%s'"),
1262 rp->command ? line2->body.line.target->string_mb : rp->target->string_mb);
1263 build_failed_seen = true;
1264 } else {
1266 * XXX??? - DMake needs to exit(),
1267 * but shouldn't call fatal().
1269 #ifdef PRINT_EXIT_STATUS
1270 warning("I'm in finish_children. rp->state == build_failed.");
1271 #endif
1273 fatal(gettext("Command failed for target `%s'"),
1274 rp->command ? line2->body.line.target->string_mb : rp->target->string_mb);
1277 if (!docheck) {
1278 delete_running_struct(rp);
1279 rp = *rp_prev;
1280 if (rp == NULL) {
1281 break;
1282 } else {
1283 goto bypass_for_loop_inc_4;
1286 update_target(get_prop(rp->target->prop, line_prop),
1287 rp->state);
1288 finish_doname(rp);
1289 delete_running_struct(rp);
1290 rp = *rp_prev;
1291 if (rp == NULL) {
1292 break;
1293 } else {
1294 goto bypass_for_loop_inc_4;
1296 } else {
1297 rp_prev = &rp->next;
1303 * dump_out_file(filename, err)
1305 * Write the contents of the file to stdout, then unlink the file.
1307 * Parameters:
1308 * filename Name of temp file containing output
1310 * Global variables used:
1312 static void
1313 dump_out_file(char *filename, Boolean err)
1315 int chars_read;
1316 char copybuf[BUFSIZ];
1317 int fd;
1318 int out_fd = (err ? 2 : 1);
1320 if ((fd = open(filename, O_RDONLY)) < 0) {
1321 fatal(gettext("open failed for output file %s: %s"),
1322 filename,
1323 errmsg(errno));
1325 if (!silent && output_mode != txt2_mode) {
1326 (void) fprintf(err ? stderr : stdout,
1327 err ?
1328 gettext("%s --> Job errors\n") :
1329 gettext("%s --> Job output\n"),
1330 local_host);
1331 (void) fflush(err ? stderr : stdout);
1333 for (chars_read = read(fd, copybuf, BUFSIZ);
1334 chars_read > 0;
1335 chars_read = read(fd, copybuf, BUFSIZ)) {
1337 * Read buffers from the source file until end or error.
1339 if (write(out_fd, copybuf, chars_read) < 0) {
1340 fatal(gettext("write failed for output file %s: %s"),
1341 filename,
1342 errmsg(errno));
1345 (void) close(fd);
1346 (void) unlink(filename);
1350 * finish_doname(rp)
1352 * Completes the processing for a target which was left running.
1354 * Parameters:
1355 * rp Running list entry for target
1357 * Global variables used:
1358 * debug_level Debug flag
1359 * recursion_level Indentation for debug output
1361 static void
1362 finish_doname(Running rp)
1364 int auto_count = rp->auto_count;
1365 Name *automatics = rp->automatics;
1366 Doname result = rp->state;
1367 Name target = rp->target;
1368 Name true_target = rp->true_target;
1369 Property *conditionals;
1371 recursion_level = rp->recursion_level;
1372 if (result == build_ok) {
1373 if (true_target == NULL) {
1374 (void) printf("Target = %s\n", target->string_mb);
1375 (void) printf(" State = %d\n", result);
1376 fatal("Internal error: NULL true_target in finish_doname");
1378 /* If all went OK, set a nice timestamp */
1379 if (true_target->stat.time == file_doesnt_exist) {
1380 true_target->stat.time = file_max_time;
1383 target->state = result;
1384 if (target->is_member) {
1385 Property member;
1387 /* Propagate the timestamp from the member file to the member */
1388 if ((target->stat.time != file_max_time) &&
1389 ((member = get_prop(target->prop, member_prop)) != NULL) &&
1390 (exists(member->body.member.member) > file_doesnt_exist)) {
1391 target->stat.time =
1393 exists(member->body.member.member);
1395 member->body.member.member->stat.time;
1399 * Check if we found any new auto dependencies when we
1400 * built the target.
1402 if ((result == build_ok) && check_auto_dependencies(target,
1403 auto_count,
1404 automatics)) {
1405 if (debug_level > 0) {
1406 (void) printf(gettext("%*sTarget `%s' acquired new dependencies from build, checking all dependencies\n"),
1407 recursion_level,
1409 true_target->string_mb);
1411 target->rechecking_target = true;
1412 target->state = build_running;
1414 /* [tolik, Tue Mar 25 1997]
1415 * Fix for bug 4038824:
1416 * command line options set by conditional macros get dropped
1417 * rp->conditional_cnt and rp->conditional_targets must be copied
1418 * to new 'rp' during add_pending(). Set_conditionals() stores
1419 * rp->conditional_targets to the global variable 'conditional_targets'
1420 * Add_pending() will use this variable to set up 'rp'.
1422 conditionals = set_conditionals(rp->conditional_cnt, rp->conditional_targets);
1423 add_pending(target,
1424 recursion_level,
1425 rp->do_get,
1426 rp->implicit,
1427 true);
1428 reset_conditionals(rp->conditional_cnt, rp->conditional_targets, conditionals);
1433 * new_running_struct()
1435 * Constructor for Running struct. Creates a structure and initializes
1436 * its fields.
1439 static Running new_running_struct()
1441 Running rp;
1443 rp = ALLOC(Running);
1444 rp->target = NULL;
1445 rp->true_target = NULL;
1446 rp->command = NULL;
1447 rp->sprodep_value = NULL;
1448 rp->sprodep_env = NULL;
1449 rp->auto_count = 0;
1450 rp->automatics = NULL;
1451 rp->pid = -1;
1452 rp->job_msg_id = -1;
1453 rp->stdout_file = NULL;
1454 rp->stderr_file = NULL;
1455 rp->temp_file = NULL;
1456 rp->next = NULL;
1457 return rp;
1461 * add_running(target, true_target, command, recursion_level, auto_count,
1462 * automatics, do_get, implicit)
1464 * Adds a record on the running list for this target, which
1465 * was just spawned and is running.
1467 * Parameters:
1468 * target Target being built
1469 * true_target True target for target
1470 * command Running command.
1471 * recursion_level Debug indentation level
1472 * auto_count Count of automatic dependencies
1473 * automatics List of automatic dependencies
1474 * do_get Sccs get flag
1475 * implicit Implicit flag
1477 * Static variables used:
1478 * running_tail Tail of running list
1479 * process_running PID of process
1481 * Global variables used:
1482 * current_line Current line for target
1483 * current_target Current target being built
1484 * stderr_file Temporary file for stdout
1485 * stdout_file Temporary file for stdout
1486 * temp_file_name Temporary file for auto dependencies
1488 void
1489 add_running(Name target, Name true_target, Property command, int recursion_level, int auto_count, Name *automatics, Boolean do_get, Boolean implicit)
1491 Running rp;
1492 Name *p;
1494 rp = new_running_struct();
1495 rp->state = build_running;
1496 rp->target = target;
1497 rp->true_target = true_target;
1498 rp->command = command;
1499 rp->recursion_level = recursion_level;
1500 rp->do_get = do_get;
1501 rp->implicit = implicit;
1502 rp->auto_count = auto_count;
1503 if (auto_count > 0) {
1504 rp->automatics = (Name *) getmem(auto_count * sizeof (Name));
1505 for (p = rp->automatics; auto_count > 0; auto_count--) {
1506 *p++ = *automatics++;
1508 } else {
1509 rp->automatics = NULL;
1512 rp->pid = process_running;
1513 process_running = -1;
1514 childPid = -1;
1516 rp->job_msg_id = job_msg_id;
1517 rp->stdout_file = stdout_file;
1518 rp->stderr_file = stderr_file;
1519 rp->temp_file = temp_file_name;
1520 rp->redo = false;
1521 rp->next = NULL;
1522 store_conditionals(rp);
1523 stdout_file = NULL;
1524 stderr_file = NULL;
1525 temp_file_name = NULL;
1526 current_target = NULL;
1527 current_line = NULL;
1528 *running_tail = rp;
1529 running_tail = &rp->next;
1533 * add_pending(target, recursion_level, do_get, implicit, redo)
1535 * Adds a record on the running list for a pending target
1536 * (waiting for its dependents to finish running).
1538 * Parameters:
1539 * target Target being built
1540 * recursion_level Debug indentation level
1541 * do_get Sccs get flag
1542 * implicit Implicit flag
1543 * redo True if this target is being redone
1545 * Static variables used:
1546 * running_tail Tail of running list
1548 void
1549 add_pending(Name target, int recursion_level, Boolean do_get, Boolean implicit, Boolean redo)
1551 Running rp;
1552 rp = new_running_struct();
1553 rp->state = build_pending;
1554 rp->target = target;
1555 rp->recursion_level = recursion_level;
1556 rp->do_get = do_get;
1557 rp->implicit = implicit;
1558 rp->redo = redo;
1559 store_conditionals(rp);
1560 *running_tail = rp;
1561 running_tail = &rp->next;
1565 * add_serial(target, recursion_level, do_get, implicit)
1567 * Adds a record on the running list for a target which must be
1568 * executed in serial after others have finished.
1570 * Parameters:
1571 * target Target being built
1572 * recursion_level Debug indentation level
1573 * do_get Sccs get flag
1574 * implicit Implicit flag
1576 * Static variables used:
1577 * running_tail Tail of running list
1579 void
1580 add_serial(Name target, int recursion_level, Boolean do_get, Boolean implicit)
1582 Running rp;
1584 rp = new_running_struct();
1585 rp->target = target;
1586 rp->recursion_level = recursion_level;
1587 rp->do_get = do_get;
1588 rp->implicit = implicit;
1589 rp->state = build_serial;
1590 rp->redo = false;
1591 store_conditionals(rp);
1592 *running_tail = rp;
1593 running_tail = &rp->next;
1597 * add_subtree(target, recursion_level, do_get, implicit)
1599 * Adds a record on the running list for a target which must be
1600 * executed in isolation after others have finished.
1602 * Parameters:
1603 * target Target being built
1604 * recursion_level Debug indentation level
1605 * do_get Sccs get flag
1606 * implicit Implicit flag
1608 * Static variables used:
1609 * running_tail Tail of running list
1611 void
1612 add_subtree(Name target, int recursion_level, Boolean do_get, Boolean implicit)
1614 Running rp;
1616 rp = new_running_struct();
1617 rp->target = target;
1618 rp->recursion_level = recursion_level;
1619 rp->do_get = do_get;
1620 rp->implicit = implicit;
1621 rp->state = build_subtree;
1622 rp->redo = false;
1623 store_conditionals(rp);
1624 *running_tail = rp;
1625 running_tail = &rp->next;
1629 * store_conditionals(rp)
1631 * Creates an array of the currently active targets with conditional
1632 * macros (found in the chain conditional_targets) and puts that
1633 * array in the Running struct.
1635 * Parameters:
1636 * rp Running struct for storing chain
1638 * Global variables used:
1639 * conditional_targets Chain of current dynamic conditionals
1641 static void
1642 store_conditionals(Running rp)
1644 int cnt;
1645 Chain cond_name;
1647 if (conditional_targets == NULL) {
1648 rp->conditional_cnt = 0;
1649 rp->conditional_targets = NULL;
1650 return;
1652 cnt = 0;
1653 for (cond_name = conditional_targets;
1654 cond_name != NULL;
1655 cond_name = cond_name->next) {
1656 cnt++;
1658 rp->conditional_cnt = cnt;
1659 rp->conditional_targets = (Name *) getmem(cnt * sizeof(Name));
1660 for (cond_name = conditional_targets;
1661 cond_name != NULL;
1662 cond_name = cond_name->next) {
1663 rp->conditional_targets[--cnt] = cond_name->name;
1668 * parallel_ok(target, line_prop_must_exists)
1670 * Returns true if the target can be run in parallel
1672 * Return value:
1673 * True if can run in parallel
1675 * Parameters:
1676 * target Target being tested
1678 * Global variables used:
1679 * all_parallel True if all targets default to parallel
1680 * only_parallel True if no targets default to parallel
1682 Boolean
1683 parallel_ok(Name target, Boolean line_prop_must_exists)
1685 Boolean assign;
1686 Boolean make_refd;
1687 Property line;
1688 Cmd_line rule;
1690 assign = make_refd = false;
1691 if (((line = get_prop(target->prop, line_prop)) == NULL) &&
1692 line_prop_must_exists) {
1693 return false;
1695 if (line != NULL) {
1696 for (rule = line->body.line.command_used;
1697 rule != NULL;
1698 rule = rule->next) {
1699 if (rule->assign) {
1700 assign = true;
1701 } else if (rule->make_refd) {
1702 make_refd = true;
1706 if (assign) {
1707 return false;
1708 } else if (target->parallel) {
1709 return true;
1710 } else if (target->no_parallel) {
1711 return false;
1712 } else if (all_parallel) {
1713 return true;
1714 } else if (only_parallel) {
1715 return false;
1716 } else if (make_refd) {
1717 return false;
1718 } else {
1719 return true;
1724 * is_running(target)
1726 * Returns true if the target is running.
1728 * Return value:
1729 * True if target is running
1731 * Parameters:
1732 * target Target to check
1734 * Global variables used:
1735 * running_list List of running processes
1737 Boolean
1738 is_running(Name target)
1740 Running rp;
1742 if (target->state != build_running) {
1743 return false;
1745 for (rp = running_list;
1746 rp != NULL && target != rp->target;
1747 rp = rp->next);
1748 if (rp == NULL) {
1749 return false;
1750 } else {
1751 return (rp->state == build_running) ? true : false;
1756 * This function replaces the makesh binary.
1760 static pid_t
1761 run_rule_commands(char *host, char **commands)
1763 Boolean always_exec;
1764 Name command;
1765 Boolean ignore;
1766 int length;
1767 Doname result;
1768 Boolean silent_flag;
1769 wchar_t *tmp_wcs_buffer;
1771 childPid = fork();
1772 switch (childPid) {
1773 case -1: /* Error */
1774 fatal(gettext("Could not fork child process for dmake job: %s"),
1775 errmsg(errno));
1776 break;
1777 case 0: /* Child */
1778 /* To control the processed targets list is not the child's business */
1779 running_list = NULL;
1780 if(out_err_same) {
1781 redirect_io(stdout_file, NULL);
1782 } else {
1783 redirect_io(stdout_file, stderr_file);
1785 for (commands = commands;
1786 (*commands != NULL);
1787 commands++) {
1788 silent_flag = silent;
1789 ignore = false;
1790 always_exec = false;
1791 while ((**commands == (int) at_char) ||
1792 (**commands == (int) hyphen_char) ||
1793 (**commands == (int) plus_char)) {
1794 if (**commands == (int) at_char) {
1795 silent_flag = true;
1797 if (**commands == (int) hyphen_char) {
1798 ignore = true;
1800 if (**commands == (int) plus_char) {
1801 always_exec = true;
1803 (*commands)++;
1805 if ((length = strlen(*commands)) >= MAXPATHLEN) {
1806 tmp_wcs_buffer = ALLOC_WC(length + 1);
1807 (void) mbstowcs(tmp_wcs_buffer, *commands, length + 1);
1808 command = GETNAME(tmp_wcs_buffer, FIND_LENGTH);
1809 retmem(tmp_wcs_buffer);
1810 } else {
1811 MBSTOWCS(wcs_buffer, *commands);
1812 command = GETNAME(wcs_buffer, FIND_LENGTH);
1814 if ((command->hash.length > 0) &&
1815 !silent_flag) {
1816 (void) printf("%s\n", command->string_mb);
1818 result = dosys(command,
1819 ignore,
1820 false,
1821 false, /* bugs #4085164 & #4990057 */
1822 /* BOOLEAN(silent_flag && ignore), */
1823 always_exec,
1824 (Name) NULL);
1825 if (result == build_failed) {
1826 if (silent_flag) {
1827 (void) printf(gettext("The following command caused the error:\n%s\n"), command->string_mb);
1829 if (!ignore) {
1830 _exit(1);
1834 _exit(0);
1835 break;
1836 default:
1837 break;
1839 return childPid;
1842 static void
1843 maybe_reread_make_state(void)
1845 /* Copying dosys()... */
1846 if (report_dependencies_level == 0) {
1847 make_state->stat.time = file_no_time;
1848 (void) exists(make_state);
1849 if (make_state_before == make_state->stat.time) {
1850 return;
1852 makefile_type = reading_statefile;
1853 if (read_trace_level > 1) {
1854 trace_reader = true;
1856 temp_file_number++;
1857 (void) read_simple_file(make_state,
1858 false,
1859 false,
1860 false,
1861 false,
1862 false,
1863 true);
1864 trace_reader = false;
1869 static void
1870 delete_running_struct(Running rp)
1872 if ((rp->conditional_cnt > 0) &&
1873 (rp->conditional_targets != NULL)) {
1874 retmem_mb((char *) rp->conditional_targets);
1876 /**/
1877 if ((rp->auto_count > 0) &&
1878 (rp->automatics != NULL)) {
1879 retmem_mb((char *) rp->automatics);
1881 /**/
1882 if(rp->sprodep_value) {
1883 free_name(rp->sprodep_value);
1885 if(rp->sprodep_env) {
1886 retmem_mb(rp->sprodep_env);
1888 retmem_mb((char *) rp);