diff --git a/include/stdlib.h b/include/stdlib.h index 671d188f..0bcc9f4f 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -95,6 +95,7 @@ int posix_memalign (void **, size_t, size_t); int setenv (const char *, const char *, int); int unsetenv (const char *); int mkstemp (char *); +int mkostemp (char *, int); char *mkdtemp (char *); int getsubopt (char **, char *const *, char **); int rand_r (unsigned *); @@ -134,6 +135,8 @@ void lcong48 (unsigned short [7]); #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) #include char *mktemp (char *); +int mkstemps (char *, int); +int mkostemps (char *, int, int); void *valloc (size_t); void *memalign(size_t, size_t); #define WCOREDUMP(s) ((s) & 0x80) @@ -150,6 +153,11 @@ char *gcvt(double, int, char *); #if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE) #define mkstemp64 mkstemp +#define mkostemp64 mkostemp +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) +#define mkstemps64 mkstemps +#define mkostemps64 mkostemps +#endif #endif #ifdef __cplusplus diff --git a/src/temp/__randname.c b/src/temp/__randname.c new file mode 100644 index 00000000..b097576d --- /dev/null +++ b/src/temp/__randname.c @@ -0,0 +1,21 @@ +#include +#include +#include + +int __clock_gettime(clockid_t, struct timespec *); + +/* This assumes that a check for the + template size has alrady been made */ +char *__randname(char *template) +{ + int i; + struct timespec ts; + unsigned long r; + + __clock_gettime(CLOCK_REALTIME, &ts); + r = ts.tv_nsec*65537 ^ (uintptr_t)&ts / 16 + (uintptr_t)template; + for (i=0; i<6; i++, r>>=5) + template[i] = 'A'+(r&15)+(r&16)*2; + + return template; +} diff --git a/src/temp/mkostemp.c b/src/temp/mkostemp.c new file mode 100644 index 00000000..e73e22a6 --- /dev/null +++ b/src/temp/mkostemp.c @@ -0,0 +1,12 @@ +#define _BSD_SOURCE +#include +#include "libc.h" + +int __mkostemps(char *, int, int); + +int mkostemp(char *template, int flags) +{ + return __mkostemps(template, 0, flags); +} + +LFS64(mkostemp); diff --git a/src/temp/mkostemps.c b/src/temp/mkostemps.c new file mode 100644 index 00000000..804a5475 --- /dev/null +++ b/src/temp/mkostemps.c @@ -0,0 +1,32 @@ +#define _BSD_SOURCE +#include +#include +#include +#include +#include "libc.h" + +char *__randname(char *); + +int __mkostemps(char *template, int len, int flags) +{ + if (len < 0) return EINVAL; + + size_t l = strlen(template)-len; + if (l < 6 || strncmp(template+l-6, "XXXXXX", 6)) { + errno = EINVAL; + *template = 0; + return -1; + } + + int fd, retries = 100; + while (retries--) { + __randname(template+l-6); + if ((fd = open(template, flags | O_RDWR | O_CREAT | O_EXCL, 0600))>=0) + return fd; + if (errno != EEXIST) return -1; + } + return -1; +} + +weak_alias(__mkostemps, mkostemps); +weak_alias(__mkostemps, mkostemps64); diff --git a/src/temp/mkstemp.c b/src/temp/mkstemp.c index a390d427..85764af7 100644 --- a/src/temp/mkstemp.c +++ b/src/temp/mkstemp.c @@ -1,28 +1,11 @@ -#include -#include #include -#include -#include -#include -#include #include "libc.h" -char *__mktemp(char *); +int __mkostemps(char *, int, int); int mkstemp(char *template) { - int fd, retries = 100, t0 = *template; - while (retries--) { - if (!*__mktemp(template)) return -1; - if ((fd = open(template, O_RDWR | O_CREAT | O_EXCL, 0600))>=0) - return fd; - if (errno != EEXIST) return -1; - /* this is safe because mktemp verified - * that we have a valid template string */ - template[0] = t0; - strcpy(template+strlen(template)-6, "XXXXXX"); - } - return -1; + return __mkostemps(template, 0, 0); } LFS64(mkstemp); diff --git a/src/temp/mkstemps.c b/src/temp/mkstemps.c new file mode 100644 index 00000000..fda710b0 --- /dev/null +++ b/src/temp/mkstemps.c @@ -0,0 +1,12 @@ +#define _BSD_SOURCE +#include +#include "libc.h" + +int __mkostemps(char *, int, int); + +int mkstemps(char *template, int len) +{ + return __mkostemps(template, len, 0); +} + +LFS64(mkstemps); diff --git a/src/temp/mktemp.c b/src/temp/mktemp.c index c0e06f5e..ed2c103e 100644 --- a/src/temp/mktemp.c +++ b/src/temp/mktemp.c @@ -1,17 +1,14 @@ #include -#include -#include #include #include #include -#include -#include #include "libc.h" +char *__randname(char *); + char *__mktemp(char *template) { - struct timespec ts; - size_t i, l = strlen(template); + size_t l = strlen(template); int retries = 10000; unsigned long r; @@ -21,10 +18,7 @@ char *__mktemp(char *template) return template; } while (retries--) { - clock_gettime(CLOCK_REALTIME, &ts); - r = ts.tv_nsec + (uintptr_t)&ts / 16 + (uintptr_t)template; - for (i=1; i<=6; i++, r>>=4) - template[l-i] = 'A'+(r&15); + __randname(template+l-6); if (access(template, F_OK) < 0) return template; } *template = 0;