Coverage Report

Created: 2024-09-16 06:10

/src/git/wrapper.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Various trivial helper wrappers around standard functions
3
 */
4
#include "git-compat-util.h"
5
#include "abspath.h"
6
#include "parse.h"
7
#include "gettext.h"
8
#include "strbuf.h"
9
#include "trace2.h"
10
11
#ifdef HAVE_RTLGENRANDOM
12
/* This is required to get access to RtlGenRandom. */
13
#define SystemFunction036 NTAPI SystemFunction036
14
#include <ntsecapi.h>
15
#undef SystemFunction036
16
#endif
17
18
static int memory_limit_check(size_t size, int gentle)
19
8.07k
{
20
8.07k
  static size_t limit = 0;
21
8.07k
  if (!limit) {
22
1
    limit = git_env_ulong("GIT_ALLOC_LIMIT", 0);
23
1
    if (!limit)
24
1
      limit = SIZE_MAX;
25
1
  }
26
8.07k
  if (size > limit) {
27
0
    if (gentle) {
28
0
      error("attempting to allocate %"PRIuMAX" over limit %"PRIuMAX,
29
0
            (uintmax_t)size, (uintmax_t)limit);
30
0
      return -1;
31
0
    } else
32
0
      die("attempting to allocate %"PRIuMAX" over limit %"PRIuMAX,
33
0
          (uintmax_t)size, (uintmax_t)limit);
34
0
  }
35
8.07k
  return 0;
36
8.07k
}
37
38
char *xstrdup(const char *str)
39
0
{
40
0
  char *ret = strdup(str);
41
0
  if (!ret)
42
0
    die("Out of memory, strdup failed");
43
0
  return ret;
44
0
}
45
46
static void *do_xmalloc(size_t size, int gentle)
47
2.47k
{
48
2.47k
  void *ret;
49
50
2.47k
  if (memory_limit_check(size, gentle))
51
0
    return NULL;
52
2.47k
  ret = malloc(size);
53
2.47k
  if (!ret && !size)
54
0
    ret = malloc(1);
55
2.47k
  if (!ret) {
56
0
    if (!gentle)
57
0
      die("Out of memory, malloc failed (tried to allocate %lu bytes)",
58
0
          (unsigned long)size);
59
0
    else {
60
0
      error("Out of memory, malloc failed (tried to allocate %lu bytes)",
61
0
            (unsigned long)size);
62
0
      return NULL;
63
0
    }
64
0
  }
65
#ifdef XMALLOC_POISON
66
  memset(ret, 0xA5, size);
67
#endif
68
2.47k
  return ret;
69
2.47k
}
70
71
void *xmalloc(size_t size)
72
2.47k
{
73
2.47k
  return do_xmalloc(size, 0);
74
2.47k
}
75
76
static void *do_xmallocz(size_t size, int gentle)
77
0
{
78
0
  void *ret;
79
0
  if (unsigned_add_overflows(size, 1)) {
80
0
    if (gentle) {
81
0
      error("Data too large to fit into virtual memory space.");
82
0
      return NULL;
83
0
    } else
84
0
      die("Data too large to fit into virtual memory space.");
85
0
  }
86
0
  ret = do_xmalloc(size + 1, gentle);
87
0
  if (ret)
88
0
    ((char*)ret)[size] = 0;
89
0
  return ret;
90
0
}
91
92
void *xmallocz(size_t size)
93
0
{
94
0
  return do_xmallocz(size, 0);
95
0
}
96
97
void *xmallocz_gently(size_t size)
98
0
{
99
0
  return do_xmallocz(size, 1);
100
0
}
101
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
 */
108
void *xmemdupz(const void *data, size_t len)
109
0
{
110
0
  return memcpy(xmallocz(len), data, len);
111
0
}
112
113
char *xstrndup(const char *str, size_t len)
114
0
{
115
0
  char *p = memchr(str, '\0', len);
116
0
  return xmemdupz(str, p ? p - str : len);
117
0
}
118
119
int xstrncmpz(const char *s, const char *t, size_t len)
120
0
{
121
0
  int res = strncmp(s, t, len);
122
0
  if (res)
123
0
    return res;
124
0
  return s[len] == '\0' ? 0 : 1;
125
0
}
126
127
void *xrealloc(void *ptr, size_t size)
128
371
{
129
371
  void *ret;
130
131
371
  if (!size) {
132
0
    free(ptr);
133
0
    return xmalloc(0);
134
0
  }
135
136
371
  memory_limit_check(size, 0);
137
371
  ret = realloc(ptr, size);
138
371
  if (!ret)
139
0
    die("Out of memory, realloc failed");
140
371
  return ret;
141
371
}
142
143
void *xcalloc(size_t nmemb, size_t size)
144
5.22k
{
145
5.22k
  void *ret;
146
147
5.22k
  if (unsigned_mult_overflows(nmemb, size))
148
0
    die("data too large to fit into virtual memory space");
149
150
5.22k
  memory_limit_check(size * nmemb, 0);
151
5.22k
  ret = calloc(nmemb, size);
152
5.22k
  if (!ret && (!nmemb || !size))
153
0
    ret = calloc(1, 1);
154
5.22k
  if (!ret)
155
0
    die("Out of memory, calloc failed");
156
5.22k
  return ret;
157
5.22k
}
158
159
void xsetenv(const char *name, const char *value, int overwrite)
160
0
{
161
0
  if (setenv(name, value, overwrite))
162
0
    die_errno(_("could not setenv '%s'"), name ? name : "(null)");
163
0
}
164
165
/**
166
 * xopen() is the same as open(), but it die()s if the open() fails.
167
 */
168
int xopen(const char *path, int oflag, ...)
169
0
{
170
0
  mode_t mode = 0;
171
0
  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
0
  va_start(ap, oflag);
180
0
  if (oflag & O_CREAT)
181
0
    mode = va_arg(ap, int);
182
0
  va_end(ap);
183
184
0
  for (;;) {
185
0
    int fd = open(path, oflag, mode);
186
0
    if (fd >= 0)
187
0
      return fd;
188
0
    if (errno == EINTR)
189
0
      continue;
190
191
0
    if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
192
0
      die_errno(_("unable to create '%s'"), path);
193
0
    else if ((oflag & O_RDWR) == O_RDWR)
194
0
      die_errno(_("could not open '%s' for reading and writing"), path);
195
0
    else if ((oflag & O_WRONLY) == O_WRONLY)
196
0
      die_errno(_("could not open '%s' for writing"), path);
197
0
    else
198
0
      die_errno(_("could not open '%s' for reading"), path);
199
0
  }
200
0
}
201
202
static int handle_nonblock(int fd, short poll_events, int err)
203
0
{
204
0
  struct pollfd pfd;
205
206
0
  if (err != EAGAIN && err != EWOULDBLOCK)
207
0
    return 0;
208
209
0
  pfd.fd = fd;
210
0
  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
0
  poll(&pfd, 1, -1);
217
0
  return 1;
218
0
}
219
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
 */
225
ssize_t xread(int fd, void *buf, size_t len)
226
0
{
227
0
  ssize_t nr;
228
0
  if (len > MAX_IO_SIZE)
229
0
    len = MAX_IO_SIZE;
230
0
  while (1) {
231
0
    nr = read(fd, buf, len);
232
0
    if (nr < 0) {
233
0
      if (errno == EINTR)
234
0
        continue;
235
0
      if (handle_nonblock(fd, POLLIN, errno))
236
0
        continue;
237
0
    }
238
0
    return nr;
239
0
  }
240
0
}
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
 */
247
ssize_t xwrite(int fd, const void *buf, size_t len)
248
594
{
249
594
  ssize_t nr;
250
594
  if (len > MAX_IO_SIZE)
251
0
    len = MAX_IO_SIZE;
252
594
  while (1) {
253
594
    nr = write(fd, buf, len);
254
594
    if (nr < 0) {
255
0
      if (errno == EINTR)
256
0
        continue;
257
0
      if (handle_nonblock(fd, POLLOUT, errno))
258
0
        continue;
259
0
    }
260
261
594
    return nr;
262
594
  }
263
594
}
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
 */
270
ssize_t xpread(int fd, void *buf, size_t len, off_t offset)
271
0
{
272
0
  ssize_t nr;
273
0
  if (len > MAX_IO_SIZE)
274
0
    len = MAX_IO_SIZE;
275
0
  while (1) {
276
0
    nr = pread(fd, buf, len, offset);
277
0
    if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
278
0
      continue;
279
0
    return nr;
280
0
  }
281
0
}
282
283
ssize_t read_in_full(int fd, void *buf, size_t count)
284
0
{
285
0
  char *p = buf;
286
0
  ssize_t total = 0;
287
288
0
  while (count > 0) {
289
0
    ssize_t loaded = xread(fd, p, count);
290
0
    if (loaded < 0)
291
0
      return -1;
292
0
    if (loaded == 0)
293
0
      return total;
294
0
    count -= loaded;
295
0
    p += loaded;
296
0
    total += loaded;
297
0
  }
298
299
0
  return total;
300
0
}
301
302
ssize_t write_in_full(int fd, const void *buf, size_t count)
303
594
{
304
594
  const char *p = buf;
305
594
  ssize_t total = 0;
306
307
1.18k
  while (count > 0) {
308
594
    ssize_t written = xwrite(fd, p, count);
309
594
    if (written < 0)
310
0
      return -1;
311
594
    if (!written) {
312
0
      errno = ENOSPC;
313
0
      return -1;
314
0
    }
315
594
    count -= written;
316
594
    p += written;
317
594
    total += written;
318
594
  }
319
320
594
  return total;
321
594
}
322
323
ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset)
324
0
{
325
0
  char *p = buf;
326
0
  ssize_t total = 0;
327
328
0
  while (count > 0) {
329
0
    ssize_t loaded = xpread(fd, p, count, offset);
330
0
    if (loaded < 0)
331
0
      return -1;
332
0
    if (loaded == 0)
333
0
      return total;
334
0
    count -= loaded;
335
0
    p += loaded;
336
0
    total += loaded;
337
0
    offset += loaded;
338
0
  }
339
340
0
  return total;
341
0
}
342
343
int xdup(int fd)
344
0
{
345
0
  int ret = dup(fd);
346
0
  if (ret < 0)
347
0
    die_errno("dup failed");
348
0
  return ret;
349
0
}
350
351
/**
352
 * xfopen() is the same as fopen(), but it die()s if the fopen() fails.
353
 */
354
FILE *xfopen(const char *path, const char *mode)
355
0
{
356
0
  for (;;) {
357
0
    FILE *fp = fopen(path, mode);
358
0
    if (fp)
359
0
      return fp;
360
0
    if (errno == EINTR)
361
0
      continue;
362
363
0
    if (*mode && mode[1] == '+')
364
0
      die_errno(_("could not open '%s' for reading and writing"), path);
365
0
    else if (*mode == 'w' || *mode == 'a')
366
0
      die_errno(_("could not open '%s' for writing"), path);
367
0
    else
368
0
      die_errno(_("could not open '%s' for reading"), path);
369
0
  }
370
0
}
371
372
FILE *xfdopen(int fd, const char *mode)
373
0
{
374
0
  FILE *stream = fdopen(fd, mode);
375
0
  if (!stream)
376
0
    die_errno("Out of memory? fdopen failed");
377
0
  return stream;
378
0
}
379
380
FILE *fopen_for_writing(const char *path)
381
0
{
382
0
  FILE *ret = fopen(path, "w");
383
384
0
  if (!ret && errno == EPERM) {
385
0
    if (!unlink(path))
386
0
      ret = fopen(path, "w");
387
0
    else
388
0
      errno = EPERM;
389
0
  }
390
0
  return ret;
391
0
}
392
393
static void warn_on_inaccessible(const char *path)
394
0
{
395
0
  warning_errno(_("unable to access '%s'"), path);
396
0
}
397
398
int warn_on_fopen_errors(const char *path)
399
0
{
400
0
  if (errno != ENOENT && errno != ENOTDIR) {
401
0
    warn_on_inaccessible(path);
402
0
    return -1;
403
0
  }
404
405
0
  return 0;
406
0
}
407
408
FILE *fopen_or_warn(const char *path, const char *mode)
409
0
{
410
0
  FILE *fp = fopen(path, mode);
411
412
0
  if (fp)
413
0
    return fp;
414
415
0
  warn_on_fopen_errors(path);
416
0
  return NULL;
417
0
}
418
419
int xmkstemp(char *filename_template)
420
0
{
421
0
  int fd;
422
0
  char origtemplate[PATH_MAX];
423
0
  strlcpy(origtemplate, filename_template, sizeof(origtemplate));
424
425
0
  fd = mkstemp(filename_template);
426
0
  if (fd < 0) {
427
0
    int saved_errno = errno;
428
0
    const char *nonrelative_template;
429
430
0
    if (strlen(filename_template) != strlen(origtemplate))
431
0
      filename_template = origtemplate;
432
433
0
    nonrelative_template = absolute_path(filename_template);
434
0
    errno = saved_errno;
435
0
    die_errno("Unable to create temporary file '%s'",
436
0
      nonrelative_template);
437
0
  }
438
0
  return fd;
439
0
}
440
441
/* Adapted from libiberty's mkstemp.c. */
442
443
#undef TMP_MAX
444
0
#define TMP_MAX 16384
445
446
int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
447
0
{
448
0
  static const char letters[] =
449
0
    "abcdefghijklmnopqrstuvwxyz"
450
0
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
451
0
    "0123456789";
452
0
  static const int num_letters = ARRAY_SIZE(letters) - 1;
453
0
  static const char x_pattern[] = "XXXXXX";
454
0
  static const int num_x = ARRAY_SIZE(x_pattern) - 1;
455
0
  char *filename_template;
456
0
  size_t len;
457
0
  int fd, count;
458
459
0
  len = strlen(pattern);
460
461
0
  if (len < num_x + suffix_len) {
462
0
    errno = EINVAL;
463
0
    return -1;
464
0
  }
465
466
0
  if (strncmp(&pattern[len - num_x - suffix_len], x_pattern, num_x)) {
467
0
    errno = EINVAL;
468
0
    return -1;
469
0
  }
470
471
  /*
472
   * Replace pattern's XXXXXX characters with randomness.
473
   * Try TMP_MAX different filenames.
474
   */
475
0
  filename_template = &pattern[len - num_x - suffix_len];
476
0
  for (count = 0; count < TMP_MAX; ++count) {
477
0
    int i;
478
0
    uint64_t v;
479
0
    if (csprng_bytes(&v, sizeof(v)) < 0)
480
0
      return error_errno("unable to get random bytes for temporary file");
481
482
    /* Fill in the random bits. */
483
0
    for (i = 0; i < num_x; i++) {
484
0
      filename_template[i] = letters[v % num_letters];
485
0
      v /= num_letters;
486
0
    }
487
488
0
    fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);
489
0
    if (fd >= 0)
490
0
      return fd;
491
    /*
492
     * Fatal error (EPERM, ENOSPC etc).
493
     * It doesn't make sense to loop.
494
     */
495
0
    if (errno != EEXIST)
496
0
      break;
497
0
  }
498
  /* We return the null string if we can't find a unique file name.  */
499
0
  pattern[0] = '\0';
500
0
  return -1;
501
0
}
502
503
int git_mkstemp_mode(char *pattern, int mode)
504
0
{
505
  /* mkstemp is just mkstemps with no suffix */
506
0
  return git_mkstemps_mode(pattern, 0, mode);
507
0
}
508
509
int xmkstemp_mode(char *filename_template, int mode)
510
0
{
511
0
  int fd;
512
0
  char origtemplate[PATH_MAX];
513
0
  strlcpy(origtemplate, filename_template, sizeof(origtemplate));
514
515
0
  fd = git_mkstemp_mode(filename_template, mode);
516
0
  if (fd < 0) {
517
0
    int saved_errno = errno;
518
0
    const char *nonrelative_template;
519
520
0
    if (!filename_template[0])
521
0
      filename_template = origtemplate;
522
523
0
    nonrelative_template = absolute_path(filename_template);
524
0
    errno = saved_errno;
525
0
    die_errno("Unable to create temporary file '%s'",
526
0
      nonrelative_template);
527
0
  }
528
0
  return fd;
529
0
}
530
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
 */
535
static int fsync_loop(int fd)
536
0
{
537
0
  int err;
538
539
0
  do {
540
0
    err = fsync(fd);
541
0
  } while (err < 0 && errno == EINTR);
542
0
  return err;
543
0
}
544
545
int git_fsync(int fd, enum fsync_action action)
546
0
{
547
0
  switch (action) {
548
0
  case FSYNC_WRITEOUT_ONLY:
549
0
    trace2_counter_add(TRACE2_COUNTER_ID_FSYNC_WRITEOUT_ONLY, 1);
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
0
#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
0
    return sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WAIT_BEFORE |
569
0
             SYNC_FILE_RANGE_WRITE |
570
0
             SYNC_FILE_RANGE_WAIT_AFTER);
571
0
#endif
572
573
#ifdef fsync_no_flush
574
    return fsync_no_flush(fd);
575
#endif
576
577
0
    errno = ENOSYS;
578
0
    return -1;
579
580
0
  case FSYNC_HARDWARE_FLUSH:
581
0
    trace2_counter_add(TRACE2_COUNTER_ID_FSYNC_HARDWARE_FLUSH, 1);
582
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
0
    return fsync_loop(fd);
592
0
#endif
593
0
  default:
594
0
    BUG("unexpected git_fsync(%d) call", action);
595
0
  }
596
0
}
597
598
static int warn_if_unremovable(const char *op, const char *file, int rc)
599
0
{
600
0
  int err;
601
0
  if (!rc || errno == ENOENT)
602
0
    return 0;
603
0
  err = errno;
604
0
  warning_errno("unable to %s '%s'", op, file);
605
0
  errno = err;
606
0
  return rc;
607
0
}
608
609
int unlink_or_msg(const char *file, struct strbuf *err)
610
0
{
611
0
  int rc = unlink(file);
612
613
0
  assert(err);
614
615
0
  if (!rc || errno == ENOENT)
616
0
    return 0;
617
618
0
  strbuf_addf(err, "unable to unlink '%s': %s",
619
0
        file, strerror(errno));
620
0
  return -1;
621
0
}
622
623
int unlink_or_warn(const char *file)
624
0
{
625
0
  return warn_if_unremovable("unlink", file, unlink(file));
626
0
}
627
628
int rmdir_or_warn(const char *file)
629
0
{
630
0
  return warn_if_unremovable("rmdir", file, rmdir(file));
631
0
}
632
633
static int access_error_is_ok(int err, unsigned flag)
634
0
{
635
0
  return (is_missing_file_error(err) ||
636
0
    ((flag & ACCESS_EACCES_OK) && err == EACCES));
637
0
}
638
639
int access_or_warn(const char *path, int mode, unsigned flag)
640
0
{
641
0
  int ret = access(path, mode);
642
0
  if (ret && !access_error_is_ok(errno, flag))
643
0
    warn_on_inaccessible(path);
644
0
  return ret;
645
0
}
646
647
int access_or_die(const char *path, int mode, unsigned flag)
648
0
{
649
0
  int ret = access(path, mode);
650
0
  if (ret && !access_error_is_ok(errno, flag))
651
0
    die_errno(_("unable to access '%s'"), path);
652
0
  return ret;
653
0
}
654
655
char *xgetcwd(void)
656
0
{
657
0
  struct strbuf sb = STRBUF_INIT;
658
0
  if (strbuf_getcwd(&sb))
659
0
    die_errno(_("unable to get current working directory"));
660
0
  return strbuf_detach(&sb, NULL);
661
0
}
662
663
int xsnprintf(char *dst, size_t max, const char *fmt, ...)
664
0
{
665
0
  va_list ap;
666
0
  int len;
667
668
0
  va_start(ap, fmt);
669
0
  len = vsnprintf(dst, max, fmt, ap);
670
0
  va_end(ap);
671
672
0
  if (len < 0)
673
0
    die(_("unable to format message: %s"), fmt);
674
0
  if (len >= max)
675
0
    BUG("attempt to snprintf into too-small buffer");
676
0
  return len;
677
0
}
678
679
void write_file_buf(const char *path, const char *buf, size_t len)
680
0
{
681
0
  int fd = xopen(path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
682
0
  if (write_in_full(fd, buf, len) < 0)
683
0
    die_errno(_("could not write to '%s'"), path);
684
0
  if (close(fd))
685
0
    die_errno(_("could not close '%s'"), path);
686
0
}
687
688
void write_file(const char *path, const char *fmt, ...)
689
0
{
690
0
  va_list params;
691
0
  struct strbuf sb = STRBUF_INIT;
692
693
0
  va_start(params, fmt);
694
0
  strbuf_vaddf(&sb, fmt, params);
695
0
  va_end(params);
696
697
0
  strbuf_complete_line(&sb);
698
699
0
  write_file_buf(path, sb.buf, sb.len);
700
0
  strbuf_release(&sb);
701
0
}
702
703
void sleep_millisec(int millisec)
704
0
{
705
0
  poll(NULL, 0, millisec);
706
0
}
707
708
int xgethostname(char *buf, size_t len)
709
0
{
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
0
  int ret = gethostname(buf, len);
716
0
  if (!ret)
717
0
    buf[len - 1] = 0;
718
0
  return ret;
719
0
}
720
721
int is_empty_or_missing_file(const char *filename)
722
0
{
723
0
  struct stat st;
724
725
0
  if (stat(filename, &st) < 0) {
726
0
    if (errno == ENOENT)
727
0
      return 1;
728
0
    die_errno(_("could not stat %s"), filename);
729
0
  }
730
731
0
  return !st.st_size;
732
0
}
733
734
int open_nofollow(const char *path, int flags)
735
0
{
736
0
#ifdef O_NOFOLLOW
737
0
  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
0
}
749
750
int csprng_bytes(void *buf, size_t len)
751
0
{
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
0
  ssize_t res;
795
0
  char *p = buf;
796
0
  int fd, err;
797
0
  fd = open("/dev/urandom", O_RDONLY);
798
0
  if (fd < 0)
799
0
    return -1;
800
0
  while (len) {
801
0
    res = xread(fd, p, len);
802
0
    if (res < 0) {
803
0
      err = errno;
804
0
      close(fd);
805
0
      errno = err;
806
0
      return -1;
807
0
    }
808
0
    len -= res;
809
0
    p += res;
810
0
  }
811
0
  close(fd);
812
0
  return 0;
813
0
#endif
814
0
}
815
816
uint32_t git_rand(void)
817
0
{
818
0
  uint32_t result;
819
820
0
  if (csprng_bytes(&result, sizeof(result)) < 0)
821
0
    die(_("unable to get random bytes"));
822
823
0
  return result;
824
0
}