make mkdtemp and mkstemp family leave template unchanged on fail
authorRich Felker <dalias@aerifal.cx>
Fri, 2 Aug 2013 04:48:48 +0000 (00:48 -0400)
committerRich Felker <dalias@aerifal.cx>
Fri, 2 Aug 2013 04:48:48 +0000 (00:48 -0400)
also refactor mkdtemp based on new shared temp code, removing
dependency on the deprecated mktemp, whose behavior made this logic
more difficult.

src/temp/mkdtemp.c
src/temp/mkostemps.c

index 76140c7..195e9cb 100644 (file)
@@ -8,19 +8,23 @@
 #include <sys/stat.h>
 #include "libc.h"
 
-char *__mktemp(char *);
+char *__randname(char *);
 
 char *mkdtemp(char *template)
 {
-       int retries = 100, t0 = *template;
-       while (retries--) {
-               if (!*__mktemp(template)) return 0;
-               if (!mkdir(template, 0700)) return template;
-               if (errno != EEXIST) return 0;
-               /* this is safe because mktemp verified
-                * that we have a valid template string */
-               template[0] = t0;
-               strcpy(template+strlen(template)-6, "XXXXXX");
+       size_t l = strlen(template);
+       int retries = 100;
+
+       if (l<6 || memcmp(template+l-6, "XXXXXX", 6)) {
+               errno = EINVAL;
+               return 0;
        }
+
+       do {
+               __randname(template+l-6);
+               if (!mkdir(template, 0700)) return template;
+       } while (--retries && errno == EEXIST);
+
+       memcpy(template+l-6, "XXXXXX", 6);
        return 0;
 }
index 8cc01e3..7f8492a 100644 (file)
@@ -16,12 +16,13 @@ int __mkostemps(char *template, int len, int flags)
        }
 
        int fd, retries = 100;
-       while (retries--) {
+       do {
                __randname(template+l-len-6);
                if ((fd = open(template, flags | O_RDWR | O_CREAT | O_EXCL, 0600))>=0)
                        return fd;
-               if (errno != EEXIST) return -1;
-       }
+       } while (--retries && errno == EEXIST);
+
+       memcpy(template+l-len-6, "XXXXXX", 6);
        return -1;
 }