summaryrefslogtreecommitdiff
path: root/usr.bin/time
diff options
context:
space:
mode:
authorJohn-Mark Gurney <jmg@FreeBSD.org>2015-05-18 19:18:42 +0000
committerJohn-Mark Gurney <jmg@FreeBSD.org>2015-05-18 19:18:42 +0000
commite48a49b3339ebbe256a04ee86c80004a60e9859e (patch)
tree365e7cc9deff2bc10a3d5222f1e971cf498e47b1 /usr.bin/time
parent2b6bbe110f4561592dd62938cffb7ace9177f9a8 (diff)
downloadsrc-test-e48a49b3339ebbe256a04ee86c80004a60e9859e.tar.gz
src-test-e48a49b3339ebbe256a04ee86c80004a60e9859e.zip
Don't do things we aren't allowed to do in a signal handler... Defer
the work to the main thread... This fixes a possible crash if SIGINFO is delivered at the wrong time... This still leaves getrusage broken for some reason, but I believe that is a kernel issue and cannot be fixed here...
Notes
Notes: svn path=/head/; revision=283073
Diffstat (limited to 'usr.bin/time')
-rw-r--r--usr.bin/time/time.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/usr.bin/time/time.c b/usr.bin/time/time.c
index c2ea522f5ec01..678a2afb37bc7 100644
--- a/usr.bin/time/time.c
+++ b/usr.bin/time/time.c
@@ -65,6 +65,7 @@ static void showtime(FILE *, struct timeval *, struct timeval *,
static void siginfo(int);
static void usage(void);
+static sig_atomic_t siginfo_recvd;
static char decimal_point;
static struct timeval before_tv;
static int hflag, pflag;
@@ -130,8 +131,17 @@ main(int argc, char **argv)
/* parent */
(void)signal(SIGINT, SIG_IGN);
(void)signal(SIGQUIT, SIG_IGN);
+ siginfo_recvd = 0;
(void)signal(SIGINFO, siginfo);
- while (wait4(pid, &status, 0, &ru) != pid);
+ (void)siginterrupt(SIGINFO, 1);
+ while (wait4(pid, &status, 0, &ru) != pid) {
+ if (siginfo_recvd) {
+ siginfo_recvd = 0;
+ (void)gettimeofday(&after, NULL);
+ getrusage(RUSAGE_CHILDREN, &ru);
+ showtime(stdout, &before_tv, &after, &ru);
+ }
+ }
(void)gettimeofday(&after, NULL);
if ( ! WIFEXITED(status))
warnx("command terminated abnormally");
@@ -292,10 +302,6 @@ showtime(FILE *out, struct timeval *before, struct timeval *after,
static void
siginfo(int sig __unused)
{
- struct timeval after;
- struct rusage ru;
- (void)gettimeofday(&after, NULL);
- getrusage(RUSAGE_CHILDREN, &ru);
- showtime(stdout, &before_tv, &after, &ru);
+ siginfo_recvd = 1;
}