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 /coreutils/dd.c | |
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.
Diffstat (limited to 'coreutils/dd.c')
-rw-r--r-- | coreutils/dd.c | 139 |
1 files changed, 83 insertions, 56 deletions
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 | } |