summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/stdlib.h8
-rw-r--r--src/temp/__randname.c21
-rw-r--r--src/temp/mkostemp.c12
-rw-r--r--src/temp/mkostemps.c32
-rw-r--r--src/temp/mkstemp.c21
-rw-r--r--src/temp/mkstemps.c12
-rw-r--r--src/temp/mktemp.c14
7 files changed, 91 insertions, 29 deletions
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 <alloca.h>
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 <string.h>
+#include <time.h>
+#include <stdint.h>
+
+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 <stdlib.h>
+#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 <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#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 <string.h>
-#include <stdio.h>
#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <limits.h>
-#include <errno.h>
#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 <stdlib.h>
+#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 <string.h>
-#include <stdio.h>
-#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
-#include <time.h>
-#include <stdint.h>
#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;