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