aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2017-07-11 18:48:54 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-07-11 18:48:54 +0000
commit63a7993a8feacbeebcfb3c4a07ba2b0217de5b9e (patch)
treed58ba49e43b1b7d3d53b3ab1717b32bdd9d008e4
parent7ecc0fa0e33532369a10aa86e9da3ba728235129 (diff)
parentb62e8ff3da51c85ae648c871dc76401dbfac9f0f (diff)
downloadtoybox-63a7993a8feacbeebcfb3c4a07ba2b0217de5b9e.tar.gz
Merge remote-tracking branch 'toybox/master' into HEAD
am: b62e8ff3da Change-Id: I2720c0aa0fce8d3afb854edaf4dd7b91ee48d8a9
-rw-r--r--generated/globals.h3
-rw-r--r--generated/newtoys.h2
-rw-r--r--lib/getmountlist.c5
-rw-r--r--lib/lib.c7
-rwxr-xr-xtests/dd.test5
-rw-r--r--tests/strings.test5
-rw-r--r--toys/lsb/mount.c2
-rw-r--r--toys/pending/dd.c113
-rw-r--r--toys/pending/expr.c3
9 files changed, 52 insertions, 93 deletions
diff --git a/generated/globals.h b/generated/globals.h
index 5e4f8ce5..18e101fe 100644
--- a/generated/globals.h
+++ b/generated/globals.h
@@ -499,8 +499,7 @@ struct crontab_data {
// toys/pending/dd.c
struct dd_data {
- int show_xfer;
- int show_records;
+ int show_xfer, show_records;
unsigned long long bytes, c_count, in_full, in_part, out_full, out_part;
struct timeval start;
struct {
diff --git a/generated/newtoys.h b/generated/newtoys.h
index 3d62e0d1..46cc2dbb 100644
--- a/generated/newtoys.h
+++ b/generated/newtoys.h
@@ -40,7 +40,7 @@ USE_CROND(NEWTOY(crond, "fbSl#<0=8d#<0L:c:[-bf][-LS][-ld]", TOYFLAG_USR|TOYFLAG_
USE_CRONTAB(NEWTOY(crontab, "c:u:elr[!elr]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT))
USE_CUT(NEWTOY(cut, "b:|c:|f:|d:sn[!cbf]", TOYFLAG_USR|TOYFLAG_BIN))
USE_DATE(NEWTOY(date, "d:D:r:u[!dr]", TOYFLAG_BIN))
-USE_DD(NEWTOY(dd, NULL, TOYFLAG_USR|TOYFLAG_BIN))
+USE_DD(NEWTOY(dd, 0, TOYFLAG_USR|TOYFLAG_BIN))
USE_DEALLOCVT(NEWTOY(deallocvt, ">1", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_NEEDROOT))
USE_GROUPDEL(OLDTOY(delgroup, groupdel, TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
USE_USERDEL(OLDTOY(deluser, userdel, TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
diff --git a/lib/getmountlist.c b/lib/getmountlist.c
index 332852a8..f7d58ab6 100644
--- a/lib/getmountlist.c
+++ b/lib/getmountlist.c
@@ -97,7 +97,10 @@ int comma_scan(char *optlist, char *opt, int clean)
no = 2*(*s == 'n' && s[1] == 'o');
if (optlen == len-no && !strncmp(opt, s+no, optlen)) {
got = !no;
- if (clean && optlist) memmove(s, optlist, strlen(optlist)+1);
+ if (clean) {
+ if (optlist) memmove(s, optlist, strlen(optlist)+1);
+ else *s = 0;
+ }
}
}
diff --git a/lib/lib.c b/lib/lib.c
index 6e88fd25..d011af02 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -290,17 +290,18 @@ long long xstrtol(char *str, char **end, int base)
return l;
}
-// atol() with the kilo/mega/giga/tera/peta/exa extensions.
+// atol() with the kilo/mega/giga/tera/peta/exa extensions, plus word and block.
// (zetta and yotta don't fit in 64 bits.)
long long atolx(char *numstr)
{
- char *c = numstr, *suffixes="cbkmgtpe", *end;
+ char *c = numstr, *suffixes="cwbkmgtpe", *end;
long long val;
val = xstrtol(numstr, &c, 0);
if (c != numstr && *c && (end = strchr(suffixes, tolower(*c)))) {
- int shift = end-suffixes-1;
+ int shift = end-suffixes-2;
+ if (shift==-1) val *= 2;
if (!shift) val *= 512;
else if (shift>0) {
if (toupper(*++c)=='d') while (shift--) val *= 1000;
diff --git a/tests/dd.test b/tests/dd.test
index 9da2108c..1ab06d45 100755
--- a/tests/dd.test
+++ b/tests/dd.test
@@ -13,8 +13,9 @@ opt="2>/dev/null"
# Test suffixed number parsing; `count` is representative.
testing "count=2" "dd if=input count=2 ibs=1 $opt" "hi" "high\n" ""
testing "count= 2" "dd if=input 'count= 2' ibs=1 $opt" "hi" "high\n" ""
-testing "count=0x2" "dd if=input 'count=0x2' ibs=1 $opt" "hi" "high\n" ""
-testing "count=-2" "dd if=input 'count=-2' ibs=1 2>&1" "dd: invalid number '-2'\n" "" ""
+SKIP_HOST=1 testing "count=0x2" "dd if=input 'count=0x2' ibs=1 $opt" "hi" \
+ "high\n" ""
+testing "count=-2" "dd if=input 'count=-2' ibs=1 2>/dev/null || echo errored" "errored\n" "" ""
testing "if=(file)" "dd if=input $opt" "I WANT\n" "I WANT\n" ""
testing "of=(file)" "dd of=file $opt && cat file" "I WANT\n" "" "I WANT\n"
diff --git a/tests/strings.test b/tests/strings.test
index 8becc2f5..1a9a8826 100644
--- a/tests/strings.test
+++ b/tests/strings.test
@@ -18,3 +18,8 @@ testing "-o, multiple strings" "strings -n3 -o input | sed 's/^ *//'" \
"1 foo\n7 bar\n" "\0foo\0b\0bar\n" ""
testing "-fo" "strings -fo input | sed 's/: */: /'" "input: 6 foobar\n" \
"\0\0\0\0\0\0foobar\n" ""
+
+OFFSET_10="\0\0\0\0\0\0\0\0\0\0foobar\n"
+testing "-t o" "strings -t o | sed 's/^ *//'" "12 foobar\n" "" $OFFSET_10
+testing "-t d" "strings -t d | sed 's/^ *//'" "10 foobar\n" "" $OFFSET_10
+testing "-t x" "strings -t x | sed 's/^ *//'" "a foobar\n" "" $OFFSET_10
diff --git a/toys/lsb/mount.c b/toys/lsb/mount.c
index daf2edca..0fd9dc52 100644
--- a/toys/lsb/mount.c
+++ b/toys/lsb/mount.c
@@ -300,7 +300,7 @@ void mount_main(void)
// For remount we need _last_ match (in case of overmounts), so traverse
// in reverse order. (Yes I'm using remount as a boolean for a bit here,
// the double cast is to get gcc to shut up about it.)
- remount = (void *)(long)comma_scan(opts, "remount", 1);
+ remount = (void *)(long)comma_scan(opts, "remount", 0);
if (((toys.optflags & FLAG_a) && !access("/proc/mounts", R_OK)) || remount) {
mm = dlist_terminate(mtl = mtl2 = xgetmountlist(0));
if (remount) remount = mm;
diff --git a/toys/pending/dd.c b/toys/pending/dd.c
index 0bb48494..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"
@@ -40,8 +40,7 @@ config DD
#include "toys.h"
GLOBALS(
- int show_xfer;
- int show_records;
+ int show_xfer, show_records;
unsigned long long bytes, c_count, in_full, in_part, out_full, out_part;
struct timeval start;
struct {
@@ -53,52 +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 suffixes[] = {
- { "c", 1 }, { "w", 2 }, { "b", 512 },
- { "kD", 1000 }, { "k", 1024 }, { "K", 1024 },
- { "MD", 1000000 }, { "M", 1048576 },
- { "GD", 1000000000 }, { "G", 1073741824 }
-};
-
-static struct pair clist[] = {
- { "fsync", C_FSYNC },
- { "noerror", C_NOERROR },
- { "notrunc", C_NOTRUNC },
- { "sync", C_SYNC },
-};
-
-static unsigned long long strsuftoll(char *arg, int def, unsigned long long max)
-{
- unsigned long long result;
- char *p = arg;
- int i, idx = -1;
-
- while (isspace(*p)) p++;
- if (*p == '-') error_exit("invalid number '%s'", arg);
-
- errno = 0;
- result = strtoull(p, &p, 0);
- if (errno == ERANGE || result > max || result < def)
- perror_exit("invalid number '%s'", arg);
- if (*p != '\0') {
- for (i = 0; i < ARRAY_LEN(suffixes); i++)
- if (!strcmp(p, suffixes[i].name)) idx = i;
- if (idx == -1 || (max/suffixes[idx].val < result))
- error_exit("invalid number '%s'", arg);
- result *= suffixes[idx].val;
- }
- return result;
-}
+#define C_FSYNC 1
+#define C_NOERROR 2
+#define C_NOTRUNC 4
+#define C_SYNC 8
static void status()
{
@@ -143,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;
@@ -169,28 +116,30 @@ void dd_main()
for (args = toys.optargs; *args; args++) {
char *arg = *args;
- if (strstarteq(&arg, "bs")) bs = strsuftoll(arg, 1, LONG_MAX);
- else if (strstarteq(&arg, "ibs")) TT.in.sz = strsuftoll(arg, 1, LONG_MAX);
- else if (strstarteq(&arg, "obs")) TT.out.sz = strsuftoll(arg, 1, LONG_MAX);
- else if (strstarteq(&arg, "count")) TT.c_count = strsuftoll(arg, 0, ULLONG_MAX-1);
+ if (strstarteq(&arg, "bs")) bs = atolx_range(arg, 1, LONG_MAX);
+ else if (strstarteq(&arg, "ibs")) TT.in.sz = atolx_range(arg, 1, LONG_MAX);
+ else if (strstarteq(&arg, "obs")) TT.out.sz = atolx_range(arg, 1, LONG_MAX);
+ else if (strstarteq(&arg, "count"))
+ TT.c_count = atolx_range(arg, 0, LLONG_MAX);
else if (strstarteq(&arg, "if")) TT.in.name = arg;
else if (strstarteq(&arg, "of")) TT.out.name = arg;
else if (strstarteq(&arg, "seek"))
- TT.out.offset = strsuftoll(arg, 0, ULLONG_MAX);
+ TT.out.offset = atolx_range(arg, 0, LLONG_MAX);
else if (strstarteq(&arg, "skip"))
- TT.in.offset = strsuftoll(arg, 0, ULLONG_MAX);
+ TT.in.offset = atolx_range(arg, 0, LLONG_MAX);
else if (strstarteq(&arg, "status")) {
if (!strcmp(arg, "noxfer")) TT.show_xfer = 0;
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);
}
@@ -209,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) {
@@ -226,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);
@@ -254,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;
}
@@ -272,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;
}
@@ -289,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);
diff --git a/toys/pending/expr.c b/toys/pending/expr.c
index 743a9536..9e094a75 100644
--- a/toys/pending/expr.c
+++ b/toys/pending/expr.c
@@ -113,7 +113,8 @@ static void re(char *target, char *pattern, struct value *ret)
if (!regexec(&pat, target, 2, m, 0) && !m[0].rm_so) {
// Return first parenthesized subexpression as string, or length of match
if (pat.re_nsub>0) {
- ret->s = xmprintf("%.*s", m[1].rm_eo-m[1].rm_so, target+m[1].rm_so);
+ ret->s = xmprintf("%.*s", (int)(m[1].rm_eo-m[1].rm_so),
+ target+m[1].rm_so);
if (TT.refree) free(TT.refree);
TT.refree = ret->s;
} else assign_int(ret, m[0].rm_eo);