]> git.ipfire.org Git - thirdparty/git.git/blame - wrapper.c
The ninteenth batch
[thirdparty/git.git] / wrapper.c
CommitLineData
112db553
LT
1/*
2 * Various trivial helper wrappers around standard functions
3 */
5e3f94df 4#include "git-compat-util.h"
0b027f6c 5#include "abspath.h"
b1bda751 6#include "parse.h"
f394e093 7#include "gettext.h"
69a63fe6 8#include "strbuf.h"
74ea5c95 9#include "trace2.h"
112db553 10
19d3f228
NS
11#ifdef HAVE_RTLGENRANDOM
12/* This is required to get access to RtlGenRandom. */
13#define SystemFunction036 NTAPI SystemFunction036
4a53d0d0 14#include <ntsecapi.h>
19d3f228
NS
15#undef SystemFunction036
16#endif
17
f8bb1d94 18static int memory_limit_check(size_t size, int gentle)
d41489a6 19{
9927d962
SP
20 static size_t limit = 0;
21 if (!limit) {
22 limit = git_env_ulong("GIT_ALLOC_LIMIT", 0);
23 if (!limit)
24 limit = SIZE_MAX;
d41489a6 25 }
f0d89001 26 if (size > limit) {
f8bb1d94 27 if (gentle) {
f0d89001
JH
28 error("attempting to allocate %"PRIuMAX" over limit %"PRIuMAX,
29 (uintmax_t)size, (uintmax_t)limit);
f8bb1d94
NTND
30 return -1;
31 } else
f0d89001
JH
32 die("attempting to allocate %"PRIuMAX" over limit %"PRIuMAX,
33 (uintmax_t)size, (uintmax_t)limit);
f8bb1d94
NTND
34 }
35 return 0;
d41489a6
NTND
36}
37
112db553
LT
38char *xstrdup(const char *str)
39{
40 char *ret = strdup(str);
9827d4c1
JK
41 if (!ret)
42 die("Out of memory, strdup failed");
112db553
LT
43 return ret;
44}
45
f8bb1d94 46static void *do_xmalloc(size_t size, int gentle)
112db553 47{
d41489a6
NTND
48 void *ret;
49
f8bb1d94
NTND
50 if (memory_limit_check(size, gentle))
51 return NULL;
d41489a6 52 ret = malloc(size);
112db553
LT
53 if (!ret && !size)
54 ret = malloc(1);
55 if (!ret) {
9827d4c1
JK
56 if (!gentle)
57 die("Out of memory, malloc failed (tried to allocate %lu bytes)",
58 (unsigned long)size);
59 else {
60 error("Out of memory, malloc failed (tried to allocate %lu bytes)",
61 (unsigned long)size);
62 return NULL;
f8bb1d94 63 }
112db553
LT
64 }
65#ifdef XMALLOC_POISON
66 memset(ret, 0xA5, size);
67#endif
68 return ret;
69}
70
f8bb1d94
NTND
71void *xmalloc(size_t size)
72{
73 return do_xmalloc(size, 0);
74}
75
76static void *do_xmallocz(size_t size, int gentle)
5bf9219d
IL
77{
78 void *ret;
f8bb1d94
NTND
79 if (unsigned_add_overflows(size, 1)) {
80 if (gentle) {
81 error("Data too large to fit into virtual memory space.");
82 return NULL;
83 } else
84 die("Data too large to fit into virtual memory space.");
85 }
86 ret = do_xmalloc(size + 1, gentle);
87 if (ret)
88 ((char*)ret)[size] = 0;
5bf9219d
IL
89 return ret;
90}
91
f8bb1d94
NTND
92void *xmallocz(size_t size)
93{
94 return do_xmallocz(size, 0);
95}
96
97void *xmallocz_gently(size_t size)
98{
99 return do_xmallocz(size, 1);
100}
101
112db553
LT
102/*
103 * xmemdupz() allocates (len + 1) bytes of memory, duplicates "len" bytes of
104 * "data" to the allocated memory, zero terminates the allocated memory,
105 * and returns a pointer to the allocated memory. If the allocation fails,
106 * the program dies.
107 */
108void *xmemdupz(const void *data, size_t len)
109{
5bf9219d 110 return memcpy(xmallocz(len), data, len);
112db553
LT
111}
112
113char *xstrndup(const char *str, size_t len)
114{
115 char *p = memchr(str, '\0', len);
116 return xmemdupz(str, p ? p - str : len);
117}
118
14570dc6 119int xstrncmpz(const char *s, const char *t, size_t len)
120{
121 int res = strncmp(s, t, len);
122 if (res)
123 return res;
124 return s[len] == '\0' ? 0 : 1;
125}
126
112db553
LT
127void *xrealloc(void *ptr, size_t size)
128{
d41489a6
NTND
129 void *ret;
130
6479ea4a
JK
131 if (!size) {
132 free(ptr);
133 return xmalloc(0);
134 }
135
f8bb1d94 136 memory_limit_check(size, 0);
d41489a6 137 ret = realloc(ptr, size);
9827d4c1
JK
138 if (!ret)
139 die("Out of memory, realloc failed");
112db553
LT
140 return ret;
141}
142
143void *xcalloc(size_t nmemb, size_t size)
144{
d41489a6
NTND
145 void *ret;
146
e7792a74
JK
147 if (unsigned_mult_overflows(nmemb, size))
148 die("data too large to fit into virtual memory space");
149
f8bb1d94 150 memory_limit_check(size * nmemb, 0);
d41489a6 151 ret = calloc(nmemb, size);
112db553
LT
152 if (!ret && (!nmemb || !size))
153 ret = calloc(1, 1);
9827d4c1
JK
154 if (!ret)
155 die("Out of memory, calloc failed");
112db553
LT
156 return ret;
157}
158
3540c71e
ÆAB
159void xsetenv(const char *name, const char *value, int overwrite)
160{
161 if (setenv(name, value, overwrite))
162 die_errno(_("could not setenv '%s'"), name ? name : "(null)");
163}
164
3ff53df7
PT
165/**
166 * xopen() is the same as open(), but it die()s if the open() fails.
167 */
168int xopen(const char *path, int oflag, ...)
169{
170 mode_t mode = 0;
171 va_list ap;
172
173 /*
174 * va_arg() will have undefined behavior if the specified type is not
175 * compatible with the argument type. Since integers are promoted to
176 * ints, we fetch the next argument as an int, and then cast it to a
177 * mode_t to avoid undefined behavior.
178 */
179 va_start(ap, oflag);
180 if (oflag & O_CREAT)
181 mode = va_arg(ap, int);
182 va_end(ap);
183
184 for (;;) {
185 int fd = open(path, oflag, mode);
186 if (fd >= 0)
187 return fd;
188 if (errno == EINTR)
189 continue;
190
a7439d0f
RS
191 if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
192 die_errno(_("unable to create '%s'"), path);
193 else if ((oflag & O_RDWR) == O_RDWR)
3ff53df7
PT
194 die_errno(_("could not open '%s' for reading and writing"), path);
195 else if ((oflag & O_WRONLY) == O_WRONLY)
196 die_errno(_("could not open '%s' for writing"), path);
197 else
198 die_errno(_("could not open '%s' for reading"), path);
199 }
200}
201
d751dd11
EW
202static int handle_nonblock(int fd, short poll_events, int err)
203{
204 struct pollfd pfd;
205
206 if (err != EAGAIN && err != EWOULDBLOCK)
207 return 0;
208
209 pfd.fd = fd;
210 pfd.events = poll_events;
211
212 /*
213 * no need to check for errors, here;
214 * a subsequent read/write will detect unrecoverable errors
215 */
216 poll(&pfd, 1, -1);
217 return 1;
218}
219
112db553
LT
220/*
221 * xread() is the same a read(), but it automatically restarts read()
222 * operations with a recoverable error (EAGAIN and EINTR). xread()
223 * DOES NOT GUARANTEE that "len" bytes is read even if the data is available.
224 */
225ssize_t xread(int fd, void *buf, size_t len)
226{
227 ssize_t nr;
0b6806b9 228 if (len > MAX_IO_SIZE)
7cd54d37 229 len = MAX_IO_SIZE;
112db553
LT
230 while (1) {
231 nr = read(fd, buf, len);
1079c4be
SB
232 if (nr < 0) {
233 if (errno == EINTR)
234 continue;
d751dd11 235 if (handle_nonblock(fd, POLLIN, errno))
c22f6202 236 continue;
1079c4be 237 }
112db553
LT
238 return nr;
239 }
240}
241
242/*
243 * xwrite() is the same a write(), but it automatically restarts write()
244 * operations with a recoverable error (EAGAIN and EINTR). xwrite() DOES NOT
245 * GUARANTEE that "len" bytes is written even if the operation is successful.
246 */
247ssize_t xwrite(int fd, const void *buf, size_t len)
248{
249 ssize_t nr;
0b6806b9 250 if (len > MAX_IO_SIZE)
7cd54d37 251 len = MAX_IO_SIZE;
112db553
LT
252 while (1) {
253 nr = write(fd, buf, len);
ef1cf016
EW
254 if (nr < 0) {
255 if (errno == EINTR)
256 continue;
d751dd11 257 if (handle_nonblock(fd, POLLOUT, errno))
ef1cf016 258 continue;
ef1cf016
EW
259 }
260
9aa91af0
YM
261 return nr;
262 }
263}
264
265/*
266 * xpread() is the same as pread(), but it automatically restarts pread()
267 * operations with a recoverable error (EAGAIN and EINTR). xpread() DOES
268 * NOT GUARANTEE that "len" bytes is read even if the data is available.
269 */
270ssize_t xpread(int fd, void *buf, size_t len, off_t offset)
271{
272 ssize_t nr;
273 if (len > MAX_IO_SIZE)
274 len = MAX_IO_SIZE;
275 while (1) {
276 nr = pread(fd, buf, len, offset);
277 if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
112db553
LT
278 continue;
279 return nr;
280 }
281}
282
559e840b
JH
283ssize_t read_in_full(int fd, void *buf, size_t count)
284{
285 char *p = buf;
286 ssize_t total = 0;
287
288 while (count > 0) {
289 ssize_t loaded = xread(fd, p, count);
56d7c27a
JK
290 if (loaded < 0)
291 return -1;
292 if (loaded == 0)
293 return total;
559e840b
JH
294 count -= loaded;
295 p += loaded;
296 total += loaded;
297 }
298
299 return total;
300}
301
302ssize_t write_in_full(int fd, const void *buf, size_t count)
303{
304 const char *p = buf;
305 ssize_t total = 0;
306
307 while (count > 0) {
308 ssize_t written = xwrite(fd, p, count);
309 if (written < 0)
310 return -1;
311 if (!written) {
312 errno = ENOSPC;
313 return -1;
314 }
315 count -= written;
316 p += written;
317 total += written;
318 }
319
320 return total;
321}
322
426ddeea
YM
323ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset)
324{
325 char *p = buf;
326 ssize_t total = 0;
327
328 while (count > 0) {
329 ssize_t loaded = xpread(fd, p, count, offset);
330 if (loaded < 0)
331 return -1;
332 if (loaded == 0)
333 return total;
334 count -= loaded;
335 p += loaded;
336 total += loaded;
337 offset += loaded;
338 }
339
340 return total;
341}
342
112db553
LT
343int xdup(int fd)
344{
345 int ret = dup(fd);
346 if (ret < 0)
d824cbba 347 die_errno("dup failed");
112db553
LT
348 return ret;
349}
350
260eec29
PT
351/**
352 * xfopen() is the same as fopen(), but it die()s if the fopen() fails.
353 */
354FILE *xfopen(const char *path, const char *mode)
355{
356 for (;;) {
357 FILE *fp = fopen(path, mode);
358 if (fp)
359 return fp;
360 if (errno == EINTR)
361 continue;
362
363 if (*mode && mode[1] == '+')
364 die_errno(_("could not open '%s' for reading and writing"), path);
365 else if (*mode == 'w' || *mode == 'a')
366 die_errno(_("could not open '%s' for writing"), path);
367 else
368 die_errno(_("could not open '%s' for reading"), path);
369 }
370}
371
112db553
LT
372FILE *xfdopen(int fd, const char *mode)
373{
374 FILE *stream = fdopen(fd, mode);
afe8a907 375 if (!stream)
d824cbba 376 die_errno("Out of memory? fdopen failed");
112db553
LT
377 return stream;
378}
379
79d7582e
JS
380FILE *fopen_for_writing(const char *path)
381{
382 FILE *ret = fopen(path, "w");
383
384 if (!ret && errno == EPERM) {
385 if (!unlink(path))
386 ret = fopen(path, "w");
387 else
388 errno = EPERM;
389 }
390 return ret;
391}
392
382fb07f
NTND
393static void warn_on_inaccessible(const char *path)
394{
395 warning_errno(_("unable to access '%s'"), path);
396}
397
11dc1fcb
NTND
398int warn_on_fopen_errors(const char *path)
399{
400 if (errno != ENOENT && errno != ENOTDIR) {
401 warn_on_inaccessible(path);
402 return -1;
403 }
404
405 return 0;
406}
407
e9d983f1
NTND
408FILE *fopen_or_warn(const char *path, const char *mode)
409{
410 FILE *fp = fopen(path, mode);
411
412 if (fp)
413 return fp;
414
415 warn_on_fopen_errors(path);
416 return NULL;
417}
418
eb78e23f 419int xmkstemp(char *filename_template)
112db553
LT
420{
421 int fd;
6cf6bb3e 422 char origtemplate[PATH_MAX];
eb78e23f 423 strlcpy(origtemplate, filename_template, sizeof(origtemplate));
112db553 424
eb78e23f 425 fd = mkstemp(filename_template);
6cf6bb3e
AE
426 if (fd < 0) {
427 int saved_errno = errno;
428 const char *nonrelative_template;
429
eb78e23f
BW
430 if (strlen(filename_template) != strlen(origtemplate))
431 filename_template = origtemplate;
6cf6bb3e 432
eb78e23f 433 nonrelative_template = absolute_path(filename_template);
6cf6bb3e
AE
434 errno = saved_errno;
435 die_errno("Unable to create temporary file '%s'",
436 nonrelative_template);
437 }
112db553
LT
438 return fd;
439}
39c68542 440
33f23936
JN
441/* Adapted from libiberty's mkstemp.c. */
442
443#undef TMP_MAX
444#define TMP_MAX 16384
445
446int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
447{
448 static const char letters[] =
449 "abcdefghijklmnopqrstuvwxyz"
450 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
451 "0123456789";
53d687bf
JK
452 static const int num_letters = ARRAY_SIZE(letters) - 1;
453 static const char x_pattern[] = "XXXXXX";
454 static const int num_x = ARRAY_SIZE(x_pattern) - 1;
eb78e23f 455 char *filename_template;
33f23936
JN
456 size_t len;
457 int fd, count;
458
459 len = strlen(pattern);
460
53d687bf 461 if (len < num_x + suffix_len) {
33f23936
JN
462 errno = EINVAL;
463 return -1;
464 }
465
53d687bf 466 if (strncmp(&pattern[len - num_x - suffix_len], x_pattern, num_x)) {
33f23936
JN
467 errno = EINVAL;
468 return -1;
469 }
470
471 /*
472 * Replace pattern's XXXXXX characters with randomness.
473 * Try TMP_MAX different filenames.
474 */
53d687bf 475 filename_template = &pattern[len - num_x - suffix_len];
33f23936 476 for (count = 0; count < TMP_MAX; ++count) {
54a80a9a 477 int i;
47efda96 478 uint64_t v;
479 if (csprng_bytes(&v, sizeof(v)) < 0)
480 return error_errno("unable to get random bytes for temporary file");
481
33f23936 482 /* Fill in the random bits. */
53d687bf 483 for (i = 0; i < num_x; i++) {
54a80a9a
AH
484 filename_template[i] = letters[v % num_letters];
485 v /= num_letters;
486 }
33f23936
JN
487
488 fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);
a2cb86c1 489 if (fd >= 0)
33f23936
JN
490 return fd;
491 /*
492 * Fatal error (EPERM, ENOSPC etc).
493 * It doesn't make sense to loop.
494 */
495 if (errno != EEXIST)
496 break;
33f23936
JN
497 }
498 /* We return the null string if we can't find a unique file name. */
499 pattern[0] = '\0';
500 return -1;
501}
502
503int git_mkstemp_mode(char *pattern, int mode)
504{
505 /* mkstemp is just mkstemps with no suffix */
506 return git_mkstemps_mode(pattern, 0, mode);
507}
508
eb78e23f 509int xmkstemp_mode(char *filename_template, int mode)
b862b61c
MM
510{
511 int fd;
6cf6bb3e 512 char origtemplate[PATH_MAX];
eb78e23f 513 strlcpy(origtemplate, filename_template, sizeof(origtemplate));
b862b61c 514
eb78e23f 515 fd = git_mkstemp_mode(filename_template, mode);
6cf6bb3e
AE
516 if (fd < 0) {
517 int saved_errno = errno;
518 const char *nonrelative_template;
519
eb78e23f
BW
520 if (!filename_template[0])
521 filename_template = origtemplate;
6cf6bb3e 522
eb78e23f 523 nonrelative_template = absolute_path(filename_template);
6cf6bb3e
AE
524 errno = saved_errno;
525 die_errno("Unable to create temporary file '%s'",
526 nonrelative_template);
527 }
b862b61c
MM
528 return fd;
529}
530
abf38abe
NS
531/*
532 * Some platforms return EINTR from fsync. Since fsync is invoked in some
533 * cases by a wrapper that dies on failure, do not expose EINTR to callers.
534 */
535static int fsync_loop(int fd)
536{
537 int err;
538
539 do {
540 err = fsync(fd);
541 } while (err < 0 && errno == EINTR);
542 return err;
543}
544
545int git_fsync(int fd, enum fsync_action action)
546{
547 switch (action) {
548 case FSYNC_WRITEOUT_ONLY:
a27eecea 549 trace2_counter_add(TRACE2_COUNTER_ID_FSYNC_WRITEOUT_ONLY, 1);
abf38abe
NS
550
551#ifdef __APPLE__
552 /*
553 * On macOS, fsync just causes filesystem cache writeback but
554 * does not flush hardware caches.
555 */
556 return fsync_loop(fd);
557#endif
558
559#ifdef HAVE_SYNC_FILE_RANGE
560 /*
561 * On linux 2.6.17 and above, sync_file_range is the way to
562 * issue a writeback without a hardware flush. An offset of
563 * 0 and size of 0 indicates writeout of the entire file and the
564 * wait flags ensure that all dirty data is written to the disk
565 * (potentially in a disk-side cache) before we continue.
566 */
567
568 return sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WAIT_BEFORE |
569 SYNC_FILE_RANGE_WRITE |
570 SYNC_FILE_RANGE_WAIT_AFTER);
571#endif
572
573#ifdef fsync_no_flush
574 return fsync_no_flush(fd);
575#endif
576
577 errno = ENOSYS;
578 return -1;
579
580 case FSYNC_HARDWARE_FLUSH:
a27eecea 581 trace2_counter_add(TRACE2_COUNTER_ID_FSYNC_HARDWARE_FLUSH, 1);
9a498767 582
abf38abe
NS
583 /*
584 * On macOS, a special fcntl is required to really flush the
585 * caches within the storage controller. As of this writing,
586 * this is a very expensive operation on Apple SSDs.
587 */
588#ifdef __APPLE__
589 return fcntl(fd, F_FULLFSYNC);
590#else
591 return fsync_loop(fd);
592#endif
593 default:
594 BUG("unexpected git_fsync(%d) call", action);
595 }
596}
597
10e13ec8 598static int warn_if_unremovable(const char *op, const char *file, int rc)
fc71db39 599{
1054af7d
RS
600 int err;
601 if (!rc || errno == ENOENT)
602 return 0;
603 err = errno;
0a288d1e 604 warning_errno("unable to %s '%s'", op, file);
1054af7d 605 errno = err;
fc71db39
AR
606 return rc;
607}
608
9ccc0c08
RS
609int unlink_or_msg(const char *file, struct strbuf *err)
610{
611 int rc = unlink(file);
612
613 assert(err);
614
615 if (!rc || errno == ENOENT)
616 return 0;
617
0a288d1e 618 strbuf_addf(err, "unable to unlink '%s': %s",
9ccc0c08
RS
619 file, strerror(errno));
620 return -1;
621}
622
10e13ec8
PC
623int unlink_or_warn(const char *file)
624{
625 return warn_if_unremovable("unlink", file, unlink(file));
626}
d1723296
PC
627
628int rmdir_or_warn(const char *file)
629{
630 return warn_if_unremovable("rmdir", file, rmdir(file));
631}
80d706af 632
4698c8fe
JN
633static int access_error_is_ok(int err, unsigned flag)
634{
c7054209
JH
635 return (is_missing_file_error(err) ||
636 ((flag & ACCESS_EACCES_OK) && err == EACCES));
4698c8fe
JN
637}
638
639int access_or_warn(const char *path, int mode, unsigned flag)
ba8bd830
JK
640{
641 int ret = access(path, mode);
4698c8fe 642 if (ret && !access_error_is_ok(errno, flag))
55b38a48 643 warn_on_inaccessible(path);
ba8bd830
JK
644 return ret;
645}
646
4698c8fe 647int access_or_die(const char *path, int mode, unsigned flag)
96b9e0e3
JN
648{
649 int ret = access(path, mode);
4698c8fe 650 if (ret && !access_error_is_ok(errno, flag))
96b9e0e3
JN
651 die_errno(_("unable to access '%s'"), path);
652 return ret;
653}
654
aa14e980
RS
655char *xgetcwd(void)
656{
657 struct strbuf sb = STRBUF_INIT;
658 if (strbuf_getcwd(&sb))
659 die_errno(_("unable to get current working directory"));
660 return strbuf_detach(&sb, NULL);
661}
316e53e6 662
7b03c89e
JK
663int xsnprintf(char *dst, size_t max, const char *fmt, ...)
664{
665 va_list ap;
666 int len;
667
668 va_start(ap, fmt);
669 len = vsnprintf(dst, max, fmt, ap);
670 va_end(ap);
671
672 if (len < 0)
033abf97 673 BUG("your snprintf is broken");
7b03c89e 674 if (len >= max)
033abf97 675 BUG("attempt to snprintf into too-small buffer");
7b03c89e
JK
676 return len;
677}
678
52563d7e 679void write_file_buf(const char *path, const char *buf, size_t len)
316e53e6 680{
52563d7e 681 int fd = xopen(path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
06f46f23 682 if (write_in_full(fd, buf, len) < 0)
0a288d1e 683 die_errno(_("could not write to '%s'"), path);
52563d7e 684 if (close(fd))
0a288d1e 685 die_errno(_("could not close '%s'"), path);
316e53e6 686}
2024d317 687
ef22318c 688void write_file(const char *path, const char *fmt, ...)
12d6ce1d 689{
12d6ce1d 690 va_list params;
316e53e6 691 struct strbuf sb = STRBUF_INIT;
12d6ce1d
JH
692
693 va_start(params, fmt);
ef22318c 694 strbuf_vaddf(&sb, fmt, params);
12d6ce1d 695 va_end(params);
12d6ce1d 696
ef22318c 697 strbuf_complete_line(&sb);
12d6ce1d 698
52563d7e 699 write_file_buf(path, sb.buf, sb.len);
ef22318c 700 strbuf_release(&sb);
12d6ce1d
JH
701}
702
2024d317
JS
703void sleep_millisec(int millisec)
704{
705 poll(NULL, 0, millisec);
706}
5781a9a2
DT
707
708int xgethostname(char *buf, size_t len)
709{
710 /*
711 * If the full hostname doesn't fit in buf, POSIX does not
712 * specify whether the buffer will be null-terminated, so to
713 * be safe, do it ourselves.
714 */
715 int ret = gethostname(buf, len);
716 if (!ret)
717 buf[len - 1] = 0;
718 return ret;
719}
e3b1e3bd
PB
720
721int is_empty_or_missing_file(const char *filename)
722{
723 struct stat st;
724
725 if (stat(filename, &st) < 0) {
726 if (errno == ENOENT)
727 return 1;
728 die_errno(_("could not stat %s"), filename);
729 }
730
731 return !st.st_size;
732}
00611d84
JK
733
734int open_nofollow(const char *path, int flags)
735{
736#ifdef O_NOFOLLOW
737 return open(path, flags | O_NOFOLLOW);
738#else
739 struct stat st;
740 if (lstat(path, &st) < 0)
741 return -1;
742 if (S_ISLNK(st.st_mode)) {
743 errno = ELOOP;
744 return -1;
745 }
746 return open(path, flags);
747#endif
748}
05cd988d 749
750int csprng_bytes(void *buf, size_t len)
751{
752#if defined(HAVE_ARC4RANDOM) || defined(HAVE_ARC4RANDOM_LIBBSD)
753 /* This function never returns an error. */
754 arc4random_buf(buf, len);
755 return 0;
756#elif defined(HAVE_GETRANDOM)
757 ssize_t res;
758 char *p = buf;
759 while (len) {
760 res = getrandom(p, len, 0);
761 if (res < 0)
762 return -1;
763 len -= res;
764 p += res;
765 }
766 return 0;
767#elif defined(HAVE_GETENTROPY)
768 int res;
769 char *p = buf;
770 while (len) {
771 /* getentropy has a maximum size of 256 bytes. */
772 size_t chunk = len < 256 ? len : 256;
773 res = getentropy(p, chunk);
774 if (res < 0)
775 return -1;
776 len -= chunk;
777 p += chunk;
778 }
779 return 0;
780#elif defined(HAVE_RTLGENRANDOM)
781 if (!RtlGenRandom(buf, len))
782 return -1;
783 return 0;
784#elif defined(HAVE_OPENSSL_CSPRNG)
785 int res = RAND_bytes(buf, len);
786 if (res == 1)
787 return 0;
788 if (res == -1)
789 errno = ENOTSUP;
790 else
791 errno = EIO;
792 return -1;
793#else
794 ssize_t res;
795 char *p = buf;
796 int fd, err;
797 fd = open("/dev/urandom", O_RDONLY);
798 if (fd < 0)
799 return -1;
800 while (len) {
801 res = xread(fd, p, len);
802 if (res < 0) {
803 err = errno;
804 close(fd);
805 errno = err;
806 return -1;
807 }
808 len -= res;
809 p += res;
810 }
811 close(fd);
812 return 0;
813#endif
814}
89024a0a
DS
815
816uint32_t git_rand(void)
817{
818 uint32_t result;
819
820 if (csprng_bytes(&result, sizeof(result)) < 0)
821 die(_("unable to get random bytes"));
822
823 return result;
824}