1*10d63b7dSRichard Lowe /* 2*10d63b7dSRichard Lowe * CDDL HEADER START 3*10d63b7dSRichard Lowe * 4*10d63b7dSRichard Lowe * The contents of this file are subject to the terms of the 5*10d63b7dSRichard Lowe * Common Development and Distribution License (the "License"). 6*10d63b7dSRichard Lowe * You may not use this file except in compliance with the License. 7*10d63b7dSRichard Lowe * 8*10d63b7dSRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*10d63b7dSRichard Lowe * or http://www.opensolaris.org/os/licensing. 10*10d63b7dSRichard Lowe * See the License for the specific language governing permissions 11*10d63b7dSRichard Lowe * and limitations under the License. 12*10d63b7dSRichard Lowe * 13*10d63b7dSRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each 14*10d63b7dSRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*10d63b7dSRichard Lowe * If applicable, add the following below this CDDL HEADER, with the 16*10d63b7dSRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying 17*10d63b7dSRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner] 18*10d63b7dSRichard Lowe * 19*10d63b7dSRichard Lowe * CDDL HEADER END 20*10d63b7dSRichard Lowe */ 21*10d63b7dSRichard Lowe /* 22*10d63b7dSRichard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 23*10d63b7dSRichard Lowe * Use is subject to license terms. 24*10d63b7dSRichard Lowe */ 25*10d63b7dSRichard Lowe 26*10d63b7dSRichard Lowe /* 27*10d63b7dSRichard Lowe * state.c 28*10d63b7dSRichard Lowe * 29*10d63b7dSRichard Lowe * This file contains the routines that write the .make.state file 30*10d63b7dSRichard Lowe */ 31*10d63b7dSRichard Lowe 32*10d63b7dSRichard Lowe /* 33*10d63b7dSRichard Lowe * Included files 34*10d63b7dSRichard Lowe */ 35*10d63b7dSRichard Lowe #include <mk/defs.h> 36*10d63b7dSRichard Lowe #include <mksh/misc.h> /* errmsg() */ 37*10d63b7dSRichard Lowe #include <setjmp.h> /* setjmp() */ 38*10d63b7dSRichard Lowe #include <unistd.h> /* getpid() */ 39*10d63b7dSRichard Lowe #include <errno.h> /* errno */ 40*10d63b7dSRichard Lowe #include <locale.h> /* MB_CUR_MAX */ 41*10d63b7dSRichard Lowe 42*10d63b7dSRichard Lowe /* 43*10d63b7dSRichard Lowe * Defined macros 44*10d63b7dSRichard Lowe */ 45*10d63b7dSRichard Lowe #define LONGJUMP_VALUE 17 46*10d63b7dSRichard Lowe #define XFWRITE(string, length, fd) {if (fwrite(string, 1, length, fd) == 0) \ 47*10d63b7dSRichard Lowe longjmp(long_jump, LONGJUMP_VALUE);} 48*10d63b7dSRichard Lowe #define XPUTC(ch, fd) { \ 49*10d63b7dSRichard Lowe if (putc((int) ch, fd) == EOF) \ 50*10d63b7dSRichard Lowe longjmp(long_jump, LONGJUMP_VALUE); \ 51*10d63b7dSRichard Lowe } 52*10d63b7dSRichard Lowe #define XFPUTS(string, fd) fputs(string, fd) 53*10d63b7dSRichard Lowe 54*10d63b7dSRichard Lowe /* 55*10d63b7dSRichard Lowe * typedefs & structs 56*10d63b7dSRichard Lowe */ 57*10d63b7dSRichard Lowe 58*10d63b7dSRichard Lowe /* 59*10d63b7dSRichard Lowe * Static variables 60*10d63b7dSRichard Lowe */ 61*10d63b7dSRichard Lowe 62*10d63b7dSRichard Lowe /* 63*10d63b7dSRichard Lowe * File table of contents 64*10d63b7dSRichard Lowe */ 65*10d63b7dSRichard Lowe static char * escape_target_name(Name np) 66*10d63b7dSRichard Lowe { 67*10d63b7dSRichard Lowe if(np->dollar) { 68*10d63b7dSRichard Lowe int len = strlen(np->string_mb); 69*10d63b7dSRichard Lowe char * buff = (char*)malloc(2 * len); 70*10d63b7dSRichard Lowe int pos = 0; 71*10d63b7dSRichard Lowe wchar_t wc; 72*10d63b7dSRichard Lowe int pp = 0; 73*10d63b7dSRichard Lowe while(pos < len) { 74*10d63b7dSRichard Lowe int n = mbtowc(&wc, np->string_mb + pos, MB_CUR_MAX); 75*10d63b7dSRichard Lowe if(n < 0) { // error - this shouldn't happen 76*10d63b7dSRichard Lowe (void)free(buff); 77*10d63b7dSRichard Lowe return strdup(np->string_mb); 78*10d63b7dSRichard Lowe } 79*10d63b7dSRichard Lowe if(wc == dollar_char) { 80*10d63b7dSRichard Lowe buff[pp] = '\\'; pp++; 81*10d63b7dSRichard Lowe buff[pp] = '$'; pp++; 82*10d63b7dSRichard Lowe } else { 83*10d63b7dSRichard Lowe for(int j=0;j<n;j++) { 84*10d63b7dSRichard Lowe buff[pp] = np->string_mb[pos+j]; pp++; 85*10d63b7dSRichard Lowe } 86*10d63b7dSRichard Lowe } 87*10d63b7dSRichard Lowe pos += n; 88*10d63b7dSRichard Lowe } 89*10d63b7dSRichard Lowe buff[pp] = '\0'; 90*10d63b7dSRichard Lowe return buff; 91*10d63b7dSRichard Lowe } else { 92*10d63b7dSRichard Lowe return strdup(np->string_mb); 93*10d63b7dSRichard Lowe } 94*10d63b7dSRichard Lowe } 95*10d63b7dSRichard Lowe 96*10d63b7dSRichard Lowe static 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); 97*10d63b7dSRichard Lowe 98*10d63b7dSRichard Lowe /* 99*10d63b7dSRichard Lowe * write_state_file(report_recursive, exiting) 100*10d63b7dSRichard Lowe * 101*10d63b7dSRichard Lowe * Write a new version of .make.state 102*10d63b7dSRichard Lowe * 103*10d63b7dSRichard Lowe * Parameters: 104*10d63b7dSRichard Lowe * report_recursive Should only be done at end of run 105*10d63b7dSRichard Lowe * exiting true if called from the exit handler 106*10d63b7dSRichard Lowe * 107*10d63b7dSRichard Lowe * Global variables used: 108*10d63b7dSRichard Lowe * built_last_make_run The Name ".BUILT_LAST_MAKE_RUN", written 109*10d63b7dSRichard Lowe * command_changed If no command changed we do not need to write 110*10d63b7dSRichard Lowe * current_make_version The Name "<current version>", written 111*10d63b7dSRichard Lowe * do_not_exec_rule If -n is on we do not write statefile 112*10d63b7dSRichard Lowe * hashtab The hashtable that contains all names 113*10d63b7dSRichard Lowe * keep_state If .KEEP_STATE is no on we do not write file 114*10d63b7dSRichard Lowe * make_state The Name ".make.state", used for opening file 115*10d63b7dSRichard Lowe * make_version The Name ".MAKE_VERSION", written 116*10d63b7dSRichard Lowe * recursive_name The Name ".RECURSIVE", written 117*10d63b7dSRichard Lowe * rewrite_statefile Indicates that something changed 118*10d63b7dSRichard Lowe */ 119*10d63b7dSRichard Lowe 120*10d63b7dSRichard Lowe void 121*10d63b7dSRichard Lowe write_state_file(int, Boolean exiting) 122*10d63b7dSRichard Lowe { 123*10d63b7dSRichard Lowe register FILE *fd; 124*10d63b7dSRichard Lowe int lock_err; 125*10d63b7dSRichard Lowe char buffer[MAXPATHLEN]; 126*10d63b7dSRichard Lowe char make_state_tempfile[MAXPATHLEN]; 127*10d63b7dSRichard Lowe jmp_buf long_jump; 128*10d63b7dSRichard Lowe register int attempts = 0; 129*10d63b7dSRichard Lowe Name_set::iterator np, e; 130*10d63b7dSRichard Lowe register Property lines; 131*10d63b7dSRichard Lowe register int m; 132*10d63b7dSRichard Lowe Dependency dependency; 133*10d63b7dSRichard Lowe register Boolean name_printed; 134*10d63b7dSRichard Lowe Boolean built_this_run = false; 135*10d63b7dSRichard Lowe char *target_name; 136*10d63b7dSRichard Lowe int line_length; 137*10d63b7dSRichard Lowe register Cmd_line cp; 138*10d63b7dSRichard Lowe 139*10d63b7dSRichard Lowe 140*10d63b7dSRichard Lowe if (!rewrite_statefile || 141*10d63b7dSRichard Lowe !command_changed || 142*10d63b7dSRichard Lowe !keep_state || 143*10d63b7dSRichard Lowe do_not_exec_rule || 144*10d63b7dSRichard Lowe (report_dependencies_level > 0)) { 145*10d63b7dSRichard Lowe return; 146*10d63b7dSRichard Lowe } 147*10d63b7dSRichard Lowe /* Lock the file for writing. */ 148*10d63b7dSRichard Lowe make_state_lockfile = getmem(strlen(make_state->string_mb) + strlen(".lock") + 1); 149*10d63b7dSRichard Lowe (void) sprintf(make_state_lockfile, 150*10d63b7dSRichard Lowe "%s.lock", 151*10d63b7dSRichard Lowe make_state->string_mb); 152*10d63b7dSRichard Lowe if (lock_err = file_lock(make_state->string_mb, 153*10d63b7dSRichard Lowe make_state_lockfile, 154*10d63b7dSRichard Lowe (int *) &make_state_locked, 0)) { 155*10d63b7dSRichard Lowe retmem_mb(make_state_lockfile); 156*10d63b7dSRichard Lowe make_state_lockfile = NULL; 157*10d63b7dSRichard Lowe 158*10d63b7dSRichard Lowe /* 159*10d63b7dSRichard Lowe * We need to make sure that we are not being 160*10d63b7dSRichard Lowe * called by the exit handler so we don't call 161*10d63b7dSRichard Lowe * it again. 162*10d63b7dSRichard Lowe */ 163*10d63b7dSRichard Lowe 164*10d63b7dSRichard Lowe if (exiting) { 165*10d63b7dSRichard Lowe (void) sprintf(buffer, "%s/.make.state.%d.XXXXXX", tmpdir, getpid()); 166*10d63b7dSRichard Lowe report_pwd = true; 167*10d63b7dSRichard Lowe warning(gettext("Writing to %s"), buffer); 168*10d63b7dSRichard Lowe int fdes = mkstemp(buffer); 169*10d63b7dSRichard Lowe if ((fdes < 0) || (fd = fdopen(fdes, "w")) == NULL) { 170*10d63b7dSRichard Lowe fprintf(stderr, 171*10d63b7dSRichard Lowe gettext("Could not open statefile `%s': %s"), 172*10d63b7dSRichard Lowe buffer, 173*10d63b7dSRichard Lowe errmsg(errno)); 174*10d63b7dSRichard Lowe return; 175*10d63b7dSRichard Lowe } 176*10d63b7dSRichard Lowe } else { 177*10d63b7dSRichard Lowe report_pwd = true; 178*10d63b7dSRichard Lowe fatal(gettext("Can't lock .make.state")); 179*10d63b7dSRichard Lowe } 180*10d63b7dSRichard Lowe } 181*10d63b7dSRichard Lowe 182*10d63b7dSRichard Lowe (void) sprintf(make_state_tempfile, 183*10d63b7dSRichard Lowe "%s.tmp", 184*10d63b7dSRichard Lowe make_state->string_mb); 185*10d63b7dSRichard Lowe /* Delete old temporary statefile (in case it exists) */ 186*10d63b7dSRichard Lowe (void) unlink(make_state_tempfile); 187*10d63b7dSRichard Lowe if ((fd = fopen(make_state_tempfile, "w")) == NULL) { 188*10d63b7dSRichard Lowe lock_err = errno; /* Save it! unlink() can change errno */ 189*10d63b7dSRichard Lowe (void) unlink(make_state_lockfile); 190*10d63b7dSRichard Lowe retmem_mb(make_state_lockfile); 191*10d63b7dSRichard Lowe make_state_lockfile = NULL; 192*10d63b7dSRichard Lowe make_state_locked = false; 193*10d63b7dSRichard Lowe fatal(gettext("Could not open temporary statefile `%s': %s"), 194*10d63b7dSRichard Lowe make_state_tempfile, 195*10d63b7dSRichard Lowe errmsg(lock_err)); 196*10d63b7dSRichard Lowe } 197*10d63b7dSRichard Lowe /* 198*10d63b7dSRichard Lowe * Set a trap for failed writes. If a write fails, the routine 199*10d63b7dSRichard Lowe * will try saving the .make.state file under another name in /tmp. 200*10d63b7dSRichard Lowe */ 201*10d63b7dSRichard Lowe if (setjmp(long_jump)) { 202*10d63b7dSRichard Lowe (void) fclose(fd); 203*10d63b7dSRichard Lowe if (attempts++ > 5) { 204*10d63b7dSRichard Lowe if ((make_state_lockfile != NULL) && 205*10d63b7dSRichard Lowe make_state_locked) { 206*10d63b7dSRichard Lowe (void) unlink(make_state_lockfile); 207*10d63b7dSRichard Lowe retmem_mb(make_state_lockfile); 208*10d63b7dSRichard Lowe make_state_lockfile = NULL; 209*10d63b7dSRichard Lowe make_state_locked = false; 210*10d63b7dSRichard Lowe } 211*10d63b7dSRichard Lowe fatal(gettext("Giving up on writing statefile")); 212*10d63b7dSRichard Lowe } 213*10d63b7dSRichard Lowe sleep(10); 214*10d63b7dSRichard Lowe (void) sprintf(buffer, "%s/.make.state.%d.XXXXXX", tmpdir, getpid()); 215*10d63b7dSRichard Lowe int fdes = mkstemp(buffer); 216*10d63b7dSRichard Lowe if ((fdes < 0) || (fd = fdopen(fdes, "w")) == NULL) { 217*10d63b7dSRichard Lowe fatal(gettext("Could not open statefile `%s': %s"), 218*10d63b7dSRichard Lowe buffer, 219*10d63b7dSRichard Lowe errmsg(errno)); 220*10d63b7dSRichard Lowe } 221*10d63b7dSRichard Lowe warning(gettext("Initial write of statefile failed. Trying again on %s"), 222*10d63b7dSRichard Lowe buffer); 223*10d63b7dSRichard Lowe } 224*10d63b7dSRichard Lowe 225*10d63b7dSRichard Lowe /* Write the version stamp. */ 226*10d63b7dSRichard Lowe XFWRITE(make_version->string_mb, 227*10d63b7dSRichard Lowe strlen(make_version->string_mb), 228*10d63b7dSRichard Lowe fd); 229*10d63b7dSRichard Lowe XPUTC(colon_char, fd); 230*10d63b7dSRichard Lowe XPUTC(tab_char, fd); 231*10d63b7dSRichard Lowe XFWRITE(current_make_version->string_mb, 232*10d63b7dSRichard Lowe strlen(current_make_version->string_mb), 233*10d63b7dSRichard Lowe fd); 234*10d63b7dSRichard Lowe XPUTC(newline_char, fd); 235*10d63b7dSRichard Lowe 236*10d63b7dSRichard Lowe /* 237*10d63b7dSRichard Lowe * Go through all the targets, dump their dependencies and 238*10d63b7dSRichard Lowe * command used. 239*10d63b7dSRichard Lowe */ 240*10d63b7dSRichard Lowe for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) { 241*10d63b7dSRichard Lowe /* 242*10d63b7dSRichard Lowe * If the target has no command used nor dependencies, 243*10d63b7dSRichard Lowe * we can go to the next one. 244*10d63b7dSRichard Lowe */ 245*10d63b7dSRichard Lowe if ((lines = get_prop(np->prop, line_prop)) == NULL) { 246*10d63b7dSRichard Lowe continue; 247*10d63b7dSRichard Lowe } 248*10d63b7dSRichard Lowe /* If this target is a special target, don't print. */ 249*10d63b7dSRichard Lowe if (np->special_reader != no_special) { 250*10d63b7dSRichard Lowe continue; 251*10d63b7dSRichard Lowe } 252*10d63b7dSRichard Lowe /* 253*10d63b7dSRichard Lowe * Find out if any of the targets dependencies should 254*10d63b7dSRichard Lowe * be written to .make.state. 255*10d63b7dSRichard Lowe */ 256*10d63b7dSRichard Lowe for (m = 0, dependency = lines->body.line.dependencies; 257*10d63b7dSRichard Lowe dependency != NULL; 258*10d63b7dSRichard Lowe dependency = dependency->next) { 259*10d63b7dSRichard Lowe if (m = !dependency->stale 260*10d63b7dSRichard Lowe && (dependency->name != force) 261*10d63b7dSRichard Lowe #ifndef PRINT_EXPLICIT_DEPEN 262*10d63b7dSRichard Lowe && dependency->automatic 263*10d63b7dSRichard Lowe #endif 264*10d63b7dSRichard Lowe ) { 265*10d63b7dSRichard Lowe break; 266*10d63b7dSRichard Lowe } 267*10d63b7dSRichard Lowe } 268*10d63b7dSRichard Lowe /* Only print if dependencies listed. */ 269*10d63b7dSRichard Lowe if (m || (lines->body.line.command_used != NULL)) { 270*10d63b7dSRichard Lowe name_printed = false; 271*10d63b7dSRichard Lowe /* 272*10d63b7dSRichard Lowe * If this target was built during this make run, 273*10d63b7dSRichard Lowe * we mark it. 274*10d63b7dSRichard Lowe */ 275*10d63b7dSRichard Lowe built_this_run = false; 276*10d63b7dSRichard Lowe if (np->has_built) { 277*10d63b7dSRichard Lowe built_this_run = true; 278*10d63b7dSRichard Lowe XFWRITE(built_last_make_run->string_mb, 279*10d63b7dSRichard Lowe strlen(built_last_make_run->string_mb), 280*10d63b7dSRichard Lowe fd); 281*10d63b7dSRichard Lowe XPUTC(colon_char, fd); 282*10d63b7dSRichard Lowe XPUTC(newline_char, fd); 283*10d63b7dSRichard Lowe } 284*10d63b7dSRichard Lowe /* If the target has dependencies, we dump them. */ 285*10d63b7dSRichard Lowe target_name = escape_target_name(np); 286*10d63b7dSRichard Lowe if (np->has_long_member_name) { 287*10d63b7dSRichard Lowe target_name = 288*10d63b7dSRichard Lowe get_prop(np->prop, long_member_name_prop) 289*10d63b7dSRichard Lowe ->body.long_member_name.member_name-> 290*10d63b7dSRichard Lowe string_mb; 291*10d63b7dSRichard Lowe } 292*10d63b7dSRichard Lowe if (m) { 293*10d63b7dSRichard Lowe XFPUTS(target_name, fd); 294*10d63b7dSRichard Lowe XPUTC(colon_char, fd); 295*10d63b7dSRichard Lowe XFPUTS("\t", fd); 296*10d63b7dSRichard Lowe name_printed = true; 297*10d63b7dSRichard Lowe line_length = 0; 298*10d63b7dSRichard Lowe for (dependency = 299*10d63b7dSRichard Lowe lines->body.line.dependencies; 300*10d63b7dSRichard Lowe dependency != NULL; 301*10d63b7dSRichard Lowe dependency = dependency->next) { 302*10d63b7dSRichard Lowe print_auto_depes(dependency, 303*10d63b7dSRichard Lowe fd, 304*10d63b7dSRichard Lowe built_this_run, 305*10d63b7dSRichard Lowe &line_length, 306*10d63b7dSRichard Lowe target_name, 307*10d63b7dSRichard Lowe long_jump); 308*10d63b7dSRichard Lowe } 309*10d63b7dSRichard Lowe XFPUTS("\n", fd); 310*10d63b7dSRichard Lowe } 311*10d63b7dSRichard Lowe /* If there is a command used, we dump it. */ 312*10d63b7dSRichard Lowe if (lines->body.line.command_used != NULL) { 313*10d63b7dSRichard Lowe /* 314*10d63b7dSRichard Lowe * Only write the target name if it 315*10d63b7dSRichard Lowe * wasn't done for the dependencies. 316*10d63b7dSRichard Lowe */ 317*10d63b7dSRichard Lowe if (!name_printed) { 318*10d63b7dSRichard Lowe XFPUTS(target_name, fd); 319*10d63b7dSRichard Lowe XPUTC(colon_char, fd); 320*10d63b7dSRichard Lowe XPUTC(newline_char, fd); 321*10d63b7dSRichard Lowe } 322*10d63b7dSRichard Lowe /* 323*10d63b7dSRichard Lowe * Write the command lines. 324*10d63b7dSRichard Lowe * Prefix each textual line with a tab. 325*10d63b7dSRichard Lowe */ 326*10d63b7dSRichard Lowe for (cp = lines->body.line.command_used; 327*10d63b7dSRichard Lowe cp != NULL; 328*10d63b7dSRichard Lowe cp = cp->next) { 329*10d63b7dSRichard Lowe char *csp; 330*10d63b7dSRichard Lowe int n; 331*10d63b7dSRichard Lowe 332*10d63b7dSRichard Lowe XPUTC(tab_char, fd); 333*10d63b7dSRichard Lowe if (cp->command_line != NULL) { 334*10d63b7dSRichard Lowe for (csp = cp-> 335*10d63b7dSRichard Lowe command_line-> 336*10d63b7dSRichard Lowe string_mb, 337*10d63b7dSRichard Lowe n = strlen(cp-> 338*10d63b7dSRichard Lowe command_line-> 339*10d63b7dSRichard Lowe string_mb); 340*10d63b7dSRichard Lowe n > 0; 341*10d63b7dSRichard Lowe n--, csp++) { 342*10d63b7dSRichard Lowe XPUTC(*csp, fd); 343*10d63b7dSRichard Lowe if (*csp == 344*10d63b7dSRichard Lowe (int) newline_char) { 345*10d63b7dSRichard Lowe XPUTC(tab_char, 346*10d63b7dSRichard Lowe fd); 347*10d63b7dSRichard Lowe } 348*10d63b7dSRichard Lowe } 349*10d63b7dSRichard Lowe } 350*10d63b7dSRichard Lowe XPUTC(newline_char, fd); 351*10d63b7dSRichard Lowe } 352*10d63b7dSRichard Lowe } 353*10d63b7dSRichard Lowe (void)free(target_name); 354*10d63b7dSRichard Lowe } 355*10d63b7dSRichard Lowe } 356*10d63b7dSRichard Lowe if (fclose(fd) == EOF) { 357*10d63b7dSRichard Lowe longjmp(long_jump, LONGJUMP_VALUE); 358*10d63b7dSRichard Lowe } 359*10d63b7dSRichard Lowe if (attempts == 0) { 360*10d63b7dSRichard Lowe if (unlink(make_state->string_mb) != 0 && errno != ENOENT) { 361*10d63b7dSRichard Lowe lock_err = errno; /* Save it! unlink() can change errno */ 362*10d63b7dSRichard Lowe /* Delete temporary statefile */ 363*10d63b7dSRichard Lowe (void) unlink(make_state_tempfile); 364*10d63b7dSRichard Lowe (void) unlink(make_state_lockfile); 365*10d63b7dSRichard Lowe retmem_mb(make_state_lockfile); 366*10d63b7dSRichard Lowe make_state_lockfile = NULL; 367*10d63b7dSRichard Lowe make_state_locked = false; 368*10d63b7dSRichard Lowe fatal(gettext("Could not delete old statefile `%s': %s"), 369*10d63b7dSRichard Lowe make_state->string_mb, 370*10d63b7dSRichard Lowe errmsg(lock_err)); 371*10d63b7dSRichard Lowe } 372*10d63b7dSRichard Lowe if (rename(make_state_tempfile, make_state->string_mb) != 0) { 373*10d63b7dSRichard Lowe lock_err = errno; /* Save it! unlink() can change errno */ 374*10d63b7dSRichard Lowe /* Delete temporary statefile */ 375*10d63b7dSRichard Lowe (void) unlink(make_state_tempfile); 376*10d63b7dSRichard Lowe (void) unlink(make_state_lockfile); 377*10d63b7dSRichard Lowe retmem_mb(make_state_lockfile); 378*10d63b7dSRichard Lowe make_state_lockfile = NULL; 379*10d63b7dSRichard Lowe make_state_locked = false; 380*10d63b7dSRichard Lowe fatal(gettext("Could not rename `%s' to `%s': %s"), 381*10d63b7dSRichard Lowe make_state_tempfile, 382*10d63b7dSRichard Lowe make_state->string_mb, 383*10d63b7dSRichard Lowe errmsg(lock_err)); 384*10d63b7dSRichard Lowe } 385*10d63b7dSRichard Lowe } 386*10d63b7dSRichard Lowe if ((make_state_lockfile != NULL) && make_state_locked) { 387*10d63b7dSRichard Lowe (void) unlink(make_state_lockfile); 388*10d63b7dSRichard Lowe retmem_mb(make_state_lockfile); 389*10d63b7dSRichard Lowe make_state_lockfile = NULL; 390*10d63b7dSRichard Lowe make_state_locked = false; 391*10d63b7dSRichard Lowe } 392*10d63b7dSRichard Lowe } 393*10d63b7dSRichard Lowe 394*10d63b7dSRichard Lowe /* 395*10d63b7dSRichard Lowe * print_auto_depes(dependency, fd, built_this_run, 396*10d63b7dSRichard Lowe * line_length, target_name, long_jump) 397*10d63b7dSRichard Lowe * 398*10d63b7dSRichard Lowe * Will print a dependency list for automatic entries. 399*10d63b7dSRichard Lowe * 400*10d63b7dSRichard Lowe * Parameters: 401*10d63b7dSRichard Lowe * dependency The dependency to print 402*10d63b7dSRichard Lowe * fd The file to print it to 403*10d63b7dSRichard Lowe * built_this_run If on we prefix each line with .BUILT_THIS... 404*10d63b7dSRichard Lowe * line_length Pointer to line length var that we update 405*10d63b7dSRichard Lowe * target_name We need this when we restart line 406*10d63b7dSRichard Lowe * long_jump setjmp/longjmp buffer used for IO error action 407*10d63b7dSRichard Lowe * 408*10d63b7dSRichard Lowe * Global variables used: 409*10d63b7dSRichard Lowe * built_last_make_run The Name ".BUILT_LAST_MAKE_RUN", written 410*10d63b7dSRichard Lowe * force The Name " FORCE", compared against 411*10d63b7dSRichard Lowe */ 412*10d63b7dSRichard Lowe static void 413*10d63b7dSRichard Lowe 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) 414*10d63b7dSRichard Lowe { 415*10d63b7dSRichard Lowe if (!dependency->automatic || 416*10d63b7dSRichard Lowe dependency->stale || 417*10d63b7dSRichard Lowe (dependency->name == force)) { 418*10d63b7dSRichard Lowe return; 419*10d63b7dSRichard Lowe } 420*10d63b7dSRichard Lowe XFWRITE(dependency->name->string_mb, 421*10d63b7dSRichard Lowe strlen(dependency->name->string_mb), 422*10d63b7dSRichard Lowe fd); 423*10d63b7dSRichard Lowe /* 424*10d63b7dSRichard Lowe * Check if the dependency line is too long. 425*10d63b7dSRichard Lowe * If so, break it and start a new one. 426*10d63b7dSRichard Lowe */ 427*10d63b7dSRichard Lowe if ((*line_length += (int) strlen(dependency->name->string_mb) + 1) > 450) { 428*10d63b7dSRichard Lowe *line_length = 0; 429*10d63b7dSRichard Lowe XPUTC(newline_char, fd); 430*10d63b7dSRichard Lowe if (built_this_run) { 431*10d63b7dSRichard Lowe XFPUTS(built_last_make_run->string_mb, fd); 432*10d63b7dSRichard Lowe XPUTC(colon_char, fd); 433*10d63b7dSRichard Lowe XPUTC(newline_char, fd); 434*10d63b7dSRichard Lowe } 435*10d63b7dSRichard Lowe XFPUTS(target_name, fd); 436*10d63b7dSRichard Lowe XPUTC(colon_char, fd); 437*10d63b7dSRichard Lowe XPUTC(tab_char, fd); 438*10d63b7dSRichard Lowe } else { 439*10d63b7dSRichard Lowe XFPUTS(" ", fd); 440*10d63b7dSRichard Lowe } 441*10d63b7dSRichard Lowe return; 442*10d63b7dSRichard Lowe } 443*10d63b7dSRichard Lowe 444*10d63b7dSRichard Lowe 445