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

Reply via email to