]> git.sven.stormbind.net Git - sven/vym.git/blob - mkdtemp.cpp
17e348a071fcf8b39750e3c8d7e3c5d0f052d849
[sven/vym.git] / 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 <time.h>
14 #include <direct.h>
15 #endif
16
17
18 QString
19 mkdtemp(QString tmpl)
20 {
21     static const char letters[] =
22         "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
23
24     static uint64_t value;
25
26     const unsigned int ATTEMPTS_MIN = (62 * 62 * 62);
27
28     if (tmpl.length() < 6 || !tmpl.endsWith("XXXXXX"))
29     {
30         return QString();
31     }
32
33     uint64_t random_time_bits = time(NULL);
34
35     value += (random_time_bits ^ getpid());
36
37     unsigned int count;
38     for (count = 0; count < ATTEMPTS_MIN; value += 7777, ++count)
39     {
40         uint64_t v = value;
41         QString XXXXXX;
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         v /= 62;
50         XXXXXX.append(letters[v % 62]);
51         v /= 62;
52         XXXXXX.append(letters[v % 62]);
53
54         tmpl.replace(tmpl.length()-6,6,XXXXXX);
55         QDir dir;
56         if (dir.exists(tmpl))
57             continue;
58         if (dir.mkpath(tmpl)){
59             return tmpl;
60         }
61     }
62     return QString();
63 }