This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
portable Perl_my_mkostemp()
authorZefram <zefram@fysh.org>
Tue, 19 Dec 2017 18:32:05 +0000 (18:32 +0000)
committerZefram <zefram@fysh.org>
Fri, 22 Dec 2017 16:22:52 +0000 (16:22 +0000)
Akin to the existing Perl_my_mkstemp(), Perl_my_mkostemp() is defined
as a macro for mkostemp() where available, and otherwise as our own
implementation of it.  The guts of our own implementations of the two
functions are shared.  Perl_my_mkostemp() is not guaranteed to handle
O_CLOEXEC: that depends on open() handling it.

embed.fnc
metaconfig.h
proto.h
util.c
util.h

index b768861..ac36719 100644 (file)
--- a/embed.fnc
+++ b/embed.fnc
@@ -3076,6 +3076,9 @@ Apnod     |Size_t |my_strlcpy     |NULLOK char *dst|NULLOK const char *src|Size_t si
 Apnod  |Size_t |my_strnlen     |NN const char *str|Size_t maxlen
 #endif
 
+#ifndef HAS_MKOSTEMP
+pno    |int    |my_mkostemp    |NN char *templte|int flags
+#endif
 #ifndef HAS_MKSTEMP
 pno    |int    |my_mkstemp     |NN char *templte
 #endif
index 346bde2..ba8ee4a 100644 (file)
@@ -22,5 +22,4 @@
  * HAS_NANOSLEEP
  * HAS_STRTOLD_L
  * I_WCHAR
- * HAS_MKOSTEMP
  */
diff --git a/proto.h b/proto.h
index 47e348a..1ae6c12 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -3857,6 +3857,11 @@ STATIC int       S_dooneliner(pTHX_ const char *cmd, const char *filename)
 
 #  endif
 #endif
+#if !defined(HAS_MKOSTEMP)
+PERL_CALLCONV int      Perl_my_mkostemp(char *templte, int flags);
+#define PERL_ARGS_ASSERT_MY_MKOSTEMP   \
+       assert(templte)
+#endif
 #if !defined(HAS_MKSTEMP)
 PERL_CALLCONV int      Perl_my_mkstemp(char *templte);
 #define PERL_ARGS_ASSERT_MY_MKSTEMP    \
diff --git a/util.c b/util.c
index 91ef4ec..14f9204 100644 (file)
--- a/util.c
+++ b/util.c
@@ -5627,24 +5627,22 @@ Perl_my_dirfd(DIR * dir) {
 #endif 
 }
 
-#ifndef HAS_MKSTEMP
+#if !defined(HAS_MKOSTEMP) || !defined(HAS_MKSTEMP)
 
 #define TEMP_FILE_CH "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvxyz0123456789"
 #define TEMP_FILE_CH_COUNT (sizeof(TEMP_FILE_CH)-1)
 
-int
-Perl_my_mkstemp(char *templte) {
+static int
+S_my_mkostemp(char *templte, int flags) {
     dTHX;
     STRLEN len = strlen(templte);
     int fd;
     int attempts = 0;
 
-    PERL_ARGS_ASSERT_MY_MKSTEMP;
-
     if (len < 6 ||
         templte[len-1] != 'X' || templte[len-2] != 'X' || templte[len-3] != 'X' ||
         templte[len-4] != 'X' || templte[len-5] != 'X' || templte[len-6] != 'X') {
-        errno = EINVAL;
+        SETERRNO(EINVAL, LIB_INVARG);
         return -1;
     }
 
@@ -5653,7 +5651,7 @@ Perl_my_mkstemp(char *templte) {
         for (i = 1; i <= 6; ++i) {
             templte[len-i] = TEMP_FILE_CH[(int)(Perl_internal_drand48() * TEMP_FILE_CH_COUNT)];
         }
-        fd = PerlLIO_open3(templte, O_RDWR | O_CREAT | O_EXCL, 0600);
+        fd = PerlLIO_open3(templte, O_RDWR | O_CREAT | O_EXCL | flags, 0600);
     } while (fd == -1 && errno == EEXIST && ++attempts <= 100);
 
     return fd;
@@ -5661,6 +5659,24 @@ Perl_my_mkstemp(char *templte) {
 
 #endif
 
+#ifndef HAS_MKOSTEMP
+int
+Perl_my_mkostemp(char *templte, int flags)
+{
+    PERL_ARGS_ASSERT_MY_MKOSTEMP;
+    return S_my_mkostemp(templte, flags);
+}
+#endif
+
+#ifndef HAS_MKSTEMP
+int
+Perl_my_mkstemp(char *templte)
+{
+    PERL_ARGS_ASSERT_MY_MKSTEMP;
+    return S_my_mkostemp(templte, 0);
+}
+#endif
+
 REGEXP *
 Perl_get_re_arg(pTHX_ SV *sv) {
 
diff --git a/util.h b/util.h
index 62cb05b..7bec0fc 100644 (file)
--- a/util.h
+++ b/util.h
@@ -241,6 +241,9 @@ means arg not present, 1 is empty string/null byte */
                              (little), (lend) - (little)))
 #endif
 
+#if defined(HAS_MKOSTEMP) && defined(PERL_CORE)
+#   define Perl_my_mkostemp(templte, flags) mkostemp(templte, flags)
+#endif
 #if defined(HAS_MKSTEMP) && defined(PERL_CORE)
 #   define Perl_my_mkstemp(templte) mkstemp(templte)
 #endif