diff options
-rw-r--r-- | miscutils/make.c | 67 | ||||
-rwxr-xr-x | testsuite/make.tests | 26 |
2 files changed, 60 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 | /* |
diff --git a/testsuite/make.tests b/testsuite/make.tests index 33e730602..c2b62532a 100755 --- a/testsuite/make.tests +++ b/testsuite/make.tests | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | . ./testing.sh | 3 | . ./testing.sh |
4 | unset MAKEFLAGS | 4 | unset MAKEFLAGS |
5 | rm -rf make.tempdir | ||
5 | 6 | ||
6 | # testing "test name" "command" "expected result" "file input" "stdin" | 7 | # testing "test name" "command" "expected result" "file input" "stdin" |
7 | 8 | ||
@@ -116,6 +117,31 @@ baz: | |||
116 | @: | 117 | @: |
117 | ' | 118 | ' |
118 | 119 | ||
120 | # The -t option touches files that are out-of-date unless the target | ||
121 | # has no commands or they're already up-to-date. | ||
122 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
123 | touch baz | ||
124 | testing "make check -t option" \ | ||
125 | "make -t -f - 2>/dev/null" "touch bar\n" "" ' | ||
126 | all: foo bar baz | ||
127 | foo: | ||
128 | bar: | ||
129 | @echo bar | ||
130 | baz: | ||
131 | @echo baz | ||
132 | ' | ||
133 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
134 | |||
135 | # Build commands with a '+' prefix are executed even with the -t option. | ||
136 | mkdir make.tempdir && cd make.tempdir || exit 1 | ||
137 | testing "make execute build command with + prefix and -t" \ | ||
138 | "make -t -f - 2>/dev/null" "OK\n" "" ' | ||
139 | all: bar | ||
140 | bar: | ||
141 | @+echo OK | ||
142 | ' | ||
143 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | ||
144 | |||
119 | # A macro created using ::= remembers it's of type immediate-expansion. | 145 | # A macro created using ::= remembers it's of type immediate-expansion. |
120 | # Immediate expansion also occurs when += is used to append to such a macro. | 146 | # Immediate expansion also occurs when += is used to append to such a macro. |
121 | testing "make appending to immediate-expansion macro" \ | 147 | testing "make appending to immediate-expansion macro" \ |