summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2013-02-20 22:43:23 -0500
committerRich Felker <dalias@aerifal.cx>2013-02-20 22:43:23 -0500
commit2cc63358cdb0309ca996ffe56ccf402c2f2f16d5 (patch)
tree067001fb5f1a5a09de6d8417c5d1d80249e382ce /src
parentf78cdbe8993d072bf60a65754544199016a1fe29 (diff)
downloadmusl-2cc63358cdb0309ca996ffe56ccf402c2f2f16d5.tar.gz
add mkostemp, mkstemps, and mkostemps functions and reorganize temp internals
based on patch contributed by Anthony G. Basile (blueness) some issues remain with the filename generation algorithm and other small bugs, but this patch has been sitting around long enough that I feel it's best to get it committed and then work out any remaining issues.
Diffstat (limited to 'src')
-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
6 files changed, 83 insertions, 29 deletions
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;