diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-12-02 01:44:42 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-12-02 01:44:42 +0000 |
commit | e2532ab5f2446ec736b10b24f57a36456deb197f (patch) | |
tree | 8d982e42b7e48d9c6949fddd312b08a36dedbcba /coreutils/dd.c | |
parent | 1796e2c49507e701e18b09281478cc33131dbbd8 (diff) | |
download | busybox-w32-e2532ab5f2446ec736b10b24f57a36456deb197f.tar.gz busybox-w32-e2532ab5f2446ec736b10b24f57a36456deb197f.tar.bz2 busybox-w32-e2532ab5f2446ec736b10b24f57a36456deb197f.zip |
dd: fix a bug where we don't report write errors
testsuite: small cleanup
full_write_or_warn 38 40 +2
write_and_stats 66 67 +1
dd_main 1358 1335 -23
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 3/-23) Total: -20 bytes
Diffstat (limited to 'coreutils/dd.c')
-rw-r--r-- | coreutils/dd.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/coreutils/dd.c b/coreutils/dd.c index fd4e7e8a2..7552c8518 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c | |||
@@ -14,6 +14,11 @@ | |||
14 | /* This is a NOEXEC applet. Be very careful! */ | 14 | /* This is a NOEXEC applet. Be very careful! */ |
15 | 15 | ||
16 | 16 | ||
17 | enum { | ||
18 | ifd = STDIN_FILENO, | ||
19 | ofd = STDOUT_FILENO, | ||
20 | }; | ||
21 | |||
17 | static const struct suffix_mult dd_suffixes[] = { | 22 | static const struct suffix_mult dd_suffixes[] = { |
18 | { "c", 1 }, | 23 | { "c", 1 }, |
19 | { "w", 2 }, | 24 | { "w", 2 }, |
@@ -45,19 +50,19 @@ static void dd_output_status(int ATTRIBUTE_UNUSED cur_signal) | |||
45 | G.out_full, G.out_part); | 50 | G.out_full, G.out_part); |
46 | } | 51 | } |
47 | 52 | ||
48 | static ssize_t full_write_or_warn(int fd, const void *buf, size_t len, | 53 | static ssize_t full_write_or_warn(const void *buf, size_t len, |
49 | const char *const filename) | 54 | const char *const filename) |
50 | { | 55 | { |
51 | ssize_t n = full_write(fd, buf, len); | 56 | ssize_t n = full_write(ofd, buf, len); |
52 | if (n < 0) | 57 | if (n < 0) |
53 | bb_perror_msg("writing '%s'", filename); | 58 | bb_perror_msg("writing '%s'", filename); |
54 | return n; | 59 | return n; |
55 | } | 60 | } |
56 | 61 | ||
57 | static bool write_and_stats(int fd, const void *buf, size_t len, size_t obs, | 62 | static bool write_and_stats(const void *buf, size_t len, size_t obs, |
58 | const char *filename) | 63 | const char *filename) |
59 | { | 64 | { |
60 | ssize_t n = full_write_or_warn(fd, buf, len, filename); | 65 | ssize_t n = full_write_or_warn(buf, len, filename); |
61 | if (n < 0) | 66 | if (n < 0) |
62 | return 1; | 67 | return 1; |
63 | if (n == obs) | 68 | if (n == obs) |
@@ -105,13 +110,13 @@ int dd_main(int argc, char **argv) | |||
105 | OP_conv_noerror, | 110 | OP_conv_noerror, |
106 | #endif | 111 | #endif |
107 | }; | 112 | }; |
113 | int exitcode = EXIT_FAILURE; | ||
108 | size_t ibs = 512, obs = 512; | 114 | size_t ibs = 512, obs = 512; |
109 | ssize_t n, w; | 115 | ssize_t n, w; |
110 | char *ibuf, *obuf; | 116 | char *ibuf, *obuf; |
111 | /* And these are all zeroed at once! */ | 117 | /* And these are all zeroed at once! */ |
112 | struct { | 118 | struct { |
113 | int flags; | 119 | int flags; |
114 | int ifd, ofd; | ||
115 | size_t oc; | 120 | size_t oc; |
116 | off_t count; | 121 | off_t count; |
117 | off_t seek, skip; | 122 | off_t seek, skip; |
@@ -121,8 +126,6 @@ int dd_main(int argc, char **argv) | |||
121 | #endif | 126 | #endif |
122 | } Z; | 127 | } Z; |
123 | #define flags (Z.flags ) | 128 | #define flags (Z.flags ) |
124 | #define ifd (Z.ifd ) | ||
125 | #define ofd (Z.ofd ) | ||
126 | #define oc (Z.oc ) | 129 | #define oc (Z.oc ) |
127 | #define count (Z.count ) | 130 | #define count (Z.count ) |
128 | #define seek (Z.seek ) | 131 | #define seek (Z.seek ) |
@@ -133,6 +136,7 @@ int dd_main(int argc, char **argv) | |||
133 | 136 | ||
134 | memset(&Z, 0, sizeof(Z)); | 137 | memset(&Z, 0, sizeof(Z)); |
135 | INIT_G(); | 138 | INIT_G(); |
139 | //fflush(NULL); - is this needed because of NOEXEC? | ||
136 | 140 | ||
137 | #if ENABLE_FEATURE_DD_SIGNAL_HANDLING | 141 | #if ENABLE_FEATURE_DD_SIGNAL_HANDLING |
138 | sigact.sa_handler = dd_output_status; | 142 | sigact.sa_handler = dd_output_status; |
@@ -227,9 +231,8 @@ int dd_main(int argc, char **argv) | |||
227 | obuf = xmalloc(obs); | 231 | obuf = xmalloc(obs); |
228 | } | 232 | } |
229 | if (infile != NULL) | 233 | if (infile != NULL) |
230 | ifd = xopen(infile, O_RDONLY); | 234 | xmove_fd(xopen(infile, O_RDONLY), ifd); |
231 | else { | 235 | else { |
232 | /* ifd = STDIN_FILENO; - it's zero and it's already there */ | ||
233 | infile = bb_msg_standard_input; | 236 | infile = bb_msg_standard_input; |
234 | } | 237 | } |
235 | if (outfile != NULL) { | 238 | if (outfile != NULL) { |
@@ -238,7 +241,7 @@ int dd_main(int argc, char **argv) | |||
238 | if (!seek && !(flags & FLAG_NOTRUNC)) | 241 | if (!seek && !(flags & FLAG_NOTRUNC)) |
239 | oflag |= O_TRUNC; | 242 | oflag |= O_TRUNC; |
240 | 243 | ||
241 | ofd = xopen(outfile, oflag); | 244 | xmove_fd(xopen(outfile, oflag), ofd); |
242 | 245 | ||
243 | if (seek && !(flags & FLAG_NOTRUNC)) { | 246 | if (seek && !(flags & FLAG_NOTRUNC)) { |
244 | if (ftruncate(ofd, seek * obs) < 0) { | 247 | if (ftruncate(ofd, seek * obs) < 0) { |
@@ -250,7 +253,6 @@ int dd_main(int argc, char **argv) | |||
250 | } | 253 | } |
251 | } | 254 | } |
252 | } else { | 255 | } else { |
253 | ofd = STDOUT_FILENO; | ||
254 | outfile = bb_msg_standard_output; | 256 | outfile = bb_msg_standard_output; |
255 | } | 257 | } |
256 | if (skip) { | 258 | if (skip) { |
@@ -276,11 +278,10 @@ int dd_main(int argc, char **argv) | |||
276 | if (n == 0) | 278 | if (n == 0) |
277 | break; | 279 | break; |
278 | if (n < 0) { | 280 | if (n < 0) { |
279 | if (flags & FLAG_NOERROR) { | 281 | if (!(flags & FLAG_NOERROR)) |
280 | n = ibs; | ||
281 | bb_simple_perror_msg(infile); | ||
282 | } else | ||
283 | goto die_infile; | 282 | goto die_infile; |
283 | n = ibs; | ||
284 | bb_simple_perror_msg(infile); | ||
284 | } | 285 | } |
285 | if ((size_t)n == ibs) | 286 | if ((size_t)n == ibs) |
286 | G.in_full++; | 287 | G.in_full++; |
@@ -303,17 +304,17 @@ int dd_main(int argc, char **argv) | |||
303 | tmp += d; | 304 | tmp += d; |
304 | oc += d; | 305 | oc += d; |
305 | if (oc == obs) { | 306 | if (oc == obs) { |
306 | if (write_and_stats(ofd, obuf, obs, obs, outfile)) | 307 | if (write_and_stats(obuf, obs, obs, outfile)) |
307 | goto out_status; | 308 | goto out_status; |
308 | oc = 0; | 309 | oc = 0; |
309 | } | 310 | } |
310 | } | 311 | } |
311 | } else if (write_and_stats(ofd, ibuf, n, obs, outfile)) | 312 | } else if (write_and_stats(ibuf, n, obs, outfile)) |
312 | goto out_status; | 313 | goto out_status; |
313 | } | 314 | } |
314 | 315 | ||
315 | if (ENABLE_FEATURE_DD_IBS_OBS && oc) { | 316 | if (ENABLE_FEATURE_DD_IBS_OBS && oc) { |
316 | w = full_write_or_warn(ofd, obuf, oc, outfile); | 317 | w = full_write_or_warn(obuf, oc, outfile); |
317 | if (w < 0) goto out_status; | 318 | if (w < 0) goto out_status; |
318 | if (w > 0) | 319 | if (w > 0) |
319 | G.out_part++; | 320 | G.out_part++; |
@@ -327,8 +328,10 @@ int dd_main(int argc, char **argv) | |||
327 | die_outfile: | 328 | die_outfile: |
328 | bb_simple_perror_msg_and_die(outfile); | 329 | bb_simple_perror_msg_and_die(outfile); |
329 | } | 330 | } |
331 | |||
332 | exitcode = EXIT_SUCCESS; | ||
330 | out_status: | 333 | out_status: |
331 | dd_output_status(0); | 334 | dd_output_status(0); |
332 | 335 | ||
333 | return EXIT_SUCCESS; | 336 | return exitcode; |
334 | } | 337 | } |