aboutsummaryrefslogtreecommitdiff
path: root/coreutils/dd.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-04-02 21:20:35 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-04-02 21:20:35 +0000
commit7b6d9d687d30c0ef9662fc01f154a847da59410f (patch)
tree0a5037a0745d3380ad6a2d613e67d5d91472e608 /coreutils/dd.c
parenta7f4e4bbd8d7a47a49404d28bc07ab3b5dc1c19b (diff)
downloadbusybox-w32-7b6d9d687d30c0ef9662fc01f154a847da59410f.tar.gz
busybox-w32-7b6d9d687d30c0ef9662fc01f154a847da59410f.tar.bz2
busybox-w32-7b6d9d687d30c0ef9662fc01f154a847da59410f.zip
dd: support conv=fsync
dd: support "dd --" if CONFIG_DESKTOP=y function old new delta static.conv_words - 28 +28 dd_main 1369 1373 +4 static.keywords 848 827 -21 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/1 up/down: 32/-21) Total: 11 bytes
Diffstat (limited to 'coreutils/dd.c')
-rw-r--r--coreutils/dd.c146
1 files changed, 86 insertions, 60 deletions
diff --git a/coreutils/dd.c b/coreutils/dd.c
index f3330e624..e172b0c29 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -79,23 +79,31 @@ static bool write_and_stats(const void *buf, size_t len, size_t obs,
79#endif 79#endif
80 80
81int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 81int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
82int dd_main(int argc, char **argv) 82int dd_main(int argc ATTRIBUTE_UNUSED, char **argv)
83{ 83{
84 enum { 84 enum {
85 FLAG_SYNC = 1 << 0, 85 /* Must be in the same order as OP_conv_XXX! */
86 FLAG_NOERROR = 1 << 1, 86 /* (see "flags |= (1 << what)" below) */
87 FLAG_NOTRUNC = 1 << 2, 87 FLAG_NOTRUNC = 1 << 0,
88 FLAG_TWOBUFS = 1 << 3, 88 FLAG_SYNC = 1 << 1,
89 FLAG_COUNT = 1 << 4, 89 FLAG_NOERROR = 1 << 2,
90 FLAG_FSYNC = 1 << 3,
91 /* end of conv flags */
92 FLAG_TWOBUFS = 1 << 4,
93 FLAG_COUNT = 1 << 5,
90 }; 94 };
91 static const char keywords[] ALIGN1 = 95 static const char keywords[] ALIGN1 =
92 "bs=\0""count=\0""seek=\0""skip=\0""if=\0""of=\0" 96 "bs=\0""count=\0""seek=\0""skip=\0""if=\0""of=\0"
93#if ENABLE_FEATURE_DD_IBS_OBS 97#if ENABLE_FEATURE_DD_IBS_OBS
94 "ibs=\0""obs=\0""conv=\0""notrunc\0""sync\0""noerror\0" 98 "ibs=\0""obs=\0""conv=\0"
95#endif 99#endif
96 ; 100 ;
101#if ENABLE_FEATURE_DD_IBS_OBS
102 static const char conv_words[] ALIGN1 =
103 "notrunc\0""sync\0""noerror\0""fsync\0";
104#endif
97 enum { 105 enum {
98 OP_bs = 1, 106 OP_bs = 0,
99 OP_count, 107 OP_count,
100 OP_seek, 108 OP_seek,
101 OP_skip, 109 OP_skip,
@@ -105,9 +113,23 @@ int dd_main(int argc, char **argv)
105 OP_ibs, 113 OP_ibs,
106 OP_obs, 114 OP_obs,
107 OP_conv, 115 OP_conv,
108 OP_conv_notrunc, 116 /* Must be in the same order as FLAG_XXX! */
117 OP_conv_notrunc = 0,
109 OP_conv_sync, 118 OP_conv_sync,
110 OP_conv_noerror, 119 OP_conv_noerror,
120 OP_conv_fsync,
121 /* Unimplemented conv=XXX: */
122 //nocreat do not create the output file
123 //excl fail if the output file already exists
124 //fdatasync physically write output file data before finishing
125 //swab swap every pair of input bytes
126 //lcase change upper case to lower case
127 //ucase change lower case to upper case
128 //block pad newline-terminated records with spaces to cbs-size
129 //unblock replace trailing spaces in cbs-size records with newline
130 //ascii from EBCDIC to ASCII
131 //ebcdic from ASCII to EBCDIC
132 //ibm from ASCII to alternate EBCDIC
111#endif 133#endif
112 }; 134 };
113 int exitcode = EXIT_FAILURE; 135 int exitcode = EXIT_FAILURE;
@@ -138,85 +160,85 @@ int dd_main(int argc, char **argv)
138 signal_SA_RESTART_empty_mask(SIGUSR1, dd_output_status); 160 signal_SA_RESTART_empty_mask(SIGUSR1, dd_output_status);
139#endif 161#endif
140 162
141 for (n = 1; n < argc; n++) { 163 for (n = 1; argv[n]; n++) {
142 smalluint key_len; 164 int what;
143 smalluint what; 165 char *val;
144 char *key;
145 char *arg = argv[n]; 166 char *arg = argv[n];
146 167
147//XXX:FIXME: we reject plain "dd --" This would cost ~20 bytes, so.. 168#if ENABLE_DESKTOP
148//if (*arg == '-' && *++arg == '-' && !*++arg) continue; 169 /* "dd --". NB: coreutils 6.9 will complain if they see
149 key = strstr(arg, "="); 170 * more than one of them. We wouldn't. */
150 if (key == NULL) 171 if (arg[0] == '-' && arg[1] == '-' && arg[2] == '\0')
172 continue;
173#endif
174 val = strchr(arg, '=');
175 if (val == NULL)
151 bb_show_usage(); 176 bb_show_usage();
152 key_len = key - arg + 1; 177 *val = '\0';
153 key = xstrndup(arg, key_len); 178 what = index_in_strings(keywords, arg);
154 what = index_in_strings(keywords, key) + 1; 179 if (what < 0)
155 if (ENABLE_FEATURE_CLEAN_UP)
156 free(key);
157 if (what == 0)
158 bb_show_usage(); 180 bb_show_usage();
159 arg += key_len; 181 /* *val = '='; - to preserve ps listing? */
182 val++;
160#if ENABLE_FEATURE_DD_IBS_OBS 183#if ENABLE_FEATURE_DD_IBS_OBS
161 if (what == OP_ibs) { 184 if (what == OP_ibs) {
162 /* Must fit into positive ssize_t */ 185 /* Must fit into positive ssize_t */
163 ibs = xatoul_range_sfx(arg, 1, ((size_t)-1L)/2, dd_suffixes); 186 ibs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, dd_suffixes);
164 continue; 187 /*continue;*/
165 } 188 }
166 if (what == OP_obs) { 189 if (what == OP_obs) {
167 obs = xatoul_range_sfx(arg, 1, ((size_t)-1L)/2, dd_suffixes); 190 obs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, dd_suffixes);
168 continue; 191 /*continue;*/
169 } 192 }
170 if (what == OP_conv) { 193 if (what == OP_conv) {
171 while (1) { 194 while (1) {
172 /* find ',', replace them with NUL so we can use arg for 195 /* find ',', replace them with NUL so we can use val for
173 * index_in_strings() without copying. 196 * index_in_strings() without copying.
174 * We rely on arg being non-null, else strchr would fault. 197 * We rely on val being non-null, else strchr would fault.
175 */ 198 */
176 key = strchr(arg, ','); 199 arg = strchr(val, ',');
177 if (key) 200 if (arg)
178 *key = '\0'; 201 *arg = '\0';
179 what = index_in_strings(keywords, arg) + 1; 202 what = index_in_strings(conv_words, val);
180 if (what < OP_conv_notrunc) 203 if (what < 0)
181 bb_error_msg_and_die(bb_msg_invalid_arg, arg, "conv"); 204 bb_error_msg_and_die(bb_msg_invalid_arg, val, "conv");
182 if (what == OP_conv_notrunc) 205 flags |= (1 << what);
183 flags |= FLAG_NOTRUNC; 206 if (!arg) /* no ',' left, so this was the last specifier */
184 if (what == OP_conv_sync)
185 flags |= FLAG_SYNC;
186 if (what == OP_conv_noerror)
187 flags |= FLAG_NOERROR;
188 if (!key) /* no ',' left, so this was the last specifier */
189 break; 207 break;
190 arg = key + 1; /* skip this keyword and ',' */ 208 /* *arg = ','; - to preserve ps listing? */
209 val = arg + 1; /* skip this keyword and ',' */
191 } 210 }
192 continue; 211 continue; /* we trashed 'what', can't fall through */
193 } 212 }
194#endif 213#endif
195 if (what == OP_bs) { 214 if (what == OP_bs) {
196 ibs = obs = xatoul_range_sfx(arg, 1, ((size_t)-1L)/2, dd_suffixes); 215 ibs = obs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, dd_suffixes);
197 continue; 216 /*continue;*/
198 } 217 }
199 /* These can be large: */ 218 /* These can be large: */
200 if (what == OP_count) { 219 if (what == OP_count) {
201 flags |= FLAG_COUNT; 220 flags |= FLAG_COUNT;
202 count = XATOU_SFX(arg, dd_suffixes); 221 count = XATOU_SFX(val, dd_suffixes);
203 continue; 222 /*continue;*/
204 } 223 }
205 if (what == OP_seek) { 224 if (what == OP_seek) {
206 seek = XATOU_SFX(arg, dd_suffixes); 225 seek = XATOU_SFX(val, dd_suffixes);
207 continue; 226 /*continue;*/
208 } 227 }
209 if (what == OP_skip) { 228 if (what == OP_skip) {
210 skip = XATOU_SFX(arg, dd_suffixes); 229 skip = XATOU_SFX(val, dd_suffixes);
211 continue; 230 /*continue;*/
212 } 231 }
213 if (what == OP_if) { 232 if (what == OP_if) {
214 infile = arg; 233 infile = val;
215 continue; 234 /*continue;*/
216 } 235 }
217 if (what == OP_of) 236 if (what == OP_of) {
218 outfile = arg; 237 outfile = val;
219 } 238 /*continue;*/
239 }
240 } /* end of "for (argv[n])" */
241
220//XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever 242//XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever
221 ibuf = obuf = xmalloc(ibs); 243 ibuf = obuf = xmalloc(ibs);
222 if (ibs != obs) { 244 if (ibs != obs) {
@@ -304,13 +326,17 @@ int dd_main(int argc, char **argv)
304 } 326 }
305 } else if (write_and_stats(ibuf, n, obs, outfile)) 327 } else if (write_and_stats(ibuf, n, obs, outfile))
306 goto out_status; 328 goto out_status;
329
330 if (flags & FLAG_FSYNC) {
331 if (fsync(ofd) < 0)
332 goto die_outfile;
333 }
307 } 334 }
308 335
309 if (ENABLE_FEATURE_DD_IBS_OBS && oc) { 336 if (ENABLE_FEATURE_DD_IBS_OBS && oc) {
310 w = full_write_or_warn(obuf, oc, outfile); 337 w = full_write_or_warn(obuf, oc, outfile);
311 if (w < 0) goto out_status; 338 if (w < 0) goto out_status;
312 if (w > 0) 339 if (w > 0) G.out_part++;
313 G.out_part++;
314 } 340 }
315 if (close(ifd) < 0) { 341 if (close(ifd) < 0) {
316 die_infile: 342 die_infile: