| #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 |