mailing list of musl libc
 help / color / mirror / code / Atom feed
* [PATCH] Add support for mkostemp, mkstemps and mkostemps
@ 2013-02-02 21:15 Anthony G. Basile
  2013-02-02 21:17 ` Anthony G. Basile
  2013-02-03  3:30 ` Rich Felker
  0 siblings, 2 replies; 27+ messages in thread
From: Anthony G. Basile @ 2013-02-02 21:15 UTC (permalink / raw)
  To: musl; +Cc: Anthony G. Basile

From: "Anthony G. Basile" <blueness@gentoo.org>

Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
---
 include/stdlib.h           |  6 ++++++
 src/temp/__open_tempfile.c | 27 +++++++++++++++++++++++++++
 src/temp/__randname.c      | 19 +++++++++++++++++++
 src/temp/mkostemp.c        | 11 +++++++++++
 src/temp/mkostemps.c       | 11 +++++++++++
 src/temp/mkstemp.c         | 21 ++-------------------
 src/temp/mkstemps.c        | 12 ++++++++++++
 src/temp/mktemp.c          | 14 ++++----------
 8 files changed, 92 insertions(+), 29 deletions(-)
 create mode 100644 src/temp/__open_tempfile.c
 create mode 100644 src/temp/__randname.c
 create mode 100644 src/temp/mkostemp.c
 create mode 100644 src/temp/mkostemps.c
 create mode 100644 src/temp/mkstemps.c

diff --git a/include/stdlib.h b/include/stdlib.h
index 671d188..4210f40 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -95,6 +95,9 @@ 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);
+int mkstemps (char *, int);
+int mkostemps (char *, int, int);
 char *mkdtemp (char *);
 int getsubopt (char **, char *const *, char **);
 int rand_r (unsigned *);
@@ -150,6 +153,9 @@ char *gcvt(double, int, char *);
 
 #if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
 #define mkstemp64 mkstemp
+#define mkostemp64 mkostemp
+#define mkstemps64 mkstemps
+#define mkostemps64 mkostemps
 #endif
 
 #ifdef __cplusplus
diff --git a/src/temp/__open_tempfile.c b/src/temp/__open_tempfile.c
new file mode 100644
index 0000000..797d3b3
--- /dev/null
+++ b/src/temp/__open_tempfile.c
@@ -0,0 +1,27 @@
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+char *__randname(char *);
+
+int __open_tempfile (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_CREAT | O_EXCL, 0600))>=0)
+			return fd;
+		if (errno != EEXIST) return -1;
+	}
+	return -1;
+}
diff --git a/src/temp/__randname.c b/src/temp/__randname.c
new file mode 100644
index 0000000..0dd5725
--- /dev/null
+++ b/src/temp/__randname.c
@@ -0,0 +1,19 @@
+#include <string.h>
+#include <time.h>
+#include <stdint.h>
+
+/* 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 0000000..92a7bc4
--- /dev/null
+++ b/src/temp/mkostemp.c
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+#include "libc.h"
+
+int __open_tempfile (char *, int, int);
+
+int __mkostemp(char *template, int flags)
+{
+	return __open_tempfile (template, 0, flags);
+}
+
+weak_alias(__mkostemp, mkostemp);
diff --git a/src/temp/mkostemps.c b/src/temp/mkostemps.c
new file mode 100644
index 0000000..6c60323
--- /dev/null
+++ b/src/temp/mkostemps.c
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+#include "libc.h"
+
+int __open_tempfile (char *, int, int);
+
+int __mkostemps(char *template, int len, int flags)
+{
+	return __open_tempfile (template, len, flags);
+}
+
+weak_alias(__mkostemps, mkostemps);
diff --git a/src/temp/mkstemp.c b/src/temp/mkstemp.c
index a390d42..72ab7d1 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 __open_tempfile (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 __open_tempfile (template, 0, O_RDWR);
 }
 
 LFS64(mkstemp);
diff --git a/src/temp/mkstemps.c b/src/temp/mkstemps.c
new file mode 100644
index 0000000..fcfc010
--- /dev/null
+++ b/src/temp/mkstemps.c
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "libc.h"
+
+int __open_tempfile (char *, int, int);
+
+int __mkstemps(char *template, int len)
+{
+	return __open_tempfile (template, len, O_RDWR);
+}
+
+weak_alias(__mkstemps, mkstemps);
diff --git a/src/temp/mktemp.c b/src/temp/mktemp.c
index c0e06f5..ed2c103 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;
-- 
1.7.12.4



^ permalink raw reply	[flat|nested] 27+ messages in thread
* [PATCH] Add support for mkostemp, mkstemps and mkostemps
@ 2013-02-02 18:45 Anthony G. Basile
  2013-02-02 19:51 ` John Spencer
  2013-02-02 20:14 ` Szabolcs Nagy
  0 siblings, 2 replies; 27+ messages in thread
From: Anthony G. Basile @ 2013-02-02 18:45 UTC (permalink / raw)
  To: musl; +Cc: Anthony G. Basile

From: "Anthony G. Basile" <blueness@gentoo.org>

Signed-off-by: Anthony G. Basile <blueness@gentoo.org>

1
---
 include/stdlib.h           |  6 ++++++
 src/temp/__open_tempfile.c | 35 +++++++++++++++++++++++++++++++++++
 src/temp/__randname.c      | 35 +++++++++++++++++++++++++++++++++++
 src/temp/mkostemp.c        | 18 ++++++++++++++++++
 src/temp/mkostemps.c       | 18 ++++++++++++++++++
 src/temp/mkstemp.c         | 15 ++-------------
 src/temp/mkstemps.c        | 18 ++++++++++++++++++
 src/temp/mktemp.c          |  7 +++----
 8 files changed, 135 insertions(+), 17 deletions(-)
 create mode 100644 src/temp/__open_tempfile.c
 create mode 100644 src/temp/__randname.c
 create mode 100644 src/temp/mkostemp.c
 create mode 100644 src/temp/mkostemps.c
 create mode 100644 src/temp/mkstemps.c

diff --git a/include/stdlib.h b/include/stdlib.h
index 671d188..4210f40 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -95,6 +95,9 @@ 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);
+int mkstemps (char *, int);
+int mkostemps (char *, int, int);
 char *mkdtemp (char *);
 int getsubopt (char **, char *const *, char **);
 int rand_r (unsigned *);
@@ -150,6 +153,9 @@ char *gcvt(double, int, char *);
 
 #if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
 #define mkstemp64 mkstemp
+#define mkostemp64 mkostemp
+#define mkstemps64 mkstemps
+#define mkostemps64 mkostemps
 #endif
 
 #ifdef __cplusplus
diff --git a/src/temp/__open_tempfile.c b/src/temp/__open_tempfile.c
new file mode 100644
index 0000000..7797e01
--- /dev/null
+++ b/src/temp/__open_tempfile.c
@@ -0,0 +1,35 @@
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+char *__randname(char *);
+
+int __open_tempfile (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;
+	}
+
+	/* Null terminate the template before the suffix,
+	   and save the char for adding back the suffix */
+	char suffix = template[l];
+	template[l] = '\0';
+
+	int fd, retries = 100;
+	while (retries--) {
+		if (!*__randname(template)) return -1;
+		/* Add back the suffix */
+		template[l] = suffix;
+		if ((fd = open(template, flags | O_CREAT | O_EXCL, 0600))>=0)
+			return fd;
+		if (errno != EEXIST) return -1;
+	}
+	return -1;
+}
diff --git a/src/temp/__randname.c b/src/temp/__randname.c
new file mode 100644
index 0000000..ac48545
--- /dev/null
+++ b/src/temp/__randname.c
@@ -0,0 +1,35 @@
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <stdint.h>
+
+/* We prefer this to a static const char[] array for a smaller footprint */
+
+char __map_letter(unsigned long x)
+{
+	x %= 62;
+	if (x<10)
+		return '0'+x;
+	else if (x<36)
+		return 'a'+(x-10);
+	else
+		return 'A'+(x-36);
+}
+
+/* This assumes that a check for the
+   template size has alrady been made */
+char *__randname(char *template)
+{
+	struct timespec ts;
+	size_t i, l = strlen(template);
+
+	/* r is intentially uninialized and 'dirty' */
+	unsigned long r;
+
+	clock_gettime(CLOCK_REALTIME, &ts);
+	r += ((uint64_t) ts.tv_nsec << 16) ^ ts.tv_sec;
+	for (i=1; i<=6; i++, r>>=6)
+		template[l-i] = __map_letter(r);
+
+	return template;
+}
diff --git a/src/temp/mkostemp.c b/src/temp/mkostemp.c
new file mode 100644
index 0000000..750d880
--- /dev/null
+++ b/src/temp/mkostemp.c
@@ -0,0 +1,18 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include "libc.h"
+
+int __open_tempfile (char *, int, int);
+
+int __mkostemp(char *template, int flags)
+{
+	return __open_tempfile (template, 0, flags);
+}
+
+weak_alias(__mkostemp, mkostemp);
diff --git a/src/temp/mkostemps.c b/src/temp/mkostemps.c
new file mode 100644
index 0000000..8c810ce
--- /dev/null
+++ b/src/temp/mkostemps.c
@@ -0,0 +1,18 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include "libc.h"
+
+int __open_tempfile (char *, int, int);
+
+int __mkostemps(char *template, int len, int flags)
+{
+	return __open_tempfile (template, len, flags);
+}
+
+weak_alias(__mkostemps, mkostemps);
diff --git a/src/temp/mkstemp.c b/src/temp/mkstemp.c
index a390d42..ccaf3c6 100644
--- a/src/temp/mkstemp.c
+++ b/src/temp/mkstemp.c
@@ -7,22 +7,11 @@
 #include <errno.h>
 #include "libc.h"
 
-char *__mktemp(char *);
+int __open_tempfile (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 __open_tempfile (template, 0, O_RDWR);
 }
 
 LFS64(mkstemp);
diff --git a/src/temp/mkstemps.c b/src/temp/mkstemps.c
new file mode 100644
index 0000000..53fea07
--- /dev/null
+++ b/src/temp/mkstemps.c
@@ -0,0 +1,18 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include "libc.h"
+
+int __open_tempfile (char *, int, int);
+
+int __mkstemps(char *template, int len)
+{
+	return __open_tempfile (template, len, O_RDWR);
+}
+
+weak_alias(__mkstemps, mkstemps);
diff --git a/src/temp/mktemp.c b/src/temp/mktemp.c
index c0e06f5..de1afb4 100644
--- a/src/temp/mktemp.c
+++ b/src/temp/mktemp.c
@@ -8,6 +8,8 @@
 #include <stdint.h>
 #include "libc.h"
 
+char *__randname(char *);
+
 char *__mktemp(char *template)
 {
 	struct timespec ts;
@@ -21,10 +23,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);
 		if (access(template, F_OK) < 0) return template;
 	}
 	*template = 0;
-- 
1.7.12.4



^ permalink raw reply	[flat|nested] 27+ messages in thread
* [PATCH] Add support for mkostemp, mkstemps and mkostemps
@ 2013-01-28  5:06 Anthony G. Basile
  2013-01-28  8:47 ` John Spencer
                   ` (3 more replies)
  0 siblings, 4 replies; 27+ messages in thread
From: Anthony G. Basile @ 2013-01-28  5:06 UTC (permalink / raw)
  To: musl; +Cc: Anthony G. Basile, Anthony G. Basile

From: "Anthony G. Basile" <basile@opensource.dyc.edu>

Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
---
 include/stdlib.h     |  6 ++++++
 src/temp/mkostemp.c  | 18 ++++++++++++++++++
 src/temp/mkostemps.c | 18 ++++++++++++++++++
 src/temp/mkstemp.c   | 15 ++-------------
 src/temp/mkstemps.c  | 18 ++++++++++++++++++
 src/temp/mktemp.c    |  7 +++----
 src/temp/randname.c  | 22 ++++++++++++++++++++++
 src/temp/tempfile.c  | 42 ++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 129 insertions(+), 17 deletions(-)
 create mode 100644 src/temp/mkostemp.c
 create mode 100644 src/temp/mkostemps.c
 create mode 100644 src/temp/mkstemps.c
 create mode 100644 src/temp/randname.c
 create mode 100644 src/temp/tempfile.c

diff --git a/include/stdlib.h b/include/stdlib.h
index 671d188..4210f40 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -95,6 +95,9 @@ 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);
+int mkstemps (char *, int);
+int mkostemps (char *, int, int);
 char *mkdtemp (char *);
 int getsubopt (char **, char *const *, char **);
 int rand_r (unsigned *);
@@ -150,6 +153,9 @@ char *gcvt(double, int, char *);
 
 #if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
 #define mkstemp64 mkstemp
+#define mkostemp64 mkostemp
+#define mkstemps64 mkstemps
+#define mkostemps64 mkostemps
 #endif
 
 #ifdef __cplusplus
diff --git a/src/temp/mkostemp.c b/src/temp/mkostemp.c
new file mode 100644
index 0000000..750d880
--- /dev/null
+++ b/src/temp/mkostemp.c
@@ -0,0 +1,18 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include "libc.h"
+
+int __open_tempfile (char *, int, int);
+
+int __mkostemp(char *template, int flags)
+{
+	return __open_tempfile (template, 0, flags);
+}
+
+weak_alias(__mkostemp, mkostemp);
diff --git a/src/temp/mkostemps.c b/src/temp/mkostemps.c
new file mode 100644
index 0000000..8c810ce
--- /dev/null
+++ b/src/temp/mkostemps.c
@@ -0,0 +1,18 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include "libc.h"
+
+int __open_tempfile (char *, int, int);
+
+int __mkostemps(char *template, int len, int flags)
+{
+	return __open_tempfile (template, len, flags);
+}
+
+weak_alias(__mkostemps, mkostemps);
diff --git a/src/temp/mkstemp.c b/src/temp/mkstemp.c
index a390d42..ccaf3c6 100644
--- a/src/temp/mkstemp.c
+++ b/src/temp/mkstemp.c
@@ -7,22 +7,11 @@
 #include <errno.h>
 #include "libc.h"
 
-char *__mktemp(char *);
+int __open_tempfile (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 __open_tempfile (template, 0, O_RDWR);
 }
 
 LFS64(mkstemp);
diff --git a/src/temp/mkstemps.c b/src/temp/mkstemps.c
new file mode 100644
index 0000000..53fea07
--- /dev/null
+++ b/src/temp/mkstemps.c
@@ -0,0 +1,18 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include "libc.h"
+
+int __open_tempfile (char *, int, int);
+
+int __mkstemps(char *template, int len)
+{
+	return __open_tempfile (template, len, O_RDWR);
+}
+
+weak_alias(__mkstemps, mkstemps);
diff --git a/src/temp/mktemp.c b/src/temp/mktemp.c
index c0e06f5..de1afb4 100644
--- a/src/temp/mktemp.c
+++ b/src/temp/mktemp.c
@@ -8,6 +8,8 @@
 #include <stdint.h>
 #include "libc.h"
 
+char *__randname(char *);
+
 char *__mktemp(char *template)
 {
 	struct timespec ts;
@@ -21,10 +23,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);
 		if (access(template, F_OK) < 0) return template;
 	}
 	*template = 0;
diff --git a/src/temp/randname.c b/src/temp/randname.c
new file mode 100644
index 0000000..4d3476f
--- /dev/null
+++ b/src/temp/randname.c
@@ -0,0 +1,22 @@
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <time.h>
+#include <stdint.h>
+#include "libc.h"
+
+char *__randname(char *template)
+{
+	struct timespec ts;
+	size_t i, l = strlen(template);
+	unsigned long r;
+
+	/* This assumes that a check for the template
+	   size has alrady been made */
+	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);
+
+	return template;
+}
diff --git a/src/temp/tempfile.c b/src/temp/tempfile.c
new file mode 100644
index 0000000..93808a6
--- /dev/null
+++ b/src/temp/tempfile.c
@@ -0,0 +1,42 @@
+#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 *__randname(char *);
+
+int __open_tempfile (char *template, int len, int flags)
+{
+	if (len < 0) return EINVAL;
+
+	int l = strlen(template)-len;
+	if (l < 6 || strncmp(template+l-6, "XXXXXX",6)) {
+		errno = EINVAL;
+		*template = 0;
+		return -1;
+	}
+
+	/* Null terminate the template before the suffix,
+	   and save the char for adding back the suffix */
+	char suffix = template[l];
+	template[l] = '\0';
+
+	int fd, retries = 100, t0 = *template;
+	while (retries--) {
+		if (!*__randname(template)) return -1;
+		/* Add back the suffix */
+		template[l] = suffix;
+		if ((fd = open(template, flags | 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+l-6, "XXXXXX");
+	}
+	return -1;
+}
-- 
1.7.12.4



^ permalink raw reply	[flat|nested] 27+ messages in thread
* [PATCH] Add support for mkostemp, mkstemps and mkostemps
@ 2013-01-28  2:36 Anthony G. Basile
  2013-01-28  5:01 ` Anthony G. Basile
  0 siblings, 1 reply; 27+ messages in thread
From: Anthony G. Basile @ 2013-01-28  2:36 UTC (permalink / raw)
  To: musl; +Cc: Anthony G. Basile, Anthony G. Basile

From: "Anthony G. Basile" <basile@opensource.dyc.edu>

Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
---
 include/stdlib.h     |  6 ++++++
 src/temp/mkostemp.c  | 16 ++++++++++++++++
 src/temp/mkostemps.c | 16 ++++++++++++++++
 src/temp/mkstemp.c   | 15 ++-------------
 src/temp/mkstemps.c  | 16 ++++++++++++++++
 src/temp/tempname.c  | 42 ++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 98 insertions(+), 13 deletions(-)
 create mode 100644 src/temp/mkostemp.c
 create mode 100644 src/temp/mkostemps.c
 create mode 100644 src/temp/mkstemps.c
 create mode 100644 src/temp/tempname.c

diff --git a/include/stdlib.h b/include/stdlib.h
index 671d188..4210f40 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -95,6 +95,9 @@ 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);
+int mkstemps (char *, int);
+int mkostemps (char *, int, int);
 char *mkdtemp (char *);
 int getsubopt (char **, char *const *, char **);
 int rand_r (unsigned *);
@@ -150,6 +153,9 @@ char *gcvt(double, int, char *);
 
 #if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
 #define mkstemp64 mkstemp
+#define mkostemp64 mkostemp
+#define mkstemps64 mkstemps
+#define mkostemps64 mkostemps
 #endif
 
 #ifdef __cplusplus
diff --git a/src/temp/mkostemp.c b/src/temp/mkostemp.c
new file mode 100644
index 0000000..4fd374c
--- /dev/null
+++ b/src/temp/mkostemp.c
@@ -0,0 +1,16 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include "libc.h"
+
+int __gen_tempname (char *, int, int);
+
+int mkostemp(char *template, int flags)
+{
+	return __gen_tempname (template, 0, flags);
+}
diff --git a/src/temp/mkostemps.c b/src/temp/mkostemps.c
new file mode 100644
index 0000000..9affae3
--- /dev/null
+++ b/src/temp/mkostemps.c
@@ -0,0 +1,16 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include "libc.h"
+
+int __gen_tempname (char *, int, int);
+
+int mkostemps(char *template, int len, int flags)
+{
+	return __gen_tempname (template, len, flags);
+}
diff --git a/src/temp/mkstemp.c b/src/temp/mkstemp.c
index a390d42..08914d4 100644
--- a/src/temp/mkstemp.c
+++ b/src/temp/mkstemp.c
@@ -7,22 +7,11 @@
 #include <errno.h>
 #include "libc.h"
 
-char *__mktemp(char *);
+int __gen_tempname (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 __gen_tempname (template, 0, O_RDWR);
 }
 
 LFS64(mkstemp);
diff --git a/src/temp/mkstemps.c b/src/temp/mkstemps.c
new file mode 100644
index 0000000..e194444
--- /dev/null
+++ b/src/temp/mkstemps.c
@@ -0,0 +1,16 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include "libc.h"
+
+int __gen_tempname (char *, int, int);
+
+int mkstemps(char *template, int len)
+{
+	return __gen_tempname (template, len, O_RDWR);
+}
diff --git a/src/temp/tempname.c b/src/temp/tempname.c
new file mode 100644
index 0000000..1c198bf
--- /dev/null
+++ b/src/temp/tempname.c
@@ -0,0 +1,42 @@
+#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 __gen_tempname (char *template, int len, int flags)
+{
+	if (len < 0) return EINVAL;
+
+	int templen = strlen(template)-len;
+	if (templen<6) return EINVAL;
+
+	char *suffix = (char *)malloc((len+1)*sizeof(char));
+	/* Copy the last len chars plus the null termination */
+	int i;
+	for (i = 0; i <= len; i++)
+		suffix[i] = template[templen+i];
+	/* Null terminate the template before the suffice */
+	template[templen] = '\0';
+
+	int fd, retries = 100, t0 = *template;
+	while (retries--) {
+		if (!*__mktemp(template)) return -1;
+		/* Copy back the suffix */
+		for (i = 0; i <= len; i++)
+			template[templen+i] = suffix[i];
+		if ((fd = open(template, flags | 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+templen-6, "XXXXXX");
+	}
+	return -1;
+}
-- 
1.7.12.4



^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2013-02-03  3:30 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-02 21:15 [PATCH] Add support for mkostemp, mkstemps and mkostemps Anthony G. Basile
2013-02-02 21:17 ` Anthony G. Basile
2013-02-03  3:30 ` Rich Felker
  -- strict thread matches above, loose matches on Subject: below --
2013-02-02 18:45 Anthony G. Basile
2013-02-02 19:51 ` John Spencer
2013-02-02 19:59   ` John Spencer
2013-02-02 22:11   ` Szabolcs Nagy
2013-02-02 20:14 ` Szabolcs Nagy
2013-02-02 20:38   ` Anthony G. Basile
2013-02-02 22:22     ` Szabolcs Nagy
2013-01-28  5:06 Anthony G. Basile
2013-01-28  8:47 ` John Spencer
2013-01-28  9:37 ` Szabolcs Nagy
2013-01-28 17:33   ` Szabolcs Nagy
2013-01-29 23:16   ` Anthony G. Basile
2013-01-30  7:21     ` Rich Felker
2013-01-30  7:59       ` Hardy Falk
2013-01-30 13:45         ` Szabolcs Nagy
2013-01-30 16:51           ` Rich Felker
2013-01-30 19:12             ` Szabolcs Nagy
2013-01-30 19:22               ` Rich Felker
2013-01-31  0:28                 ` Szabolcs Nagy
2013-01-28 16:33 ` Rich Felker
2013-02-02  3:48 ` Rich Felker
2013-02-02 18:46   ` Anthony G. Basile
2013-01-28  2:36 Anthony G. Basile
2013-01-28  5:01 ` Anthony G. Basile

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).