@matheusbsbs / matheus-bagliano / commits / 00787ed55a
Fork 0

Move gitmkstemps to path.c

This function used to be only a compatibility function, but we're going to extend it and actually use it, so make it part of Git. Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Matthieu Moy committed Feb 22, 2010 at 23:32 UTC 00787ed55adbc2350efa911bf0bdebf6ca08c095
3 files changed +69 -71
Makefile
-1
@@ -1200,7 +1200,6 @@ ifdef NO_MKDTEMP
1200 endif
1201 ifdef NO_MKSTEMPS
1202 COMPAT_CFLAGS += -DNO_MKSTEMPS
1203 - COMPAT_OBJS += compat/mkstemps.o
1203 endif
1204 ifdef NO_UNSETENV
1205 COMPAT_CFLAGS += -DNO_UNSETENV
compat/mkstemps.c deleted
-70
@@ -1,70 +0,0 @@
1 -#include "../git-compat-util.h"
2 -
3 -/* Adapted from libiberty's mkstemp.c. */
4 -
5 -#undef TMP_MAX
6 -#define TMP_MAX 16384
7 -
8 -int gitmkstemps(char *pattern, int suffix_len)
9 -{
10 - static const char letters[] =
11 - "abcdefghijklmnopqrstuvwxyz"
12 - "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
13 - "0123456789";
14 - static const int num_letters = 62;
15 - uint64_t value;
16 - struct timeval tv;
17 - char *template;
18 - size_t len;
19 - int fd, count;
20 -
21 - len = strlen(pattern);
22 -
23 - if (len < 6 + suffix_len) {
24 - errno = EINVAL;
25 - return -1;
26 - }
27 -
28 - if (strncmp(&pattern[len - 6 - suffix_len], "XXXXXX", 6)) {
29 - errno = EINVAL;
30 - return -1;
31 - }
32 -
33 - /*
34 - * Replace pattern's XXXXXX characters with randomness.
35 - * Try TMP_MAX different filenames.
36 - */
37 - gettimeofday(&tv, NULL);
38 - value = ((size_t)(tv.tv_usec << 16)) ^ tv.tv_sec ^ getpid();
39 - template = &pattern[len - 6 - suffix_len];
40 - for (count = 0; count < TMP_MAX; ++count) {
41 - uint64_t v = value;
42 - /* Fill in the random bits. */
43 - template[0] = letters[v % num_letters]; v /= num_letters;
44 - template[1] = letters[v % num_letters]; v /= num_letters;
45 - template[2] = letters[v % num_letters]; v /= num_letters;
46 - template[3] = letters[v % num_letters]; v /= num_letters;
47 - template[4] = letters[v % num_letters]; v /= num_letters;
48 - template[5] = letters[v % num_letters]; v /= num_letters;
49 -
50 - fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, 0600);
51 - if (fd > 0)
52 - return fd;
53 - /*
54 - * Fatal error (EPERM, ENOSPC etc).
55 - * It doesn't make sense to loop.
56 - */
57 - if (errno != EEXIST)
58 - break;
59 - /*
60 - * This is a random value. It is only necessary that
61 - * the next TMP_MAX values generated by adding 7777 to
62 - * VALUE are different with (module 2^32).
63 - */
64 - value += 7777;
65 - }
66 - /* We return the null string if we can't find a unique file name. */
67 - pattern[0] = '\0';
68 - errno = EINVAL;
69 - return -1;
70 -}
path.c
+69
@@ -157,6 +157,75 @@ int git_mkstemps(char *path, size_t len, const char *template, int suffix_len)
157 return mkstemps(path, suffix_len);
158 }
159
160 +/* Adapted from libiberty's mkstemp.c. */
161 +
162 +#undef TMP_MAX
163 +#define TMP_MAX 16384
164 +
165 +int gitmkstemps(char *pattern, int suffix_len)
166 +{
167 + static const char letters[] =
168 + "abcdefghijklmnopqrstuvwxyz"
169 + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
170 + "0123456789";
171 + static const int num_letters = 62;
172 + uint64_t value;
173 + struct timeval tv;
174 + char *template;
175 + size_t len;
176 + int fd, count;
177 +
178 + len = strlen(pattern);
179 +
180 + if (len < 6 + suffix_len) {
181 + errno = EINVAL;
182 + return -1;
183 + }
184 +
185 + if (strncmp(&pattern[len - 6 - suffix_len], "XXXXXX", 6)) {
186 + errno = EINVAL;
187 + return -1;
188 + }
189 +
190 + /*
191 + * Replace pattern's XXXXXX characters with randomness.
192 + * Try TMP_MAX different filenames.
193 + */
194 + gettimeofday(&tv, NULL);
195 + value = ((size_t)(tv.tv_usec << 16)) ^ tv.tv_sec ^ getpid();
196 + template = &pattern[len - 6 - suffix_len];
197 + for (count = 0; count < TMP_MAX; ++count) {
198 + uint64_t v = value;
199 + /* Fill in the random bits. */
200 + template[0] = letters[v % num_letters]; v /= num_letters;
201 + template[1] = letters[v % num_letters]; v /= num_letters;
202 + template[2] = letters[v % num_letters]; v /= num_letters;
203 + template[3] = letters[v % num_letters]; v /= num_letters;
204 + template[4] = letters[v % num_letters]; v /= num_letters;
205 + template[5] = letters[v % num_letters]; v /= num_letters;
206 +
207 + fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, 0600);
208 + if (fd > 0)
209 + return fd;
210 + /*
211 + * Fatal error (EPERM, ENOSPC etc).
212 + * It doesn't make sense to loop.
213 + */
214 + if (errno != EEXIST)
215 + break;
216 + /*
217 + * This is a random value. It is only necessary that
218 + * the next TMP_MAX values generated by adding 7777 to
219 + * VALUE are different with (module 2^32).
220 + */
221 + value += 7777;
222 + }
223 + /* We return the null string if we can't find a unique file name. */
224 + pattern[0] = '\0';
225 + errno = EINVAL;
226 + return -1;
227 +}
228 +
229 int validate_headref(const char *path)
230 {
231 struct stat st;