diff options
author | Rob Landley <rob@landley.net> | 2006-05-16 16:52:12 +0000 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2006-05-16 16:52:12 +0000 |
commit | 2686d3bc38dd1b296c4191160bd4336c0ed11388 (patch) | |
tree | 56a2608bb8209cd8f2043396b8dc54fd5fe8feb0 | |
parent | adde79883ffe726fc3237edb4756a99fba608797 (diff) | |
download | busybox-w32-2686d3bc38dd1b296c4191160bd4336c0ed11388.tar.gz busybox-w32-2686d3bc38dd1b296c4191160bd4336c0ed11388.tar.bz2 busybox-w32-2686d3bc38dd1b296c4191160bd4336c0ed11388.zip |
Rob Sullivan cleaned up the longstanding patch from Hideki IWAMOTO to add
ibs and obs support to dd, and made it configurable. I cleaned it up a bit
further and moved conv= into the same config option.
-rw-r--r-- | coreutils/Config.in | 8 | ||||
-rw-r--r-- | coreutils/dd.c | 139 | ||||
-rw-r--r-- | include/usage.h | 14 | ||||
-rw-r--r-- | patches/dd_ibs_and_obs.diff | 252 |
4 files changed, 100 insertions, 313 deletions
diff --git a/coreutils/Config.in b/coreutils/Config.in index d0ac000d3..d7e31e868 100644 --- a/coreutils/Config.in +++ b/coreutils/Config.in | |||
@@ -127,6 +127,14 @@ config CONFIG_FEATURE_DD_SIGNAL_HANDLING | |||
127 | $ dd if=/dev/zero of=/dev/null& pid=$! $ kill -USR1 $pid; sleep 1; kill $pid | 127 | $ dd if=/dev/zero of=/dev/null& pid=$! $ kill -USR1 $pid; sleep 1; kill $pid |
128 | 10899206+0 records in 10899206+0 records out | 128 | 10899206+0 records in 10899206+0 records out |
129 | 129 | ||
130 | config CONFIG_FEATURE_DD_IBS_OBS | ||
131 | bool "Enable ibs, obs and conv options" | ||
132 | default n | ||
133 | depends on CONFIG_DD | ||
134 | help | ||
135 | Enables support for writing a certain number of bytes in and out, | ||
136 | at a time, and performing conversions on the data stream. | ||
137 | |||
130 | config CONFIG_DF | 138 | config CONFIG_DF |
131 | bool "df" | 139 | bool "df" |
132 | default n | 140 | default n |
diff --git a/coreutils/dd.c b/coreutils/dd.c index 378e212de..53aa085ed 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c | |||
@@ -45,21 +45,13 @@ static void dd_output_status(int cur_signal) | |||
45 | 45 | ||
46 | int dd_main(int argc, char **argv) | 46 | int dd_main(int argc, char **argv) |
47 | { | 47 | { |
48 | size_t count = -1; | 48 | size_t count = -1, oc = 0, ibs = 512, obs = 512; |
49 | size_t bs = 512; | ||
50 | ssize_t n; | 49 | ssize_t n; |
51 | off_t seek = 0; | 50 | off_t seek = 0, skip = 0; |
52 | off_t skip = 0; | 51 | int sync_flag = FALSE, noerror = FALSE, trunc_flag = TRUE, twobufs_flag = 0, |
53 | int sync_flag = FALSE; | 52 | oflag, ifd, ofd, i; |
54 | int noerror = FALSE; | 53 | const char *infile = NULL, *outfile = NULL; |
55 | int trunc_flag = TRUE; | 54 | char *ibuf, *obuf; |
56 | int oflag; | ||
57 | int ifd; | ||
58 | int ofd; | ||
59 | int i; | ||
60 | const char *infile = NULL; | ||
61 | const char *outfile = NULL; | ||
62 | char *buf; | ||
63 | 55 | ||
64 | if (ENABLE_FEATURE_DD_SIGNAL_HANDLING) | 56 | if (ENABLE_FEATURE_DD_SIGNAL_HANDLING) |
65 | { | 57 | { |
@@ -73,43 +65,49 @@ int dd_main(int argc, char **argv) | |||
73 | } | 65 | } |
74 | 66 | ||
75 | for (i = 1; i < argc; i++) { | 67 | for (i = 1; i < argc; i++) { |
76 | if (strncmp("bs=", argv[i], 3) == 0) | 68 | if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", argv[i], 4)) { |
77 | bs = bb_xparse_number(argv[i]+3, dd_suffixes); | 69 | ibs = bb_xparse_number(argv[i]+4, dd_suffixes); |
78 | else if (strncmp("count=", argv[i], 6) == 0) | 70 | twobufs_flag++; |
71 | } else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", argv[i], 4)) { | ||
72 | obs = bb_xparse_number(argv[i]+4, dd_suffixes); | ||
73 | twobufs_flag++; | ||
74 | } else if (!strncmp("bs=", argv[i], 3)) { | ||
75 | ibs = obs = bb_xparse_number(argv[i]+3, dd_suffixes); | ||
76 | } else if (!strncmp("count=", argv[i], 6)) | ||
79 | count = bb_xparse_number(argv[i]+6, dd_suffixes); | 77 | count = bb_xparse_number(argv[i]+6, dd_suffixes); |
80 | else if (strncmp("seek=", argv[i], 5) == 0) | 78 | else if (!strncmp("seek=", argv[i], 5)) |
81 | seek = bb_xparse_number(argv[i]+5, dd_suffixes); | 79 | seek = bb_xparse_number(argv[i]+5, dd_suffixes); |
82 | else if (strncmp("skip=", argv[i], 5) == 0) | 80 | else if (!strncmp("skip=", argv[i], 5)) |
83 | skip = bb_xparse_number(argv[i]+5, dd_suffixes); | 81 | skip = bb_xparse_number(argv[i]+5, dd_suffixes); |
84 | else if (strncmp("if=", argv[i], 3) == 0) | 82 | else if (!strncmp("if=", argv[i], 3)) |
85 | infile = argv[i]+3; | 83 | infile = argv[i]+3; |
86 | else if (strncmp("of=", argv[i], 3) == 0) | 84 | else if (!strncmp("of=", argv[i], 3)) |
87 | outfile = argv[i]+3; | 85 | outfile = argv[i]+3; |
88 | else if (strncmp("conv=", argv[i], 5) == 0) { | 86 | else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", argv[i], 5)) { |
89 | buf = argv[i]+5; | 87 | ibuf = argv[i]+5; |
90 | while (1) { | 88 | while (1) { |
91 | if (strncmp("notrunc", buf, 7) == 0) { | 89 | if (!strncmp("notrunc", ibuf, 7)) { |
92 | trunc_flag = FALSE; | 90 | trunc_flag = FALSE; |
93 | buf += 7; | 91 | ibuf += 7; |
94 | } else if (strncmp("sync", buf, 4) == 0) { | 92 | } else if (!strncmp("sync", ibuf, 4)) { |
95 | sync_flag = TRUE; | 93 | sync_flag = TRUE; |
96 | buf += 4; | 94 | ibuf += 4; |
97 | } else if (strncmp("noerror", buf, 7) == 0) { | 95 | } else if (!strncmp("noerror", ibuf, 7)) { |
98 | noerror = TRUE; | 96 | noerror = TRUE; |
99 | buf += 7; | 97 | ibuf += 7; |
100 | } else { | 98 | } else { |
101 | bb_error_msg_and_die("invalid conversion `%s'", argv[i]+5); | 99 | bb_error_msg_and_die("invalid conversion `%s'", argv[i]+5); |
102 | } | 100 | } |
103 | if (buf[0] == '\0') | 101 | if (ibuf[0] == '\0') break; |
104 | break; | 102 | if (ibuf[0] == ',') ibuf++; |
105 | if (buf[0] == ',') | ||
106 | buf++; | ||
107 | } | 103 | } |
108 | } else | 104 | } else |
109 | bb_show_usage(); | 105 | bb_show_usage(); |
110 | } | 106 | } |
107 | ibuf = xmalloc(ibs); | ||
111 | 108 | ||
112 | buf = xmalloc(bs); | 109 | if (twobufs_flag) obuf = xmalloc(obs); |
110 | else obuf = ibuf; | ||
113 | 111 | ||
114 | if (infile != NULL) { | 112 | if (infile != NULL) { |
115 | ifd = bb_xopen(infile, O_RDONLY); | 113 | ifd = bb_xopen(infile, O_RDONLY); |
@@ -128,7 +126,7 @@ int dd_main(int argc, char **argv) | |||
128 | ofd = bb_xopen3(outfile, oflag, 0666); | 126 | ofd = bb_xopen3(outfile, oflag, 0666); |
129 | 127 | ||
130 | if (seek && trunc_flag) { | 128 | if (seek && trunc_flag) { |
131 | if (ftruncate(ofd, seek * bs) < 0) { | 129 | if (ftruncate(ofd, seek * obs) < 0) { |
132 | struct stat st; | 130 | struct stat st; |
133 | 131 | ||
134 | if (fstat (ofd, &st) < 0 || S_ISREG (st.st_mode) || | 132 | if (fstat (ofd, &st) < 0 || S_ISREG (st.st_mode) || |
@@ -143,13 +141,19 @@ int dd_main(int argc, char **argv) | |||
143 | } | 141 | } |
144 | 142 | ||
145 | if (skip) { | 143 | if (skip) { |
146 | if (lseek(ifd, skip * bs, SEEK_CUR) < 0) { | 144 | if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) { |
147 | bb_perror_msg_and_die("%s", infile); | 145 | while (skip-- > 0) { |
146 | n = safe_read(ifd, ibuf, ibs); | ||
147 | if (n < 0) | ||
148 | bb_perror_msg_and_die("%s", infile); | ||
149 | if (n == 0) | ||
150 | break; | ||
151 | } | ||
148 | } | 152 | } |
149 | } | 153 | } |
150 | 154 | ||
151 | if (seek) { | 155 | if (seek) { |
152 | if (lseek(ofd, seek * bs, SEEK_CUR) < 0) { | 156 | if (lseek(ofd, seek * obs, SEEK_CUR) < 0) { |
153 | bb_perror_msg_and_die("%s", outfile); | 157 | bb_perror_msg_and_die("%s", outfile); |
154 | } | 158 | } |
155 | } | 159 | } |
@@ -157,40 +161,63 @@ int dd_main(int argc, char **argv) | |||
157 | while (in_full + in_part != count) { | 161 | while (in_full + in_part != count) { |
158 | if (noerror) { | 162 | if (noerror) { |
159 | /* Pre-zero the buffer when doing the noerror thing */ | 163 | /* Pre-zero the buffer when doing the noerror thing */ |
160 | memset(buf, '\0', bs); | 164 | memset(ibuf, '\0', ibs); |
165 | } | ||
166 | |||
167 | n = safe_read(ifd, ibuf, ibs); | ||
168 | if (n == 0) { | ||
169 | break; | ||
161 | } | 170 | } |
162 | n = safe_read(ifd, buf, bs); | ||
163 | if (n < 0) { | 171 | if (n < 0) { |
164 | if (noerror) { | 172 | if (noerror) { |
165 | n = bs; | 173 | n = ibs; |
166 | bb_perror_msg("%s", infile); | 174 | bb_perror_msg("%s", infile); |
167 | } else { | 175 | } else { |
168 | bb_perror_msg_and_die("%s", infile); | 176 | bb_perror_msg_and_die("%s", infile); |
169 | } | 177 | } |
170 | } | 178 | } |
171 | if (n == 0) { | 179 | if ((size_t)n == ibs) { |
172 | break; | ||
173 | } | ||
174 | if ((size_t)n == bs) { | ||
175 | in_full++; | 180 | in_full++; |
176 | } else { | 181 | } else { |
177 | in_part++; | 182 | in_part++; |
183 | if (sync_flag) { | ||
184 | memset(ibuf + n, '\0', ibs - n); | ||
185 | n = ibs; | ||
186 | } | ||
178 | } | 187 | } |
179 | if (sync_flag) { | 188 | if (twobufs_flag) { |
180 | memset(buf + n, '\0', bs - n); | 189 | char *tmp = ibuf; |
181 | n = bs; | 190 | while (n) { |
191 | size_t d = obs - oc; | ||
192 | |||
193 | if (d > n) d = n; | ||
194 | memcpy(obuf + oc, tmp, d); | ||
195 | n -= d; | ||
196 | tmp += d; | ||
197 | oc += d; | ||
198 | if (oc == obs) { | ||
199 | if (bb_full_write(ofd, obuf, obs) < 0) { | ||
200 | bb_perror_msg_and_die("%s", outfile); | ||
201 | } | ||
202 | out_full++; | ||
203 | oc = 0; | ||
204 | } | ||
205 | } | ||
206 | } else { | ||
207 | if ((n = bb_full_write(ofd, ibuf, n)) < 0) { | ||
208 | bb_perror_msg_and_die("%s", outfile); | ||
209 | } | ||
210 | if (n == ibs) out_full++; | ||
211 | else out_part++; | ||
182 | } | 212 | } |
183 | n = bb_full_write(ofd, buf, n); | 213 | } |
184 | if (n < 0) { | 214 | |
215 | if (ENABLE_FEATURE_DD_IBS_OBS && oc) { | ||
216 | if (bb_full_write(ofd, obuf, oc) < 0) { | ||
185 | bb_perror_msg_and_die("%s", outfile); | 217 | bb_perror_msg_and_die("%s", outfile); |
186 | } | 218 | } |
187 | if ((size_t)n == bs) { | 219 | out_part++; |
188 | out_full++; | ||
189 | } else { | ||
190 | out_part++; | ||
191 | } | ||
192 | } | 220 | } |
193 | |||
194 | if (close (ifd) < 0) { | 221 | if (close (ifd) < 0) { |
195 | bb_perror_msg_and_die("%s", infile); | 222 | bb_perror_msg_and_die("%s", infile); |
196 | } | 223 | } |
diff --git a/include/usage.h b/include/usage.h index 0e3ecae05..9ec25c49f 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -370,19 +370,23 @@ USE_FEATURE_DATE_ISOFMT( \ | |||
370 | "64\n" | 370 | "64\n" |
371 | 371 | ||
372 | #define dd_trivial_usage \ | 372 | #define dd_trivial_usage \ |
373 | "[if=FILE] [of=FILE] [bs=N] [count=N] [skip=N]\n" \ | 373 | "[if=FILE] [of=FILE] " USE_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n" \ |
374 | "\t [seek=N] [conv=notrunc|noerror|sync]" | 374 | "\t [seek=N]" USE_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync]") |
375 | #define dd_full_usage \ | 375 | #define dd_full_usage \ |
376 | "Copy a file, converting and formatting according to options\n\n" \ | 376 | "Copy a file, converting and formatting according to options\n\n" \ |
377 | "\tif=FILE\t\tread from FILE instead of stdin\n" \ | 377 | "\tif=FILE\t\tread from FILE instead of stdin\n" \ |
378 | "\tof=FILE\t\twrite to FILE instead of stdout\n" \ | 378 | "\tof=FILE\t\twrite to FILE instead of stdout\n" \ |
379 | "\tbs=N\t\tread and write N bytes at a time\n" \ | 379 | "\tbs=N\t\tread and write N bytes at a time\n" \ |
380 | USE_FEATURE_DD_IBS_OBS("\tibs=N\t\tread N bytes at a time\n") \ | ||
381 | USE_FEATURE_DD_IBS_OBS("\tobs=N\t\twrite N bytes at a time\n") \ | ||
380 | "\tcount=N\t\tcopy only N input blocks\n" \ | 382 | "\tcount=N\t\tcopy only N input blocks\n" \ |
381 | "\tskip=N\t\tskip N input blocks\n" \ | 383 | "\tskip=N\t\tskip N input blocks\n" \ |
382 | "\tseek=N\t\tskip N output blocks\n" \ | 384 | "\tseek=N\t\tskip N output blocks\n" \ |
383 | "\tconv=notrunc\tdon't truncate output file\n" \ | 385 | USE_FEATURE_DD_IBS_OBS( \ |
384 | "\tconv=noerror\tcontinue after read errors\n" \ | 386 | "\tconv=notrunc\tdon't truncate output file\n" \ |
385 | "\tconv=sync\tpad blocks with zeros\n" \ | 387 | "\tconv=noerror\tcontinue after read errors\n" \ |
388 | "\tconv=sync\tpad blocks with zeros\n" \ | ||
389 | ) \ | ||
386 | "\n" \ | 390 | "\n" \ |
387 | "Numbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024),\n" \ | 391 | "Numbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024),\n" \ |
388 | "MD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)" | 392 | "MD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)" |
diff --git a/patches/dd_ibs_and_obs.diff b/patches/dd_ibs_and_obs.diff deleted file mode 100644 index 3bbf4b989..000000000 --- a/patches/dd_ibs_and_obs.diff +++ /dev/null | |||
@@ -1,252 +0,0 @@ | |||
1 | This patch adds support of ibs= and obs= to dd. | ||
2 | ---- | ||
3 | Hideki IWAMOTO h-iwamoto@kit.hi-ho.ne.jp | ||
4 | |||
5 | |||
6 | --- a/include/usage.h 29 Mar 2004 08:20:08 -0000 1.198 | ||
7 | +++ b/include/usage.h 4 Apr 2004 07:15:21 -0000 | ||
8 | @@ -309,13 +309,15 @@ | ||
9 | "64\n" | ||
10 | |||
11 | #define dd_trivial_usage \ | ||
12 | - "[if=FILE] [of=FILE] [bs=N] [count=N] [skip=N]\n" \ | ||
13 | - "\t [seek=N] [conv=notrunc|noerror|sync]" | ||
14 | + "[if=FILE] [of=FILE] [ibs=N] [obs=N] [bs=N] [count=N]\n" \ | ||
15 | + "\t [skip=N] [seek=N] [conv=notrunc|noerror|sync]" | ||
16 | #define dd_full_usage \ | ||
17 | "Copy a file, converting and formatting according to options\n\n" \ | ||
18 | "\tif=FILE\t\tread from FILE instead of stdin\n" \ | ||
19 | "\tof=FILE\t\twrite to FILE instead of stdout\n" \ | ||
20 | - "\tbs=N\t\tread and write N bytes at a time\n" \ | ||
21 | + "\tibs=N\t\tread N bytes at a time\n" \ | ||
22 | + "\tobs=N\t\twrite N bytes at a time\n" \ | ||
23 | + "\tbs=N\t\tforce ibs=N and obs=N\n" \ | ||
24 | "\tcount=N\t\tcopy only N input blocks\n" \ | ||
25 | "\tskip=N\t\tskip N input blocks\n" \ | ||
26 | "\tseek=N\t\tskip N output blocks\n" \ | ||
27 | @@ -323,6 +325,8 @@ | ||
28 | "\tconv=noerror\tcontinue after read errors\n" \ | ||
29 | "\tconv=sync\tpad blocks with zeros\n" \ | ||
30 | "\n" \ | ||
31 | + "If the bs= expr operand is not specified, the input is processed and collected\n" \ | ||
32 | + "into full-sized output blocks until the end of the input is reached.\n" \ | ||
33 | "Numbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024),\n" \ | ||
34 | "MD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)." | ||
35 | #define dd_example_usage \ | ||
36 | --- a/coreutils/dd.c 30 Jan 2004 22:24:32 -0000 1.55 | ||
37 | +++ b/coreutils/dd.c 4 Apr 2004 07:15:21 -0000 | ||
38 | @@ -30,6 +30,10 @@ | ||
39 | #include <fcntl.h> | ||
40 | #include "busybox.h" | ||
41 | |||
42 | +#define C_NOERROR 0x0001 | ||
43 | +#define C_TRUNC 0x0002 | ||
44 | +#define C_SYNC 0x0004 | ||
45 | +#define C_TWOBUFS 0x0008 | ||
46 | |||
47 | static const struct suffix_mult dd_suffixes[] = { | ||
48 | { "c", 1 }, | ||
49 | @@ -51,13 +55,13 @@ | ||
50 | size_t in_full = 0; | ||
51 | size_t in_part = 0; | ||
52 | size_t count = -1; | ||
53 | - size_t bs = 512; | ||
54 | + size_t ibs = 512; | ||
55 | + size_t obs = 512; | ||
56 | + size_t oc = 0; | ||
57 | ssize_t n; | ||
58 | off_t seek = 0; | ||
59 | off_t skip = 0; | ||
60 | - int sync_flag = FALSE; | ||
61 | - int noerror = FALSE; | ||
62 | - int trunc_flag = TRUE; | ||
63 | + unsigned int dd_flags = C_TWOBUFS | C_TRUNC; | ||
64 | int oflag; | ||
65 | int ifd; | ||
66 | int ofd; | ||
67 | @@ -65,11 +69,18 @@ | ||
68 | const char *infile = NULL; | ||
69 | const char *outfile = NULL; | ||
70 | char *buf; | ||
71 | + char *ibuf; | ||
72 | + char *obuf; | ||
73 | |||
74 | for (i = 1; i < argc; i++) { | ||
75 | - if (strncmp("bs=", argv[i], 3) == 0) | ||
76 | - bs = bb_xparse_number(argv[i]+3, dd_suffixes); | ||
77 | - else if (strncmp("count=", argv[i], 6) == 0) | ||
78 | + if (strncmp("ibs=", argv[i], 4) == 0) | ||
79 | + ibs = bb_xparse_number(argv[i]+4, dd_suffixes); | ||
80 | + else if (strncmp("obs=", argv[i], 4) == 0) | ||
81 | + obs = bb_xparse_number(argv[i]+4, dd_suffixes); | ||
82 | + else if (strncmp("bs=", argv[i], 3) == 0) { | ||
83 | + ibs = obs = bb_xparse_number(argv[i]+3, dd_suffixes); | ||
84 | + dd_flags &= ~C_TWOBUFS; | ||
85 | + } else if (strncmp("count=", argv[i], 6) == 0) | ||
86 | count = bb_xparse_number(argv[i]+6, dd_suffixes); | ||
87 | else if (strncmp("seek=", argv[i], 5) == 0) | ||
88 | seek = bb_xparse_number(argv[i]+5, dd_suffixes); | ||
89 | @@ -83,13 +94,13 @@ | ||
90 | buf = argv[i]+5; | ||
91 | while (1) { | ||
92 | if (strncmp("notrunc", buf, 7) == 0) { | ||
93 | - trunc_flag = FALSE; | ||
94 | + dd_flags &= ~C_TRUNC; | ||
95 | buf += 7; | ||
96 | } else if (strncmp("sync", buf, 4) == 0) { | ||
97 | - sync_flag = TRUE; | ||
98 | + dd_flags |= C_SYNC; | ||
99 | buf += 4; | ||
100 | } else if (strncmp("noerror", buf, 7) == 0) { | ||
101 | - noerror = TRUE; | ||
102 | + dd_flags |= C_NOERROR; | ||
103 | buf += 7; | ||
104 | } else { | ||
105 | bb_error_msg_and_die("invalid conversion `%s'", argv[i]+5); | ||
106 | @@ -103,7 +114,12 @@ | ||
107 | bb_show_usage(); | ||
108 | } | ||
109 | |||
110 | - buf = xmalloc(bs); | ||
111 | + ibuf = xmalloc(ibs); | ||
112 | + | ||
113 | + if (dd_flags & C_TWOBUFS) | ||
114 | + obuf = xmalloc(obs); | ||
115 | + else | ||
116 | + obuf = ibuf; | ||
117 | |||
118 | if (infile != NULL) { | ||
119 | ifd = bb_xopen(infile, O_RDONLY); | ||
120 | @@ -115,7 +131,7 @@ | ||
121 | if (outfile != NULL) { | ||
122 | oflag = O_WRONLY | O_CREAT; | ||
123 | |||
124 | - if (!seek && trunc_flag) { | ||
125 | + if (!seek && (dd_flags & C_TRUNC)) { | ||
126 | oflag |= O_TRUNC; | ||
127 | } | ||
128 | |||
129 | @@ -123,8 +139,8 @@ | ||
130 | bb_perror_msg_and_die("%s", outfile); | ||
131 | } | ||
132 | |||
133 | - if (seek && trunc_flag) { | ||
134 | - if (ftruncate(ofd, seek * bs) < 0) { | ||
135 | + if (seek && (dd_flags & C_TRUNC)) { | ||
136 | + if (ftruncate(ofd, seek * obs) < 0) { | ||
137 | struct stat st; | ||
138 | |||
139 | if (fstat (ofd, &st) < 0 || S_ISREG (st.st_mode) || | ||
140 | @@ -139,52 +155,88 @@ | ||
141 | } | ||
142 | |||
143 | if (skip) { | ||
144 | - if (lseek(ifd, skip * bs, SEEK_CUR) < 0) { | ||
145 | - bb_perror_msg_and_die("%s", infile); | ||
146 | + if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) { | ||
147 | + while (skip-- > 0) { | ||
148 | + n = safe_read(ifd, ibuf, ibs); | ||
149 | + if (n < 0) | ||
150 | + bb_perror_msg_and_die("%s", infile); | ||
151 | + if (n == 0) | ||
152 | + break; | ||
153 | + } | ||
154 | } | ||
155 | } | ||
156 | |||
157 | if (seek) { | ||
158 | - if (lseek(ofd, seek * bs, SEEK_CUR) < 0) { | ||
159 | + if (lseek(ofd, seek * obs, SEEK_CUR) < 0) { | ||
160 | bb_perror_msg_and_die("%s", outfile); | ||
161 | } | ||
162 | } | ||
163 | |||
164 | while (in_full + in_part != count) { | ||
165 | - if (noerror) { | ||
166 | + if (dd_flags & C_NOERROR) { | ||
167 | /* Pre-zero the buffer when doing the noerror thing */ | ||
168 | - memset(buf, '\0', bs); | ||
169 | + memset(ibuf, '\0', ibs); | ||
170 | + } | ||
171 | + | ||
172 | + n = safe_read(ifd, ibuf, ibs); | ||
173 | + if (n == 0) { | ||
174 | + break; | ||
175 | } | ||
176 | - n = safe_read(ifd, buf, bs); | ||
177 | if (n < 0) { | ||
178 | - if (noerror) { | ||
179 | - n = bs; | ||
180 | + if (dd_flags & C_NOERROR) { | ||
181 | + n = ibs; | ||
182 | bb_perror_msg("%s", infile); | ||
183 | } else { | ||
184 | bb_perror_msg_and_die("%s", infile); | ||
185 | } | ||
186 | } | ||
187 | - if (n == 0) { | ||
188 | - break; | ||
189 | - } | ||
190 | - if (n == bs) { | ||
191 | + if (n == ibs) { | ||
192 | in_full++; | ||
193 | } else { | ||
194 | in_part++; | ||
195 | + if (dd_flags & C_SYNC) { | ||
196 | + memset(ibuf + n, '\0', ibs - n); | ||
197 | + n = ibs; | ||
198 | + } | ||
199 | } | ||
200 | - if (sync_flag) { | ||
201 | - memset(buf + n, '\0', bs - n); | ||
202 | - n = bs; | ||
203 | + | ||
204 | + if (dd_flags & C_TWOBUFS) { | ||
205 | + size_t d; | ||
206 | + char *tmp = ibuf; | ||
207 | + | ||
208 | + while (n) { | ||
209 | + d = obs - oc; | ||
210 | + if (d > n) | ||
211 | + d = n; | ||
212 | + memcpy(obuf + oc, tmp, d); | ||
213 | + n -= d; | ||
214 | + tmp += d; | ||
215 | + oc += d; | ||
216 | + if (oc == obs) { | ||
217 | + if (bb_full_write(ofd, obuf, obs) < 0) { | ||
218 | + bb_perror_msg_and_die("%s", outfile); | ||
219 | + } | ||
220 | + out_full++; | ||
221 | + oc = 0; | ||
222 | + } | ||
223 | + } | ||
224 | + } else { | ||
225 | + if (bb_full_write(ofd, ibuf, n) < 0) { | ||
226 | + bb_perror_msg_and_die("%s", outfile); | ||
227 | + } | ||
228 | + if (n == ibs) { | ||
229 | + out_full++; | ||
230 | + } else { | ||
231 | + out_part++; | ||
232 | + } | ||
233 | } | ||
234 | - n = bb_full_write(ofd, buf, n); | ||
235 | - if (n < 0) { | ||
236 | + } | ||
237 | + | ||
238 | + if (oc) { | ||
239 | + if (bb_full_write(ofd, obuf, oc) < 0) { | ||
240 | bb_perror_msg_and_die("%s", outfile); | ||
241 | } | ||
242 | - if (n == bs) { | ||
243 | - out_full++; | ||
244 | - } else { | ||
245 | - out_part++; | ||
246 | - } | ||
247 | + out_part++; | ||
248 | } | ||
249 | |||
250 | if (close (ifd) < 0) { | ||
251 | |||
252 | |||