diff options
-rw-r--r-- | toys/pending/dd.c | 67 |
1 files changed, 23 insertions, 44 deletions
diff --git a/toys/pending/dd.c b/toys/pending/dd.c index 2160e723..aebc90e8 100644 --- a/toys/pending/dd.c +++ b/toys/pending/dd.c @@ -7,7 +7,7 @@ * * todo: ctrl-c doesn't work, the read() is restarting. -USE_DD(NEWTOY(dd, NULL, TOYFLAG_USR|TOYFLAG_BIN)) +USE_DD(NEWTOY(dd, 0, TOYFLAG_USR|TOYFLAG_BIN)) config DD bool "dd" @@ -52,22 +52,10 @@ GLOBALS( } in, out; ); -#define C_SYNC 0x0100 -#define C_FSYNC 0x0200 -#define C_NOERROR 0x0400 -#define C_NOTRUNC 0x0800 - -struct pair { - char *name; - unsigned val; -}; - -static struct pair clist[] = { - { "fsync", C_FSYNC }, - { "noerror", C_NOERROR }, - { "notrunc", C_NOTRUNC }, - { "sync", C_SYNC }, -}; +#define C_FSYNC 1 +#define C_NOERROR 2 +#define C_NOTRUNC 4 +#define C_SYNC 8 static void status() { @@ -112,24 +100,14 @@ int strstarteq(char **a, char *b) { char *aa = *a; - if (!strstart(&aa, b)) return 0; - if (*aa != '=') return 0; - *a = ++aa; - - return 1; -} - -static int comp(const void *a, const void *b) //const to shut compiler up -{ - return strcmp(((struct pair*)a)->name, ((struct pair*)b)->name); + return strstart(&aa, b) && *aa == '=' && (*a = aa+1); } void dd_main() { - struct pair *res, key; char **args; unsigned long long bs = 0; - int trunc = O_TRUNC; + int trunc = O_TRUNC, conv = 0; TT.show_xfer = TT.show_records = 1; TT.c_count = ULLONG_MAX; @@ -154,13 +132,14 @@ void dd_main() else if (!strcmp(arg, "none")) TT.show_xfer = TT.show_records = 0; else error_exit("unknown status '%s'", arg); } else if (strstarteq(&arg, "conv")) { - while (arg) { - key.name = strsep(&arg, ","); - if (!(res = bsearch(&key, clist, ARRAY_LEN(clist), - sizeof(struct pair), comp))) - error_exit("unknown conversion %s", key.name); - - toys.optflags |= res->val; + char *ss, *convs[] = {"fsync", "noerror", "notrunc", "sync"}; + int i, len; + + while ((ss = comma_iterate(&arg, &len))) { + for (i = 0; i<ARRAY_LEN(convs); i++) + if (len == strlen(convs[i]) && !strncmp(ss, convs[i], len)) break; + if (i == ARRAY_LEN(convs)) error_exit("bad conv=%.*s", len, ss); + conv |= 1<<i; } } else error_exit("bad arg %s", arg); } @@ -179,7 +158,7 @@ void dd_main() if (!TT.in.name) TT.in.name = "stdin"; else TT.in.fd = xopenro(TT.in.name); - if (toys.optflags&C_NOTRUNC) trunc = 0; + if (conv&C_NOTRUNC) trunc = 0; //setup output if (!TT.out.name) { @@ -196,7 +175,7 @@ void dd_main() if (n < 0) { perror_msg("%s", TT.in.name); - if (toys.optflags & C_NOERROR) status(); + if (conv&C_NOERROR) status(); else return; } else if (!n) { xprintf("%s: Can't skip\n", TT.in.name); @@ -224,16 +203,16 @@ void dd_main() } TT.in.bp = TT.in.buff + TT.in.count; - if (toys.optflags & C_SYNC) memset(TT.in.bp, 0, TT.in.sz); + if (conv&C_SYNC) memset(TT.in.bp, 0, TT.in.sz); if (!(n = read(TT.in.fd, TT.in.bp, TT.in.sz))) break; if (n < 0) { if (errno == EINTR) continue; //read error case. perror_msg("%s: read error", TT.in.name); - if (!(toys.optflags & C_NOERROR)) exit(1); + if (!(conv&C_NOERROR)) exit(1); status(); xlseek(TT.in.fd, TT.in.sz, SEEK_CUR); - if (!(toys.optflags & C_SYNC)) continue; + if (!(conv&C_SYNC)) continue; // if SYNC, then treat as full block of nuls n = TT.in.sz; } @@ -242,7 +221,7 @@ void dd_main() TT.in.count += n; } else { TT.in_part++; - if (toys.optflags & C_SYNC) TT.in.count += TT.in.sz; + if (conv&C_SYNC) TT.in.count += TT.in.sz; else TT.in.count += n; } @@ -259,8 +238,8 @@ void dd_main() } } if (TT.out.count) write_out(1); //write any remaining input blocks - if (toys.optflags & C_FSYNC && fsync(TT.out.fd) < 0) - perror_exit("%s: fsync fail", TT.out.name); + if ((conv&C_FSYNC) && fsync(TT.out.fd)<0) + perror_exit("%s: fsync", TT.out.name); close(TT.in.fd); close(TT.out.fd); |