mkdtemp.cpp
changeset 721 12958f987bcf
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mkdtemp.cpp	Wed Jul 16 10:46:14 2008 +0000
     1.3 @@ -0,0 +1,67 @@
     1.4 +#include <stdint.h>
     1.5 +#include <string.h>
     1.6 +#include <errno.h>
     1.7 +#include <io.h>
     1.8 +#include <sys/time.h>
     1.9 +
    1.10 +extern "C" {
    1.11 +pid_t getpid (void);
    1.12 +}
    1.13 +
    1.14 +char *
    1.15 +mkdtemp(char *tmpl)
    1.16 +{
    1.17 +    // Implementation based on GLIBC implementation.
    1.18 +
    1.19 +    static const char letters[] =
    1.20 +        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    1.21 +
    1.22 +    static uint64_t value;
    1.23 +
    1.24 +    const unsigned int ATTEMPTS_MIN = (62 * 62 * 62);
    1.25 +
    1.26 +    int save_errno = errno;
    1.27 +
    1.28 +    size_t len = strlen(tmpl);
    1.29 +    if (len < 6 || strcmp(&tmpl[len - 6], "XXXXXX"))
    1.30 +    {
    1.31 +        errno = EINVAL;
    1.32 +        return NULL;
    1.33 +    }
    1.34 +
    1.35 +    char *XXXXXX = &tmpl[len - 6];
    1.36 +
    1.37 +    uint64_t random_time_bits = time(NULL);
    1.38 +
    1.39 +    value += (random_time_bits ^ getpid());
    1.40 +
    1.41 +    unsigned int count;
    1.42 +    for (count = 0; count < ATTEMPTS_MIN; value += 7777, ++count)
    1.43 +    {
    1.44 +        uint64_t v = value;
    1.45 +
    1.46 +        XXXXXX[0] = letters[v % 62];
    1.47 +        v /= 62;
    1.48 +        XXXXXX[1] = letters[v % 62];
    1.49 +        v /= 62;
    1.50 +        XXXXXX[2] = letters[v % 62];
    1.51 +        v /= 62;
    1.52 +        XXXXXX[3] = letters[v % 62];
    1.53 +        v /= 62;
    1.54 +        XXXXXX[4] = letters[v % 62];
    1.55 +        v /= 62;
    1.56 +        XXXXXX[5] = letters[v % 62];
    1.57 +
    1.58 +		if (mkdir(tmpl) == 0)
    1.59 +        {
    1.60 +            errno = save_errno;
    1.61 +			return tmpl;
    1.62 +        }
    1.63 +
    1.64 +		if (errno != EEXIST)
    1.65 +			return NULL;
    1.66 +    }
    1.67 +
    1.68 +    errno = EEXIST;
    1.69 +    return NULL;
    1.70 +}