diff options
author | Ron Yorston <rmy@pobox.com> | 2024-05-28 11:54:51 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2024-05-28 11:54:51 +0100 |
commit | 208d9858409f823d533d1e95396dde00be03d7d3 (patch) | |
tree | 34c0ea21c8d1b23c2bc72909843b12bd1c0cb9ca /miscutils/make.c | |
parent | 0224cfd5e5c8157e5bc74a81027fa508687abfbf (diff) | |
download | busybox-w32-208d9858409f823d533d1e95396dde00be03d7d3.tar.gz busybox-w32-208d9858409f823d533d1e95396dde00be03d7d3.tar.bz2 busybox-w32-208d9858409f823d533d1e95396dde00be03d7d3.zip |
make: fixes to -t option
The -t option (in general) causes targets to be touched instead of
having build commands run to create them. There were two problems.
The flag variable 'ssilent' in docmds was too small (uint8_t) to
contain the value of 'dotouch' (uint32_t). Truncation of the
value resulted in build commands being echoed when they shouldn't
have been.
The POSIX specification is unclear as to how build commands with
a '+' prefix interact with touch. The rationale indicates that
this feature was imported from GNU make, so the behaviour has been
made to match what it does: if a '+' build command is run the
target is not touched.
The code has been rearranged to move the call to touch() up into
docmds().
Adds 48 bytes.
Diffstat (limited to 'miscutils/make.c')
-rw-r--r-- | miscutils/make.c | 67 |
1 files changed, 34 insertions, 33 deletions
diff --git a/miscutils/make.c b/miscutils/make.c index 056cb2909..70fd30440 100644 --- a/miscutils/make.c +++ b/miscutils/make.c | |||
@@ -2295,6 +2295,31 @@ remove_target(void) | |||
2295 | } | 2295 | } |
2296 | 2296 | ||
2297 | /* | 2297 | /* |
2298 | * Update the modification time of a file to now. | ||
2299 | */ | ||
2300 | static void | ||
2301 | touch(struct name *np) | ||
2302 | { | ||
2303 | if (dryrun || !silent) | ||
2304 | printf("touch %s\n", np->n_name); | ||
2305 | |||
2306 | if (!dryrun) { | ||
2307 | const struct timespec timebuf[2] = {{0, UTIME_NOW}, {0, UTIME_NOW}}; | ||
2308 | |||
2309 | if (utimensat(AT_FDCWD, np->n_name, timebuf, 0) < 0) { | ||
2310 | if (errno == ENOENT) { | ||
2311 | int fd = open(np->n_name, O_RDWR | O_CREAT, 0666); | ||
2312 | if (fd >= 0) { | ||
2313 | close(fd); | ||
2314 | return; | ||
2315 | } | ||
2316 | } | ||
2317 | warning("touch %s failed", np->n_name); | ||
2318 | } | ||
2319 | } | ||
2320 | } | ||
2321 | |||
2322 | /* | ||
2298 | * Do commands to make a target | 2323 | * Do commands to make a target |
2299 | */ | 2324 | */ |
2300 | static int | 2325 | static int |
@@ -2304,7 +2329,7 @@ docmds(struct name *np, struct cmd *cp) | |||
2304 | char *q, *command; | 2329 | char *q, *command; |
2305 | 2330 | ||
2306 | for (; cp; cp = cp->c_next) { | 2331 | for (; cp; cp = cp->c_next) { |
2307 | uint8_t ssilent, signore, sdomake; | 2332 | uint32_t ssilent, signore, sdomake; |
2308 | 2333 | ||
2309 | // Location of command in makefile (for use in error messages) | 2334 | // Location of command in makefile (for use in error messages) |
2310 | makefile = cp->c_makefile; | 2335 | makefile = cp->c_makefile; |
@@ -2380,44 +2405,24 @@ docmds(struct name *np, struct cmd *cp) | |||
2380 | } | 2405 | } |
2381 | } | 2406 | } |
2382 | } | 2407 | } |
2383 | if (sdomake || dryrun || dotouch) | 2408 | if (sdomake || dryrun) |
2384 | estat = MAKE_DIDSOMETHING; | 2409 | estat = MAKE_DIDSOMETHING; |
2385 | free(command); | 2410 | free(command); |
2386 | } | 2411 | } |
2387 | makefile = NULL; | ||
2388 | return estat; | ||
2389 | } | ||
2390 | |||
2391 | /* | ||
2392 | * Update the modification time of a file to now. | ||
2393 | */ | ||
2394 | static void | ||
2395 | touch(struct name *np) | ||
2396 | { | ||
2397 | if (dryrun || !silent) | ||
2398 | printf("touch %s\n", np->n_name); | ||
2399 | 2412 | ||
2400 | if (!dryrun) { | 2413 | if (dotouch && !(np->n_flag & N_PHONY) && !(estat & MAKE_DIDSOMETHING)) { |
2401 | const struct timespec timebuf[2] = {{0, UTIME_NOW}, {0, UTIME_NOW}}; | 2414 | touch(np); |
2402 | 2415 | estat = MAKE_DIDSOMETHING; | |
2403 | if (utimensat(AT_FDCWD, np->n_name, timebuf, 0) < 0) { | ||
2404 | if (errno == ENOENT) { | ||
2405 | int fd = open(np->n_name, O_RDWR | O_CREAT, 0666); | ||
2406 | if (fd >= 0) { | ||
2407 | close(fd); | ||
2408 | return; | ||
2409 | } | ||
2410 | } | ||
2411 | warning("touch %s failed", np->n_name); | ||
2412 | } | ||
2413 | } | 2416 | } |
2417 | |||
2418 | makefile = NULL; | ||
2419 | return estat; | ||
2414 | } | 2420 | } |
2415 | 2421 | ||
2416 | static int | 2422 | static int |
2417 | make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc, | 2423 | make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc, |
2418 | char *dedup, struct name *implicit) | 2424 | char *dedup, struct name *implicit) |
2419 | { | 2425 | { |
2420 | int estat; | ||
2421 | char *name, *member = NULL, *base = NULL, *prereq = NULL; | 2426 | char *name, *member = NULL, *base = NULL, *prereq = NULL; |
2422 | 2427 | ||
2423 | name = splitlib(np->n_name, &member); | 2428 | name = splitlib(np->n_name, &member); |
@@ -2457,11 +2462,7 @@ make1(struct name *np, struct cmd *cp, char *oodate, char *allsrc, | |||
2457 | setmacro("*", base, 0 | M_VALID); | 2462 | setmacro("*", base, 0 | M_VALID); |
2458 | free(name); | 2463 | free(name); |
2459 | 2464 | ||
2460 | estat = docmds(np, cp); | 2465 | return docmds(np, cp); |
2461 | if (dotouch && !(np->n_flag & N_PHONY)) | ||
2462 | touch(np); | ||
2463 | |||
2464 | return estat; | ||
2465 | } | 2466 | } |
2466 | 2467 | ||
2467 | /* | 2468 | /* |