dd: fix bug where we assume count=INT_MAX when count is unspecified;
shrink dd while at it function old new delta dd_main 1453 1368 -85 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-85) Total: -85 bytes text data bss dec hex filename 669216 2668 13616 685500 a75bc busybox_old 669128 2668 13616 685412 a7564 busybox_unstripped
This commit is contained in:
parent
1d10aaf116
commit
7587870617
@ -32,6 +32,9 @@ struct globals {
|
||||
off_t out_full, out_part, in_full, in_part;
|
||||
};
|
||||
#define G (*(struct globals*)&bb_common_bufsiz1)
|
||||
/* We have to zero it out because of NOEXEC */
|
||||
#define INIT_G() memset(&G, 0, sizeof(G))
|
||||
|
||||
|
||||
static void dd_output_status(int ATTRIBUTE_UNUSED cur_signal)
|
||||
{
|
||||
@ -73,10 +76,11 @@ 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,
|
||||
FLAG_SYNC = 1 << 0,
|
||||
FLAG_NOERROR = 1 << 1,
|
||||
FLAG_NOTRUNC = 1 << 2,
|
||||
FLAG_TWOBUFS = 1 << 3,
|
||||
FLAG_COUNT = 1 << 4,
|
||||
};
|
||||
static const char keywords[] =
|
||||
"bs=\0""count=\0""seek=\0""skip=\0""if=\0""of=\0"
|
||||
@ -100,25 +104,41 @@ int dd_main(int argc, char **argv)
|
||||
OP_conv_noerror,
|
||||
#endif
|
||||
};
|
||||
int flags = TRUNC_FLAG;
|
||||
size_t oc = 0, ibs = 512, obs = 512;
|
||||
size_t ibs = 512, obs = 512;
|
||||
ssize_t n, w;
|
||||
off_t seek = 0, skip = 0, count = OFF_T_MAX;
|
||||
int ifd, ofd;
|
||||
const char *infile = NULL, *outfile = NULL;
|
||||
char *ibuf, *obuf;
|
||||
/* And these are all zeroed at once! */
|
||||
struct {
|
||||
int flags;
|
||||
int ifd, ofd;
|
||||
size_t oc;
|
||||
off_t count;
|
||||
off_t seek, skip;
|
||||
const char *infile, *outfile;
|
||||
#if ENABLE_FEATURE_DD_SIGNAL_HANDLING
|
||||
struct sigaction sigact;
|
||||
#endif
|
||||
} Z;
|
||||
#define flags (Z.flags )
|
||||
#define ifd (Z.ifd )
|
||||
#define ofd (Z.ofd )
|
||||
#define oc (Z.oc )
|
||||
#define count (Z.count )
|
||||
#define seek (Z.seek )
|
||||
#define skip (Z.skip )
|
||||
#define infile (Z.infile )
|
||||
#define outfile (Z.outfile)
|
||||
#define sigact (Z.sigact )
|
||||
|
||||
memset(&G, 0, sizeof(G)); /* because of NOEXEC */
|
||||
memset(&Z, 0, sizeof(Z));
|
||||
INIT_G();
|
||||
|
||||
if (ENABLE_FEATURE_DD_SIGNAL_HANDLING) {
|
||||
struct sigaction sa;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_handler = dd_output_status;
|
||||
sa.sa_flags = SA_RESTART;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sigaction(SIGUSR1, &sa, 0);
|
||||
}
|
||||
#if ENABLE_FEATURE_DD_SIGNAL_HANDLING
|
||||
sigact.sa_handler = dd_output_status;
|
||||
sigact.sa_flags = SA_RESTART;
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigaction(SIGUSR1, &sigact, NULL);
|
||||
#endif
|
||||
|
||||
for (n = 1; n < argc; n++) {
|
||||
smalluint key_len;
|
||||
@ -162,11 +182,11 @@ int dd_main(int argc, char **argv)
|
||||
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 |= FLAG_NOTRUNC;
|
||||
if (what == OP_conv_sync)
|
||||
flags |= SYNC_FLAG;
|
||||
flags |= FLAG_SYNC;
|
||||
if (what == OP_conv_noerror)
|
||||
flags |= NOERROR;
|
||||
flags |= FLAG_NOERROR;
|
||||
if (!key) /* no ',' left, so this was the last specifier */
|
||||
break;
|
||||
arg = key + 1; /* skip this keyword and ',' */
|
||||
@ -180,6 +200,7 @@ int dd_main(int argc, char **argv)
|
||||
}
|
||||
/* These can be large: */
|
||||
if (what == OP_count) {
|
||||
flags |= FLAG_COUNT;
|
||||
count = XATOU_SFX(arg, dd_suffixes);
|
||||
continue;
|
||||
}
|
||||
@ -201,24 +222,24 @@ 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 |= FLAG_TWOBUFS;
|
||||
obuf = xmalloc(obs);
|
||||
}
|
||||
if (infile != NULL)
|
||||
ifd = xopen(infile, O_RDONLY);
|
||||
else {
|
||||
ifd = STDIN_FILENO;
|
||||
/* ifd = STDIN_FILENO; - it's zero and it's already there */
|
||||
infile = bb_msg_standard_input;
|
||||
}
|
||||
if (outfile != NULL) {
|
||||
int oflag = O_WRONLY | O_CREAT;
|
||||
|
||||
if (!seek && (flags & TRUNC_FLAG))
|
||||
if (!seek && !(flags & FLAG_NOTRUNC))
|
||||
oflag |= O_TRUNC;
|
||||
|
||||
ofd = xopen(outfile, oflag);
|
||||
|
||||
if (seek && (flags & TRUNC_FLAG)) {
|
||||
if (seek && !(flags & FLAG_NOTRUNC)) {
|
||||
if (ftruncate(ofd, seek * obs) < 0) {
|
||||
struct stat st;
|
||||
|
||||
@ -247,14 +268,14 @@ int dd_main(int argc, char **argv)
|
||||
goto die_outfile;
|
||||
}
|
||||
|
||||
while (G.in_full + G.in_part != count) {
|
||||
if (flags & NOERROR) /* Pre-zero the buffer when for NOERROR */
|
||||
memset(ibuf, '\0', ibs);
|
||||
while ((flags & FLAG_COUNT) && (G.in_full + G.in_part != count)) {
|
||||
if (flags & FLAG_NOERROR) /* Pre-zero the buffer if conv=noerror */
|
||||
memset(ibuf, 0, ibs);
|
||||
n = safe_read(ifd, ibuf, ibs);
|
||||
if (n == 0)
|
||||
break;
|
||||
if (n < 0) {
|
||||
if (flags & NOERROR) {
|
||||
if (flags & FLAG_NOERROR) {
|
||||
n = ibs;
|
||||
bb_perror_msg("%s", infile);
|
||||
} else
|
||||
@ -264,12 +285,12 @@ int dd_main(int argc, char **argv)
|
||||
G.in_full++;
|
||||
else {
|
||||
G.in_part++;
|
||||
if (flags & SYNC_FLAG) {
|
||||
if (flags & FLAG_SYNC) {
|
||||
memset(ibuf + n, '\0', ibs - n);
|
||||
n = ibs;
|
||||
}
|
||||
}
|
||||
if (flags & TWOBUFS_FLAG) {
|
||||
if (flags & FLAG_TWOBUFS) {
|
||||
char *tmp = ibuf;
|
||||
while (n) {
|
||||
size_t d = obs - oc;
|
||||
|
Loading…
x
Reference in New Issue
Block a user