aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraldot <aldot@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-04-04 14:01:23 +0000
committeraldot <aldot@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-04-04 14:01:23 +0000
commite7afc91560feabfaf16db9bc5e30661cd6ecf0c0 (patch)
treeaa59c9f272cdc8883516460fcf7874352dde1f51
parent5063ac0a267b08feab2573bb6e5796b94145adfd (diff)
downloadbusybox-w32-e7afc91560feabfaf16db9bc5e30661cd6ecf0c0.tar.gz
busybox-w32-e7afc91560feabfaf16db9bc5e30661cd6ecf0c0.tar.bz2
busybox-w32-e7afc91560feabfaf16db9bc5e30661cd6ecf0c0.zip
- remove bss users. Shrinkage while at it. See XXX for further, pre-existing bugs
text data bss dec hex filename 1969 0 32 2001 7d1 dd.o.oorig 1941 0 0 1941 795 dd.o git-svn-id: svn://busybox.net/trunk/busybox@18322 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--coreutils/dd.c204
1 files changed, 130 insertions, 74 deletions
diff --git a/coreutils/dd.c b/coreutils/dd.c
index 4a094e81a..518c5fed2 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -17,7 +17,7 @@ static const struct suffix_mult dd_suffixes[] = {
17 { "b", 512 }, 17 { "b", 512 },
18 { "kD", 1000 }, 18 { "kD", 1000 },
19 { "k", 1024 }, 19 { "k", 1024 },
20 { "K", 1024 }, // compat with coreutils dd 20 { "K", 1024 }, /* compat with coreutils dd */
21 { "MD", 1000000 }, 21 { "MD", 1000000 },
22 { "M", 1048576 }, 22 { "M", 1048576 },
23 { "GD", 1000000000 }, 23 { "GD", 1000000000 },
@@ -25,18 +25,21 @@ static const struct suffix_mult dd_suffixes[] = {
25 { NULL, 0 } 25 { NULL, 0 }
26}; 26};
27 27
28static off_t out_full, out_part, in_full, in_part; 28struct globals {
29 off_t out_full, out_part, in_full, in_part;
30};
31#define G (*(struct globals*)&bb_common_bufsiz1)
29 32
30static void dd_output_status(int ATTRIBUTE_UNUSED cur_signal) 33static void dd_output_status(int ATTRIBUTE_UNUSED cur_signal)
31{ 34{
32 fprintf(stderr, "%"OFF_FMT"d+%"OFF_FMT"d records in\n" 35 fprintf(stderr, "%"OFF_FMT"d+%"OFF_FMT"d records in\n"
33 "%"OFF_FMT"d+%"OFF_FMT"d records out\n", 36 "%"OFF_FMT"d+%"OFF_FMT"d records out\n",
34 in_full, in_part, 37 G.in_full, G.in_part,
35 out_full, out_part); 38 G.out_full, G.out_part);
36} 39}
37 40
38static ssize_t full_write_or_warn(int fd, const void *buf, size_t len, 41static ssize_t full_write_or_warn(int fd, const void *buf, size_t len,
39 const char* filename) 42 const char * const filename)
40{ 43{
41 ssize_t n = full_write(fd, buf, len); 44 ssize_t n = full_write(fd, buf, len);
42 if (n < 0) 45 if (n < 0)
@@ -44,6 +47,19 @@ static ssize_t full_write_or_warn(int fd, const void *buf, size_t len,
44 return n; 47 return n;
45} 48}
46 49
50static bool write_and_stats(int fd, const void *buf, size_t len, size_t obs,
51 const char * const filename)
52{
53 ssize_t n = full_write_or_warn(fd, buf, len, filename);
54 if (n < 0)
55 return 1;
56 if (n == obs)
57 G.out_full++;
58 else if (n > 0)
59 G.out_part++;
60 return 0;
61}
62
47#if ENABLE_LFS 63#if ENABLE_LFS
48#define XATOU_SFX xatoull_sfx 64#define XATOU_SFX xatoull_sfx
49#else 65#else
@@ -59,11 +75,31 @@ int dd_main(int argc, char **argv)
59 trunc_flag = 1 << 2, 75 trunc_flag = 1 << 2,
60 twobufs_flag = 1 << 3, 76 twobufs_flag = 1 << 3,
61 }; 77 };
78 const char * const keywords[] = {
79 "bs=", "count=", "seek=", "skip=", "if=", "of=",
80#if ENABLE_FEATURE_DD_IBS_OBS
81 "ibs=", "obs=", "conv=", "notrunc", "sync", "noerror",
82#endif
83 NULL
84 };
85#define OP_bs 0 + 1
86#define OP_count OP_bs + 1
87#define OP_seek OP_count + 1
88#define OP_skip OP_seek + 1
89#define OP_if OP_skip + 1
90#define OP_of OP_if + 1
91#define OP_ibs OP_of + ENABLE_FEATURE_DD_IBS_OBS
92#define OP_obs OP_ibs + ENABLE_FEATURE_DD_IBS_OBS
93#define OP_conv OP_obs + ENABLE_FEATURE_DD_IBS_OBS
94#define OP_conv_notrunc OP_conv + ENABLE_FEATURE_DD_IBS_OBS
95#define OP_conv_sync OP_conv_notrunc + ENABLE_FEATURE_DD_IBS_OBS
96#define OP_conv_noerror OP_conv_sync + ENABLE_FEATURE_DD_IBS_OBS
97
62 int flags = trunc_flag; 98 int flags = trunc_flag;
63 size_t oc = 0, ibs = 512, obs = 512; 99 size_t oc = 0, ibs = 512, obs = 512;
64 ssize_t n, w; 100 ssize_t n, w;
65 off_t seek = 0, skip = 0, count = OFF_T_MAX; 101 off_t seek = 0, skip = 0, count = OFF_T_MAX;
66 int oflag, ifd, ofd; 102 int ifd, ofd;
67 const char *infile = NULL, *outfile = NULL; 103 const char *infile = NULL, *outfile = NULL;
68 char *ibuf, *obuf; 104 char *ibuf, *obuf;
69 105
@@ -78,63 +114,96 @@ int dd_main(int argc, char **argv)
78 } 114 }
79 115
80 for (n = 1; n < argc; n++) { 116 for (n = 1; n < argc; n++) {
117 smalluint key_len, what;
118 char *key;
81 char *arg = argv[n]; 119 char *arg = argv[n];
120
121//XXX:FIXME: we reject plain "dd --" This would cost ~20 bytes, so..
122//if (*arg == '-' && *++arg == '-' && !*++arg) continue;
123 key = strstr(arg, "=");
124 if (key == NULL)
125 bb_show_usage();
126 key_len = key - arg + 1;
127 key = xstrndup(arg, key_len);
128 what = index_in_str_array(keywords, key) + 1;
129 if (ENABLE_FEATURE_CLEAN_UP)
130 free(key);
131 if (what == 0)
132 bb_show_usage();
133 arg += key_len;
82 /* Must fit into positive ssize_t */ 134 /* Must fit into positive ssize_t */
83 if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", arg, 4)) 135 if (ENABLE_FEATURE_DD_IBS_OBS) {
84 ibs = xatoul_range_sfx(arg+4, 0, ((size_t)-1L)/2, dd_suffixes); 136 if (what == OP_ibs) {
85 else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", arg, 4)) 137 ibs = xatoul_range_sfx(arg, 1, ((size_t)-1L)/2, dd_suffixes);
86 obs = xatoul_range_sfx(arg+4, 0, ((size_t)-1L)/2, dd_suffixes); 138 continue;
87 else if (!strncmp("bs=", arg, 3)) 139 }
88 ibs = obs = xatoul_range_sfx(arg+3, 0, ((size_t)-1L)/2, dd_suffixes); 140 if (what == OP_obs) {
89 /* These can be large: */ 141 obs = xatoul_range_sfx(arg, 1, ((size_t)-1L)/2, dd_suffixes);
90 else if (!strncmp("count=", arg, 6)) 142 continue;
91 count = XATOU_SFX(arg+6, dd_suffixes); 143 }
92 else if (!strncmp("seek=", arg, 5)) 144 if (what == OP_conv) {
93 seek = XATOU_SFX(arg+5, dd_suffixes); 145 while (1) {
94 else if (!strncmp("skip=", arg, 5)) 146 /* find ',', replace them with nil so we can use arg for
95 skip = XATOU_SFX(arg+5, dd_suffixes); 147 * index_in_str_array without copying.
96 148 * We rely on arg being non-null, else strstr would fault.
97 else if (!strncmp("if=", arg, 3)) 149 */
98 infile = arg+3; 150 key = strstr(arg, ",");
99 else if (!strncmp("of=", arg, 3)) 151 if (key)
100 outfile = arg+3; 152 *key = '\0';
101 else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", arg, 5)) { 153 what = index_in_str_array(keywords, arg) + 1;
102 arg += 5; 154 if (what < OP_conv_notrunc)
103 while (1) { 155 bb_error_msg_and_die(bb_msg_invalid_arg, arg, "conv");
104 if (!strncmp("notrunc", arg, 7)) { 156 if (what == OP_conv_notrunc)
105 flags &= ~trunc_flag; 157 flags &= ~trunc_flag;
106 arg += 7; 158 if (what == OP_conv_sync)
107 } else if (!strncmp("sync", arg, 4)) { 159 flags |= sync_flag;
108 flags |= sync_flag; 160 if (what == OP_conv_noerror)
109 arg += 4; 161 flags |= noerror;
110 } else if (!strncmp("noerror", arg, 7)) { 162 if (!key) /* no ',' left, so this was the last specifier */
111 flags |= noerror; 163 break;
112 arg += 7; 164 arg += key - arg + 1; /* skip this keyword plus ',' */
113 } else {
114 bb_error_msg_and_die(bb_msg_invalid_arg, arg, "conv");
115 } 165 }
116 if (arg[0] == '\0') break; 166 continue;
117 if (*arg++ != ',') bb_show_usage();
118 } 167 }
119 } else 168 }
120 bb_show_usage(); 169 if (what == OP_bs) {
170 ibs = obs = xatoul_range_sfx(arg, 1, ((size_t)-1L)/2, dd_suffixes);
171 continue;
172 }
173 /* These can be large: */
174 if (what == OP_count) {
175 count = XATOU_SFX(arg, dd_suffixes);
176 continue;
177 }
178 if (what == OP_seek) {
179 seek = XATOU_SFX(arg, dd_suffixes);
180 continue;
181 }
182 if (what == skip) {
183 skip = XATOU_SFX(arg, dd_suffixes);
184 continue;
185 }
186 if (what == OP_if) {
187 infile = arg;
188 continue;
189 }
190 if (what == OP_of)
191 outfile = arg;
121 } 192 }
122 193//XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever
123 ibuf = obuf = xmalloc(ibs); 194 ibuf = obuf = xmalloc(ibs);
124 if (ibs != obs) { 195 if (ibs != obs) {
125 flags |= twobufs_flag; 196 flags |= twobufs_flag;
126 obuf = xmalloc(obs); 197 obuf = xmalloc(obs);
127 } 198 }
128
129 if (infile != NULL) 199 if (infile != NULL)
130 ifd = xopen(infile, O_RDONLY); 200 ifd = xopen(infile, O_RDONLY);
131 else { 201 else {
132 ifd = STDIN_FILENO; 202 ifd = STDIN_FILENO;
133 infile = bb_msg_standard_input; 203 infile = bb_msg_standard_input;
134 } 204 }
135
136 if (outfile != NULL) { 205 if (outfile != NULL) {
137 oflag = O_WRONLY | O_CREAT; 206 int oflag = O_WRONLY | O_CREAT;
138 207
139 if (!seek && (flags & trunc_flag)) 208 if (!seek && (flags & trunc_flag))
140 oflag |= O_TRUNC; 209 oflag |= O_TRUNC;
@@ -154,30 +223,25 @@ int dd_main(int argc, char **argv)
154 ofd = STDOUT_FILENO; 223 ofd = STDOUT_FILENO;
155 outfile = bb_msg_standard_output; 224 outfile = bb_msg_standard_output;
156 } 225 }
157
158 if (skip) { 226 if (skip) {
159 if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) { 227 if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) {
160 while (skip-- > 0) { 228 while (skip-- > 0) {
161 n = safe_read(ifd, ibuf, ibs); 229 n = safe_read(ifd, ibuf, ibs);
162 if (n < 0) 230 if (n < 0)
163 bb_perror_msg_and_die("%s", infile); 231 goto die_infile;
164 if (n == 0) 232 if (n == 0)
165 break; 233 break;
166 } 234 }
167 } 235 }
168 } 236 }
169
170 if (seek) { 237 if (seek) {
171 if (lseek(ofd, seek * obs, SEEK_CUR) < 0) 238 if (lseek(ofd, seek * obs, SEEK_CUR) < 0)
172 goto die_outfile; 239 goto die_outfile;
173 } 240 }
174 241
175 while (in_full + in_part != count) { 242 while (G.in_full + G.in_part != count) {
176 if (flags & noerror) { 243 if (flags & noerror) /* Pre-zero the buffer when for noerror */
177 /* Pre-zero the buffer when doing the noerror thing */
178 memset(ibuf, '\0', ibs); 244 memset(ibuf, '\0', ibs);
179 }
180
181 n = safe_read(ifd, ibuf, ibs); 245 n = safe_read(ifd, ibuf, ibs);
182 if (n == 0) 246 if (n == 0)
183 break; 247 break;
@@ -186,12 +250,12 @@ int dd_main(int argc, char **argv)
186 n = ibs; 250 n = ibs;
187 bb_perror_msg("%s", infile); 251 bb_perror_msg("%s", infile);
188 } else 252 } else
189 bb_perror_msg_and_die("%s", infile); 253 goto die_infile;
190 } 254 }
191 if ((size_t)n == ibs) 255 if ((size_t)n == ibs)
192 in_full++; 256 G.in_full++;
193 else { 257 else {
194 in_part++; 258 G.in_part++;
195 if (flags & sync_flag) { 259 if (flags & sync_flag) {
196 memset(ibuf + n, '\0', ibs - n); 260 memset(ibuf + n, '\0', ibs - n);
197 n = ibs; 261 n = ibs;
@@ -209,40 +273,32 @@ int dd_main(int argc, char **argv)
209 tmp += d; 273 tmp += d;
210 oc += d; 274 oc += d;
211 if (oc == obs) { 275 if (oc == obs) {
212 w = full_write_or_warn(ofd, obuf, obs, outfile); 276 if (write_and_stats(ofd, obuf, obs, obs, outfile))
213 if (w < 0) goto out_status; 277 goto out_status;
214 if (w == obs)
215 out_full++;
216 else if (w > 0)
217 out_part++;
218 oc = 0; 278 oc = 0;
219 } 279 }
220 } 280 }
221 } else { 281 } else
222 w = full_write_or_warn(ofd, ibuf, n, outfile); 282 if (write_and_stats(ofd, ibuf, n, obs, outfile))
223 if (w < 0) goto out_status; 283 goto out_status;
224 if (w == obs)
225 out_full++;
226 else if (w > 0)
227 out_part++;
228 }
229 } 284 }
230 285
231 if (ENABLE_FEATURE_DD_IBS_OBS && oc) { 286 if (ENABLE_FEATURE_DD_IBS_OBS && oc) {
232 w = full_write_or_warn(ofd, obuf, oc, outfile); 287 w = full_write_or_warn(ofd, obuf, oc, outfile);
233 if (w < 0) goto out_status; 288 if (w < 0) goto out_status;
234 if (w > 0) 289 if (w > 0)
235 out_part++; 290 G.out_part++;
236 } 291 }
237 if (close(ifd) < 0) { 292 if (close(ifd) < 0) {
293die_infile:
238 bb_perror_msg_and_die("%s", infile); 294 bb_perror_msg_and_die("%s", infile);
239 } 295 }
240 296
241 if (close(ofd) < 0) { 297 if (close(ofd) < 0) {
242 die_outfile: 298die_outfile:
243 bb_perror_msg_and_die("%s", outfile); 299 bb_perror_msg_and_die("%s", outfile);
244 } 300 }
245 out_status: 301out_status:
246 dd_output_status(0); 302 dd_output_status(0);
247 303
248 return EXIT_SUCCESS; 304 return EXIT_SUCCESS;