author | insilmaril |
Fri, 05 Mar 2010 20:16:46 +0000 | |
branch | release-1-12-maintained |
changeset 80 | 5c5b4464b24f |
permissions | -rwxr-xr-x |
insilmaril@80 | 1 |
#include "mkdtemp.h" |
insilmaril@80 | 2 |
#include <stdint.h> |
insilmaril@80 | 3 |
#include <string.h> |
insilmaril@80 | 4 |
#include <errno.h> |
insilmaril@80 | 5 |
#include <io.h> |
insilmaril@80 | 6 |
|
insilmaril@80 | 7 |
char * |
insilmaril@80 | 8 |
mkdtemp(char *tmpl) |
insilmaril@80 | 9 |
{ |
insilmaril@80 | 10 |
// Implementation based on GLIBC implementation. |
insilmaril@80 | 11 |
|
insilmaril@80 | 12 |
static const char letters[] = |
insilmaril@80 | 13 |
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; |
insilmaril@80 | 14 |
|
insilmaril@80 | 15 |
static uint64_t value; |
insilmaril@80 | 16 |
|
insilmaril@80 | 17 |
const unsigned int ATTEMPTS_MIN = (62 * 62 * 62); |
insilmaril@80 | 18 |
|
insilmaril@80 | 19 |
int save_errno = errno; |
insilmaril@80 | 20 |
|
insilmaril@80 | 21 |
size_t len = strlen(tmpl); |
insilmaril@80 | 22 |
if (len < 6 || strcmp(&tmpl[len - 6], "XXXXXX")) |
insilmaril@80 | 23 |
{ |
insilmaril@80 | 24 |
errno = EINVAL; |
insilmaril@80 | 25 |
return NULL; |
insilmaril@80 | 26 |
} |
insilmaril@80 | 27 |
|
insilmaril@80 | 28 |
char *XXXXXX = &tmpl[len - 6]; |
insilmaril@80 | 29 |
|
insilmaril@80 | 30 |
uint64_t random_time_bits = time(NULL); |
insilmaril@80 | 31 |
|
insilmaril@80 | 32 |
value += (random_time_bits ^ getpid()); |
insilmaril@80 | 33 |
|
insilmaril@80 | 34 |
unsigned int count; |
insilmaril@80 | 35 |
for (count = 0; count < ATTEMPTS_MIN; value += 7777, ++count) |
insilmaril@80 | 36 |
{ |
insilmaril@80 | 37 |
uint64_t v = value; |
insilmaril@80 | 38 |
|
insilmaril@80 | 39 |
XXXXXX[0] = letters[v % 62]; |
insilmaril@80 | 40 |
v /= 62; |
insilmaril@80 | 41 |
XXXXXX[1] = letters[v % 62]; |
insilmaril@80 | 42 |
v /= 62; |
insilmaril@80 | 43 |
XXXXXX[2] = letters[v % 62]; |
insilmaril@80 | 44 |
v /= 62; |
insilmaril@80 | 45 |
XXXXXX[3] = letters[v % 62]; |
insilmaril@80 | 46 |
v /= 62; |
insilmaril@80 | 47 |
XXXXXX[4] = letters[v % 62]; |
insilmaril@80 | 48 |
v /= 62; |
insilmaril@80 | 49 |
XXXXXX[5] = letters[v % 62]; |
insilmaril@80 | 50 |
|
insilmaril@80 | 51 |
if (mkdir(tmpl) == 0) |
insilmaril@80 | 52 |
{ |
insilmaril@80 | 53 |
errno = save_errno; |
insilmaril@80 | 54 |
return tmpl; |
insilmaril@80 | 55 |
} |
insilmaril@80 | 56 |
|
insilmaril@80 | 57 |
if (errno != EEXIST) |
insilmaril@80 | 58 |
return NULL; |
insilmaril@80 | 59 |
} |
insilmaril@80 | 60 |
|
insilmaril@80 | 61 |
errno = EEXIST; |
insilmaril@80 | 62 |
return NULL; |
insilmaril@80 | 63 |
} |