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