insilmaril@80: #include "mkdtemp.h" insilmaril@80: #include insilmaril@80: #include insilmaril@80: #include insilmaril@80: #include insilmaril@80: insilmaril@80: char * insilmaril@80: mkdtemp(char *tmpl) insilmaril@80: { insilmaril@80: // Implementation based on GLIBC implementation. insilmaril@80: insilmaril@80: static const char letters[] = insilmaril@80: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; insilmaril@80: insilmaril@80: static uint64_t value; insilmaril@80: insilmaril@80: const unsigned int ATTEMPTS_MIN = (62 * 62 * 62); insilmaril@80: insilmaril@80: int save_errno = errno; insilmaril@80: insilmaril@80: size_t len = strlen(tmpl); insilmaril@80: if (len < 6 || strcmp(&tmpl[len - 6], "XXXXXX")) insilmaril@80: { insilmaril@80: errno = EINVAL; insilmaril@80: return NULL; insilmaril@80: } insilmaril@80: insilmaril@80: char *XXXXXX = &tmpl[len - 6]; insilmaril@80: insilmaril@80: uint64_t random_time_bits = time(NULL); insilmaril@80: insilmaril@80: value += (random_time_bits ^ getpid()); insilmaril@80: insilmaril@80: unsigned int count; insilmaril@80: for (count = 0; count < ATTEMPTS_MIN; value += 7777, ++count) insilmaril@80: { insilmaril@80: uint64_t v = value; insilmaril@80: insilmaril@80: XXXXXX[0] = letters[v % 62]; insilmaril@80: v /= 62; insilmaril@80: XXXXXX[1] = letters[v % 62]; insilmaril@80: v /= 62; insilmaril@80: XXXXXX[2] = letters[v % 62]; insilmaril@80: v /= 62; insilmaril@80: XXXXXX[3] = letters[v % 62]; insilmaril@80: v /= 62; insilmaril@80: XXXXXX[4] = letters[v % 62]; insilmaril@80: v /= 62; insilmaril@80: XXXXXX[5] = letters[v % 62]; insilmaril@80: insilmaril@80: if (mkdir(tmpl) == 0) insilmaril@80: { insilmaril@80: errno = save_errno; insilmaril@80: return tmpl; insilmaril@80: } insilmaril@80: insilmaril@80: if (errno != EEXIST) insilmaril@80: return NULL; insilmaril@80: } insilmaril@80: insilmaril@80: errno = EEXIST; insilmaril@80: return NULL; insilmaril@80: }