dd: fix skip= parse error (spotted by Dirk Clemens <develop@cle-mens.de>)
This commit is contained in:
parent
9ace613406
commit
d1801a4430
@ -58,7 +58,7 @@ static bool write_and_stats(int fd, const void *buf, size_t len, size_t obs,
|
|||||||
return 1;
|
return 1;
|
||||||
if (n == obs)
|
if (n == obs)
|
||||||
G.out_full++;
|
G.out_full++;
|
||||||
else if (n > 0)
|
else if (n) /* > 0 */
|
||||||
G.out_part++;
|
G.out_part++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -73,10 +73,10 @@ int dd_main(int argc, char **argv);
|
|||||||
int dd_main(int argc, char **argv)
|
int dd_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
sync_flag = 1 << 0,
|
SYNC_FLAG = 1 << 0,
|
||||||
noerror = 1 << 1,
|
NOERROR = 1 << 1,
|
||||||
trunc_flag = 1 << 2,
|
TRUNC_FLAG = 1 << 2,
|
||||||
twobufs_flag = 1 << 3,
|
TWOBUFS_FLAG = 1 << 3,
|
||||||
};
|
};
|
||||||
static const char * const keywords[] = {
|
static const char * const keywords[] = {
|
||||||
"bs=", "count=", "seek=", "skip=", "if=", "of=",
|
"bs=", "count=", "seek=", "skip=", "if=", "of=",
|
||||||
@ -98,10 +98,10 @@ int dd_main(int argc, char **argv)
|
|||||||
OP_conv,
|
OP_conv,
|
||||||
OP_conv_notrunc,
|
OP_conv_notrunc,
|
||||||
OP_conv_sync,
|
OP_conv_sync,
|
||||||
OP_conv_noerror,
|
OP_conv_NOERROR,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
int flags = trunc_flag;
|
int flags = TRUNC_FLAG;
|
||||||
size_t oc = 0, ibs = 512, obs = 512;
|
size_t oc = 0, ibs = 512, obs = 512;
|
||||||
ssize_t n, w;
|
ssize_t n, w;
|
||||||
off_t seek = 0, skip = 0, count = OFF_T_MAX;
|
off_t seek = 0, skip = 0, count = OFF_T_MAX;
|
||||||
@ -152,23 +152,23 @@ int dd_main(int argc, char **argv)
|
|||||||
while (1) {
|
while (1) {
|
||||||
/* find ',', replace them with nil so we can use arg for
|
/* find ',', replace them with nil so we can use arg for
|
||||||
* index_in_str_array without copying.
|
* 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)
|
if (key)
|
||||||
*key = '\0';
|
*key = '\0';
|
||||||
what = index_in_str_array(keywords, arg) + 1;
|
what = index_in_str_array(keywords, arg) + 1;
|
||||||
if (what < OP_conv_notrunc)
|
if (what < OP_conv_notrunc)
|
||||||
bb_error_msg_and_die(bb_msg_invalid_arg, arg, "conv");
|
bb_error_msg_and_die(bb_msg_invalid_arg, arg, "conv");
|
||||||
if (what == OP_conv_notrunc)
|
if (what == OP_conv_notrunc)
|
||||||
flags &= ~trunc_flag;
|
flags &= ~TRUNC_FLAG;
|
||||||
if (what == OP_conv_sync)
|
if (what == OP_conv_sync)
|
||||||
flags |= sync_flag;
|
flags |= SYNC_FLAG;
|
||||||
if (what == OP_conv_noerror)
|
if (what == OP_conv_NOERROR)
|
||||||
flags |= noerror;
|
flags |= NOERROR;
|
||||||
if (!key) /* no ',' left, so this was the last specifier */
|
if (!key) /* no ',' left, so this was the last specifier */
|
||||||
break;
|
break;
|
||||||
arg += key - arg + 1; /* skip this keyword plus ',' */
|
arg = key + 1; /* skip this keyword and ',' */
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -186,7 +186,7 @@ int dd_main(int argc, char **argv)
|
|||||||
seek = XATOU_SFX(arg, dd_suffixes);
|
seek = XATOU_SFX(arg, dd_suffixes);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (what == skip) {
|
if (what == OP_skip) {
|
||||||
skip = XATOU_SFX(arg, dd_suffixes);
|
skip = XATOU_SFX(arg, dd_suffixes);
|
||||||
continue;
|
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
|
//XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever
|
||||||
ibuf = obuf = xmalloc(ibs);
|
ibuf = obuf = xmalloc(ibs);
|
||||||
if (ibs != obs) {
|
if (ibs != obs) {
|
||||||
flags |= twobufs_flag;
|
flags |= TWOBUFS_FLAG;
|
||||||
obuf = xmalloc(obs);
|
obuf = xmalloc(obs);
|
||||||
}
|
}
|
||||||
if (infile != NULL)
|
if (infile != NULL)
|
||||||
@ -212,12 +212,12 @@ int dd_main(int argc, char **argv)
|
|||||||
if (outfile != NULL) {
|
if (outfile != NULL) {
|
||||||
int oflag = O_WRONLY | O_CREAT;
|
int oflag = O_WRONLY | O_CREAT;
|
||||||
|
|
||||||
if (!seek && (flags & trunc_flag))
|
if (!seek && (flags & TRUNC_FLAG))
|
||||||
oflag |= O_TRUNC;
|
oflag |= O_TRUNC;
|
||||||
|
|
||||||
ofd = xopen(outfile, oflag);
|
ofd = xopen(outfile, oflag);
|
||||||
|
|
||||||
if (seek && (flags & trunc_flag)) {
|
if (seek && (flags & TRUNC_FLAG)) {
|
||||||
if (ftruncate(ofd, seek * obs) < 0) {
|
if (ftruncate(ofd, seek * obs) < 0) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
@ -247,13 +247,13 @@ int dd_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (G.in_full + G.in_part != count) {
|
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);
|
memset(ibuf, '\0', ibs);
|
||||||
n = safe_read(ifd, ibuf, ibs);
|
n = safe_read(ifd, ibuf, ibs);
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
break;
|
break;
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
if (flags & noerror) {
|
if (flags & NOERROR) {
|
||||||
n = ibs;
|
n = ibs;
|
||||||
bb_perror_msg("%s", infile);
|
bb_perror_msg("%s", infile);
|
||||||
} else
|
} else
|
||||||
@ -263,12 +263,12 @@ int dd_main(int argc, char **argv)
|
|||||||
G.in_full++;
|
G.in_full++;
|
||||||
else {
|
else {
|
||||||
G.in_part++;
|
G.in_part++;
|
||||||
if (flags & sync_flag) {
|
if (flags & SYNC_FLAG) {
|
||||||
memset(ibuf + n, '\0', ibs - n);
|
memset(ibuf + n, '\0', ibs - n);
|
||||||
n = ibs;
|
n = ibs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flags & twobufs_flag) {
|
if (flags & TWOBUFS_FLAG) {
|
||||||
char *tmp = ibuf;
|
char *tmp = ibuf;
|
||||||
while (n) {
|
while (n) {
|
||||||
size_t d = obs - oc;
|
size_t d = obs - oc;
|
||||||
@ -285,9 +285,8 @@ int dd_main(int argc, char **argv)
|
|||||||
oc = 0;
|
oc = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else if (write_and_stats(ofd, ibuf, n, obs, outfile))
|
||||||
if (write_and_stats(ofd, ibuf, n, obs, outfile))
|
goto out_status;
|
||||||
goto out_status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ENABLE_FEATURE_DD_IBS_OBS && oc) {
|
if (ENABLE_FEATURE_DD_IBS_OBS && oc) {
|
||||||
|
@ -2,8 +2,12 @@ strace of "sleep 1 | sleep 2" being run from interactive bash 3.0
|
|||||||
|
|
||||||
|
|
||||||
Synopsis:
|
Synopsis:
|
||||||
|
open /dev/tty [, if fails, open ttyname(0)]; close /* helps re-establish ctty */
|
||||||
get current signal mask
|
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
|
install common handler for HUP INT ILL TRAP ABRT FPE BUS SEGV SYS PIPE ALRM TERM XCPU XFSZ VTALRM USR1 USR2
|
||||||
ignore QUIT
|
ignore QUIT
|
||||||
install handler for INT
|
install handler for INT
|
||||||
@ -34,11 +38,73 @@ get our pprocess group
|
|||||||
signal followed by a SIGCONT signal will be sent to each process
|
signal followed by a SIGCONT signal will be sent to each process
|
||||||
in the newly-orphaned process group.
|
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
|
execve("/bin/sh", ["sh"], [/* 34 vars */]) = 0
|
||||||
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 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(SIGCHLD, {SIG_DFL}, {SIG_DFL}, 8) = 0
|
||||||
rt_sigaction(SIGQUIT, {SIG_DFL}, {SIG_DFL}, 8) = 0
|
rt_sigaction(SIGQUIT, {SIG_DFL}, {SIG_DFL}, 8) = 0
|
||||||
rt_sigaction(SIGTERM, {SIG_DFL}, {SIG_DFL}, 8) = 0
|
rt_sigaction(SIGTERM, {SIG_DFL}, {SIG_DFL}, 8) = 0
|
||||||
|
Loading…
Reference in New Issue
Block a user