diff options
author | Ari Sundholm <ari@tuxera.com> | 2015-02-07 01:41:22 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2015-02-07 01:41:22 +0100 |
commit | f22a838aed8264f2f3a20ea9865d7d2e9ccb26c1 (patch) | |
tree | cbeb6470f501536461bb0dbb7da6b943fcc0627c /coreutils | |
parent | 7e66102f762a7d80715f0c7e5925433256b78cee (diff) | |
download | busybox-w32-f22a838aed8264f2f3a20ea9865d7d2e9ccb26c1.tar.gz busybox-w32-f22a838aed8264f2f3a20ea9865d7d2e9ccb26c1.tar.bz2 busybox-w32-f22a838aed8264f2f3a20ea9865d7d2e9ccb26c1.zip |
dd: add optional support for status=noxfer/none
While at it, added 'B' number suffixes, upstream compat
function old new delta
dd_main 1469 1543 +74
dd_suffixes 88 112 +24
packed_usage 30156 30176 +20
dd_output_status 372 388 +16
static.status_words - 13 +13
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 4/0 up/down: 147/0) Total: 147 bytes
Signed-off-by: Ari Sundholm <ari@tuxera.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/Config.src | 38 | ||||
-rw-r--r-- | coreutils/dd.c | 143 |
2 files changed, 111 insertions, 70 deletions
diff --git a/coreutils/Config.src b/coreutils/Config.src index 68c717883..1bbb91ee9 100644 --- a/coreutils/Config.src +++ b/coreutils/Config.src | |||
@@ -87,44 +87,6 @@ config CUT | |||
87 | cut is used to print selected parts of lines from | 87 | cut is used to print selected parts of lines from |
88 | each file to stdout. | 88 | each file to stdout. |
89 | 89 | ||
90 | config DD | ||
91 | bool "dd" | ||
92 | default y | ||
93 | help | ||
94 | dd copies a file (from standard input to standard output, | ||
95 | by default) using specific input and output blocksizes, | ||
96 | while optionally performing conversions on it. | ||
97 | |||
98 | config FEATURE_DD_SIGNAL_HANDLING | ||
99 | bool "Enable DD signal handling for status reporting" | ||
100 | default y | ||
101 | depends on DD | ||
102 | help | ||
103 | Sending a SIGUSR1 signal to a running `dd' process makes it | ||
104 | print to standard error the number of records read and written | ||
105 | so far, then to resume copying. | ||
106 | |||
107 | $ dd if=/dev/zero of=/dev/null& | ||
108 | $ pid=$! kill -USR1 $pid; sleep 1; kill $pid | ||
109 | 10899206+0 records in | ||
110 | 10899206+0 records out | ||
111 | |||
112 | config FEATURE_DD_THIRD_STATUS_LINE | ||
113 | bool "Enable the third status line upon signal" | ||
114 | default y | ||
115 | depends on DD && FEATURE_DD_SIGNAL_HANDLING | ||
116 | help | ||
117 | Displays a coreutils-like third status line with transferred bytes, | ||
118 | elapsed time and speed. | ||
119 | |||
120 | config FEATURE_DD_IBS_OBS | ||
121 | bool "Enable ibs, obs and conv options" | ||
122 | default y | ||
123 | depends on DD | ||
124 | help | ||
125 | Enables support for writing a certain number of bytes in and out, | ||
126 | at a time, and performing conversions on the data stream. | ||
127 | |||
128 | config DF | 90 | config DF |
129 | bool "df" | 91 | bool "df" |
130 | default y | 92 | default y |
diff --git a/coreutils/dd.c b/coreutils/dd.c index 2838f6341..302497074 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c | |||
@@ -8,6 +8,51 @@ | |||
8 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 8 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | //config:config DD | ||
12 | //config: bool "dd" | ||
13 | //config: default y | ||
14 | //config: help | ||
15 | //config: dd copies a file (from standard input to standard output, | ||
16 | //config: by default) using specific input and output blocksizes, | ||
17 | //config: while optionally performing conversions on it. | ||
18 | //config: | ||
19 | //config:config FEATURE_DD_SIGNAL_HANDLING | ||
20 | //config: bool "Enable signal handling for status reporting" | ||
21 | //config: default y | ||
22 | //config: depends on DD | ||
23 | //config: help | ||
24 | //config: Sending a SIGUSR1 signal to a running `dd' process makes it | ||
25 | //config: print to standard error the number of records read and written | ||
26 | //config: so far, then to resume copying. | ||
27 | //config: | ||
28 | //config: $ dd if=/dev/zero of=/dev/null & | ||
29 | //config: $ pid=$!; kill -USR1 $pid; sleep 1; kill $pid | ||
30 | //config: 10899206+0 records in | ||
31 | //config: 10899206+0 records out | ||
32 | //config: | ||
33 | //config:config FEATURE_DD_THIRD_STATUS_LINE | ||
34 | //config: bool "Enable the third status line upon signal" | ||
35 | //config: default y | ||
36 | //config: depends on DD && FEATURE_DD_SIGNAL_HANDLING | ||
37 | //config: help | ||
38 | //config: Displays a coreutils-like third status line with transferred bytes, | ||
39 | //config: elapsed time and speed. | ||
40 | //config: | ||
41 | //config:config FEATURE_DD_IBS_OBS | ||
42 | //config: bool "Enable ibs, obs and conv options" | ||
43 | //config: default y | ||
44 | //config: depends on DD | ||
45 | //config: help | ||
46 | //config: Enables support for writing a certain number of bytes in and out, | ||
47 | //config: at a time, and performing conversions on the data stream. | ||
48 | //config: | ||
49 | //config:config FEATURE_DD_STATUS | ||
50 | //config: bool "Enable status display options" | ||
51 | //config: default y | ||
52 | //config: depends on DD | ||
53 | //config: help | ||
54 | //config: Enables support for status=noxfer/none option. | ||
55 | |||
11 | //usage:#define dd_trivial_usage | 56 | //usage:#define dd_trivial_usage |
12 | //usage: "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n" | 57 | //usage: "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n" |
13 | //usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync]") | 58 | //usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync]") |
@@ -32,8 +77,12 @@ | |||
32 | //usage: "\n conv=fsync Physically write data out before finishing" | 77 | //usage: "\n conv=fsync Physically write data out before finishing" |
33 | //usage: "\n conv=swab Swap every pair of bytes" | 78 | //usage: "\n conv=swab Swap every pair of bytes" |
34 | //usage: ) | 79 | //usage: ) |
80 | //usage: IF_FEATURE_DD_STATUS( | ||
81 | //usage: "\n status=noxfer Suppress rate output" | ||
82 | //usage: "\n status=none Suppress all output" | ||
83 | //usage: ) | ||
35 | //usage: "\n" | 84 | //usage: "\n" |
36 | //usage: "\nN may be suffixed by c (1), w (2), b (512), kD (1000), k (1024), MD, M, GD, G" | 85 | //usage: "\nN may be suffixed by c (1), w (2), b (512), kB (1000), k (1024), MB, M, GB, G" |
37 | //usage: | 86 | //usage: |
38 | //usage:#define dd_example_usage | 87 | //usage:#define dd_example_usage |
39 | //usage: "$ dd if=/dev/zero of=/dev/ram1 bs=1M count=4\n" | 88 | //usage: "$ dd if=/dev/zero of=/dev/ram1 bs=1M count=4\n" |
@@ -54,13 +103,18 @@ static const struct suffix_mult dd_suffixes[] = { | |||
54 | { "c", 1 }, | 103 | { "c", 1 }, |
55 | { "w", 2 }, | 104 | { "w", 2 }, |
56 | { "b", 512 }, | 105 | { "b", 512 }, |
106 | { "kB", 1000 }, | ||
57 | { "kD", 1000 }, | 107 | { "kD", 1000 }, |
58 | { "k", 1024 }, | 108 | { "k", 1024 }, |
59 | { "K", 1024 }, /* compat with coreutils dd */ | 109 | { "K", 1024 }, /* compat with coreutils dd (it also accepts KB and KD, TODO?) */ |
110 | { "MB", 1000000 }, | ||
60 | { "MD", 1000000 }, | 111 | { "MD", 1000000 }, |
61 | { "M", 1048576 }, | 112 | { "M", 1024*1024 }, |
113 | { "GB", 1000000000 }, | ||
62 | { "GD", 1000000000 }, | 114 | { "GD", 1000000000 }, |
63 | { "G", 1073741824 }, | 115 | { "G", 1024*1024*1024 }, |
116 | /* "D" suffix for decimal is not in coreutils manpage, looks like it's deprecated */ | ||
117 | /* coreutils also understands TPEZY suffixes for tera- and so on, with B suffix for decimal */ | ||
64 | { "", 0 } | 118 | { "", 0 } |
65 | }; | 119 | }; |
66 | 120 | ||
@@ -70,6 +124,7 @@ struct globals { | |||
70 | unsigned long long total_bytes; | 124 | unsigned long long total_bytes; |
71 | unsigned long long begin_time_us; | 125 | unsigned long long begin_time_us; |
72 | #endif | 126 | #endif |
127 | int flags; | ||
73 | } FIX_ALIASING; | 128 | } FIX_ALIASING; |
74 | #define G (*(struct globals*)&bb_common_bufsiz1) | 129 | #define G (*(struct globals*)&bb_common_bufsiz1) |
75 | #define INIT_G() do { \ | 130 | #define INIT_G() do { \ |
@@ -77,6 +132,21 @@ struct globals { | |||
77 | memset(&G, 0, sizeof(G)); \ | 132 | memset(&G, 0, sizeof(G)); \ |
78 | } while (0) | 133 | } while (0) |
79 | 134 | ||
135 | enum { | ||
136 | /* Must be in the same order as OP_conv_XXX! */ | ||
137 | /* (see "flags |= (1 << what)" below) */ | ||
138 | FLAG_NOTRUNC = (1 << 0) * ENABLE_FEATURE_DD_IBS_OBS, | ||
139 | FLAG_SYNC = (1 << 1) * ENABLE_FEATURE_DD_IBS_OBS, | ||
140 | FLAG_NOERROR = (1 << 2) * ENABLE_FEATURE_DD_IBS_OBS, | ||
141 | FLAG_FSYNC = (1 << 3) * ENABLE_FEATURE_DD_IBS_OBS, | ||
142 | FLAG_SWAB = (1 << 4) * ENABLE_FEATURE_DD_IBS_OBS, | ||
143 | /* end of conv flags */ | ||
144 | FLAG_TWOBUFS = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS, | ||
145 | FLAG_COUNT = 1 << 6, | ||
146 | FLAG_STATUS = 1 << 7, | ||
147 | FLAG_STATUS_NONE = 1 << 7, | ||
148 | FLAG_STATUS_NOXFER = 1 << 8, | ||
149 | }; | ||
80 | 150 | ||
81 | static void dd_output_status(int UNUSED_PARAM cur_signal) | 151 | static void dd_output_status(int UNUSED_PARAM cur_signal) |
82 | { | 152 | { |
@@ -93,6 +163,13 @@ static void dd_output_status(int UNUSED_PARAM cur_signal) | |||
93 | G.out_full, G.out_part); | 163 | G.out_full, G.out_part); |
94 | 164 | ||
95 | #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE | 165 | #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE |
166 | # if ENABLE_FEATURE_DD_STATUS | ||
167 | if (G.flags & FLAG_STATUS_NOXFER) /* status=noxfer active? */ | ||
168 | return; | ||
169 | //TODO: should status=none make dd stop reacting to USR1 entirely? | ||
170 | //So far we react to it (we print the stats), | ||
171 | //status=none only suppresses final, non-USR1 generated status message. | ||
172 | # endif | ||
96 | fprintf(stderr, "%llu bytes (%sB) copied, ", | 173 | fprintf(stderr, "%llu bytes (%sB) copied, ", |
97 | G.total_bytes, | 174 | G.total_bytes, |
98 | /* show fractional digit, use suffixes */ | 175 | /* show fractional digit, use suffixes */ |
@@ -148,20 +225,8 @@ static bool write_and_stats(const void *buf, size_t len, size_t obs, | |||
148 | int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 225 | int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
149 | int dd_main(int argc UNUSED_PARAM, char **argv) | 226 | int dd_main(int argc UNUSED_PARAM, char **argv) |
150 | { | 227 | { |
151 | enum { | ||
152 | /* Must be in the same order as OP_conv_XXX! */ | ||
153 | /* (see "flags |= (1 << what)" below) */ | ||
154 | FLAG_NOTRUNC = (1 << 0) * ENABLE_FEATURE_DD_IBS_OBS, | ||
155 | FLAG_SYNC = (1 << 1) * ENABLE_FEATURE_DD_IBS_OBS, | ||
156 | FLAG_NOERROR = (1 << 2) * ENABLE_FEATURE_DD_IBS_OBS, | ||
157 | FLAG_FSYNC = (1 << 3) * ENABLE_FEATURE_DD_IBS_OBS, | ||
158 | FLAG_SWAB = (1 << 4) * ENABLE_FEATURE_DD_IBS_OBS, | ||
159 | /* end of conv flags */ | ||
160 | FLAG_TWOBUFS = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS, | ||
161 | FLAG_COUNT = 1 << 6, | ||
162 | }; | ||
163 | static const char keywords[] ALIGN1 = | 228 | static const char keywords[] ALIGN1 = |
164 | "bs\0""count\0""seek\0""skip\0""if\0""of\0" | 229 | "bs\0""count\0""seek\0""skip\0""if\0""of\0"IF_FEATURE_DD_STATUS("status\0") |
165 | #if ENABLE_FEATURE_DD_IBS_OBS | 230 | #if ENABLE_FEATURE_DD_IBS_OBS |
166 | "ibs\0""obs\0""conv\0" | 231 | "ibs\0""obs\0""conv\0" |
167 | #endif | 232 | #endif |
@@ -170,6 +235,10 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
170 | static const char conv_words[] ALIGN1 = | 235 | static const char conv_words[] ALIGN1 = |
171 | "notrunc\0""sync\0""noerror\0""fsync\0""swab\0"; | 236 | "notrunc\0""sync\0""noerror\0""fsync\0""swab\0"; |
172 | #endif | 237 | #endif |
238 | #if ENABLE_FEATURE_DD_STATUS | ||
239 | static const char status_words[] ALIGN1 = | ||
240 | "none\0""noxfer\0"; | ||
241 | #endif | ||
173 | enum { | 242 | enum { |
174 | OP_bs = 0, | 243 | OP_bs = 0, |
175 | OP_count, | 244 | OP_count, |
@@ -177,6 +246,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
177 | OP_skip, | 246 | OP_skip, |
178 | OP_if, | 247 | OP_if, |
179 | OP_of, | 248 | OP_of, |
249 | IF_FEATURE_DD_STATUS(OP_status,) | ||
180 | #if ENABLE_FEATURE_DD_IBS_OBS | 250 | #if ENABLE_FEATURE_DD_IBS_OBS |
181 | OP_ibs, | 251 | OP_ibs, |
182 | OP_obs, | 252 | OP_obs, |
@@ -215,14 +285,12 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
215 | #endif | 285 | #endif |
216 | /* These are all zeroed at once! */ | 286 | /* These are all zeroed at once! */ |
217 | struct { | 287 | struct { |
218 | int flags; | ||
219 | size_t oc; | 288 | size_t oc; |
220 | ssize_t prev_read_size; /* for detecting swab failure */ | 289 | ssize_t prev_read_size; /* for detecting swab failure */ |
221 | off_t count; | 290 | off_t count; |
222 | off_t seek, skip; | 291 | off_t seek, skip; |
223 | const char *infile, *outfile; | 292 | const char *infile, *outfile; |
224 | } Z; | 293 | } Z; |
225 | #define flags (Z.flags ) | ||
226 | #define oc (Z.oc ) | 294 | #define oc (Z.oc ) |
227 | #define prev_read_size (Z.prev_read_size) | 295 | #define prev_read_size (Z.prev_read_size) |
228 | #define count (Z.count ) | 296 | #define count (Z.count ) |
@@ -278,7 +346,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
278 | n = index_in_strings(conv_words, val); | 346 | n = index_in_strings(conv_words, val); |
279 | if (n < 0) | 347 | if (n < 0) |
280 | bb_error_msg_and_die(bb_msg_invalid_arg, val, "conv"); | 348 | bb_error_msg_and_die(bb_msg_invalid_arg, val, "conv"); |
281 | flags |= (1 << n); | 349 | G.flags |= (1 << n); |
282 | if (!arg) /* no ',' left, so this was the last specifier */ | 350 | if (!arg) /* no ',' left, so this was the last specifier */ |
283 | break; | 351 | break; |
284 | /* *arg = ','; - to preserve ps listing? */ | 352 | /* *arg = ','; - to preserve ps listing? */ |
@@ -294,7 +362,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
294 | } | 362 | } |
295 | /* These can be large: */ | 363 | /* These can be large: */ |
296 | if (what == OP_count) { | 364 | if (what == OP_count) { |
297 | flags |= FLAG_COUNT; | 365 | G.flags |= FLAG_COUNT; |
298 | count = XATOU_SFX(val, dd_suffixes); | 366 | count = XATOU_SFX(val, dd_suffixes); |
299 | /*continue;*/ | 367 | /*continue;*/ |
300 | } | 368 | } |
@@ -314,6 +382,16 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
314 | outfile = val; | 382 | outfile = val; |
315 | /*continue;*/ | 383 | /*continue;*/ |
316 | } | 384 | } |
385 | #if ENABLE_FEATURE_DD_STATUS | ||
386 | if (what == OP_status) { | ||
387 | int n; | ||
388 | n = index_in_strings(status_words, val); | ||
389 | if (n < 0) | ||
390 | bb_error_msg_and_die(bb_msg_invalid_arg, val, "status"); | ||
391 | G.flags |= FLAG_STATUS << n; | ||
392 | /*continue;*/ | ||
393 | } | ||
394 | #endif | ||
317 | } /* end of "for (argv[i])" */ | 395 | } /* end of "for (argv[i])" */ |
318 | 396 | ||
319 | //XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever | 397 | //XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever |
@@ -321,7 +399,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
321 | obuf = ibuf; | 399 | obuf = ibuf; |
322 | #if ENABLE_FEATURE_DD_IBS_OBS | 400 | #if ENABLE_FEATURE_DD_IBS_OBS |
323 | if (ibs != obs) { | 401 | if (ibs != obs) { |
324 | flags |= FLAG_TWOBUFS; | 402 | G.flags |= FLAG_TWOBUFS; |
325 | obuf = xmalloc(obs); | 403 | obuf = xmalloc(obs); |
326 | } | 404 | } |
327 | #endif | 405 | #endif |
@@ -341,12 +419,12 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
341 | if (outfile) { | 419 | if (outfile) { |
342 | int oflag = O_WRONLY | O_CREAT; | 420 | int oflag = O_WRONLY | O_CREAT; |
343 | 421 | ||
344 | if (!seek && !(flags & FLAG_NOTRUNC)) | 422 | if (!seek && !(G.flags & FLAG_NOTRUNC)) |
345 | oflag |= O_TRUNC; | 423 | oflag |= O_TRUNC; |
346 | 424 | ||
347 | xmove_fd(xopen(outfile, oflag), ofd); | 425 | xmove_fd(xopen(outfile, oflag), ofd); |
348 | 426 | ||
349 | if (seek && !(flags & FLAG_NOTRUNC)) { | 427 | if (seek && !(G.flags & FLAG_NOTRUNC)) { |
350 | if (ftruncate(ofd, seek * obs) < 0) { | 428 | if (ftruncate(ofd, seek * obs) < 0) { |
351 | struct stat st; | 429 | struct stat st; |
352 | 430 | ||
@@ -377,7 +455,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
377 | goto die_outfile; | 455 | goto die_outfile; |
378 | } | 456 | } |
379 | 457 | ||
380 | while (!(flags & FLAG_COUNT) || (G.in_full + G.in_part != count)) { | 458 | while (!(G.flags & FLAG_COUNT) || (G.in_full + G.in_part != count)) { |
381 | ssize_t n; | 459 | ssize_t n; |
382 | 460 | ||
383 | n = safe_read(ifd, ibuf, ibs); | 461 | n = safe_read(ifd, ibuf, ibs); |
@@ -385,7 +463,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
385 | break; | 463 | break; |
386 | if (n < 0) { | 464 | if (n < 0) { |
387 | /* "Bad block" */ | 465 | /* "Bad block" */ |
388 | if (!(flags & FLAG_NOERROR)) | 466 | if (!(G.flags & FLAG_NOERROR)) |
389 | goto die_infile; | 467 | goto die_infile; |
390 | bb_simple_perror_msg(infile); | 468 | bb_simple_perror_msg(infile); |
391 | /* GNU dd with conv=noerror skips over bad blocks */ | 469 | /* GNU dd with conv=noerror skips over bad blocks */ |
@@ -394,7 +472,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
394 | * conv=noerror just ignores input bad blocks */ | 472 | * conv=noerror just ignores input bad blocks */ |
395 | n = 0; | 473 | n = 0; |
396 | } | 474 | } |
397 | if (flags & FLAG_SWAB) { | 475 | if (G.flags & FLAG_SWAB) { |
398 | uint16_t *p16; | 476 | uint16_t *p16; |
399 | ssize_t n2; | 477 | ssize_t n2; |
400 | 478 | ||
@@ -419,12 +497,12 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
419 | G.in_full++; | 497 | G.in_full++; |
420 | else { | 498 | else { |
421 | G.in_part++; | 499 | G.in_part++; |
422 | if (flags & FLAG_SYNC) { | 500 | if (G.flags & FLAG_SYNC) { |
423 | memset(ibuf + n, 0, ibs - n); | 501 | memset(ibuf + n, 0, ibs - n); |
424 | n = ibs; | 502 | n = ibs; |
425 | } | 503 | } |
426 | } | 504 | } |
427 | if (flags & FLAG_TWOBUFS) { | 505 | if (G.flags & FLAG_TWOBUFS) { |
428 | char *tmp = ibuf; | 506 | char *tmp = ibuf; |
429 | while (n) { | 507 | while (n) { |
430 | size_t d = obs - oc; | 508 | size_t d = obs - oc; |
@@ -446,7 +524,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
446 | goto out_status; | 524 | goto out_status; |
447 | } | 525 | } |
448 | 526 | ||
449 | if (flags & FLAG_FSYNC) { | 527 | if (G.flags & FLAG_FSYNC) { |
450 | if (fsync(ofd) < 0) | 528 | if (fsync(ofd) < 0) |
451 | goto die_outfile; | 529 | goto die_outfile; |
452 | } | 530 | } |
@@ -468,11 +546,12 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
468 | 546 | ||
469 | exitcode = EXIT_SUCCESS; | 547 | exitcode = EXIT_SUCCESS; |
470 | out_status: | 548 | out_status: |
471 | dd_output_status(0); | 549 | if (!ENABLE_FEATURE_DD_STATUS || !(G.flags & FLAG_STATUS_NONE)) |
550 | dd_output_status(0); | ||
472 | 551 | ||
473 | if (ENABLE_FEATURE_CLEAN_UP) { | 552 | if (ENABLE_FEATURE_CLEAN_UP) { |
474 | free(obuf); | 553 | free(obuf); |
475 | if (flags & FLAG_TWOBUFS) | 554 | if (G.flags & FLAG_TWOBUFS) |
476 | free(ibuf); | 555 | free(ibuf); |
477 | } | 556 | } |
478 | 557 | ||