]> git.sven.stormbind.net Git - sven/vym.git/blob - src/mkdtemp.cpp
Replace Pierre as the maintainer
[sven/vym.git] / src / mkdtemp.cpp
1
2 #include <QDir>
3 #include <stdint.h>
4 #ifndef _WIN32
5 #include <sys/time.h>
6
7 extern "C" {
8 pid_t getpid(void);
9 }
10 #else
11 #include <windows.h>
12 #define getpid GetCurrentProcessId
13 #include <direct.h>
14 #include <time.h>
15 #endif
16
17 QString mkdtemp(QString tmpl)
18 {
19     static const char letters[] =
20         "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
21
22     static uint64_t value;
23
24     const unsigned int ATTEMPTS_MIN = (62 * 62 * 62);
25
26     if (tmpl.length() < 6 || !tmpl.endsWith("XXXXXX")) {
27         return QString();
28     }
29
30     uint64_t random_time_bits = time(NULL);
31
32     value += (random_time_bits ^ getpid());
33
34     unsigned int count;
35     for (count = 0; count < ATTEMPTS_MIN; value += 7777, ++count) {
36         uint64_t v = value;
37         QString XXXXXX;
38         XXXXXX.append(letters[v % 62]);
39         v /= 62;
40         XXXXXX.append(letters[v % 62]);
41         v /= 62;
42         XXXXXX.append(letters[v % 62]);
43         v /= 62;
44         XXXXXX.append(letters[v % 62]);
45         v /= 62;
46         XXXXXX.append(letters[v % 62]);
47         v /= 62;
48         XXXXXX.append(letters[v % 62]);
49
50         tmpl.replace(tmpl.length() - 6, 6, XXXXXX);
51         QDir dir;
52         if (dir.exists(tmpl))
53             continue;
54         if (dir.mkpath(tmpl)) {
55             return tmpl;
56         }
57     }
58     return QString();
59 }