aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2006-10-31 15:55:56 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2006-10-31 15:55:56 +0000
commit861773fd9a4ba0a118bea39db8413d209665ce53 (patch)
tree45d737179fbcb33a7daabc77022ff71268e9310b
parent73762202396d6080aa071ff70f5afb735f18816a (diff)
downloadbusybox-w32-861773fd9a4ba0a118bea39db8413d209665ce53.tar.gz
busybox-w32-861773fd9a4ba0a118bea39db8413d209665ce53.tar.bz2
busybox-w32-861773fd9a4ba0a118bea39db8413d209665ce53.zip
dd: fix bugs: always assumed conv=sync, died on write errors
w/o perror and statictics. Several small improvements git-svn-id: svn://busybox.net/trunk/busybox@16476 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--coreutils/dd.c119
-rw-r--r--libbb/full_write.c2
2 files changed, 70 insertions, 51 deletions
diff --git a/coreutils/dd.c b/coreutils/dd.c
index 78d831525..c0df0b75c 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -35,15 +35,26 @@ static void dd_output_status(int ATTRIBUTE_UNUSED cur_signal)
35 out_full, out_part); 35 out_full, out_part);
36} 36}
37 37
38static ssize_t full_write_or_warn(int fd, const void *buf, size_t len,
39 const char* filename)
40{
41 ssize_t n = full_write(fd, buf, len);
42 if (n < 0)
43 bb_perror_msg("writing '%s'", filename);
44 return n;
45}
46
38int dd_main(int argc, char **argv) 47int dd_main(int argc, char **argv)
39{ 48{
40#define sync_flag (1<<0) 49 enum {
41#define noerror (1<<1) 50 sync_flag = 1 << 0,
42#define trunc_flag (1<<2) 51 noerror = 1 << 1,
43#define twobufs_flag (1<<3) 52 trunc_flag = 1 << 2,
53 twobufs_flag = 1 << 3,
54 };
44 int flags = trunc_flag; 55 int flags = trunc_flag;
45 size_t oc = 0, ibs = 512, obs = 512; 56 size_t oc = 0, ibs = 512, obs = 512;
46 ssize_t n; 57 ssize_t n, w;
47 off_t seek = 0, skip = 0, count = OFF_T_MAX; 58 off_t seek = 0, skip = 0, count = OFF_T_MAX;
48 int oflag, ifd, ofd; 59 int oflag, ifd, ofd;
49 const char *infile = NULL, *outfile = NULL; 60 const char *infile = NULL, *outfile = NULL;
@@ -60,52 +71,53 @@ int dd_main(int argc, char **argv)
60 } 71 }
61 72
62 for (n = 1; n < argc; n++) { 73 for (n = 1; n < argc; n++) {
74 char *arg = argv[n];
75 /* Must fit into positive ssize_t */
76 if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", arg, 4))
77 ibs = xatoul_range_sfx(arg+4, 0, ((size_t)-1L)/2, dd_suffixes);
78 else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", arg, 4))
79 obs = xatoul_range_sfx(arg+4, 0, ((size_t)-1L)/2, dd_suffixes);
80 else if (!strncmp("bs=", arg, 3))
81 ibs = obs = xatoul_range_sfx(arg+3, 0, ((size_t)-1L)/2, dd_suffixes);
63 // FIXME: make them capable of eating LARGE numbers 82 // FIXME: make them capable of eating LARGE numbers
64 if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", argv[n], 4)) { 83 else if (!strncmp("count=", arg, 6))
65 ibs = xatoul_sfx(argv[n]+4, dd_suffixes); 84 count = xatoul_sfx(arg+6, dd_suffixes);
66 flags |= twobufs_flag; 85 else if (!strncmp("seek=", arg, 5))
67 } else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", argv[n], 4)) { 86 seek = xatoul_sfx(arg+5, dd_suffixes);
68 obs = xatoul_sfx(argv[n]+4, dd_suffixes); 87 else if (!strncmp("skip=", arg, 5))
69 flags |= twobufs_flag; 88 skip = xatoul_sfx(arg+5, dd_suffixes);
70 } else if (!strncmp("bs=", argv[n], 3)) 89
71 ibs = obs = xatoul_sfx(argv[n]+3, dd_suffixes); 90 else if (!strncmp("if=", arg, 3))
72 else if (!strncmp("count=", argv[n], 6)) 91 infile = arg+3;
73 count = xatoul_sfx(argv[n]+6, dd_suffixes); 92 else if (!strncmp("of=", arg, 3))
74 else if (!strncmp("seek=", argv[n], 5)) 93 outfile = arg+3;
75 seek = xatoul_sfx(argv[n]+5, dd_suffixes); 94 else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", arg, 5)) {
76 else if (!strncmp("skip=", argv[n], 5)) 95 arg += 5;
77 skip = xatoul_sfx(argv[n]+5, dd_suffixes);
78 else if (!strncmp("if=", argv[n], 3))
79 infile = argv[n]+3;
80 else if (!strncmp("of=", argv[n], 3))
81 outfile = argv[n]+3;
82 else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", argv[n], 5)) {
83 ibuf = argv[n]+5;
84 while (1) { 96 while (1) {
85 if (!strncmp("notrunc", ibuf, 7)) { 97 if (!strncmp("notrunc", arg, 7)) {
86 flags &= ~trunc_flag; 98 flags &= ~trunc_flag;
87 ibuf += 7; 99 arg += 7;
88 } else if (!strncmp("sync", ibuf, 4)) { 100 } else if (!strncmp("sync", arg, 4)) {
89 flags |= sync_flag; 101 flags |= sync_flag;
90 ibuf += 4; 102 arg += 4;
91 } else if (!strncmp("noerror", ibuf, 7)) { 103 } else if (!strncmp("noerror", arg, 7)) {
92 flags |= noerror; 104 flags |= noerror;
93 ibuf += 7; 105 arg += 7;
94 } else { 106 } else {
95 bb_error_msg_and_die(bb_msg_invalid_arg, argv[n]+5, "conv"); 107 bb_error_msg_and_die(bb_msg_invalid_arg, arg, "conv");
96 } 108 }
97 if (ibuf[0] == '\0') break; 109 if (arg[0] == '\0') break;
98 if (ibuf[0] == ',') ibuf++; 110 if (*arg++ != ',') bb_show_usage();
99 } 111 }
100 } else 112 } else
101 bb_show_usage(); 113 bb_show_usage();
102 } 114 }
103 ibuf = xmalloc(ibs);
104 115
105 if (flags & twobufs_flag) 116 ibuf = obuf = xmalloc(ibs);
117 if (ibs != obs) {
118 flags |= twobufs_flag;
106 obuf = xmalloc(obs); 119 obuf = xmalloc(obs);
107 else 120 }
108 obuf = ibuf;
109 121
110 if (infile != NULL) 122 if (infile != NULL)
111 ifd = xopen(infile, O_RDONLY); 123 ifd = xopen(infile, O_RDONLY);
@@ -173,7 +185,7 @@ int dd_main(int argc, char **argv)
173 in_full++; 185 in_full++;
174 else { 186 else {
175 in_part++; 187 in_part++;
176 if (sync_flag) { 188 if (flags & sync_flag) {
177 memset(ibuf + n, '\0', ibs - n); 189 memset(ibuf + n, '\0', ibs - n);
178 n = ibs; 190 n = ibs;
179 } 191 }
@@ -190,33 +202,40 @@ int dd_main(int argc, char **argv)
190 tmp += d; 202 tmp += d;
191 oc += d; 203 oc += d;
192 if (oc == obs) { 204 if (oc == obs) {
193 xwrite(ofd, obuf, obs); 205 w = full_write_or_warn(ofd, obuf, obs, outfile);
194 out_full++; 206 if (w < 0) goto out_status;
207 if (w == obs)
208 out_full++;
209 else if (w > 0)
210 out_part++;
195 oc = 0; 211 oc = 0;
196 } 212 }
197 } 213 }
198 } else { 214 } else {
199 xwrite(ofd, ibuf, n); 215 w = full_write_or_warn(ofd, ibuf, n, outfile);
200 if (n == ibs) 216 if (w < 0) goto out_status;
217 if (w == obs)
201 out_full++; 218 out_full++;
202 else 219 else if (w > 0)
203 out_part++; 220 out_part++;
204 } 221 }
205 } 222 }
206 223
207 if (ENABLE_FEATURE_DD_IBS_OBS && oc) { 224 if (ENABLE_FEATURE_DD_IBS_OBS && oc) {
208 xwrite(ofd, obuf, oc); 225 w = full_write_or_warn(ofd, obuf, oc, outfile);
209 out_part++; 226 if (w < 0) goto out_status;
227 if (w > 0)
228 out_part++;
210 } 229 }
211 if (close (ifd) < 0) { 230 if (close(ifd) < 0) {
212 bb_perror_msg_and_die("%s", infile); 231 bb_perror_msg_and_die("%s", infile);
213 } 232 }
214 233
215 if (close (ofd) < 0) { 234 if (close(ofd) < 0) {
216die_outfile: 235 die_outfile:
217 bb_perror_msg_and_die("%s", outfile); 236 bb_perror_msg_and_die("%s", outfile);
218 } 237 }
219 238 out_status:
220 dd_output_status(0); 239 dd_output_status(0);
221 240
222 return EXIT_SUCCESS; 241 return EXIT_SUCCESS;
diff --git a/libbb/full_write.c b/libbb/full_write.c
index 563f4a851..bceac6de5 100644
--- a/libbb/full_write.c
+++ b/libbb/full_write.c
@@ -27,7 +27,7 @@ ssize_t full_write(int fd, const void *buf, size_t len)
27 cc = safe_write(fd, buf, len); 27 cc = safe_write(fd, buf, len);
28 28
29 if (cc < 0) 29 if (cc < 0)
30 return cc; /* write() returns -1 on failure. */ 30 return cc; /* write() returns -1 on failure. */
31 31
32 total += cc; 32 total += cc;
33 buf = ((const char *)buf) + cc; 33 buf = ((const char *)buf) + cc;