diff options
author | cheloha <cheloha@cvs.openbsd.org> | 2018-04-07 18:52:40 +0000 |
---|---|---|
committer | cheloha <cheloha@cvs.openbsd.org> | 2018-04-07 18:52:40 +0000 |
commit | 556b2de36e47a2161bf8c211e92a7adca0b31d7d (patch) | |
tree | 9f0cd393eef5dc0f7708dd2e243ff28bf49e75b1 /bin | |
parent | 6c7ce49f7a877ee6a409fbdb705af8955396a717 (diff) |
snprintf+writev -> dprintf
Much simpler.
Dropping writev makes the output from summary() non-atomic, so
output lines triggered by SIGINFO can intermingle with output
lines triggered by SIGINT or atexit(3).
This behavior is difficult to trigger, even deliberately.
The buffer in dprintf is large enough so that lines produced by
summary() are not garbled if this occurs, though, so this is unlikely
to break any scripts.
Discussed at length with deraadt@, who helpfully noted that
"not all problems have perfect solutions."
ok millert@
Diffstat (limited to 'bin')
-rw-r--r-- | bin/dd/misc.c | 38 |
1 files changed, 9 insertions, 29 deletions
diff --git a/bin/dd/misc.c b/bin/dd/misc.c index 8153971d8f8..a0c20191137 100644 --- a/bin/dd/misc.c +++ b/bin/dd/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.22 2017/10/24 14:21:10 schwarze Exp $ */ +/* $OpenBSD: misc.c,v 1.23 2018/04/07 18:52:39 cheloha Exp $ */ /* $NetBSD: misc.c,v 1.4 1995/03/21 09:04:10 cgd Exp $ */ /*- @@ -36,13 +36,9 @@ #include <sys/types.h> #include <sys/time.h> -#include <sys/uio.h> -#include <err.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <errno.h> +#include <stdio.h> #include <time.h> #include <unistd.h> @@ -53,10 +49,7 @@ void summary(void) { struct timespec elapsed, now; - char buf[4][100]; - struct iovec iov[4]; double nanosecs; - int i = 0; if (ddflags & C_NOINFO) return; @@ -67,38 +60,25 @@ summary(void) if (nanosecs == 0) nanosecs = 1; - /* Use snprintf(3) so that we don't reenter stdio(3). */ - (void)snprintf(buf[0], sizeof(buf[0]), - "%zu+%zu records in\n%zu+%zu records out\n", + /* Be async safe: use dprintf(3). */ + dprintf(STDERR_FILENO, "%zu+%zu records in\n%zu+%zu records out\n", st.in_full, st.in_part, st.out_full, st.out_part); - iov[i].iov_base = buf[0]; - iov[i++].iov_len = strlen(buf[0]); if (st.swab) { - (void)snprintf(buf[1], sizeof(buf[1]), - "%zu odd length swab %s\n", - st.swab, (st.swab == 1) ? "block" : "blocks"); - iov[i].iov_base = buf[1]; - iov[i++].iov_len = strlen(buf[1]); + dprintf(STDERR_FILENO, "%zu odd length swab %s\n", + st.swab, (st.swab == 1) ? "block" : "blocks"); } if (st.trunc) { - (void)snprintf(buf[2], sizeof(buf[2]), - "%zu truncated %s\n", - st.trunc, (st.trunc == 1) ? "block" : "blocks"); - iov[i].iov_base = buf[2]; - iov[i++].iov_len = strlen(buf[2]); + dprintf(STDERR_FILENO, "%zu truncated %s\n", + st.trunc, (st.trunc == 1) ? "block" : "blocks"); } if (!(ddflags & C_NOXFER)) { - (void)snprintf(buf[3], sizeof(buf[3]), + dprintf(STDERR_FILENO, "%lld bytes transferred in %lld.%03ld secs " "(%0.0f bytes/sec)\n", (long long)st.bytes, (long long)elapsed.tv_sec, elapsed.tv_nsec / 1000000, ((double)st.bytes * 1000000000) / nanosecs); - iov[i].iov_base = buf[3]; - iov[i++].iov_len = strlen(buf[3]); } - - (void)writev(STDERR_FILENO, iov, i); } void |