mkdtemp.cpp
author insilmaril
Tue, 15 Dec 2009 09:14:59 +0000
changeset 818 25ee6b988b73
parent 630 4998bb082c73
permissions -rwxr-xr-x
Fixed A&O report to show subitems
     1 #include <stdint.h>
     2 #include <string.h>
     3 #include <errno.h>
     4 #include <io.h>
     5 #include <sys/time.h>
     6 
     7 extern "C" {
     8 pid_t getpid (void);
     9 }
    10 
    11 char *
    12 mkdtemp(char *tmpl)
    13 {
    14     // Implementation based on GLIBC implementation.
    15 
    16     static const char letters[] =
    17         "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    18 
    19     static uint64_t value;
    20 
    21     const unsigned int ATTEMPTS_MIN = (62 * 62 * 62);
    22 
    23     int save_errno = errno;
    24 
    25     size_t len = strlen(tmpl);
    26     if (len < 6 || strcmp(&tmpl[len - 6], "XXXXXX"))
    27     {
    28         errno = EINVAL;
    29         return NULL;
    30     }
    31 
    32     char *XXXXXX = &tmpl[len - 6];
    33 
    34     uint64_t random_time_bits = time(NULL);
    35 
    36     value += (random_time_bits ^ getpid());
    37 
    38     unsigned int count;
    39     for (count = 0; count < ATTEMPTS_MIN; value += 7777, ++count)
    40     {
    41         uint64_t v = value;
    42 
    43         XXXXXX[0] = letters[v % 62];
    44         v /= 62;
    45         XXXXXX[1] = letters[v % 62];
    46         v /= 62;
    47         XXXXXX[2] = letters[v % 62];
    48         v /= 62;
    49         XXXXXX[3] = letters[v % 62];
    50         v /= 62;
    51         XXXXXX[4] = letters[v % 62];
    52         v /= 62;
    53         XXXXXX[5] = letters[v % 62];
    54 
    55 		if (mkdir(tmpl) == 0)
    56         {
    57             errno = save_errno;
    58 			return tmpl;
    59         }
    60 
    61 		if (errno != EEXIST)
    62 			return NULL;
    63     }
    64 
    65     errno = EEXIST;
    66     return NULL;
    67 }