From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/2713 Path: news.gmane.org!not-for-mail From: "Anthony G. Basile" Newsgroups: gmane.linux.lib.musl.general Subject: [PATCH] Add support for mkostemp, mkstemps and mkostemps Date: Sat, 2 Feb 2013 13:45:31 -0500 Message-ID: <1359830731-24717-1-git-send-email-basile@opensource.dyc.edu> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org X-Trace: ger.gmane.org 1359830502 4701 80.91.229.3 (2 Feb 2013 18:41:42 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 2 Feb 2013 18:41:42 +0000 (UTC) Cc: "Anthony G. Basile" To: musl@lists.openwall.com Original-X-From: musl-return-2714-gllmg-musl=m.gmane.org@lists.openwall.com Sat Feb 02 19:42:03 2013 Return-path: Envelope-to: gllmg-musl@plane.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1U1i2F-0004vg-Jw for gllmg-musl@plane.gmane.org; Sat, 02 Feb 2013 19:41:55 +0100 Original-Received: (qmail 13654 invoked by uid 550); 2 Feb 2013 18:41:35 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Original-Received: (qmail 13646 invoked from network); 2 Feb 2013 18:41:35 -0000 X-Mailer: git-send-email 1.7.6.1 Xref: news.gmane.org gmane.linux.lib.musl.general:2713 Archived-At: From: "Anthony G. Basile" Signed-off-by: Anthony G. Basile 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 +#include +#include +#include +#include + +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 +#include +#include +#include + +/* 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 +#include +#include +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#include +#include +#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 #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 +#include +#include +#include +#include +#include +#include +#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 #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