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