dd: fix skip= parse error (spotted by Dirk Clemens <develop@cle-mens.de>)
authorDenis Vlasenko <vda.linux@googlemail.com>
Thu, 19 Apr 2007 20:08:19 +0000 (20:08 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Thu, 19 Apr 2007 20:08:19 +0000 (20:08 -0000)
coreutils/dd.c
shell/README.job

index 8b374aa8bc039bce6f89fd4e648f8f187e4cd3b8..797aabdd931ad1ecca395ad743a0987a34db8acd 100644 (file)
@@ -58,7 +58,7 @@ static bool write_and_stats(int fd, const void *buf, size_t len, size_t obs,
                return 1;
        if (n == obs)
                G.out_full++;
-       else if (n > 0)
+       else if (n) /* > 0 */
                G.out_part++;
        return 0;
 }
@@ -73,10 +73,10 @@ int dd_main(int argc, char **argv);
 int dd_main(int argc, char **argv)
 {
        enum {
-               sync_flag    = 1 << 0,
-               noerror      = 1 << 1,
-               trunc_flag   = 1 << 2,
-               twobufs_flag = 1 << 3,
+               SYNC_FLAG    = 1 << 0,
+               NOERROR      = 1 << 1,
+               TRUNC_FLAG   = 1 << 2,
+               TWOBUFS_FLAG = 1 << 3,
        };
        static const char * const keywords[] = {
                "bs=", "count=", "seek=", "skip=", "if=", "of=",
@@ -98,10 +98,10 @@ int dd_main(int argc, char **argv)
                OP_conv,
                OP_conv_notrunc,
                OP_conv_sync,
-               OP_conv_noerror,
+               OP_conv_NOERROR,
 #endif
        };
-       int flags = trunc_flag;
+       int flags = TRUNC_FLAG;
        size_t oc = 0, ibs = 512, obs = 512;
        ssize_t n, w;
        off_t seek = 0, skip = 0, count = OFF_T_MAX;
@@ -152,23 +152,23 @@ int dd_main(int argc, char **argv)
                                while (1) {
                                        /* find ',', replace them with nil so we can use arg for
                                         * index_in_str_array without copying.
-                                        * We rely on arg being non-null, else strstr would fault.
+                                        * We rely on arg being non-null, else strchr would fault.
                                         */
-                                       key = strstr(arg, ",");
+                                       key = strchr(arg, ',');
                                        if (key)
                                                *key = '\0';
                                        what = index_in_str_array(keywords, arg) + 1;
                                        if (what < OP_conv_notrunc)
                                                bb_error_msg_and_die(bb_msg_invalid_arg, arg, "conv");
                                        if (what == OP_conv_notrunc)
-                                               flags &= ~trunc_flag;
+                                               flags &= ~TRUNC_FLAG;
                                        if (what == OP_conv_sync)
-                                               flags |= sync_flag;
-                                       if (what == OP_conv_noerror)
-                                               flags |= noerror;
+                                               flags |= SYNC_FLAG;
+                                       if (what == OP_conv_NOERROR)
+                                               flags |= NOERROR;
                                        if (!key) /* no ',' left, so this was the last specifier */
                                                break;
-                                       arg += key - arg + 1; /* skip this keyword plus ',' */
+                                       arg = key + 1; /* skip this keyword and ',' */
                                }
                                continue;
                        }
@@ -186,7 +186,7 @@ int dd_main(int argc, char **argv)
                        seek = XATOU_SFX(arg, dd_suffixes);
                        continue;
                }
-               if (what == skip) {
+               if (what == OP_skip) {
                        skip = XATOU_SFX(arg, dd_suffixes);
                        continue;
                }
@@ -200,7 +200,7 @@ int dd_main(int argc, char **argv)
 //XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever
        ibuf = obuf = xmalloc(ibs);
        if (ibs != obs) {
-               flags |= twobufs_flag;
+               flags |= TWOBUFS_FLAG;
                obuf = xmalloc(obs);
        }
        if (infile != NULL)
@@ -212,12 +212,12 @@ int dd_main(int argc, char **argv)
        if (outfile != NULL) {
                int oflag = O_WRONLY | O_CREAT;
 
-               if (!seek && (flags & trunc_flag))
+               if (!seek && (flags & TRUNC_FLAG))
                        oflag |= O_TRUNC;
 
                ofd = xopen(outfile, oflag);
 
-               if (seek && (flags & trunc_flag)) {
+               if (seek && (flags & TRUNC_FLAG)) {
                        if (ftruncate(ofd, seek * obs) < 0) {
                                struct stat st;
 
@@ -247,13 +247,13 @@ int dd_main(int argc, char **argv)
        }
 
        while (G.in_full + G.in_part != count) {
-               if (flags & noerror) /* Pre-zero the buffer when for noerror */
+               if (flags & NOERROR) /* Pre-zero the buffer when for NOERROR */
                        memset(ibuf, '\0', ibs);
                n = safe_read(ifd, ibuf, ibs);
                if (n == 0)
                        break;
                if (n < 0) {
-                       if (flags & noerror) {
+                       if (flags & NOERROR) {
                                n = ibs;
                                bb_perror_msg("%s", infile);
                        } else
@@ -263,12 +263,12 @@ int dd_main(int argc, char **argv)
                        G.in_full++;
                else {
                        G.in_part++;
-                       if (flags & sync_flag) {
+                       if (flags & SYNC_FLAG) {
                                memset(ibuf + n, '\0', ibs - n);
                                n = ibs;
                        }
                }
-               if (flags & twobufs_flag) {
+               if (flags & TWOBUFS_FLAG) {
                        char *tmp = ibuf;
                        while (n) {
                                size_t d = obs - oc;
@@ -285,9 +285,8 @@ int dd_main(int argc, char **argv)
                                        oc = 0;
                                }
                        }
-               } else
-                       if (write_and_stats(ofd, ibuf, n, obs, outfile))
-                               goto out_status;
+               } else if (write_and_stats(ofd, ibuf, n, obs, outfile))
+                       goto out_status;
        }
 
        if (ENABLE_FEATURE_DD_IBS_OBS && oc) {
index b29d3158825eed3bb40bd5067433bf993f51d81f..7e262b4898e2fc1a9ab77f60a6313ffe09f61f09 100644 (file)
@@ -2,8 +2,12 @@ strace of "sleep 1 | sleep 2" being run from interactive bash 3.0
 
 
 Synopsis:
+open /dev/tty [, if fails, open ttyname(0)]; close /* helps re-establish ctty */
 get current signal mask
-install default handlers for GHLD QUIT TERM
+TCGETS on fd# 0
+TCGETS on fd# 2 /* NB: if returns ENOTTY (2>/dev/null), sh seems to disable job control,
+                   does not show prompt, but still executes cmds from fd# 0 */
+install default handlers for CHLD QUIT TERM
 install common handler for HUP INT ILL TRAP ABRT FPE BUS SEGV SYS PIPE ALRM TERM XCPU XFSZ VTALRM USR1 USR2
 ignore QUIT
 install handler for INT
@@ -34,11 +38,73 @@ get our pprocess group
     signal followed by a SIGCONT signal will be sent to each process
     in the newly-orphaned process group.
 ...
-
+dup stderr to fd# 255
+move ourself to our own process group
+block CHLD TSTP TTIN TTOU
+set tty's (255, stderr's) foreground process group to our group
+allow all signals
+mark 255 CLOEXEC
+set CHLD handler
+get signal mask
+get fd#0 flags
+get signal mask
+set INT handler
+block CHLD TSTP TTIN TTOU
+set fd #255 foreground process group to our group
+allow all signals
+set INT handler
+block all signals
+allow all signals
+block INT
+allow all signals
+lotsa sigactions: set INT,ALRM,WINCH handlers, ignore TERM,QUIT,TSTP,TTOU,TTIN
+block all signals
+allow all signals
+block all signals
+allow all signals
+block all signals
+allow all signals
+read "sleep 1 | sleep 2\n"
+block INT
+TCSETSW on fd# 0
+allow all signals
+lotsa sigactions: set INT,ALRM,WINCH handlers, ignore TERM,QUIT,TSTP,TTOU,TTIN
+block CHLD
+pipe([4, 5])  /* oops seems I lost another pipe() in editing... */
+fork child #1
+put child in it's own process group
+block only CHLD
+close(5)
+block only INT CHLD
+fork child #2
+put child in the same process group as first one
+block only CHLD
+close(4)
+block only CHLD
+block only CHLD TSTP TTIN TTOU
+set fd# 255 foreground process group to first child's one
+block only CHLD
+block only CHLD
+block only CHLD
+wait4 for children to die or stop - first child exits
+wait4 for children to die or stop - second child exits
+block CHLD TSTP TTIN TTOU
+set fd# 255 foreground process group to our own one
+block only CHLD
+block only CHLD
+block nothing
+--- SIGCHLD (Child exited) @ 0 (0) ---
+    wait for it - no child (already waited for)
+    sigreturn()
+read signal mask
+lotsa sigactions...
+read next command
 
 
 execve("/bin/sh", ["sh"], [/* 34 vars */]) = 0
 rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
+ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
+ioctl(2, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
 rt_sigaction(SIGCHLD, {SIG_DFL}, {SIG_DFL}, 8) = 0
 rt_sigaction(SIGQUIT, {SIG_DFL}, {SIG_DFL}, 8) = 0
 rt_sigaction(SIGTERM, {SIG_DFL}, {SIG_DFL}, 8) = 0