diff options
Diffstat (limited to 'miscutils/time.c')
-rw-r--r-- | miscutils/time.c | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/miscutils/time.c b/miscutils/time.c index a73a837d8..e377bb6b7 100644 --- a/miscutils/time.c +++ b/miscutils/time.c | |||
@@ -21,10 +21,14 @@ | |||
21 | //kbuild:lib-$(CONFIG_TIME) += time.o | 21 | //kbuild:lib-$(CONFIG_TIME) += time.o |
22 | 22 | ||
23 | //usage:#define time_trivial_usage | 23 | //usage:#define time_trivial_usage |
24 | //usage: "[-v] PROG ARGS" | 24 | //usage: "[-vpa] [-o FILE] PROG ARGS" |
25 | //usage:#define time_full_usage "\n\n" | 25 | //usage:#define time_full_usage "\n\n" |
26 | //usage: "Run PROG, display resource usage when it exits\n" | 26 | //usage: "Run PROG, display resource usage when it exits\n" |
27 | //usage: "\n -v Verbose" | 27 | //usage: "\n -v Verbose" |
28 | //usage: "\n -p POSIX output format" | ||
29 | //usage: "\n -f FMT Custom format" | ||
30 | //usage: "\n -o FILE Write result to FILE" | ||
31 | //usage: "\n -a Append (else overwrite)" | ||
28 | 32 | ||
29 | #include "libbb.h" | 33 | #include "libbb.h" |
30 | #include <sys/resource.h> /* getrusage */ | 34 | #include <sys/resource.h> /* getrusage */ |
@@ -397,7 +401,7 @@ static void run_command(char *const *cmd, resource_t *resp) | |||
397 | } | 401 | } |
398 | 402 | ||
399 | /* Have signals kill the child but not self (if possible). */ | 403 | /* Have signals kill the child but not self (if possible). */ |
400 | //TODO: just block all sigs? and reenable them in the very end in main? | 404 | //TODO: just block all sigs? and re-enable them in the very end in main? |
401 | interrupt_signal = signal(SIGINT, SIG_IGN); | 405 | interrupt_signal = signal(SIGINT, SIG_IGN); |
402 | quit_signal = signal(SIGQUIT, SIG_IGN); | 406 | quit_signal = signal(SIGQUIT, SIG_IGN); |
403 | 407 | ||
@@ -412,29 +416,50 @@ int time_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
412 | int time_main(int argc UNUSED_PARAM, char **argv) | 416 | int time_main(int argc UNUSED_PARAM, char **argv) |
413 | { | 417 | { |
414 | resource_t res; | 418 | resource_t res; |
415 | const char *output_format = default_format; | 419 | /* $TIME has lowest prio (-v,-p,-f FMT overrride it) */ |
420 | const char *output_format = getenv("TIME") ? : default_format; | ||
421 | char *output_filename; | ||
422 | int output_fd; | ||
416 | int opt; | 423 | int opt; |
424 | int ex; | ||
425 | enum { | ||
426 | OPT_v = (1 << 0), | ||
427 | OPT_p = (1 << 1), | ||
428 | OPT_a = (1 << 2), | ||
429 | OPT_o = (1 << 3), | ||
430 | OPT_f = (1 << 4), | ||
431 | }; | ||
417 | 432 | ||
418 | opt_complementary = "-1"; /* at least one arg */ | 433 | opt_complementary = "-1"; /* at least one arg */ |
419 | /* "+": stop on first non-option */ | 434 | /* "+": stop on first non-option */ |
420 | opt = getopt32(argv, "+vp"); | 435 | opt = getopt32(argv, "+vpao:f:", &output_filename, &output_format); |
421 | argv += optind; | 436 | argv += optind; |
422 | if (opt & 1) | 437 | if (opt & OPT_v) |
423 | output_format = long_format; | 438 | output_format = long_format; |
424 | if (opt & 2) | 439 | if (opt & OPT_p) |
425 | output_format = posix_format; | 440 | output_format = posix_format; |
441 | output_fd = STDERR_FILENO; | ||
442 | if (opt & OPT_o) { | ||
443 | output_fd = xopen(output_filename, | ||
444 | (opt & OPT_a) /* append? */ | ||
445 | ? (O_CREAT | O_WRONLY | O_CLOEXEC | O_APPEND) | ||
446 | : (O_CREAT | O_WRONLY | O_CLOEXEC | O_TRUNC) | ||
447 | ); | ||
448 | } | ||
426 | 449 | ||
427 | run_command(argv, &res); | 450 | run_command(argv, &res); |
428 | 451 | ||
429 | /* Cheat. printf's are shorter :) */ | 452 | /* Cheat. printf's are shorter :) */ |
430 | xdup2(STDERR_FILENO, STDOUT_FILENO); | 453 | xdup2(output_fd, STDOUT_FILENO); |
431 | summarize(output_format, argv, &res); | 454 | summarize(output_format, argv, &res); |
432 | 455 | ||
456 | ex = WEXITSTATUS(res.waitstatus); | ||
457 | /* Impossible: we do not use WUNTRACED flag in wait()... | ||
433 | if (WIFSTOPPED(res.waitstatus)) | 458 | if (WIFSTOPPED(res.waitstatus)) |
434 | return WSTOPSIG(res.waitstatus); | 459 | ex = WSTOPSIG(res.waitstatus); |
460 | */ | ||
435 | if (WIFSIGNALED(res.waitstatus)) | 461 | if (WIFSIGNALED(res.waitstatus)) |
436 | return WTERMSIG(res.waitstatus); | 462 | ex = WTERMSIG(res.waitstatus); |
437 | if (WIFEXITED(res.waitstatus)) | 463 | |
438 | return WEXITSTATUS(res.waitstatus); | 464 | fflush_stdout_and_exit(ex); |
439 | fflush_stdout_and_exit(EXIT_SUCCESS); | ||
440 | } | 465 | } |