diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-04-02 21:20:35 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-04-02 21:20:35 +0000 |
commit | 7b6d9d687d30c0ef9662fc01f154a847da59410f (patch) | |
tree | 0a5037a0745d3380ad6a2d613e67d5d91472e608 /coreutils/dd.c | |
parent | a7f4e4bbd8d7a47a49404d28bc07ab3b5dc1c19b (diff) | |
download | busybox-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.c | 146 |
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 | ||
81 | int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 81 | int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
82 | int dd_main(int argc, char **argv) | 82 | int 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: |