10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * CDDL HEADER START
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The contents of this file are subject to the terms of the
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Common Development and Distribution License (the "License").
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * You may not use this file except in compliance with the License.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * or http://www.opensolaris.org/os/licensing.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * See the License for the specific language governing permissions
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * and limitations under the License.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * When distributing Covered Code, include this CDDL HEADER in each
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * If applicable, add the following below this CDDL HEADER, with the
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * CDDL HEADER END
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Use is subject to license terms.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * state.c
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * This file contains the routines that write the .make.state file
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Included files
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <mk/defs.h>
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <mksh/misc.h> /* errmsg() */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <setjmp.h> /* setjmp() */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <unistd.h> /* getpid() */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <errno.h> /* errno */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <locale.h> /* MB_CUR_MAX */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Defined macros
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#define LONGJUMP_VALUE 17
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#define XFWRITE(string, length, fd) {if (fwrite(string, 1, length, fd) == 0) \
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe longjmp(long_jump, LONGJUMP_VALUE);}
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#define XPUTC(ch, fd) { \
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (putc((int) ch, fd) == EOF) \
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe longjmp(long_jump, LONGJUMP_VALUE); \
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#define XFPUTS(string, fd) fputs(string, fd)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * typedefs & structs
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Static variables
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * File table of contents
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestatic char * escape_target_name(Name np)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe{
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if(np->dollar) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int len = strlen(np->string_mb);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char * buff = (char*)malloc(2 * len);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int pos = 0;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe wchar_t wc;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int pp = 0;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe while(pos < len) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int n = mbtowc(&wc, np->string_mb + pos, MB_CUR_MAX);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if(n < 0) { // error - this shouldn't happen
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void)free(buff);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return strdup(np->string_mb);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if(wc == dollar_char) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe buff[pp] = '\\'; pp++;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe buff[pp] = '$'; pp++;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe for(int j=0;j<n;j++) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe buff[pp] = np->string_mb[pos+j]; pp++;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe pos += n;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe buff[pp] = '\0';
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return buff;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return strdup(np->string_mb);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe}
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestatic void print_auto_depes(register Dependency dependency, register FILE *fd, register Boolean built_this_run, register int *line_length, register char *target_name, jmp_buf long_jump);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * write_state_file(report_recursive, exiting)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Write a new version of .make.state
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Parameters:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * report_recursive Should only be done at end of run
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * exiting true if called from the exit handler
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * built_last_make_run The Name ".BUILT_LAST_MAKE_RUN", written
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * command_changed If no command changed we do not need to write
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * current_make_version The Name "<current version>", written
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * do_not_exec_rule If -n is on we do not write statefile
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * hashtab The hashtable that contains all names
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * keep_state If .KEEP_STATE is no on we do not write file
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * make_state The Name ".make.state", used for opening file
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * make_version The Name ".MAKE_VERSION", written
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * recursive_name The Name ".RECURSIVE", written
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * rewrite_statefile Indicates that something changed
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowevoid
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowewrite_state_file(int, Boolean exiting)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe{
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register FILE *fd;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int lock_err;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char buffer[MAXPATHLEN];
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char make_state_tempfile[MAXPATHLEN];
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe jmp_buf long_jump;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register int attempts = 0;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Name_set::iterator np, e;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register Property lines;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register int m;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Dependency dependency;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register Boolean name_printed;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Boolean built_this_run = false;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char *target_name;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int line_length;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register Cmd_line cp;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (!rewrite_statefile ||
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe !command_changed ||
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe !keep_state ||
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe do_not_exec_rule ||
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (report_dependencies_level > 0)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* Lock the file for writing. */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_lockfile = getmem(strlen(make_state->string_mb) + strlen(".lock") + 1);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) sprintf(make_state_lockfile,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe "%s.lock",
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state->string_mb);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (lock_err = file_lock(make_state->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_lockfile,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (int *) &make_state_locked, 0)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe retmem_mb(make_state_lockfile);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_lockfile = NULL;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * We need to make sure that we are not being
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * called by the exit handler so we don't call
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * it again.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (exiting) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) sprintf(buffer, "%s/.make.state.%d.XXXXXX", tmpdir, getpid());
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe report_pwd = true;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe warning(gettext("Writing to %s"), buffer);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int fdes = mkstemp(buffer);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((fdes < 0) || (fd = fdopen(fdes, "w")) == NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fprintf(stderr,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe gettext("Could not open statefile `%s': %s"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe buffer,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe errmsg(errno));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe report_pwd = true;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Can't lock .make.state"));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) sprintf(make_state_tempfile,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe "%s.tmp",
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state->string_mb);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* Delete old temporary statefile (in case it exists) */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) unlink(make_state_tempfile);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((fd = fopen(make_state_tempfile, "w")) == NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe lock_err = errno; /* Save it! unlink() can change errno */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) unlink(make_state_lockfile);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe retmem_mb(make_state_lockfile);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_lockfile = NULL;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_locked = false;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Could not open temporary statefile `%s': %s"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_tempfile,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe errmsg(lock_err));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Set a trap for failed writes. If a write fails, the routine
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * will try saving the .make.state file under another name in /tmp.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (setjmp(long_jump)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) fclose(fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (attempts++ > 5) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((make_state_lockfile != NULL) &&
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_locked) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) unlink(make_state_lockfile);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe retmem_mb(make_state_lockfile);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_lockfile = NULL;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_locked = false;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Giving up on writing statefile"));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe sleep(10);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) sprintf(buffer, "%s/.make.state.%d.XXXXXX", tmpdir, getpid());
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int fdes = mkstemp(buffer);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((fdes < 0) || (fd = fdopen(fdes, "w")) == NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Could not open statefile `%s': %s"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe buffer,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe errmsg(errno));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe warning(gettext("Initial write of statefile failed. Trying again on %s"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe buffer);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* Write the version stamp. */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XFWRITE(make_version->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe strlen(make_version->string_mb),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(colon_char, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(tab_char, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XFWRITE(current_make_version->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe strlen(current_make_version->string_mb),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(newline_char, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Go through all the targets, dump their dependencies and
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * command used.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * If the target has no command used nor dependencies,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * we can go to the next one.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((lines = get_prop(np->prop, line_prop)) == NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe continue;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* If this target is a special target, don't print. */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (np->special_reader != no_special) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe continue;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Find out if any of the targets dependencies should
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * be written to .make.state.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe for (m = 0, dependency = lines->body.line.dependencies;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe dependency != NULL;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe dependency = dependency->next) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (m = !dependency->stale
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe && (dependency->name != force)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#ifndef PRINT_EXPLICIT_DEPEN
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe && dependency->automatic
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#endif
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* Only print if dependencies listed. */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (m || (lines->body.line.command_used != NULL)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe name_printed = false;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * If this target was built during this make run,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * we mark it.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe built_this_run = false;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (np->has_built) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe built_this_run = true;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XFWRITE(built_last_make_run->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe strlen(built_last_make_run->string_mb),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(colon_char, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(newline_char, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* If the target has dependencies, we dump them. */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe target_name = escape_target_name(np);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (np->has_long_member_name) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe target_name =
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe get_prop(np->prop, long_member_name_prop)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ->body.long_member_name.member_name->
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe string_mb;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (m) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XFPUTS(target_name, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(colon_char, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XFPUTS("\t", fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe name_printed = true;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe line_length = 0;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe for (dependency =
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe lines->body.line.dependencies;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe dependency != NULL;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe dependency = dependency->next) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe print_auto_depes(dependency,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fd,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe built_this_run,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe &line_length,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe target_name,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe long_jump);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XFPUTS("\n", fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* If there is a command used, we dump it. */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (lines->body.line.command_used != NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Only write the target name if it
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * wasn't done for the dependencies.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (!name_printed) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XFPUTS(target_name, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(colon_char, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(newline_char, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Write the command lines.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Prefix each textual line with a tab.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe for (cp = lines->body.line.command_used;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe cp != NULL;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe cp = cp->next) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char *csp;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int n;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(tab_char, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (cp->command_line != NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe for (csp = cp->
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe command_line->
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe n = strlen(cp->
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe command_line->
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe string_mb);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe n > 0;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe n--, csp++) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(*csp, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (*csp ==
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (int) newline_char) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(tab_char,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(newline_char, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void)free(target_name);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fclose(fd) == EOF) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe longjmp(long_jump, LONGJUMP_VALUE);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (attempts == 0) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (unlink(make_state->string_mb) != 0 && errno != ENOENT) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe lock_err = errno; /* Save it! unlink() can change errno */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* Delete temporary statefile */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) unlink(make_state_tempfile);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) unlink(make_state_lockfile);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe retmem_mb(make_state_lockfile);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_lockfile = NULL;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_locked = false;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Could not delete old statefile `%s': %s"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe errmsg(lock_err));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (rename(make_state_tempfile, make_state->string_mb) != 0) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe lock_err = errno; /* Save it! unlink() can change errno */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* Delete temporary statefile */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) unlink(make_state_tempfile);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) unlink(make_state_lockfile);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe retmem_mb(make_state_lockfile);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_lockfile = NULL;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_locked = false;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Could not rename `%s' to `%s': %s"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_tempfile,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe errmsg(lock_err));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((make_state_lockfile != NULL) && make_state_locked) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) unlink(make_state_lockfile);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe retmem_mb(make_state_lockfile);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_lockfile = NULL;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_locked = false;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe}
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * print_auto_depes(dependency, fd, built_this_run,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * line_length, target_name, long_jump)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Will print a dependency list for automatic entries.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Parameters:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * dependency The dependency to print
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * fd The file to print it to
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * built_this_run If on we prefix each line with .BUILT_THIS...
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * line_length Pointer to line length var that we update
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * target_name We need this when we restart line
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * long_jump setjmp/longjmp buffer used for IO error action
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * built_last_make_run The Name ".BUILT_LAST_MAKE_RUN", written
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * force The Name " FORCE", compared against
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestatic void
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweprint_auto_depes(register Dependency dependency, register FILE *fd, register Boolean built_this_run, register int *line_length, register char *target_name, jmp_buf long_jump)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe{
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (!dependency->automatic ||
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe dependency->stale ||
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (dependency->name == force)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XFWRITE(dependency->name->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe strlen(dependency->name->string_mb),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Check if the dependency line is too long.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * If so, break it and start a new one.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((*line_length += (int) strlen(dependency->name->string_mb) + 1) > 450) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *line_length = 0;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(newline_char, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (built_this_run) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XFPUTS(built_last_make_run->string_mb, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(colon_char, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(newline_char, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XFPUTS(target_name, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(colon_char, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XPUTC(tab_char, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe XFPUTS(" ", fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe}
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe