diff options
-rw-r--r-- | coreutils/Config.in | 12 | ||||
-rw-r--r-- | coreutils/dd.c | 33 |
2 files changed, 37 insertions, 8 deletions
diff --git a/coreutils/Config.in b/coreutils/Config.in index 4eb3db052..6841ec96d 100644 --- a/coreutils/Config.in +++ b/coreutils/Config.in | |||
@@ -115,6 +115,18 @@ config CONFIG_DD | |||
115 | by default) using specific input and output blocksizes, | 115 | by default) using specific input and output blocksizes, |
116 | while optionally performing conversions on it. | 116 | while optionally performing conversions on it. |
117 | 117 | ||
118 | config CONFIG_FEATURE_DD_SIGNAL_HANDLING | ||
119 | bool "Enable DD signal handling for status reporting" | ||
120 | default y | ||
121 | depends on CONFIG_DD | ||
122 | help | ||
123 | sending a SIGUSR1 signal to a running `dd' process makes it | ||
124 | print to standard error the number of records read and written | ||
125 | so far, then to resume copying. | ||
126 | |||
127 | $ dd if=/dev/zero of=/dev/null& pid=$! $ kill -USR1 $pid; sleep 1; kill $pid | ||
128 | 10899206+0 records in 10899206+0 records out | ||
129 | |||
118 | config CONFIG_DF | 130 | config CONFIG_DF |
119 | bool "df" | 131 | bool "df" |
120 | default n | 132 | default n |
diff --git a/coreutils/dd.c b/coreutils/dd.c index ce8bcc6a5..378e212de 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c | |||
@@ -15,9 +15,9 @@ | |||
15 | #include <unistd.h> | 15 | #include <unistd.h> |
16 | #include <string.h> | 16 | #include <string.h> |
17 | #include <fcntl.h> | 17 | #include <fcntl.h> |
18 | #include <signal.h> // For FEATURE_DD_SIGNAL_HANDLING | ||
18 | #include "busybox.h" | 19 | #include "busybox.h" |
19 | 20 | ||
20 | |||
21 | static const struct suffix_mult dd_suffixes[] = { | 21 | static const struct suffix_mult dd_suffixes[] = { |
22 | { "c", 1 }, | 22 | { "c", 1 }, |
23 | { "w", 2 }, | 23 | { "w", 2 }, |
@@ -31,12 +31,20 @@ static const struct suffix_mult dd_suffixes[] = { | |||
31 | { NULL, 0 } | 31 | { NULL, 0 } |
32 | }; | 32 | }; |
33 | 33 | ||
34 | static size_t out_full; | ||
35 | static size_t out_part; | ||
36 | static size_t in_full; | ||
37 | static size_t in_part; | ||
38 | |||
39 | static void dd_output_status(int cur_signal) | ||
40 | { | ||
41 | fprintf(stderr, "%ld+%ld records in\n%ld+%ld records out\n", | ||
42 | (long)in_full, (long)in_part, | ||
43 | (long)out_full, (long)out_part); | ||
44 | } | ||
45 | |||
34 | int dd_main(int argc, char **argv) | 46 | int dd_main(int argc, char **argv) |
35 | { | 47 | { |
36 | size_t out_full = 0; | ||
37 | size_t out_part = 0; | ||
38 | size_t in_full = 0; | ||
39 | size_t in_part = 0; | ||
40 | size_t count = -1; | 48 | size_t count = -1; |
41 | size_t bs = 512; | 49 | size_t bs = 512; |
42 | ssize_t n; | 50 | ssize_t n; |
@@ -53,6 +61,17 @@ int dd_main(int argc, char **argv) | |||
53 | const char *outfile = NULL; | 61 | const char *outfile = NULL; |
54 | char *buf; | 62 | char *buf; |
55 | 63 | ||
64 | if (ENABLE_FEATURE_DD_SIGNAL_HANDLING) | ||
65 | { | ||
66 | struct sigaction sa; | ||
67 | |||
68 | memset(&sa, 0, sizeof(sa)); | ||
69 | sa.sa_handler = dd_output_status; | ||
70 | sa.sa_flags = SA_RESTART; | ||
71 | sigemptyset(&sa.sa_mask); | ||
72 | sigaction(SIGUSR1, &sa, 0); | ||
73 | } | ||
74 | |||
56 | for (i = 1; i < argc; i++) { | 75 | for (i = 1; i < argc; i++) { |
57 | if (strncmp("bs=", argv[i], 3) == 0) | 76 | if (strncmp("bs=", argv[i], 3) == 0) |
58 | bs = bb_xparse_number(argv[i]+3, dd_suffixes); | 77 | bs = bb_xparse_number(argv[i]+3, dd_suffixes); |
@@ -180,9 +199,7 @@ int dd_main(int argc, char **argv) | |||
180 | bb_perror_msg_and_die("%s", outfile); | 199 | bb_perror_msg_and_die("%s", outfile); |
181 | } | 200 | } |
182 | 201 | ||
183 | fprintf(stderr, "%ld+%ld records in\n%ld+%ld records out\n", | 202 | dd_output_status(0); |
184 | (long)in_full, (long)in_part, | ||
185 | (long)out_full, (long)out_part); | ||
186 | 203 | ||
187 | return EXIT_SUCCESS; | 204 | return EXIT_SUCCESS; |
188 | } | 205 | } |