make mkdtemp and mkstemp family leave template unchanged on fail

also refactor mkdtemp based on new shared temp code, removing
dependency on the deprecated mktemp, whose behavior made this logic
more difficult.
This commit is contained in:
Rich Felker 2013-08-02 00:48:48 -04:00
parent 926272ddff
commit c4685ae429
2 changed files with 18 additions and 13 deletions

View File

@ -8,19 +8,23 @@
#include <sys/stat.h> #include <sys/stat.h>
#include "libc.h" #include "libc.h"
char *__mktemp(char *); char *__randname(char *);
char *mkdtemp(char *template) char *mkdtemp(char *template)
{ {
int retries = 100, t0 = *template; size_t l = strlen(template);
while (retries--) { int retries = 100;
if (!*__mktemp(template)) return 0;
if (!mkdir(template, 0700)) return template; if (l<6 || memcmp(template+l-6, "XXXXXX", 6)) {
if (errno != EEXIST) return 0; errno = EINVAL;
/* this is safe because mktemp verified return 0;
* that we have a valid template string */
template[0] = t0;
strcpy(template+strlen(template)-6, "XXXXXX");
} }
do {
__randname(template+l-6);
if (!mkdir(template, 0700)) return template;
} while (--retries && errno == EEXIST);
memcpy(template+l-6, "XXXXXX", 6);
return 0; return 0;
} }

View File

@ -16,12 +16,13 @@ int __mkostemps(char *template, int len, int flags)
} }
int fd, retries = 100; int fd, retries = 100;
while (retries--) { do {
__randname(template+l-len-6); __randname(template+l-len-6);
if ((fd = open(template, flags | O_RDWR | O_CREAT | O_EXCL, 0600))>=0) if ((fd = open(template, flags | O_RDWR | O_CREAT | O_EXCL, 0600))>=0)
return fd; return fd;
if (errno != EEXIST) return -1; } while (--retries && errno == EEXIST);
}
memcpy(template+l-len-6, "XXXXXX", 6);
return -1; return -1;
} }