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