xref: /illumos-gate/usr/src/cmd/make/bin/state.cc (revision e7afc443)
110d63b7dSRichard Lowe /*
210d63b7dSRichard Lowe  * CDDL HEADER START
310d63b7dSRichard Lowe  *
410d63b7dSRichard Lowe  * The contents of this file are subject to the terms of the
510d63b7dSRichard Lowe  * Common Development and Distribution License (the "License").
610d63b7dSRichard Lowe  * You may not use this file except in compliance with the License.
710d63b7dSRichard Lowe  *
810d63b7dSRichard Lowe  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910d63b7dSRichard Lowe  * or http://www.opensolaris.org/os/licensing.
1010d63b7dSRichard Lowe  * See the License for the specific language governing permissions
1110d63b7dSRichard Lowe  * and limitations under the License.
1210d63b7dSRichard Lowe  *
1310d63b7dSRichard Lowe  * When distributing Covered Code, include this CDDL HEADER in each
1410d63b7dSRichard Lowe  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510d63b7dSRichard Lowe  * If applicable, add the following below this CDDL HEADER, with the
1610d63b7dSRichard Lowe  * fields enclosed by brackets "[]" replaced with your own identifying
1710d63b7dSRichard Lowe  * information: Portions Copyright [yyyy] [name of copyright owner]
1810d63b7dSRichard Lowe  *
1910d63b7dSRichard Lowe  * CDDL HEADER END
2010d63b7dSRichard Lowe  */
2110d63b7dSRichard Lowe /*
2210d63b7dSRichard Lowe  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
2310d63b7dSRichard Lowe  * Use is subject to license terms.
2410d63b7dSRichard Lowe  */
2510d63b7dSRichard Lowe 
2610d63b7dSRichard Lowe /*
2710d63b7dSRichard Lowe  *	state.c
2810d63b7dSRichard Lowe  *
2910d63b7dSRichard Lowe  *	This file contains the routines that write the .make.state file
3010d63b7dSRichard Lowe  */
3110d63b7dSRichard Lowe 
3210d63b7dSRichard Lowe /*
3310d63b7dSRichard Lowe  * Included files
3410d63b7dSRichard Lowe  */
3510d63b7dSRichard Lowe #include <mk/defs.h>
3610d63b7dSRichard Lowe #include <mksh/misc.h>		/* errmsg() */
3710d63b7dSRichard Lowe #include <setjmp.h>		/* setjmp() */
3810d63b7dSRichard Lowe #include <unistd.h>		/* getpid() */
3910d63b7dSRichard Lowe #include <errno.h>		/* errno    */
4010d63b7dSRichard Lowe #include <locale.h>		/* MB_CUR_MAX    */
4110d63b7dSRichard Lowe 
4210d63b7dSRichard Lowe /*
4310d63b7dSRichard Lowe  * Defined macros
4410d63b7dSRichard Lowe  */
4510d63b7dSRichard Lowe #define LONGJUMP_VALUE 17
4610d63b7dSRichard Lowe #define XFWRITE(string, length, fd) {if (fwrite(string, 1, length, fd) == 0) \
4710d63b7dSRichard Lowe 					longjmp(long_jump, LONGJUMP_VALUE);}
4810d63b7dSRichard Lowe #define XPUTC(ch, fd) { \
4910d63b7dSRichard Lowe 	if (putc((int) ch, fd) == EOF) \
5010d63b7dSRichard Lowe 		longjmp(long_jump, LONGJUMP_VALUE); \
5110d63b7dSRichard Lowe 	}
5210d63b7dSRichard Lowe #define XFPUTS(string, fd) fputs(string, fd)
5310d63b7dSRichard Lowe 
5410d63b7dSRichard Lowe /*
5510d63b7dSRichard Lowe  * typedefs & structs
5610d63b7dSRichard Lowe  */
5710d63b7dSRichard Lowe 
5810d63b7dSRichard Lowe /*
5910d63b7dSRichard Lowe  * Static variables
6010d63b7dSRichard Lowe  */
6110d63b7dSRichard Lowe 
6210d63b7dSRichard Lowe /*
6310d63b7dSRichard Lowe  * File table of contents
6410d63b7dSRichard Lowe  */
escape_target_name(Name np)6510d63b7dSRichard Lowe static char * escape_target_name(Name np)
6610d63b7dSRichard Lowe {
6710d63b7dSRichard Lowe 	if(np->dollar) {
6810d63b7dSRichard Lowe 		int len = strlen(np->string_mb);
6910d63b7dSRichard Lowe 		char * buff = (char*)malloc(2 * len);
7010d63b7dSRichard Lowe 		int pos = 0;
7110d63b7dSRichard Lowe 		wchar_t wc;
7210d63b7dSRichard Lowe 		int pp = 0;
7310d63b7dSRichard Lowe 		while(pos < len) {
7410d63b7dSRichard Lowe 			int n = mbtowc(&wc, np->string_mb + pos, MB_CUR_MAX);
7510d63b7dSRichard Lowe 			if(n < 0) { // error - this shouldn't happen
7610d63b7dSRichard Lowe 				(void)free(buff);
7710d63b7dSRichard Lowe 				return strdup(np->string_mb);
7810d63b7dSRichard Lowe 			}
7910d63b7dSRichard Lowe 			if(wc == dollar_char) {
8010d63b7dSRichard Lowe 				buff[pp] = '\\'; pp++;
8110d63b7dSRichard Lowe 				buff[pp] = '$'; pp++;
8210d63b7dSRichard Lowe 			} else {
8310d63b7dSRichard Lowe 				for(int j=0;j<n;j++) {
8410d63b7dSRichard Lowe 					buff[pp] = np->string_mb[pos+j]; pp++;
8510d63b7dSRichard Lowe 				}
8610d63b7dSRichard Lowe 			}
8710d63b7dSRichard Lowe 			pos += n;
8810d63b7dSRichard Lowe 		}
8910d63b7dSRichard Lowe 		buff[pp] = '\0';
9010d63b7dSRichard Lowe 		return buff;
9110d63b7dSRichard Lowe 	} else {
9210d63b7dSRichard Lowe 		return strdup(np->string_mb);
9310d63b7dSRichard Lowe 	}
9410d63b7dSRichard Lowe }
9510d63b7dSRichard Lowe 
96*e7afc443SToomas Soome static	void		print_auto_depes(Dependency dependency, FILE *fd, Boolean built_this_run, int *line_length, char *target_name, jmp_buf long_jump);
9710d63b7dSRichard Lowe 
9810d63b7dSRichard Lowe /*
9910d63b7dSRichard Lowe  *	write_state_file(report_recursive, exiting)
10010d63b7dSRichard Lowe  *
10110d63b7dSRichard Lowe  *	Write a new version of .make.state
10210d63b7dSRichard Lowe  *
10310d63b7dSRichard Lowe  *	Parameters:
10410d63b7dSRichard Lowe  *		report_recursive	Should only be done at end of run
10510d63b7dSRichard Lowe  *		exiting			true if called from the exit handler
10610d63b7dSRichard Lowe  *
10710d63b7dSRichard Lowe  *	Global variables used:
10810d63b7dSRichard Lowe  *		built_last_make_run The Name ".BUILT_LAST_MAKE_RUN", written
10910d63b7dSRichard Lowe  *		command_changed	If no command changed we do not need to write
11010d63b7dSRichard Lowe  *		current_make_version The Name "<current version>", written
11110d63b7dSRichard Lowe  *		do_not_exec_rule If -n is on we do not write statefile
11210d63b7dSRichard Lowe  *		hashtab		The hashtable that contains all names
11310d63b7dSRichard Lowe  *		keep_state	If .KEEP_STATE is no on we do not write file
11410d63b7dSRichard Lowe  *		make_state	The Name ".make.state", used for opening file
11510d63b7dSRichard Lowe  *		make_version	The Name ".MAKE_VERSION", written
11610d63b7dSRichard Lowe  *		recursive_name	The Name ".RECURSIVE", written
11710d63b7dSRichard Lowe  *		rewrite_statefile Indicates that something changed
11810d63b7dSRichard Lowe  */
11910d63b7dSRichard Lowe 
12010d63b7dSRichard Lowe void
write_state_file(int,Boolean exiting)12110d63b7dSRichard Lowe write_state_file(int, Boolean exiting)
12210d63b7dSRichard Lowe {
123*e7afc443SToomas Soome 	FILE		*fd;
12410d63b7dSRichard Lowe 	int			lock_err;
12510d63b7dSRichard Lowe 	char			buffer[MAXPATHLEN];
12610d63b7dSRichard Lowe 	char			make_state_tempfile[MAXPATHLEN];
12710d63b7dSRichard Lowe 	jmp_buf			long_jump;
128*e7afc443SToomas Soome 	int		attempts = 0;
12910d63b7dSRichard Lowe 	Name_set::iterator	np, e;
130*e7afc443SToomas Soome 	Property	lines;
131*e7afc443SToomas Soome 	int		m;
13210d63b7dSRichard Lowe 	Dependency		dependency;
133*e7afc443SToomas Soome 	Boolean	name_printed;
13410d63b7dSRichard Lowe 	Boolean			built_this_run = false;
13510d63b7dSRichard Lowe 	char			*target_name;
13610d63b7dSRichard Lowe 	int			line_length;
137*e7afc443SToomas Soome 	Cmd_line	cp;
13810d63b7dSRichard Lowe 
13910d63b7dSRichard Lowe 
14010d63b7dSRichard Lowe 	if (!rewrite_statefile ||
14110d63b7dSRichard Lowe 	    !command_changed ||
14210d63b7dSRichard Lowe 	    !keep_state ||
14310d63b7dSRichard Lowe 	    do_not_exec_rule ||
14410d63b7dSRichard Lowe 	    (report_dependencies_level > 0)) {
14510d63b7dSRichard Lowe 		return;
14610d63b7dSRichard Lowe 	}
14710d63b7dSRichard Lowe 	/* Lock the file for writing. */
148ae389aa9SAndy Fiddaman 	make_state_lockfile = getmem(strlen(make_state->string_mb) + strlen(".lock") + 1);
149ae389aa9SAndy Fiddaman 	(void) sprintf(make_state_lockfile,
150ae389aa9SAndy Fiddaman 	               "%s.lock",
151ae389aa9SAndy Fiddaman 	               make_state->string_mb);
152ae389aa9SAndy Fiddaman 	if (lock_err = file_lock(make_state->string_mb,
153ae389aa9SAndy Fiddaman 				 make_state_lockfile,
15410d63b7dSRichard Lowe 				 (int *) &make_state_locked, 0)) {
155ae389aa9SAndy Fiddaman 		retmem_mb(make_state_lockfile);
15610d63b7dSRichard Lowe 		make_state_lockfile = NULL;
157ae389aa9SAndy Fiddaman 
15810d63b7dSRichard Lowe 		/*
15910d63b7dSRichard Lowe 		 * We need to make sure that we are not being
16010d63b7dSRichard Lowe 		 * called by the exit handler so we don't call
16110d63b7dSRichard Lowe 		 * it again.
16210d63b7dSRichard Lowe 		 */
163ae389aa9SAndy Fiddaman 
16410d63b7dSRichard Lowe 		if (exiting) {
16510d63b7dSRichard Lowe 			(void) sprintf(buffer, "%s/.make.state.%d.XXXXXX", tmpdir, getpid());
16610d63b7dSRichard Lowe 			report_pwd = true;
16710d63b7dSRichard Lowe 			warning(gettext("Writing to %s"), buffer);
16810d63b7dSRichard Lowe 			int fdes = mkstemp(buffer);
16910d63b7dSRichard Lowe 			if ((fdes < 0) || (fd = fdopen(fdes, "w")) == NULL) {
17010d63b7dSRichard Lowe 				fprintf(stderr,
17110d63b7dSRichard Lowe 					gettext("Could not open statefile `%s': %s"),
17210d63b7dSRichard Lowe 					buffer,
17310d63b7dSRichard Lowe 					errmsg(errno));
17410d63b7dSRichard Lowe 				return;
17510d63b7dSRichard Lowe 			}
17610d63b7dSRichard Lowe 		} else {
17710d63b7dSRichard Lowe 			report_pwd = true;
17810d63b7dSRichard Lowe 			fatal(gettext("Can't lock .make.state"));
17910d63b7dSRichard Lowe 		}
18010d63b7dSRichard Lowe 	}
18110d63b7dSRichard Lowe 
18210d63b7dSRichard Lowe 	(void) sprintf(make_state_tempfile,
18310d63b7dSRichard Lowe 	               "%s.tmp",
18410d63b7dSRichard Lowe 	               make_state->string_mb);
18510d63b7dSRichard Lowe 	/* Delete old temporary statefile (in case it exists) */
18610d63b7dSRichard Lowe 	(void) unlink(make_state_tempfile);
18710d63b7dSRichard Lowe 	if ((fd = fopen(make_state_tempfile, "w")) == NULL) {
18810d63b7dSRichard Lowe 		lock_err = errno; /* Save it! unlink() can change errno */
18910d63b7dSRichard Lowe 		(void) unlink(make_state_lockfile);
190ae389aa9SAndy Fiddaman 		retmem_mb(make_state_lockfile);
19110d63b7dSRichard Lowe 		make_state_lockfile = NULL;
19210d63b7dSRichard Lowe 		make_state_locked = false;
19310d63b7dSRichard Lowe 		fatal(gettext("Could not open temporary statefile `%s': %s"),
19410d63b7dSRichard Lowe 		      make_state_tempfile,
19510d63b7dSRichard Lowe 		      errmsg(lock_err));
19610d63b7dSRichard Lowe 	}
19710d63b7dSRichard Lowe 	/*
19810d63b7dSRichard Lowe 	 * Set a trap for failed writes. If a write fails, the routine
19910d63b7dSRichard Lowe 	 * will try saving the .make.state file under another name in /tmp.
20010d63b7dSRichard Lowe 	 */
20110d63b7dSRichard Lowe 	if (setjmp(long_jump)) {
20210d63b7dSRichard Lowe 		(void) fclose(fd);
20310d63b7dSRichard Lowe 		if (attempts++ > 5) {
20410d63b7dSRichard Lowe 			if ((make_state_lockfile != NULL) &&
20510d63b7dSRichard Lowe 			    make_state_locked) {
20610d63b7dSRichard Lowe 				(void) unlink(make_state_lockfile);
207ae389aa9SAndy Fiddaman 				retmem_mb(make_state_lockfile);
20810d63b7dSRichard Lowe 				make_state_lockfile = NULL;
20910d63b7dSRichard Lowe 				make_state_locked = false;
21010d63b7dSRichard Lowe 			}
21110d63b7dSRichard Lowe 			fatal(gettext("Giving up on writing statefile"));
21210d63b7dSRichard Lowe 		}
21310d63b7dSRichard Lowe 		sleep(10);
21410d63b7dSRichard Lowe 		(void) sprintf(buffer, "%s/.make.state.%d.XXXXXX", tmpdir, getpid());
21510d63b7dSRichard Lowe 		int fdes = mkstemp(buffer);
21610d63b7dSRichard Lowe 		if ((fdes < 0) || (fd = fdopen(fdes, "w")) == NULL) {
21710d63b7dSRichard Lowe 			fatal(gettext("Could not open statefile `%s': %s"),
21810d63b7dSRichard Lowe 			      buffer,
21910d63b7dSRichard Lowe 			      errmsg(errno));
22010d63b7dSRichard Lowe 		}
22110d63b7dSRichard Lowe 		warning(gettext("Initial write of statefile failed. Trying again on %s"),
22210d63b7dSRichard Lowe 			buffer);
22310d63b7dSRichard Lowe 	}
22410d63b7dSRichard Lowe 
22510d63b7dSRichard Lowe 	/* Write the version stamp. */
22610d63b7dSRichard Lowe 	XFWRITE(make_version->string_mb,
22710d63b7dSRichard Lowe 		strlen(make_version->string_mb),
22810d63b7dSRichard Lowe 		fd);
22910d63b7dSRichard Lowe 	XPUTC(colon_char, fd);
23010d63b7dSRichard Lowe 	XPUTC(tab_char, fd);
23110d63b7dSRichard Lowe 	XFWRITE(current_make_version->string_mb,
23210d63b7dSRichard Lowe 		strlen(current_make_version->string_mb),
23310d63b7dSRichard Lowe 		fd);
23410d63b7dSRichard Lowe 	XPUTC(newline_char, fd);
23510d63b7dSRichard Lowe 
23610d63b7dSRichard Lowe 	/*
23710d63b7dSRichard Lowe 	 * Go through all the targets, dump their dependencies and
23810d63b7dSRichard Lowe 	 * command used.
23910d63b7dSRichard Lowe 	 */
24010d63b7dSRichard Lowe 	for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
24110d63b7dSRichard Lowe 		/*
24210d63b7dSRichard Lowe 		 * If the target has no command used nor dependencies,
24310d63b7dSRichard Lowe 		 * we can go to the next one.
24410d63b7dSRichard Lowe 		 */
24510d63b7dSRichard Lowe 		if ((lines = get_prop(np->prop, line_prop)) == NULL) {
24610d63b7dSRichard Lowe 			continue;
24710d63b7dSRichard Lowe 		}
24810d63b7dSRichard Lowe 		/* If this target is a special target, don't print. */
24910d63b7dSRichard Lowe 		if (np->special_reader != no_special) {
25010d63b7dSRichard Lowe 			continue;
25110d63b7dSRichard Lowe 		}
25210d63b7dSRichard Lowe 		/*
25310d63b7dSRichard Lowe 		 * Find out if any of the targets dependencies should
25410d63b7dSRichard Lowe 		 * be written to .make.state.
25510d63b7dSRichard Lowe 		 */
25610d63b7dSRichard Lowe 		for (m = 0, dependency = lines->body.line.dependencies;
25710d63b7dSRichard Lowe 		     dependency != NULL;
25810d63b7dSRichard Lowe 		     dependency = dependency->next) {
25910d63b7dSRichard Lowe 			if (m = !dependency->stale
26010d63b7dSRichard Lowe 			    && (dependency->name != force)
26110d63b7dSRichard Lowe #ifndef PRINT_EXPLICIT_DEPEN
26210d63b7dSRichard Lowe 			    && dependency->automatic
26310d63b7dSRichard Lowe #endif
26410d63b7dSRichard Lowe 			    ) {
26510d63b7dSRichard Lowe 				break;
26610d63b7dSRichard Lowe 			}
26710d63b7dSRichard Lowe 		}
26810d63b7dSRichard Lowe 		/* Only print if dependencies listed. */
26910d63b7dSRichard Lowe 		if (m || (lines->body.line.command_used != NULL)) {
27010d63b7dSRichard Lowe 			name_printed = false;
27110d63b7dSRichard Lowe 			/*
27210d63b7dSRichard Lowe 			 * If this target was built during this make run,
27310d63b7dSRichard Lowe 			 * we mark it.
27410d63b7dSRichard Lowe 			 */
27510d63b7dSRichard Lowe 			built_this_run = false;
27610d63b7dSRichard Lowe 			if (np->has_built) {
27710d63b7dSRichard Lowe 				built_this_run = true;
27810d63b7dSRichard Lowe 				XFWRITE(built_last_make_run->string_mb,
27910d63b7dSRichard Lowe 					strlen(built_last_make_run->string_mb),
28010d63b7dSRichard Lowe 					fd);
28110d63b7dSRichard Lowe 				XPUTC(colon_char, fd);
28210d63b7dSRichard Lowe 				XPUTC(newline_char, fd);
28310d63b7dSRichard Lowe 			}
28410d63b7dSRichard Lowe 			/* If the target has dependencies, we dump them. */
28510d63b7dSRichard Lowe 			target_name = escape_target_name(np);
28610d63b7dSRichard Lowe 			if (np->has_long_member_name) {
28710d63b7dSRichard Lowe 				target_name =
28810d63b7dSRichard Lowe 				  get_prop(np->prop, long_member_name_prop)
28910d63b7dSRichard Lowe 				    ->body.long_member_name.member_name->
29010d63b7dSRichard Lowe 				      string_mb;
29110d63b7dSRichard Lowe 			}
29210d63b7dSRichard Lowe 			if (m) {
29310d63b7dSRichard Lowe 				XFPUTS(target_name, fd);
29410d63b7dSRichard Lowe 				XPUTC(colon_char, fd);
29510d63b7dSRichard Lowe 				XFPUTS("\t", fd);
29610d63b7dSRichard Lowe 				name_printed = true;
29710d63b7dSRichard Lowe 				line_length = 0;
29810d63b7dSRichard Lowe 				for (dependency =
29910d63b7dSRichard Lowe 				     lines->body.line.dependencies;
30010d63b7dSRichard Lowe 				     dependency != NULL;
30110d63b7dSRichard Lowe 				     dependency = dependency->next) {
30210d63b7dSRichard Lowe 					print_auto_depes(dependency,
30310d63b7dSRichard Lowe 							 fd,
30410d63b7dSRichard Lowe 							 built_this_run,
30510d63b7dSRichard Lowe 							 &line_length,
30610d63b7dSRichard Lowe 							 target_name,
30710d63b7dSRichard Lowe 							 long_jump);
30810d63b7dSRichard Lowe 				}
30910d63b7dSRichard Lowe 				XFPUTS("\n", fd);
31010d63b7dSRichard Lowe 			}
31110d63b7dSRichard Lowe 			/* If there is a command used, we dump it. */
31210d63b7dSRichard Lowe 			if (lines->body.line.command_used != NULL) {
31310d63b7dSRichard Lowe 				/*
31410d63b7dSRichard Lowe 				 * Only write the target name if it
31510d63b7dSRichard Lowe 				 * wasn't done for the dependencies.
31610d63b7dSRichard Lowe 				 */
31710d63b7dSRichard Lowe 				if (!name_printed) {
31810d63b7dSRichard Lowe 					XFPUTS(target_name, fd);
31910d63b7dSRichard Lowe 					XPUTC(colon_char, fd);
32010d63b7dSRichard Lowe 					XPUTC(newline_char, fd);
32110d63b7dSRichard Lowe 				}
32210d63b7dSRichard Lowe 				/*
32310d63b7dSRichard Lowe 				 * Write the command lines.
32410d63b7dSRichard Lowe 				 * Prefix each textual line with a tab.
32510d63b7dSRichard Lowe 				 */
32610d63b7dSRichard Lowe 				for (cp = lines->body.line.command_used;
32710d63b7dSRichard Lowe 				     cp != NULL;
32810d63b7dSRichard Lowe 				     cp = cp->next) {
32910d63b7dSRichard Lowe 					char		*csp;
33010d63b7dSRichard Lowe 					int		n;
33110d63b7dSRichard Lowe 
33210d63b7dSRichard Lowe 					XPUTC(tab_char, fd);
33310d63b7dSRichard Lowe 					if (cp->command_line != NULL) {
33410d63b7dSRichard Lowe 						for (csp = cp->
33510d63b7dSRichard Lowe 						           command_line->
33610d63b7dSRichard Lowe 						           string_mb,
33710d63b7dSRichard Lowe 						     n = strlen(cp->
33810d63b7dSRichard Lowe 						                command_line->
33910d63b7dSRichard Lowe 						                string_mb);
34010d63b7dSRichard Lowe 						     n > 0;
34110d63b7dSRichard Lowe 						     n--, csp++) {
34210d63b7dSRichard Lowe 							XPUTC(*csp, fd);
34310d63b7dSRichard Lowe 							if (*csp ==
34410d63b7dSRichard Lowe 							    (int) newline_char) {
34510d63b7dSRichard Lowe 								XPUTC(tab_char,
34610d63b7dSRichard Lowe 								      fd);
34710d63b7dSRichard Lowe 							}
34810d63b7dSRichard Lowe 						}
34910d63b7dSRichard Lowe 					}
35010d63b7dSRichard Lowe 					XPUTC(newline_char, fd);
35110d63b7dSRichard Lowe 				}
35210d63b7dSRichard Lowe 			}
35310d63b7dSRichard Lowe 			(void)free(target_name);
35410d63b7dSRichard Lowe 		}
35510d63b7dSRichard Lowe 	}
35610d63b7dSRichard Lowe 	if (fclose(fd) == EOF) {
35710d63b7dSRichard Lowe 		longjmp(long_jump, LONGJUMP_VALUE);
35810d63b7dSRichard Lowe 	}
35910d63b7dSRichard Lowe 	if (attempts == 0) {
36010d63b7dSRichard Lowe 		if (unlink(make_state->string_mb) != 0 && errno != ENOENT) {
36110d63b7dSRichard Lowe 			lock_err = errno; /* Save it! unlink() can change errno */
36210d63b7dSRichard Lowe 			/* Delete temporary statefile */
36310d63b7dSRichard Lowe 			(void) unlink(make_state_tempfile);
36410d63b7dSRichard Lowe 			(void) unlink(make_state_lockfile);
365ae389aa9SAndy Fiddaman 			retmem_mb(make_state_lockfile);
36610d63b7dSRichard Lowe 			make_state_lockfile = NULL;
36710d63b7dSRichard Lowe 			make_state_locked = false;
36810d63b7dSRichard Lowe 			fatal(gettext("Could not delete old statefile `%s': %s"),
36910d63b7dSRichard Lowe 			      make_state->string_mb,
37010d63b7dSRichard Lowe 			      errmsg(lock_err));
37110d63b7dSRichard Lowe 		}
37210d63b7dSRichard Lowe 		if (rename(make_state_tempfile, make_state->string_mb) != 0) {
37310d63b7dSRichard Lowe 			lock_err = errno; /* Save it! unlink() can change errno */
37410d63b7dSRichard Lowe 			/* Delete temporary statefile */
37510d63b7dSRichard Lowe 			(void) unlink(make_state_tempfile);
37610d63b7dSRichard Lowe 			(void) unlink(make_state_lockfile);
377ae389aa9SAndy Fiddaman 			retmem_mb(make_state_lockfile);
37810d63b7dSRichard Lowe 			make_state_lockfile = NULL;
37910d63b7dSRichard Lowe 			make_state_locked = false;
38010d63b7dSRichard Lowe 			fatal(gettext("Could not rename `%s' to `%s': %s"),
38110d63b7dSRichard Lowe 			      make_state_tempfile,
38210d63b7dSRichard Lowe 			      make_state->string_mb,
38310d63b7dSRichard Lowe 			      errmsg(lock_err));
38410d63b7dSRichard Lowe 		}
38510d63b7dSRichard Lowe 	}
38610d63b7dSRichard Lowe 	if ((make_state_lockfile != NULL) && make_state_locked) {
38710d63b7dSRichard Lowe 		(void) unlink(make_state_lockfile);
388ae389aa9SAndy Fiddaman 		retmem_mb(make_state_lockfile);
38910d63b7dSRichard Lowe 		make_state_lockfile = NULL;
39010d63b7dSRichard Lowe 		make_state_locked = false;
39110d63b7dSRichard Lowe 	}
39210d63b7dSRichard Lowe }
39310d63b7dSRichard Lowe 
39410d63b7dSRichard Lowe /*
39510d63b7dSRichard Lowe  *	print_auto_depes(dependency, fd, built_this_run,
39610d63b7dSRichard Lowe  *			 line_length, target_name, long_jump)
39710d63b7dSRichard Lowe  *
39810d63b7dSRichard Lowe  *	Will print a dependency list for automatic entries.
39910d63b7dSRichard Lowe  *
40010d63b7dSRichard Lowe  *	Parameters:
40110d63b7dSRichard Lowe  *		dependency	The dependency to print
40210d63b7dSRichard Lowe  *		fd		The file to print it to
40310d63b7dSRichard Lowe  *		built_this_run	If on we prefix each line with .BUILT_THIS...
40410d63b7dSRichard Lowe  *		line_length	Pointer to line length var that we update
40510d63b7dSRichard Lowe  *		target_name	We need this when we restart line
40610d63b7dSRichard Lowe  *		long_jump	setjmp/longjmp buffer used for IO error action
40710d63b7dSRichard Lowe  *
40810d63b7dSRichard Lowe  *	Global variables used:
40910d63b7dSRichard Lowe  *		built_last_make_run The Name ".BUILT_LAST_MAKE_RUN", written
41010d63b7dSRichard Lowe  *		force		The Name " FORCE", compared against
41110d63b7dSRichard Lowe  */
41210d63b7dSRichard Lowe static void
print_auto_depes(Dependency dependency,FILE * fd,Boolean built_this_run,int * line_length,char * target_name,jmp_buf long_jump)413*e7afc443SToomas Soome print_auto_depes(Dependency dependency, FILE *fd, Boolean built_this_run, int *line_length, char *target_name, jmp_buf long_jump)
41410d63b7dSRichard Lowe {
41510d63b7dSRichard Lowe 	if (!dependency->automatic ||
41610d63b7dSRichard Lowe 	    dependency->stale ||
41710d63b7dSRichard Lowe 	    (dependency->name == force)) {
41810d63b7dSRichard Lowe 		return;
41910d63b7dSRichard Lowe 	}
420ae389aa9SAndy Fiddaman 	XFWRITE(dependency->name->string_mb,
42110d63b7dSRichard Lowe 		strlen(dependency->name->string_mb),
42210d63b7dSRichard Lowe 		fd);
42310d63b7dSRichard Lowe 	/*
42410d63b7dSRichard Lowe 	 * Check if the dependency line is too long.
42510d63b7dSRichard Lowe 	 * If so, break it and start a new one.
42610d63b7dSRichard Lowe 	 */
42710d63b7dSRichard Lowe 	if ((*line_length += (int) strlen(dependency->name->string_mb) + 1) > 450) {
42810d63b7dSRichard Lowe 		*line_length = 0;
42910d63b7dSRichard Lowe 		XPUTC(newline_char, fd);
43010d63b7dSRichard Lowe 		if (built_this_run) {
43110d63b7dSRichard Lowe 			XFPUTS(built_last_make_run->string_mb, fd);
43210d63b7dSRichard Lowe 			XPUTC(colon_char, fd);
43310d63b7dSRichard Lowe 			XPUTC(newline_char, fd);
43410d63b7dSRichard Lowe 		}
43510d63b7dSRichard Lowe 		XFPUTS(target_name, fd);
43610d63b7dSRichard Lowe 		XPUTC(colon_char, fd);
43710d63b7dSRichard Lowe 		XPUTC(tab_char, fd);
43810d63b7dSRichard Lowe 	} else {
43910d63b7dSRichard Lowe 		XFPUTS(" ", fd);
44010d63b7dSRichard Lowe 	}
44110d63b7dSRichard Lowe 	return;
44210d63b7dSRichard Lowe }
44310d63b7dSRichard Lowe 
44410d63b7dSRichard Lowe 
445