POSIX mkdtemp() function creates a unique temporary directory from input
template string.

Implementation is copied from mingw-w64-crt/misc/mkstemp.c file with
replaced _sopen() call by the _mkdir() call.
---
 mingw-w64-crt/Makefile.am      |  3 +-
 mingw-w64-crt/misc/mkdtemp.c   | 83 ++++++++++++++++++++++++++++++++++
 mingw-w64-headers/crt/stdlib.h |  1 +
 3 files changed, 86 insertions(+), 1 deletion(-)
 create mode 100644 mingw-w64-crt/misc/mkdtemp.c

diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index ff032f953493..7b025d213242 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -1245,7 +1245,8 @@ src_libmingwex=\
   misc/mempcpy.c         misc/mingw-aligned-malloc.c \
   misc/mingw_matherr.c   misc/mingw_mbwc_convert.c  misc/mingw_usleep.c     
misc/mingw_wcstod.c          misc/mingw_wcstof.c    \
   misc/mingw_wcstold.c \
-  misc/mkstemp.c         misc/sleep.c           \
+  misc/mkstemp.c         misc/mkdtemp.c         \
+  misc/sleep.c           \
   misc/strsafe.c \
   misc/tdelete.c         misc/tdestroy.c            misc/tfind.c           \
   misc/tsearch.c         misc/twalk.c           \
diff --git a/mingw-w64-crt/misc/mkdtemp.c b/mingw-w64-crt/misc/mkdtemp.c
new file mode 100644
index 000000000000..977aff2f13b4
--- /dev/null
+++ b/mingw-w64-crt/misc/mkdtemp.c
@@ -0,0 +1,83 @@
+#define _CRT_RAND_S
+#include <stdlib.h>
+#include <string.h>
+#include <direct.h>
+#include <errno.h>
+#include <time.h>
+#include <limits.h>
+
+/*
+    The mkdtemp() function generates a unique temporary name from template,
+    the creates the directory with that name and returns pointer to the 
modified
+    template string.
+
+    The template may be any name with at least six trailing Xs, for example
+    /tmp/temp.XXXXXXXX. The trailing Xs are replaced with a unique digit and
+    letter combination that makes the file name unique. Since it will be
+    modified, template must not be a string constant, but should be declared as
+    a character array.
+ */
+char *__cdecl mkdtemp (char *template_name)
+{
+    int j, ret, len, index;
+    unsigned int i, r;
+
+    /* These are the (62) characters used in temporary filenames. */
+    static const char letters[] = 
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+    /* The last six characters of template must be "XXXXXX" */
+    if (template_name == NULL || (len = strlen (template_name)) < 6
+            || memcmp (template_name + (len - 6), "XXXXXX", 6)) {
+        errno = EINVAL;
+        return NULL;
+    }
+
+    /* User may supply more than six trailing Xs */
+    for (index = len - 6; index > 0 && template_name[index - 1] == 'X'; 
index--);
+
+    /* Like OpenBSD, mkdtemp() will try 2 ** 31 combinations before giving up. 
*/
+    for (i = 0; i <= INT_MAX; i++) {
+        for(j = index; j < len; j++) {
+            if (rand_s(&r))
+                r = rand() ^ _time32(NULL);
+            template_name[j] = letters[r % 62];
+        }
+        ret = _mkdir(template_name);
+        if (ret == 0) return template_name;
+        if (ret != 0 && errno != EEXIST) return NULL;
+    }
+
+    return NULL;
+}
+
+#if 0
+#include <stdio.h>
+int main ()
+{
+    int i;
+
+    for (i = 0; i < 10; i++) {
+        char template_name[] = { "temp_XXXXXX" };
+        char *name = mkdtemp (template_name);
+        if (name) {
+            fprintf (stderr, "name=%s\n", name);
+            rmdir (name);
+        } else {
+            fprintf (stderr, "errno=%d\n", errno);
+        }
+    }
+
+    for (i = 0; i < 10; i++) {
+        char template_name[] = { "temp_XXXXXXXX" };
+        char *name = mkdtemp (template_name);
+        if (name) {
+            fprintf (stderr, "name=%s\n", name);
+            rmdir (name);
+        } else {
+            fprintf (stderr, "errno=%d\n", errno);
+        }
+    }
+
+    return 0;
+}
+#endif
diff --git a/mingw-w64-headers/crt/stdlib.h b/mingw-w64-headers/crt/stdlib.h
index a53c2ecb1c51..23c653d186f6 100644
--- a/mingw-w64-headers/crt/stdlib.h
+++ b/mingw-w64-headers/crt/stdlib.h
@@ -355,6 +355,7 @@ _CRTIMP int __cdecl ___mb_cur_max_func(void);
   size_t __cdecl mbstowcs(wchar_t * __restrict__ _Dest,const char * 
__restrict__ _Source,size_t _MaxCount);
   _CRTIMP size_t __cdecl _mbstowcs_l(wchar_t * __restrict__ _Dest,const char * 
__restrict__ _Source,size_t _MaxCount,_locale_t _Locale);
   int __cdecl mkstemp(char *template_name);
+  char *__cdecl mkdtemp(char *template_name);
   int __cdecl rand(void);
   _CRTIMP int __cdecl _set_error_mode(int _Mode);
   void __cdecl srand(unsigned int _Seed);
-- 
2.20.1



_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to