aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-12-02 01:44:42 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-12-02 01:44:42 +0000
commite2532ab5f2446ec736b10b24f57a36456deb197f (patch)
tree8d982e42b7e48d9c6949fddd312b08a36dedbcba /coreutils
parent1796e2c49507e701e18b09281478cc33131dbbd8 (diff)
downloadbusybox-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')
-rw-r--r--coreutils/dd.c41
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
17enum {
18 ifd = STDIN_FILENO,
19 ofd = STDOUT_FILENO,
20};
21
17static const struct suffix_mult dd_suffixes[] = { 22static 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
48static ssize_t full_write_or_warn(int fd, const void *buf, size_t len, 53static 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
57static bool write_and_stats(int fd, const void *buf, size_t len, size_t obs, 62static 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}