Line | Count | Source |
1 | | /* |
2 | | * Various trivial helper wrappers around standard functions |
3 | | */ |
4 | | |
5 | | #define DISABLE_SIGN_COMPARE_WARNINGS |
6 | | |
7 | | #include "git-compat-util.h" |
8 | | #include "abspath.h" |
9 | | #include "parse.h" |
10 | | #include "gettext.h" |
11 | | #include "strbuf.h" |
12 | | #include "trace2.h" |
13 | | |
14 | | #ifdef HAVE_RTLGENRANDOM |
15 | | /* This is required to get access to RtlGenRandom. */ |
16 | | #define SystemFunction036 NTAPI SystemFunction036 |
17 | | #include <ntsecapi.h> |
18 | | #undef SystemFunction036 |
19 | | #endif |
20 | | |
21 | | static int memory_limit_check(size_t size, int gentle) |
22 | 2.79k | { |
23 | 2.79k | static size_t limit = 0; |
24 | 2.79k | if (!limit) { |
25 | 1 | limit = git_env_ulong("GIT_ALLOC_LIMIT", 0); |
26 | 1 | if (!limit) |
27 | 1 | limit = SIZE_MAX; |
28 | 1 | } |
29 | 2.79k | if (size > limit) { |
30 | 0 | if (gentle) { |
31 | 0 | error("attempting to allocate %"PRIuMAX" over limit %"PRIuMAX, |
32 | 0 | (uintmax_t)size, (uintmax_t)limit); |
33 | 0 | return -1; |
34 | 0 | } else |
35 | 0 | die("attempting to allocate %"PRIuMAX" over limit %"PRIuMAX, |
36 | 0 | (uintmax_t)size, (uintmax_t)limit); |
37 | 0 | } |
38 | 2.79k | return 0; |
39 | 2.79k | } |
40 | | |
41 | | char *xstrdup(const char *str) |
42 | 0 | { |
43 | 0 | char *ret = strdup(str); |
44 | 0 | if (!ret) |
45 | 0 | die("Out of memory, strdup failed"); |
46 | 0 | return ret; |
47 | 0 | } |
48 | | |
49 | | static void *do_xmalloc(size_t size, int gentle) |
50 | 824 | { |
51 | 824 | void *ret; |
52 | | |
53 | 824 | if (memory_limit_check(size, gentle)) |
54 | 0 | return NULL; |
55 | 824 | ret = malloc(size); |
56 | 824 | if (!ret && !size) |
57 | 0 | ret = malloc(1); |
58 | 824 | if (!ret) { |
59 | 0 | if (!gentle) |
60 | 0 | die("Out of memory, malloc failed (tried to allocate %lu bytes)", |
61 | 0 | (unsigned long)size); |
62 | 0 | else { |
63 | 0 | error("Out of memory, malloc failed (tried to allocate %lu bytes)", |
64 | 0 | (unsigned long)size); |
65 | 0 | return NULL; |
66 | 0 | } |
67 | 0 | } |
68 | | #ifdef XMALLOC_POISON |
69 | | memset(ret, 0xA5, size); |
70 | | #endif |
71 | 824 | return ret; |
72 | 824 | } |
73 | | |
74 | | void *xmalloc(size_t size) |
75 | 385 | { |
76 | 385 | return do_xmalloc(size, 0); |
77 | 385 | } |
78 | | |
79 | | static void *do_xmallocz(size_t size, int gentle) |
80 | 439 | { |
81 | 439 | void *ret; |
82 | 439 | if (unsigned_add_overflows(size, 1)) { |
83 | 0 | if (gentle) { |
84 | 0 | error("Data too large to fit into virtual memory space."); |
85 | 0 | return NULL; |
86 | 0 | } else |
87 | 0 | die("Data too large to fit into virtual memory space."); |
88 | 0 | } |
89 | 439 | ret = do_xmalloc(size + 1, gentle); |
90 | 439 | if (ret) |
91 | 439 | ((char*)ret)[size] = 0; |
92 | 439 | return ret; |
93 | 439 | } |
94 | | |
95 | | void *xmallocz(size_t size) |
96 | 439 | { |
97 | 439 | return do_xmallocz(size, 0); |
98 | 439 | } |
99 | | |
100 | | void *xmallocz_gently(size_t size) |
101 | 0 | { |
102 | 0 | return do_xmallocz(size, 1); |
103 | 0 | } |
104 | | |
105 | | /* |
106 | | * xmemdupz() allocates (len + 1) bytes of memory, duplicates "len" bytes of |
107 | | * "data" to the allocated memory, zero terminates the allocated memory, |
108 | | * and returns a pointer to the allocated memory. If the allocation fails, |
109 | | * the program dies. |
110 | | */ |
111 | | void *xmemdupz(const void *data, size_t len) |
112 | 439 | { |
113 | 439 | return memcpy(xmallocz(len), data, len); |
114 | 439 | } |
115 | | |
116 | | char *xstrndup(const char *str, size_t len) |
117 | 0 | { |
118 | 0 | const char *p = memchr(str, '\0', len); |
119 | 0 | return xmemdupz(str, p ? p - str : len); |
120 | 0 | } |
121 | | |
122 | | int xstrncmpz(const char *s, const char *t, size_t len) |
123 | 0 | { |
124 | 0 | int res = strncmp(s, t, len); |
125 | 0 | if (res) |
126 | 0 | return res; |
127 | 0 | return s[len] == '\0' ? 0 : 1; |
128 | 0 | } |
129 | | |
130 | | void *xrealloc(void *ptr, size_t size) |
131 | 943 | { |
132 | 943 | void *ret; |
133 | | |
134 | 943 | if (!size) { |
135 | 0 | free(ptr); |
136 | 0 | return xmalloc(0); |
137 | 0 | } |
138 | | |
139 | 943 | memory_limit_check(size, 0); |
140 | 943 | ret = realloc(ptr, size); |
141 | 943 | if (!ret) |
142 | 0 | die("Out of memory, realloc failed"); |
143 | 943 | return ret; |
144 | 943 | } |
145 | | |
146 | | void *xcalloc(size_t nmemb, size_t size) |
147 | 1.02k | { |
148 | 1.02k | void *ret; |
149 | | |
150 | 1.02k | if (unsigned_mult_overflows(nmemb, size)) |
151 | 0 | die("data too large to fit into virtual memory space"); |
152 | | |
153 | 1.02k | memory_limit_check(size * nmemb, 0); |
154 | 1.02k | ret = calloc(nmemb, size); |
155 | 1.02k | if (!ret && (!nmemb || !size)) |
156 | 0 | ret = calloc(1, 1); |
157 | 1.02k | if (!ret) |
158 | 0 | die("Out of memory, calloc failed"); |
159 | 1.02k | return ret; |
160 | 1.02k | } |
161 | | |
162 | | void xsetenv(const char *name, const char *value, int overwrite) |
163 | 0 | { |
164 | 0 | if (setenv(name, value, overwrite)) |
165 | 0 | die_errno(_("could not setenv '%s'"), name ? name : "(null)"); |
166 | 0 | } |
167 | | |
168 | | /** |
169 | | * xopen() is the same as open(), but it die()s if the open() fails. |
170 | | */ |
171 | | int xopen(const char *path, int oflag, ...) |
172 | 0 | { |
173 | 0 | mode_t mode = 0; |
174 | 0 | va_list ap; |
175 | | |
176 | | /* |
177 | | * va_arg() will have undefined behavior if the specified type is not |
178 | | * compatible with the argument type. Since integers are promoted to |
179 | | * ints, we fetch the next argument as an int, and then cast it to a |
180 | | * mode_t to avoid undefined behavior. |
181 | | */ |
182 | 0 | va_start(ap, oflag); |
183 | 0 | if (oflag & O_CREAT) |
184 | 0 | mode = va_arg(ap, int); |
185 | 0 | va_end(ap); |
186 | |
|
187 | 0 | for (;;) { |
188 | 0 | int fd = open(path, oflag, mode); |
189 | 0 | if (fd >= 0) |
190 | 0 | return fd; |
191 | 0 | if (errno == EINTR) |
192 | 0 | continue; |
193 | | |
194 | 0 | if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) |
195 | 0 | die_errno(_("unable to create '%s'"), path); |
196 | 0 | else if ((oflag & O_RDWR) == O_RDWR) |
197 | 0 | die_errno(_("could not open '%s' for reading and writing"), path); |
198 | 0 | else if ((oflag & O_WRONLY) == O_WRONLY) |
199 | 0 | die_errno(_("could not open '%s' for writing"), path); |
200 | 0 | else |
201 | 0 | die_errno(_("could not open '%s' for reading"), path); |
202 | 0 | } |
203 | 0 | } |
204 | | |
205 | | static int handle_nonblock(int fd, short poll_events, int err) |
206 | 0 | { |
207 | 0 | struct pollfd pfd; |
208 | |
|
209 | 0 | if (err != EAGAIN && err != EWOULDBLOCK) |
210 | 0 | return 0; |
211 | | |
212 | 0 | pfd.fd = fd; |
213 | 0 | pfd.events = poll_events; |
214 | | |
215 | | /* |
216 | | * no need to check for errors, here; |
217 | | * a subsequent read/write will detect unrecoverable errors |
218 | | */ |
219 | 0 | poll(&pfd, 1, -1); |
220 | 0 | return 1; |
221 | 0 | } |
222 | | |
223 | | /* |
224 | | * xread() is the same a read(), but it automatically restarts read() |
225 | | * operations with a recoverable error (EAGAIN and EINTR). xread() |
226 | | * DOES NOT GUARANTEE that "len" bytes is read even if the data is available. |
227 | | */ |
228 | | ssize_t xread(int fd, void *buf, size_t len) |
229 | 0 | { |
230 | 0 | ssize_t nr; |
231 | 0 | if (len > MAX_IO_SIZE) |
232 | 0 | len = MAX_IO_SIZE; |
233 | 0 | while (1) { |
234 | 0 | nr = read(fd, buf, len); |
235 | 0 | if (nr < 0) { |
236 | 0 | if (errno == EINTR) |
237 | 0 | continue; |
238 | 0 | if (handle_nonblock(fd, POLLIN, errno)) |
239 | 0 | continue; |
240 | 0 | } |
241 | 0 | return nr; |
242 | 0 | } |
243 | 0 | } |
244 | | |
245 | | /* |
246 | | * xwrite() is the same a write(), but it automatically restarts write() |
247 | | * operations with a recoverable error (EAGAIN and EINTR). xwrite() DOES NOT |
248 | | * GUARANTEE that "len" bytes is written even if the operation is successful. |
249 | | */ |
250 | | ssize_t xwrite(int fd, const void *buf, size_t len) |
251 | 13 | { |
252 | 13 | ssize_t nr; |
253 | 13 | if (len > MAX_IO_SIZE) |
254 | 0 | len = MAX_IO_SIZE; |
255 | 13 | while (1) { |
256 | 13 | nr = write(fd, buf, len); |
257 | 13 | if (nr < 0) { |
258 | 0 | if (errno == EINTR) |
259 | 0 | continue; |
260 | 0 | if (handle_nonblock(fd, POLLOUT, errno)) |
261 | 0 | continue; |
262 | 0 | } |
263 | | |
264 | 13 | return nr; |
265 | 13 | } |
266 | 13 | } |
267 | | |
268 | | /* |
269 | | * xpread() is the same as pread(), but it automatically restarts pread() |
270 | | * operations with a recoverable error (EAGAIN and EINTR). xpread() DOES |
271 | | * NOT GUARANTEE that "len" bytes is read even if the data is available. |
272 | | */ |
273 | | ssize_t xpread(int fd, void *buf, size_t len, off_t offset) |
274 | 0 | { |
275 | 0 | ssize_t nr; |
276 | 0 | if (len > MAX_IO_SIZE) |
277 | 0 | len = MAX_IO_SIZE; |
278 | 0 | while (1) { |
279 | 0 | nr = pread(fd, buf, len, offset); |
280 | 0 | if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) |
281 | 0 | continue; |
282 | 0 | return nr; |
283 | 0 | } |
284 | 0 | } |
285 | | |
286 | | ssize_t read_in_full(int fd, void *buf, size_t count) |
287 | 0 | { |
288 | 0 | char *p = buf; |
289 | 0 | ssize_t total = 0; |
290 | |
|
291 | 0 | while (count > 0) { |
292 | 0 | ssize_t loaded = xread(fd, p, count); |
293 | 0 | if (loaded < 0) |
294 | 0 | return -1; |
295 | 0 | if (loaded == 0) |
296 | 0 | return total; |
297 | 0 | count -= loaded; |
298 | 0 | p += loaded; |
299 | 0 | total += loaded; |
300 | 0 | } |
301 | | |
302 | 0 | return total; |
303 | 0 | } |
304 | | |
305 | | ssize_t write_in_full(int fd, const void *buf, size_t count) |
306 | 13 | { |
307 | 13 | const char *p = buf; |
308 | 13 | ssize_t total = 0; |
309 | | |
310 | 26 | while (count > 0) { |
311 | 13 | ssize_t written = xwrite(fd, p, count); |
312 | 13 | if (written < 0) |
313 | 0 | return -1; |
314 | 13 | if (!written) { |
315 | 0 | errno = ENOSPC; |
316 | 0 | return -1; |
317 | 0 | } |
318 | 13 | count -= written; |
319 | 13 | p += written; |
320 | 13 | total += written; |
321 | 13 | } |
322 | | |
323 | 13 | return total; |
324 | 13 | } |
325 | | |
326 | | ssize_t xwritev(int fd, struct iovec *iov, int iovcnt) |
327 | 0 | { |
328 | 0 | size_t allowed = MAX_IO_SIZE; |
329 | 0 | int i; |
330 | | |
331 | | /* |
332 | | * Some platforms define a comparatively small `MAX_IO_SIZE` that |
333 | | * limits how many bytes can be written with a single call to |
334 | | * write(3p) or writev(3p); exceeding that limit causes the syscall to |
335 | | * fail with EINVAL. Just like xwrite() chomps overly large requests |
336 | | * for write(3p), pretend that the underlying writev(3p) performed a |
337 | | * short write by only passing along the leading iovec entries that |
338 | | * fit into that limit. |
339 | | */ |
340 | 0 | for (i = 0; i < iovcnt; i++) { |
341 | 0 | if (iov[i].iov_len > allowed) { |
342 | | /* |
343 | | * If the first buffer is larger than MAX_IO_SIZE, |
344 | | * let xwrite() deal with it. |
345 | | */ |
346 | 0 | if (!i) |
347 | 0 | return xwrite(fd, iov->iov_base, iov->iov_len); |
348 | 0 | break; |
349 | 0 | } |
350 | 0 | allowed -= iov[i].iov_len; |
351 | 0 | } |
352 | | |
353 | 0 | while (1) { |
354 | 0 | ssize_t bytes_written = writev(fd, iov, i); |
355 | 0 | if (bytes_written < 0) { |
356 | 0 | if (errno == EINTR) |
357 | 0 | continue; |
358 | 0 | if (handle_nonblock(fd, POLLOUT, errno)) |
359 | 0 | continue; |
360 | 0 | } |
361 | | |
362 | 0 | return bytes_written; |
363 | 0 | } |
364 | 0 | } |
365 | | |
366 | | ssize_t writev_in_full(int fd, struct iovec *iov, int iovcnt) |
367 | 0 | { |
368 | 0 | ssize_t total_written = 0; |
369 | |
|
370 | 0 | while (iovcnt) { |
371 | 0 | ssize_t bytes_written = xwritev(fd, iov, iovcnt); |
372 | 0 | if (bytes_written < 0) |
373 | 0 | return -1; |
374 | 0 | if (!bytes_written) { |
375 | 0 | errno = ENOSPC; |
376 | 0 | return -1; |
377 | 0 | } |
378 | | |
379 | 0 | if (signed_add_overflows(total_written, bytes_written)) { |
380 | 0 | errno = EOVERFLOW; |
381 | 0 | return -1; |
382 | 0 | } |
383 | 0 | total_written += bytes_written; |
384 | | |
385 | | /* |
386 | | * We first need to discard any iovec entities that have been |
387 | | * fully written. |
388 | | */ |
389 | 0 | while (iovcnt && (size_t)bytes_written >= iov->iov_len) { |
390 | 0 | bytes_written -= iov->iov_len; |
391 | 0 | iov++; |
392 | 0 | iovcnt--; |
393 | 0 | } |
394 | | |
395 | | /* |
396 | | * Finally, we need to adjust the last iovec in case we have |
397 | | * performed a partial write. |
398 | | */ |
399 | 0 | if (iovcnt && bytes_written) { |
400 | 0 | iov->iov_base = (char *) iov->iov_base + bytes_written; |
401 | 0 | iov->iov_len -= bytes_written; |
402 | 0 | } |
403 | 0 | } |
404 | | |
405 | 0 | return total_written; |
406 | 0 | } |
407 | | |
408 | | ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset) |
409 | 0 | { |
410 | 0 | char *p = buf; |
411 | 0 | ssize_t total = 0; |
412 | |
|
413 | 0 | while (count > 0) { |
414 | 0 | ssize_t loaded = xpread(fd, p, count, offset); |
415 | 0 | if (loaded < 0) |
416 | 0 | return -1; |
417 | 0 | if (loaded == 0) |
418 | 0 | return total; |
419 | 0 | count -= loaded; |
420 | 0 | p += loaded; |
421 | 0 | total += loaded; |
422 | 0 | offset += loaded; |
423 | 0 | } |
424 | | |
425 | 0 | return total; |
426 | 0 | } |
427 | | |
428 | | int xdup(int fd) |
429 | 0 | { |
430 | 0 | int ret = dup(fd); |
431 | 0 | if (ret < 0) |
432 | 0 | die_errno("dup failed"); |
433 | 0 | return ret; |
434 | 0 | } |
435 | | |
436 | | /** |
437 | | * xfopen() is the same as fopen(), but it die()s if the fopen() fails. |
438 | | */ |
439 | | FILE *xfopen(const char *path, const char *mode) |
440 | 0 | { |
441 | 0 | for (;;) { |
442 | 0 | FILE *fp = fopen(path, mode); |
443 | 0 | if (fp) |
444 | 0 | return fp; |
445 | 0 | if (errno == EINTR) |
446 | 0 | continue; |
447 | | |
448 | 0 | if (*mode && mode[1] == '+') |
449 | 0 | die_errno(_("could not open '%s' for reading and writing"), path); |
450 | 0 | else if (*mode == 'w' || *mode == 'a') |
451 | 0 | die_errno(_("could not open '%s' for writing"), path); |
452 | 0 | else |
453 | 0 | die_errno(_("could not open '%s' for reading"), path); |
454 | 0 | } |
455 | 0 | } |
456 | | |
457 | | FILE *xfdopen(int fd, const char *mode) |
458 | 0 | { |
459 | 0 | FILE *stream = fdopen(fd, mode); |
460 | 0 | if (!stream) |
461 | 0 | die_errno("Out of memory? fdopen failed"); |
462 | 0 | return stream; |
463 | 0 | } |
464 | | |
465 | | FILE *fopen_for_writing(const char *path) |
466 | 0 | { |
467 | 0 | FILE *ret = fopen(path, "w"); |
468 | |
|
469 | 0 | if (!ret && errno == EPERM) { |
470 | 0 | if (!unlink(path)) |
471 | 0 | ret = fopen(path, "w"); |
472 | 0 | else |
473 | 0 | errno = EPERM; |
474 | 0 | } |
475 | 0 | return ret; |
476 | 0 | } |
477 | | |
478 | | static void warn_on_inaccessible(const char *path) |
479 | 0 | { |
480 | 0 | warning_errno(_("unable to access '%s'"), path); |
481 | 0 | } |
482 | | |
483 | | int warn_on_fopen_errors(const char *path) |
484 | 0 | { |
485 | 0 | if (errno != ENOENT && errno != ENOTDIR) { |
486 | 0 | warn_on_inaccessible(path); |
487 | 0 | return -1; |
488 | 0 | } |
489 | | |
490 | 0 | return 0; |
491 | 0 | } |
492 | | |
493 | | FILE *fopen_or_warn(const char *path, const char *mode) |
494 | 0 | { |
495 | 0 | FILE *fp = fopen(path, mode); |
496 | |
|
497 | 0 | if (fp) |
498 | 0 | return fp; |
499 | | |
500 | 0 | warn_on_fopen_errors(path); |
501 | 0 | return NULL; |
502 | 0 | } |
503 | | |
504 | | int xmkstemp(char *filename_template) |
505 | 0 | { |
506 | 0 | return xmkstemp_mode(filename_template, 0600); |
507 | 0 | } |
508 | | |
509 | | /* Adapted from libiberty's mkstemp.c. */ |
510 | | |
511 | | #undef TMP_MAX |
512 | 0 | #define TMP_MAX 16384 |
513 | | |
514 | | /* |
515 | | * Returns -1 on error, 0 if it created a directory, or an open file |
516 | | * descriptor to the created regular file. |
517 | | */ |
518 | | static int git_mkdstemps_mode(char *pattern, int suffix_len, int mode, bool dir) |
519 | 0 | { |
520 | 0 | static const char letters[] = |
521 | 0 | "abcdefghijklmnopqrstuvwxyz" |
522 | 0 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
523 | 0 | "0123456789"; |
524 | 0 | static const int num_letters = ARRAY_SIZE(letters) - 1; |
525 | 0 | static const char x_pattern[] = "XXXXXX"; |
526 | 0 | static const int num_x = ARRAY_SIZE(x_pattern) - 1; |
527 | 0 | char *filename_template; |
528 | 0 | size_t len; |
529 | 0 | int fd, count; |
530 | |
|
531 | 0 | len = strlen(pattern); |
532 | |
|
533 | 0 | if (len < num_x + suffix_len) { |
534 | 0 | errno = EINVAL; |
535 | 0 | return -1; |
536 | 0 | } |
537 | | |
538 | 0 | if (strncmp(&pattern[len - num_x - suffix_len], x_pattern, num_x)) { |
539 | 0 | errno = EINVAL; |
540 | 0 | return -1; |
541 | 0 | } |
542 | | |
543 | | /* |
544 | | * Replace pattern's XXXXXX characters with randomness. |
545 | | * Try TMP_MAX different filenames. |
546 | | */ |
547 | 0 | filename_template = &pattern[len - num_x - suffix_len]; |
548 | 0 | for (count = 0; count < TMP_MAX; ++count) { |
549 | 0 | int i; |
550 | 0 | uint64_t v; |
551 | 0 | if (csprng_bytes(&v, sizeof(v), 0) < 0) |
552 | 0 | return error_errno("unable to get random bytes for temporary file"); |
553 | | |
554 | | /* Fill in the random bits. */ |
555 | 0 | for (i = 0; i < num_x; i++) { |
556 | 0 | filename_template[i] = letters[v % num_letters]; |
557 | 0 | v /= num_letters; |
558 | 0 | } |
559 | |
|
560 | 0 | if (dir) |
561 | 0 | fd = mkdir(pattern, mode); |
562 | 0 | else |
563 | 0 | fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode); |
564 | 0 | if (fd >= 0) |
565 | 0 | return fd; |
566 | | /* |
567 | | * Fatal error (EPERM, ENOSPC etc). |
568 | | * It doesn't make sense to loop. |
569 | | */ |
570 | 0 | if (errno != EEXIST) |
571 | 0 | break; |
572 | 0 | } |
573 | | /* We return the null string if we can't find a unique file name. */ |
574 | 0 | pattern[0] = '\0'; |
575 | 0 | return -1; |
576 | 0 | } |
577 | | |
578 | | char *git_mkdtemp(char *pattern) |
579 | 0 | { |
580 | 0 | return git_mkdstemps_mode(pattern, 0, 0700, true) ? NULL : pattern; |
581 | 0 | } |
582 | | |
583 | | int git_mkstemps_mode(char *pattern, int suffix_len, int mode) |
584 | 0 | { |
585 | 0 | return git_mkdstemps_mode(pattern, suffix_len, mode, false); |
586 | 0 | } |
587 | | |
588 | | int git_mkstemp_mode(char *pattern, int mode) |
589 | 0 | { |
590 | | /* mkstemp is just mkstemps with no suffix */ |
591 | 0 | return git_mkstemps_mode(pattern, 0, mode); |
592 | 0 | } |
593 | | |
594 | | int xmkstemp_mode(char *filename_template, int mode) |
595 | 0 | { |
596 | 0 | int fd; |
597 | 0 | char origtemplate[PATH_MAX]; |
598 | 0 | strlcpy(origtemplate, filename_template, sizeof(origtemplate)); |
599 | |
|
600 | 0 | fd = git_mkstemp_mode(filename_template, mode); |
601 | 0 | if (fd < 0) { |
602 | 0 | int saved_errno = errno; |
603 | 0 | const char *nonrelative_template; |
604 | |
|
605 | 0 | if (!filename_template[0]) |
606 | 0 | filename_template = origtemplate; |
607 | |
|
608 | 0 | nonrelative_template = absolute_path(filename_template); |
609 | 0 | errno = saved_errno; |
610 | 0 | die_errno("Unable to create temporary file '%s'", |
611 | 0 | nonrelative_template); |
612 | 0 | } |
613 | 0 | return fd; |
614 | 0 | } |
615 | | |
616 | | /* |
617 | | * Some platforms return EINTR from fsync. Since fsync is invoked in some |
618 | | * cases by a wrapper that dies on failure, do not expose EINTR to callers. |
619 | | */ |
620 | | static int fsync_loop(int fd) |
621 | 0 | { |
622 | 0 | int err; |
623 | |
|
624 | 0 | do { |
625 | 0 | err = fsync(fd); |
626 | 0 | } while (err < 0 && errno == EINTR); |
627 | 0 | return err; |
628 | 0 | } |
629 | | |
630 | | int git_fsync(int fd, enum fsync_action action) |
631 | 0 | { |
632 | 0 | switch (action) { |
633 | 0 | case FSYNC_WRITEOUT_ONLY: |
634 | 0 | trace2_counter_add(TRACE2_COUNTER_ID_FSYNC_WRITEOUT_ONLY, 1); |
635 | |
|
636 | | #ifdef __APPLE__ |
637 | | /* |
638 | | * On macOS, fsync just causes filesystem cache writeback but |
639 | | * does not flush hardware caches. |
640 | | */ |
641 | | return fsync_loop(fd); |
642 | | #endif |
643 | |
|
644 | 0 | #ifdef HAVE_SYNC_FILE_RANGE |
645 | | /* |
646 | | * On linux 2.6.17 and above, sync_file_range is the way to |
647 | | * issue a writeback without a hardware flush. An offset of |
648 | | * 0 and size of 0 indicates writeout of the entire file and the |
649 | | * wait flags ensure that all dirty data is written to the disk |
650 | | * (potentially in a disk-side cache) before we continue. |
651 | | */ |
652 | |
|
653 | 0 | return sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WAIT_BEFORE | |
654 | 0 | SYNC_FILE_RANGE_WRITE | |
655 | 0 | SYNC_FILE_RANGE_WAIT_AFTER); |
656 | 0 | #endif |
657 | | |
658 | | #ifdef fsync_no_flush |
659 | | return fsync_no_flush(fd); |
660 | | #endif |
661 | | |
662 | 0 | errno = ENOSYS; |
663 | 0 | return -1; |
664 | | |
665 | 0 | case FSYNC_HARDWARE_FLUSH: |
666 | 0 | trace2_counter_add(TRACE2_COUNTER_ID_FSYNC_HARDWARE_FLUSH, 1); |
667 | | |
668 | | /* |
669 | | * On macOS, a special fcntl is required to really flush the |
670 | | * caches within the storage controller. As of this writing, |
671 | | * this is a very expensive operation on Apple SSDs. |
672 | | */ |
673 | | #ifdef __APPLE__ |
674 | | return fcntl(fd, F_FULLFSYNC); |
675 | | #else |
676 | 0 | return fsync_loop(fd); |
677 | 0 | #endif |
678 | 0 | default: |
679 | 0 | BUG("unexpected git_fsync(%d) call", action); |
680 | 0 | } |
681 | 0 | } |
682 | | |
683 | | static int warn_if_unremovable(const char *op, const char *file, int rc) |
684 | 0 | { |
685 | 0 | int err; |
686 | 0 | if (!rc || errno == ENOENT) |
687 | 0 | return 0; |
688 | 0 | err = errno; |
689 | 0 | warning_errno("unable to %s '%s'", op, file); |
690 | 0 | errno = err; |
691 | 0 | return rc; |
692 | 0 | } |
693 | | |
694 | | int unlink_or_msg(const char *file, struct strbuf *err) |
695 | 0 | { |
696 | 0 | int rc = unlink(file); |
697 | |
|
698 | 0 | assert(err); |
699 | |
|
700 | 0 | if (!rc || errno == ENOENT) |
701 | 0 | return 0; |
702 | | |
703 | 0 | strbuf_addf(err, "unable to unlink '%s': %s", |
704 | 0 | file, strerror(errno)); |
705 | 0 | return -1; |
706 | 0 | } |
707 | | |
708 | | int unlink_or_warn(const char *file) |
709 | 0 | { |
710 | 0 | return warn_if_unremovable("unlink", file, unlink(file)); |
711 | 0 | } |
712 | | |
713 | | int rmdir_or_warn(const char *file) |
714 | 0 | { |
715 | 0 | return warn_if_unremovable("rmdir", file, rmdir(file)); |
716 | 0 | } |
717 | | |
718 | | static int access_error_is_ok(int err, unsigned flag) |
719 | 0 | { |
720 | 0 | return (is_missing_file_error(err) || |
721 | 0 | ((flag & ACCESS_EACCES_OK) && err == EACCES)); |
722 | 0 | } |
723 | | |
724 | | int access_or_warn(const char *path, int mode, unsigned flag) |
725 | 0 | { |
726 | 0 | int ret = access(path, mode); |
727 | 0 | if (ret && !access_error_is_ok(errno, flag)) |
728 | 0 | warn_on_inaccessible(path); |
729 | 0 | return ret; |
730 | 0 | } |
731 | | |
732 | | int access_or_die(const char *path, int mode, unsigned flag) |
733 | 0 | { |
734 | 0 | int ret = access(path, mode); |
735 | 0 | if (ret && !access_error_is_ok(errno, flag)) |
736 | 0 | die_errno(_("unable to access '%s'"), path); |
737 | 0 | return ret; |
738 | 0 | } |
739 | | |
740 | | char *xgetcwd(void) |
741 | 0 | { |
742 | 0 | struct strbuf sb = STRBUF_INIT; |
743 | 0 | if (strbuf_getcwd(&sb)) |
744 | 0 | die_errno(_("unable to get current working directory")); |
745 | 0 | return strbuf_detach(&sb, NULL); |
746 | 0 | } |
747 | | |
748 | | int xsnprintf(char *dst, size_t max, const char *fmt, ...) |
749 | 0 | { |
750 | 0 | va_list ap; |
751 | 0 | int len; |
752 | |
|
753 | 0 | va_start(ap, fmt); |
754 | 0 | len = vsnprintf(dst, max, fmt, ap); |
755 | 0 | va_end(ap); |
756 | |
|
757 | 0 | if (len < 0) |
758 | 0 | die(_("unable to format message: %s"), fmt); |
759 | 0 | if (len >= max) |
760 | 0 | BUG("attempt to snprintf into too-small buffer"); |
761 | 0 | return len; |
762 | 0 | } |
763 | | |
764 | | void write_file_buf(const char *path, const char *buf, size_t len) |
765 | 0 | { |
766 | 0 | int fd = xopen(path, O_WRONLY | O_CREAT | O_TRUNC, 0666); |
767 | 0 | if (write_in_full(fd, buf, len) < 0) |
768 | 0 | die_errno(_("could not write to '%s'"), path); |
769 | 0 | if (close(fd)) |
770 | 0 | die_errno(_("could not close '%s'"), path); |
771 | 0 | } |
772 | | |
773 | | void write_file(const char *path, const char *fmt, ...) |
774 | 0 | { |
775 | 0 | va_list params; |
776 | 0 | struct strbuf sb = STRBUF_INIT; |
777 | |
|
778 | 0 | va_start(params, fmt); |
779 | 0 | strbuf_vaddf(&sb, fmt, params); |
780 | 0 | va_end(params); |
781 | |
|
782 | 0 | strbuf_complete_line(&sb); |
783 | |
|
784 | 0 | write_file_buf(path, sb.buf, sb.len); |
785 | 0 | strbuf_release(&sb); |
786 | 0 | } |
787 | | |
788 | | void sleep_millisec(int millisec) |
789 | 0 | { |
790 | 0 | poll(NULL, 0, millisec); |
791 | 0 | } |
792 | | |
793 | | int xgethostname(char *buf, size_t len) |
794 | 0 | { |
795 | | /* |
796 | | * If the full hostname doesn't fit in buf, POSIX does not |
797 | | * specify whether the buffer will be null-terminated, so to |
798 | | * be safe, do it ourselves. |
799 | | */ |
800 | 0 | int ret = gethostname(buf, len); |
801 | 0 | if (!ret) |
802 | 0 | buf[len - 1] = 0; |
803 | 0 | return ret; |
804 | 0 | } |
805 | | |
806 | | int is_missing_file(const char *filename) |
807 | 0 | { |
808 | 0 | struct stat st; |
809 | |
|
810 | 0 | if (stat(filename, &st) < 0) { |
811 | 0 | if (errno == ENOENT) |
812 | 0 | return 1; |
813 | 0 | die_errno(_("could not stat %s"), filename); |
814 | 0 | } |
815 | | |
816 | 0 | return 0; |
817 | 0 | } |
818 | | |
819 | | int is_empty_or_missing_file(const char *filename) |
820 | 0 | { |
821 | 0 | struct stat st; |
822 | |
|
823 | 0 | if (stat(filename, &st) < 0) { |
824 | 0 | if (errno == ENOENT) |
825 | 0 | return 1; |
826 | 0 | die_errno(_("could not stat %s"), filename); |
827 | 0 | } |
828 | | |
829 | 0 | return !st.st_size; |
830 | 0 | } |
831 | | |
832 | | int open_nofollow(const char *path, int flags) |
833 | 0 | { |
834 | 0 | #ifdef O_NOFOLLOW |
835 | 0 | int ret = open(path, flags | O_NOFOLLOW); |
836 | | /* |
837 | | * NetBSD sets errno to EFTYPE when path is a symlink. The only other |
838 | | * time this errno occurs when O_REGULAR is used. Since we don't use |
839 | | * it anywhere we can avoid an lstat here. FreeBSD does the same with |
840 | | * EMLINK. |
841 | | */ |
842 | | # ifdef __NetBSD__ |
843 | | # define SYMLINK_ERRNO EFTYPE |
844 | | # elif defined(__FreeBSD__) |
845 | | # define SYMLINK_ERRNO EMLINK |
846 | | # endif |
847 | | # if SYMLINK_ERRNO |
848 | | if (ret < 0 && errno == SYMLINK_ERRNO) { |
849 | | errno = ELOOP; |
850 | | return -1; |
851 | | } |
852 | | # undef SYMLINK_ERRNO |
853 | | # endif |
854 | 0 | return ret; |
855 | | #else |
856 | | struct stat st; |
857 | | if (lstat(path, &st) < 0) |
858 | | return -1; |
859 | | if (S_ISLNK(st.st_mode)) { |
860 | | errno = ELOOP; |
861 | | return -1; |
862 | | } |
863 | | return open(path, flags); |
864 | | #endif |
865 | 0 | } |
866 | | |
867 | | int csprng_bytes(void *buf, size_t len, MAYBE_UNUSED unsigned flags) |
868 | 0 | { |
869 | | #if defined(HAVE_ARC4RANDOM) || defined(HAVE_ARC4RANDOM_LIBBSD) |
870 | | /* This function never returns an error. */ |
871 | | arc4random_buf(buf, len); |
872 | | return 0; |
873 | | #elif defined(HAVE_GETRANDOM) |
874 | | ssize_t res; |
875 | 0 | char *p = buf; |
876 | 0 | while (len) { |
877 | 0 | res = getrandom(p, len, 0); |
878 | 0 | if (res < 0) |
879 | 0 | return -1; |
880 | 0 | len -= res; |
881 | 0 | p += res; |
882 | 0 | } |
883 | 0 | return 0; |
884 | | #elif defined(HAVE_GETENTROPY) |
885 | | int res; |
886 | | char *p = buf; |
887 | | while (len) { |
888 | | /* getentropy has a maximum size of 256 bytes. */ |
889 | | size_t chunk = len < 256 ? len : 256; |
890 | | res = getentropy(p, chunk); |
891 | | if (res < 0) |
892 | | return -1; |
893 | | len -= chunk; |
894 | | p += chunk; |
895 | | } |
896 | | return 0; |
897 | | #elif defined(HAVE_RTLGENRANDOM) |
898 | | if (!RtlGenRandom(buf, len)) |
899 | | return -1; |
900 | | return 0; |
901 | | #elif defined(HAVE_OPENSSL_CSPRNG) |
902 | | switch (RAND_pseudo_bytes(buf, len)) { |
903 | | case 1: |
904 | | return 0; |
905 | | case 0: |
906 | | if (flags & CSPRNG_BYTES_INSECURE) |
907 | | return 0; |
908 | | errno = EIO; |
909 | | return -1; |
910 | | default: |
911 | | errno = ENOTSUP; |
912 | | return -1; |
913 | | } |
914 | | #else |
915 | | ssize_t res; |
916 | | char *p = buf; |
917 | | int fd, err; |
918 | | fd = open("/dev/urandom", O_RDONLY); |
919 | | if (fd < 0) |
920 | | return -1; |
921 | | while (len) { |
922 | | res = xread(fd, p, len); |
923 | | if (res < 0) { |
924 | | err = errno; |
925 | | close(fd); |
926 | | errno = err; |
927 | | return -1; |
928 | | } |
929 | | len -= res; |
930 | | p += res; |
931 | | } |
932 | | close(fd); |
933 | | return 0; |
934 | | #endif |
935 | 0 | } |
936 | | |
937 | | uint32_t git_rand(unsigned flags) |
938 | 0 | { |
939 | 0 | uint32_t result; |
940 | |
|
941 | 0 | if (csprng_bytes(&result, sizeof(result), flags) < 0) |
942 | 0 | die(_("unable to get random bytes")); |
943 | | |
944 | 0 | return result; |
945 | 0 | } |
946 | | |
947 | | static void mmap_limit_check(size_t length) |
948 | 0 | { |
949 | 0 | static size_t limit = 0; |
950 | 0 | if (!limit) { |
951 | 0 | limit = git_env_ulong("GIT_MMAP_LIMIT", 0); |
952 | 0 | if (!limit) |
953 | 0 | limit = SIZE_MAX; |
954 | 0 | } |
955 | 0 | if (length > limit) |
956 | 0 | die(_("attempting to mmap %"PRIuMAX" over limit %"PRIuMAX), |
957 | 0 | (uintmax_t)length, (uintmax_t)limit); |
958 | 0 | } |
959 | | |
960 | | void *xmmap_gently(void *start, size_t length, |
961 | | int prot, int flags, int fd, off_t offset) |
962 | 0 | { |
963 | 0 | void *ret; |
964 | |
|
965 | 0 | mmap_limit_check(length); |
966 | 0 | ret = mmap(start, length, prot, flags, fd, offset); |
967 | 0 | if (ret == MAP_FAILED && !length) |
968 | 0 | ret = NULL; |
969 | 0 | return ret; |
970 | 0 | } |
971 | | |
972 | | const char *mmap_os_err(void) |
973 | 0 | { |
974 | 0 | static const char blank[] = ""; |
975 | 0 | #if defined(__linux__) |
976 | 0 | if (errno == ENOMEM) { |
977 | | /* this continues an existing error message: */ |
978 | 0 | static const char enomem[] = |
979 | 0 | ", check sys.vm.max_map_count and/or RLIMIT_DATA"; |
980 | 0 | return enomem; |
981 | 0 | } |
982 | 0 | #endif /* OS-specific bits */ |
983 | 0 | return blank; |
984 | 0 | } |
985 | | |
986 | | void *xmmap(void *start, size_t length, |
987 | | int prot, int flags, int fd, off_t offset) |
988 | 0 | { |
989 | 0 | void *ret = xmmap_gently(start, length, prot, flags, fd, offset); |
990 | 0 | if (ret == MAP_FAILED) |
991 | 0 | die_errno(_("mmap failed%s"), mmap_os_err()); |
992 | 0 | return ret; |
993 | 0 | } |