On 12/5/18 5:03 PM, enh via Toybox wrote: > Multiple bugs: > > * We weren't outputting anything in the case where we actually create a > file or directory (but all the tests were for the -u case). > > * There are more gnarls to the behavior if TEMPLATE contains a '/'. The > new tests cover these.
Sigh. (See attached...) Lemme try to reconcile them... Rob
diff --git a/lib/portability.c b/lib/portability.c index a80ca56..5c754d7 100644 --- a/lib/portability.c +++ b/lib/portability.c @@ -30,18 +30,20 @@ pid_t xfork(void) } #endif -void xgetrandom(void *buf, unsigned buflen, unsigned flags) +int xgetrandom(void *buf, unsigned buflen, unsigned flags) { int fd; #if CFG_TOYBOX_GETRANDOM - if (buflen == getrandom(buf, buflen, flags)) return; - if (!CFG_TOYBOX_ON_ANDROID || errno!=ENOSYS) perror_exit("getrandom"); + if (buflen == getrandom(buf, buflen, flags&~WARN_ONLY)) return 1; + if (errno!=ENOSYS && !(flags&WARN_ONLY)) perror_exit("getrandom"); #endif - - fd = xopen(flags ? "/dev/random" : "/dev/urandom", O_RDONLY); + fd = xopen(flags ? "/dev/random" : "/dev/urandom",O_RDONLY|(flags&WARN_ONLY)); + if (fd == -1) return 0; xreadall(fd, buf, buflen); close(fd); + + return 1; } #if defined(__APPLE__) diff --git a/lib/portability.h b/lib/portability.h index 21d0b8a..60d4049 100644 --- a/lib/portability.h +++ b/lib/portability.h @@ -266,7 +266,7 @@ extern CODE prioritynames[], facilitynames[]; #if CFG_TOYBOX_GETRANDOM #include <sys/random.h> #endif -void xgetrandom(void *buf, unsigned len, unsigned flags); +int xgetrandom(void *buf, unsigned len, unsigned flags); // Android's bionic libc doesn't have confstr. #ifdef __BIONIC__ diff --git a/toys/lsb/mktemp.c b/toys/lsb/mktemp.c index 112f84c..6d159d6 100644 --- a/toys/lsb/mktemp.c +++ b/toys/lsb/mktemp.c @@ -34,12 +34,9 @@ GLOBALS( void mktemp_main(void) { char *template = *toys.optargs; - int use_dir = (toys.optflags & (FLAG_p|FLAG_t)); + int use_dir = (toys.optflags & (FLAG_p|FLAG_t)), len; - if (!template) { - template = "tmp.XXXXXXXXXX"; - use_dir = 1; - } + if (!template) template = "tmp.XXXXXXXXXX"; // Normally, the precedence is DIR (if set), $TMPDIR (if set), /tmp. // With -t it's $TMPDIR, DIR, /tmp. @@ -48,17 +45,38 @@ void mktemp_main(void) if (toys.optflags & FLAG_t) { if (tmpdir && *tmpdir) TT.p = tmpdir; - } else { - if (!TT.p || !*TT.p) TT.p = tmpdir; - } + } else if (!TT.p || !*TT.p) TT.p = tmpdir; if (!TT.p || !*TT.p) TT.p = "/tmp"; } // TODO: coreutils cleans paths, so -p /t/// would result in /t/xxx... template = use_dir ? xmprintf("%s/%s", TT.p, template) : xstrdup(template); + len = strlen(template); + if (len<3 || strcmp(template+len-3, "XXX")) perror_exit("need XXX"); + // In theory you just xputs(mktemp(template)) for -u, in practice there's + // link-time deprecation warnings if you do that. So we fake up our own: if (toys.optflags & FLAG_u) { - xputs(mktemp(template)); + long long rr; + char *s = template+len; + + // Fall back to random-ish if xgetrandom fails. + if (!xgetrandom(&rr, sizeof(rr), WARN_ONLY)) { + struct timespec ts; + + clock_gettime(CLOCK_REALTIME, &ts); + rr = ts.tv_nsec*65537+(long)template+getpid()+(long)&template; + } + // Replace X with 64 chars from posix portable character set (all but "_"). + while (--s>template) { + if (*s != 'X') break; + *s = '-'+(rr&63); + if (*s>'.') ++*s; + if (*s>'9') (*s) += 7; + if (*s>'Z') (*s) += 6; + rr>>=6; + } + xputs(template); } else if (toys.optflags & FLAG_d ? !mkdtemp(template) : mkstemp(template) == -1) { if (toys.optflags & FLAG_q) toys.exitval = 1; else perror_exit("Failed to create %s %s/%s",
_______________________________________________ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net