aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coreutils/dd.c49
-rw-r--r--shell/README.job70
2 files changed, 92 insertions, 27 deletions
diff --git a/coreutils/dd.c b/coreutils/dd.c
index 8b374aa8b..797aabdd9 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -58,7 +58,7 @@ static bool write_and_stats(int fd, const void *buf, size_t len, size_t obs,
58 return 1; 58 return 1;
59 if (n == obs) 59 if (n == obs)
60 G.out_full++; 60 G.out_full++;
61 else if (n > 0) 61 else if (n) /* > 0 */
62 G.out_part++; 62 G.out_part++;
63 return 0; 63 return 0;
64} 64}
@@ -73,10 +73,10 @@ int dd_main(int argc, char **argv);
73int dd_main(int argc, char **argv) 73int dd_main(int argc, char **argv)
74{ 74{
75 enum { 75 enum {
76 sync_flag = 1 << 0, 76 SYNC_FLAG = 1 << 0,
77 noerror = 1 << 1, 77 NOERROR = 1 << 1,
78 trunc_flag = 1 << 2, 78 TRUNC_FLAG = 1 << 2,
79 twobufs_flag = 1 << 3, 79 TWOBUFS_FLAG = 1 << 3,
80 }; 80 };
81 static const char * const keywords[] = { 81 static const char * const keywords[] = {
82 "bs=", "count=", "seek=", "skip=", "if=", "of=", 82 "bs=", "count=", "seek=", "skip=", "if=", "of=",
@@ -98,10 +98,10 @@ int dd_main(int argc, char **argv)
98 OP_conv, 98 OP_conv,
99 OP_conv_notrunc, 99 OP_conv_notrunc,
100 OP_conv_sync, 100 OP_conv_sync,
101 OP_conv_noerror, 101 OP_conv_NOERROR,
102#endif 102#endif
103 }; 103 };
104 int flags = trunc_flag; 104 int flags = TRUNC_FLAG;
105 size_t oc = 0, ibs = 512, obs = 512; 105 size_t oc = 0, ibs = 512, obs = 512;
106 ssize_t n, w; 106 ssize_t n, w;
107 off_t seek = 0, skip = 0, count = OFF_T_MAX; 107 off_t seek = 0, skip = 0, count = OFF_T_MAX;
@@ -152,23 +152,23 @@ int dd_main(int argc, char **argv)
152 while (1) { 152 while (1) {
153 /* find ',', replace them with nil so we can use arg for 153 /* find ',', replace them with nil so we can use arg for
154 * index_in_str_array without copying. 154 * index_in_str_array without copying.
155 * We rely on arg being non-null, else strstr would fault. 155 * We rely on arg being non-null, else strchr would fault.
156 */ 156 */
157 key = strstr(arg, ","); 157 key = strchr(arg, ',');
158 if (key) 158 if (key)
159 *key = '\0'; 159 *key = '\0';
160 what = index_in_str_array(keywords, arg) + 1; 160 what = index_in_str_array(keywords, arg) + 1;
161 if (what < OP_conv_notrunc) 161 if (what < OP_conv_notrunc)
162 bb_error_msg_and_die(bb_msg_invalid_arg, arg, "conv"); 162 bb_error_msg_and_die(bb_msg_invalid_arg, arg, "conv");
163 if (what == OP_conv_notrunc) 163 if (what == OP_conv_notrunc)
164 flags &= ~trunc_flag; 164 flags &= ~TRUNC_FLAG;
165 if (what == OP_conv_sync) 165 if (what == OP_conv_sync)
166 flags |= sync_flag; 166 flags |= SYNC_FLAG;
167 if (what == OP_conv_noerror) 167 if (what == OP_conv_NOERROR)
168 flags |= noerror; 168 flags |= NOERROR;
169 if (!key) /* no ',' left, so this was the last specifier */ 169 if (!key) /* no ',' left, so this was the last specifier */
170 break; 170 break;
171 arg += key - arg + 1; /* skip this keyword plus ',' */ 171 arg = key + 1; /* skip this keyword and ',' */
172 } 172 }
173 continue; 173 continue;
174 } 174 }
@@ -186,7 +186,7 @@ int dd_main(int argc, char **argv)
186 seek = XATOU_SFX(arg, dd_suffixes); 186 seek = XATOU_SFX(arg, dd_suffixes);
187 continue; 187 continue;
188 } 188 }
189 if (what == skip) { 189 if (what == OP_skip) {
190 skip = XATOU_SFX(arg, dd_suffixes); 190 skip = XATOU_SFX(arg, dd_suffixes);
191 continue; 191 continue;
192 } 192 }
@@ -200,7 +200,7 @@ int dd_main(int argc, char **argv)
200//XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever 200//XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever
201 ibuf = obuf = xmalloc(ibs); 201 ibuf = obuf = xmalloc(ibs);
202 if (ibs != obs) { 202 if (ibs != obs) {
203 flags |= twobufs_flag; 203 flags |= TWOBUFS_FLAG;
204 obuf = xmalloc(obs); 204 obuf = xmalloc(obs);
205 } 205 }
206 if (infile != NULL) 206 if (infile != NULL)
@@ -212,12 +212,12 @@ int dd_main(int argc, char **argv)
212 if (outfile != NULL) { 212 if (outfile != NULL) {
213 int oflag = O_WRONLY | O_CREAT; 213 int oflag = O_WRONLY | O_CREAT;
214 214
215 if (!seek && (flags & trunc_flag)) 215 if (!seek && (flags & TRUNC_FLAG))
216 oflag |= O_TRUNC; 216 oflag |= O_TRUNC;
217 217
218 ofd = xopen(outfile, oflag); 218 ofd = xopen(outfile, oflag);
219 219
220 if (seek && (flags & trunc_flag)) { 220 if (seek && (flags & TRUNC_FLAG)) {
221 if (ftruncate(ofd, seek * obs) < 0) { 221 if (ftruncate(ofd, seek * obs) < 0) {
222 struct stat st; 222 struct stat st;
223 223
@@ -247,13 +247,13 @@ int dd_main(int argc, char **argv)
247 } 247 }
248 248
249 while (G.in_full + G.in_part != count) { 249 while (G.in_full + G.in_part != count) {
250 if (flags & noerror) /* Pre-zero the buffer when for noerror */ 250 if (flags & NOERROR) /* Pre-zero the buffer when for NOERROR */
251 memset(ibuf, '\0', ibs); 251 memset(ibuf, '\0', ibs);
252 n = safe_read(ifd, ibuf, ibs); 252 n = safe_read(ifd, ibuf, ibs);
253 if (n == 0) 253 if (n == 0)
254 break; 254 break;
255 if (n < 0) { 255 if (n < 0) {
256 if (flags & noerror) { 256 if (flags & NOERROR) {
257 n = ibs; 257 n = ibs;
258 bb_perror_msg("%s", infile); 258 bb_perror_msg("%s", infile);
259 } else 259 } else
@@ -263,12 +263,12 @@ int dd_main(int argc, char **argv)
263 G.in_full++; 263 G.in_full++;
264 else { 264 else {
265 G.in_part++; 265 G.in_part++;
266 if (flags & sync_flag) { 266 if (flags & SYNC_FLAG) {
267 memset(ibuf + n, '\0', ibs - n); 267 memset(ibuf + n, '\0', ibs - n);
268 n = ibs; 268 n = ibs;
269 } 269 }
270 } 270 }
271 if (flags & twobufs_flag) { 271 if (flags & TWOBUFS_FLAG) {
272 char *tmp = ibuf; 272 char *tmp = ibuf;
273 while (n) { 273 while (n) {
274 size_t d = obs - oc; 274 size_t d = obs - oc;
@@ -285,9 +285,8 @@ int dd_main(int argc, char **argv)
285 oc = 0; 285 oc = 0;
286 } 286 }
287 } 287 }
288 } else 288 } else if (write_and_stats(ofd, ibuf, n, obs, outfile))
289 if (write_and_stats(ofd, ibuf, n, obs, outfile)) 289 goto out_status;
290 goto out_status;
291 } 290 }
292 291
293 if (ENABLE_FEATURE_DD_IBS_OBS && oc) { 292 if (ENABLE_FEATURE_DD_IBS_OBS && oc) {
diff --git a/shell/README.job b/shell/README.job
index b29d31588..7e262b489 100644
--- a/shell/README.job
+++ b/shell/README.job
@@ -2,8 +2,12 @@ strace of "sleep 1 | sleep 2" being run from interactive bash 3.0
2 2
3 3
4Synopsis: 4Synopsis:
5open /dev/tty [, if fails, open ttyname(0)]; close /* helps re-establish ctty */
5get current signal mask 6get current signal mask
6install default handlers for GHLD QUIT TERM 7TCGETS on fd# 0
8TCGETS on fd# 2 /* NB: if returns ENOTTY (2>/dev/null), sh seems to disable job control,
9 does not show prompt, but still executes cmds from fd# 0 */
10install default handlers for CHLD QUIT TERM
7install common handler for HUP INT ILL TRAP ABRT FPE BUS SEGV SYS PIPE ALRM TERM XCPU XFSZ VTALRM USR1 USR2 11install common handler for HUP INT ILL TRAP ABRT FPE BUS SEGV SYS PIPE ALRM TERM XCPU XFSZ VTALRM USR1 USR2
8ignore QUIT 12ignore QUIT
9install handler for INT 13install handler for INT
@@ -34,11 +38,73 @@ get our pprocess group
34 signal followed by a SIGCONT signal will be sent to each process 38 signal followed by a SIGCONT signal will be sent to each process
35 in the newly-orphaned process group. 39 in the newly-orphaned process group.
36... 40...
37 41dup stderr to fd# 255
42move ourself to our own process group
43block CHLD TSTP TTIN TTOU
44set tty's (255, stderr's) foreground process group to our group
45allow all signals
46mark 255 CLOEXEC
47set CHLD handler
48get signal mask
49get fd#0 flags
50get signal mask
51set INT handler
52block CHLD TSTP TTIN TTOU
53set fd #255 foreground process group to our group
54allow all signals
55set INT handler
56block all signals
57allow all signals
58block INT
59allow all signals
60lotsa sigactions: set INT,ALRM,WINCH handlers, ignore TERM,QUIT,TSTP,TTOU,TTIN
61block all signals
62allow all signals
63block all signals
64allow all signals
65block all signals
66allow all signals
67read "sleep 1 | sleep 2\n"
68block INT
69TCSETSW on fd# 0
70allow all signals
71lotsa sigactions: set INT,ALRM,WINCH handlers, ignore TERM,QUIT,TSTP,TTOU,TTIN
72block CHLD
73pipe([4, 5]) /* oops seems I lost another pipe() in editing... */
74fork child #1
75put child in it's own process group
76block only CHLD
77close(5)
78block only INT CHLD
79fork child #2
80put child in the same process group as first one
81block only CHLD
82close(4)
83block only CHLD
84block only CHLD TSTP TTIN TTOU
85set fd# 255 foreground process group to first child's one
86block only CHLD
87block only CHLD
88block only CHLD
89wait4 for children to die or stop - first child exits
90wait4 for children to die or stop - second child exits
91block CHLD TSTP TTIN TTOU
92set fd# 255 foreground process group to our own one
93block only CHLD
94block only CHLD
95block nothing
96--- SIGCHLD (Child exited) @ 0 (0) ---
97 wait for it - no child (already waited for)
98 sigreturn()
99read signal mask
100lotsa sigactions...
101read next command
38 102
39 103
40execve("/bin/sh", ["sh"], [/* 34 vars */]) = 0 104execve("/bin/sh", ["sh"], [/* 34 vars */]) = 0
41rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0 105rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
106ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
107ioctl(2, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
42rt_sigaction(SIGCHLD, {SIG_DFL}, {SIG_DFL}, 8) = 0 108rt_sigaction(SIGCHLD, {SIG_DFL}, {SIG_DFL}, 8) = 0
43rt_sigaction(SIGQUIT, {SIG_DFL}, {SIG_DFL}, 8) = 0 109rt_sigaction(SIGQUIT, {SIG_DFL}, {SIG_DFL}, 8) = 0
44rt_sigaction(SIGTERM, {SIG_DFL}, {SIG_DFL}, 8) = 0 110rt_sigaction(SIGTERM, {SIG_DFL}, {SIG_DFL}, 8) = 0