diff options
author | eadler <eadler@FreeBSD.org> | 2013-05-10 18:43:36 +0000 |
---|---|---|
committer | eadler <eadler@FreeBSD.org> | 2013-05-10 18:43:36 +0000 |
commit | 9f34a8fbd1042ff5b6aacf0953a19839a9d2f7b5 (patch) | |
tree | 70263e024132ba7c7573919f9f71f2103a1f1d06 | |
parent | 6ea39edf934cff6ee443d1e0447b0081574612e5 (diff) | |
download | FreeBSD-src-9f34a8fbd1042ff5b6aacf0953a19839a9d2f7b5.zip FreeBSD-src-9f34a8fbd1042ff5b6aacf0953a19839a9d2f7b5.tar.gz |
Make dd's signal handler async safe.
PR: bin/75258
Submitted by: "Oleg V. Nauman" <oleg@reis.zp.ua>
Arrival Date: Sun Dec 19 14:50:21 GMT 2004
Reviewed by: mjg, jhb
Reviewed by: jilles (earlier version)
MFC after: 1 week
-rw-r--r-- | bin/dd/args.c | 1 | ||||
-rw-r--r-- | bin/dd/conv_tab.c | 1 | ||||
-rw-r--r-- | bin/dd/dd.c | 6 | ||||
-rw-r--r-- | bin/dd/extern.h | 3 | ||||
-rw-r--r-- | bin/dd/misc.c | 28 | ||||
-rw-r--r-- | bin/dd/position.c | 3 |
6 files changed, 22 insertions, 20 deletions
diff --git a/bin/dd/args.c b/bin/dd/args.c index 161fbfc..cc702f9 100644 --- a/bin/dd/args.c +++ b/bin/dd/args.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include <errno.h> #include <inttypes.h> #include <limits.h> +#include <signal.h> #include <stdlib.h> #include <string.h> diff --git a/bin/dd/conv_tab.c b/bin/dd/conv_tab.c index 07449fd..ce585df 100644 --- a/bin/dd/conv_tab.c +++ b/bin/dd/conv_tab.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> +#include <signal.h> #include <stdint.h> #include "dd.h" diff --git a/bin/dd/dd.c b/bin/dd/dd.c index 9d0f9b1..7e5bd91 100644 --- a/bin/dd/dd.c +++ b/bin/dd/dd.c @@ -81,6 +81,7 @@ size_t cbsz; /* conversion block size */ uintmax_t files_cnt = 1; /* # of files to copy */ const u_char *ctab; /* conversion table */ char fill_char; /* Character to fill with if defined */ +volatile sig_atomic_t need_summary; int main(int argc __unused, char *argv[]) @@ -89,7 +90,7 @@ main(int argc __unused, char *argv[]) jcl(argv); setup(); - (void)signal(SIGINFO, summaryx); + (void)signal(SIGINFO, siginfo_handler); (void)signal(SIGINT, terminate); atexit(summary); @@ -375,6 +376,9 @@ dd_in(void) in.dbp += in.dbrcnt; (*cfunc)(); + if (need_summary) { + summary(); + } } } diff --git a/bin/dd/extern.h b/bin/dd/extern.h index 9c540ad..6984f6d 100644 --- a/bin/dd/extern.h +++ b/bin/dd/extern.h @@ -43,7 +43,7 @@ void jcl(char **); void pos_in(void); void pos_out(void); void summary(void); -void summaryx(int); +void siginfo_handler(int); void terminate(int); void unblock(void); void unblock_close(void); @@ -61,3 +61,4 @@ extern const u_char e2a_32V[], e2a_POSIX[]; extern const u_char a2ibm_32V[], a2ibm_POSIX[]; extern u_char casetab[]; extern char fill_char; +extern volatile sig_atomic_t need_summary; diff --git a/bin/dd/misc.c b/bin/dd/misc.c index 8edc5a5..84cc5ee 100644 --- a/bin/dd/misc.c +++ b/bin/dd/misc.c @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include <errno.h> #include <inttypes.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -57,41 +58,32 @@ summary(void) { struct timeval tv; double secs; - char buf[100]; (void)gettimeofday(&tv, NULL); secs = tv.tv_sec + tv.tv_usec * 1e-6 - st.start; if (secs < 1e-6) secs = 1e-6; - /* Use snprintf(3) so that we don't reenter stdio(3). */ - (void)snprintf(buf, sizeof(buf), + (void)fprintf(stderr, "%ju+%ju records in\n%ju+%ju records out\n", st.in_full, st.in_part, st.out_full, st.out_part); - (void)write(STDERR_FILENO, buf, strlen(buf)); - if (st.swab) { - (void)snprintf(buf, sizeof(buf), "%ju odd length swab %s\n", + if (st.swab) + (void)fprintf(stderr, "%ju odd length swab %s\n", st.swab, (st.swab == 1) ? "block" : "blocks"); - (void)write(STDERR_FILENO, buf, strlen(buf)); - } - if (st.trunc) { - (void)snprintf(buf, sizeof(buf), "%ju truncated %s\n", + if (st.trunc) + (void)fprintf(stderr, "%ju truncated %s\n", st.trunc, (st.trunc == 1) ? "block" : "blocks"); - (void)write(STDERR_FILENO, buf, strlen(buf)); - } - (void)snprintf(buf, sizeof(buf), + (void)fprintf(stderr, "%ju bytes transferred in %.6f secs (%.0f bytes/sec)\n", st.bytes, secs, st.bytes / secs); - (void)write(STDERR_FILENO, buf, strlen(buf)); + need_summary = 0; } /* ARGSUSED */ void -summaryx(int notused __unused) +siginfo_handler(int signo __unused) { - int save_errno = errno; - summary(); - errno = save_errno; + need_summary = 1; } /* ARGSUSED */ diff --git a/bin/dd/position.c b/bin/dd/position.c index a638597..57bfde5 100644 --- a/bin/dd/position.c +++ b/bin/dd/position.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include <err.h> #include <errno.h> #include <inttypes.h> +#include <signal.h> #include <unistd.h> #include "dd.h" @@ -91,6 +92,8 @@ pos_in(void) } } else --cnt; + if (need_summary) + summary(); continue; } |