Coverage Report

Created: 2025-12-31 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/git/wrapper.c
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
26.3k
{
23
26.3k
  static size_t limit = 0;
24
26.3k
  if (!limit) {
25
6
    limit = git_env_ulong("GIT_ALLOC_LIMIT", 0);
26
6
    if (!limit)
27
6
      limit = SIZE_MAX;
28
6
  }
29
26.3k
  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
26.3k
  return 0;
39
26.3k
}
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
2.26k
{
51
2.26k
  void *ret;
52
53
2.26k
  if (memory_limit_check(size, gentle))
54
0
    return NULL;
55
2.26k
  ret = malloc(size);
56
2.26k
  if (!ret && !size)
57
0
    ret = malloc(1);
58
2.26k
  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
2.26k
  return ret;
72
2.26k
}
73
74
void *xmalloc(size_t size)
75
577
{
76
577
  return do_xmalloc(size, 0);
77
577
}
78
79
static void *do_xmallocz(size_t size, int gentle)
80
1.68k
{
81
1.68k
  void *ret;
82
1.68k
  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
1.68k
  ret = do_xmalloc(size + 1, gentle);
90
1.68k
  if (ret)
91
1.68k
    ((char*)ret)[size] = 0;
92
1.68k
  return ret;
93
1.68k
}
94
95
void *xmallocz(size_t size)
96
1.68k
{
97
1.68k
  return do_xmallocz(size, 0);
98
1.68k
}
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
1.68k
{
113
1.68k
  return memcpy(xmallocz(len), data, len);
114
1.68k
}
115
116
char *xstrndup(const char *str, size_t len)
117
0
{
118
0
  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
22.4k
{
132
22.4k
  void *ret;
133
134
22.4k
  if (!size) {
135
0
    free(ptr);
136
0
    return xmalloc(0);
137
0
  }
138
139
22.4k
  memory_limit_check(size, 0);
140
22.4k
  ret = realloc(ptr, size);
141
22.4k
  if (!ret)
142
0
    die("Out of memory, realloc failed");
143
22.4k
  return ret;
144
22.4k
}
145
146
void *xcalloc(size_t nmemb, size_t size)
147
1.69k
{
148
1.69k
  void *ret;
149
150
1.69k
  if (unsigned_mult_overflows(nmemb, size))
151
0
    die("data too large to fit into virtual memory space");
152
153
1.69k
  memory_limit_check(size * nmemb, 0);
154
1.69k
  ret = calloc(nmemb, size);
155
1.69k
  if (!ret && (!nmemb || !size))
156
0
    ret = calloc(1, 1);
157
1.69k
  if (!ret)
158
0
    die("Out of memory, calloc failed");
159
1.69k
  return ret;
160
1.69k
}
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
531
{
252
531
  ssize_t nr;
253
531
  if (len > MAX_IO_SIZE)
254
0
    len = MAX_IO_SIZE;
255
531
  while (1) {
256
531
    nr = write(fd, buf, len);
257
531
    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
531
    return nr;
265
531
  }
266
531
}
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
531
{
307
531
  const char *p = buf;
308
531
  ssize_t total = 0;
309
310
1.06k
  while (count > 0) {
311
531
    ssize_t written = xwrite(fd, p, count);
312
531
    if (written < 0)
313
0
      return -1;
314
531
    if (!written) {
315
0
      errno = ENOSPC;
316
0
      return -1;
317
0
    }
318
531
    count -= written;
319
531
    p += written;
320
531
    total += written;
321
531
  }
322
323
531
  return total;
324
531
}
325
326
ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset)
327
0
{
328
0
  char *p = buf;
329
0
  ssize_t total = 0;
330
331
0
  while (count > 0) {
332
0
    ssize_t loaded = xpread(fd, p, count, offset);
333
0
    if (loaded < 0)
334
0
      return -1;
335
0
    if (loaded == 0)
336
0
      return total;
337
0
    count -= loaded;
338
0
    p += loaded;
339
0
    total += loaded;
340
0
    offset += loaded;
341
0
  }
342
343
0
  return total;
344
0
}
345
346
int xdup(int fd)
347
0
{
348
0
  int ret = dup(fd);
349
0
  if (ret < 0)
350
0
    die_errno("dup failed");
351
0
  return ret;
352
0
}
353
354
/**
355
 * xfopen() is the same as fopen(), but it die()s if the fopen() fails.
356
 */
357
FILE *xfopen(const char *path, const char *mode)
358
0
{
359
0
  for (;;) {
360
0
    FILE *fp = fopen(path, mode);
361
0
    if (fp)
362
0
      return fp;
363
0
    if (errno == EINTR)
364
0
      continue;
365
366
0
    if (*mode && mode[1] == '+')
367
0
      die_errno(_("could not open '%s' for reading and writing"), path);
368
0
    else if (*mode == 'w' || *mode == 'a')
369
0
      die_errno(_("could not open '%s' for writing"), path);
370
0
    else
371
0
      die_errno(_("could not open '%s' for reading"), path);
372
0
  }
373
0
}
374
375
FILE *xfdopen(int fd, const char *mode)
376
0
{
377
0
  FILE *stream = fdopen(fd, mode);
378
0
  if (!stream)
379
0
    die_errno("Out of memory? fdopen failed");
380
0
  return stream;
381
0
}
382
383
FILE *fopen_for_writing(const char *path)
384
0
{
385
0
  FILE *ret = fopen(path, "w");
386
387
0
  if (!ret && errno == EPERM) {
388
0
    if (!unlink(path))
389
0
      ret = fopen(path, "w");
390
0
    else
391
0
      errno = EPERM;
392
0
  }
393
0
  return ret;
394
0
}
395
396
static void warn_on_inaccessible(const char *path)
397
0
{
398
0
  warning_errno(_("unable to access '%s'"), path);
399
0
}
400
401
int warn_on_fopen_errors(const char *path)
402
0
{
403
0
  if (errno != ENOENT && errno != ENOTDIR) {
404
0
    warn_on_inaccessible(path);
405
0
    return -1;
406
0
  }
407
408
0
  return 0;
409
0
}
410
411
FILE *fopen_or_warn(const char *path, const char *mode)
412
0
{
413
0
  FILE *fp = fopen(path, mode);
414
415
0
  if (fp)
416
0
    return fp;
417
418
0
  warn_on_fopen_errors(path);
419
0
  return NULL;
420
0
}
421
422
int xmkstemp(char *filename_template)
423
0
{
424
0
  return xmkstemp_mode(filename_template, 0600);
425
0
}
426
427
/* Adapted from libiberty's mkstemp.c. */
428
429
#undef TMP_MAX
430
0
#define TMP_MAX 16384
431
432
/*
433
 * Returns -1 on error, 0 if it created a directory, or an open file
434
 * descriptor to the created regular file.
435
 */
436
static int git_mkdstemps_mode(char *pattern, int suffix_len, int mode, bool dir)
437
0
{
438
0
  static const char letters[] =
439
0
    "abcdefghijklmnopqrstuvwxyz"
440
0
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
441
0
    "0123456789";
442
0
  static const int num_letters = ARRAY_SIZE(letters) - 1;
443
0
  static const char x_pattern[] = "XXXXXX";
444
0
  static const int num_x = ARRAY_SIZE(x_pattern) - 1;
445
0
  char *filename_template;
446
0
  size_t len;
447
0
  int fd, count;
448
449
0
  len = strlen(pattern);
450
451
0
  if (len < num_x + suffix_len) {
452
0
    errno = EINVAL;
453
0
    return -1;
454
0
  }
455
456
0
  if (strncmp(&pattern[len - num_x - suffix_len], x_pattern, num_x)) {
457
0
    errno = EINVAL;
458
0
    return -1;
459
0
  }
460
461
  /*
462
   * Replace pattern's XXXXXX characters with randomness.
463
   * Try TMP_MAX different filenames.
464
   */
465
0
  filename_template = &pattern[len - num_x - suffix_len];
466
0
  for (count = 0; count < TMP_MAX; ++count) {
467
0
    int i;
468
0
    uint64_t v;
469
0
    if (csprng_bytes(&v, sizeof(v), 0) < 0)
470
0
      return error_errno("unable to get random bytes for temporary file");
471
472
    /* Fill in the random bits. */
473
0
    for (i = 0; i < num_x; i++) {
474
0
      filename_template[i] = letters[v % num_letters];
475
0
      v /= num_letters;
476
0
    }
477
478
0
    if (dir)
479
0
      fd = mkdir(pattern, mode);
480
0
    else
481
0
      fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);
482
0
    if (fd >= 0)
483
0
      return fd;
484
    /*
485
     * Fatal error (EPERM, ENOSPC etc).
486
     * It doesn't make sense to loop.
487
     */
488
0
    if (errno != EEXIST)
489
0
      break;
490
0
  }
491
  /* We return the null string if we can't find a unique file name.  */
492
0
  pattern[0] = '\0';
493
0
  return -1;
494
0
}
495
496
char *git_mkdtemp(char *pattern)
497
0
{
498
0
  return git_mkdstemps_mode(pattern, 0, 0700, true) ? NULL : pattern;
499
0
}
500
501
int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
502
0
{
503
0
  return git_mkdstemps_mode(pattern, suffix_len, mode, false);
504
0
}
505
506
int git_mkstemp_mode(char *pattern, int mode)
507
0
{
508
  /* mkstemp is just mkstemps with no suffix */
509
0
  return git_mkstemps_mode(pattern, 0, mode);
510
0
}
511
512
int xmkstemp_mode(char *filename_template, int mode)
513
0
{
514
0
  int fd;
515
0
  char origtemplate[PATH_MAX];
516
0
  strlcpy(origtemplate, filename_template, sizeof(origtemplate));
517
518
0
  fd = git_mkstemp_mode(filename_template, mode);
519
0
  if (fd < 0) {
520
0
    int saved_errno = errno;
521
0
    const char *nonrelative_template;
522
523
0
    if (!filename_template[0])
524
0
      filename_template = origtemplate;
525
526
0
    nonrelative_template = absolute_path(filename_template);
527
0
    errno = saved_errno;
528
0
    die_errno("Unable to create temporary file '%s'",
529
0
      nonrelative_template);
530
0
  }
531
0
  return fd;
532
0
}
533
534
/*
535
 * Some platforms return EINTR from fsync. Since fsync is invoked in some
536
 * cases by a wrapper that dies on failure, do not expose EINTR to callers.
537
 */
538
static int fsync_loop(int fd)
539
0
{
540
0
  int err;
541
542
0
  do {
543
0
    err = fsync(fd);
544
0
  } while (err < 0 && errno == EINTR);
545
0
  return err;
546
0
}
547
548
int git_fsync(int fd, enum fsync_action action)
549
0
{
550
0
  switch (action) {
551
0
  case FSYNC_WRITEOUT_ONLY:
552
0
    trace2_counter_add(TRACE2_COUNTER_ID_FSYNC_WRITEOUT_ONLY, 1);
553
554
#ifdef __APPLE__
555
    /*
556
     * On macOS, fsync just causes filesystem cache writeback but
557
     * does not flush hardware caches.
558
     */
559
    return fsync_loop(fd);
560
#endif
561
562
0
#ifdef HAVE_SYNC_FILE_RANGE
563
    /*
564
     * On linux 2.6.17 and above, sync_file_range is the way to
565
     * issue a writeback without a hardware flush. An offset of
566
     * 0 and size of 0 indicates writeout of the entire file and the
567
     * wait flags ensure that all dirty data is written to the disk
568
     * (potentially in a disk-side cache) before we continue.
569
     */
570
571
0
    return sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WAIT_BEFORE |
572
0
             SYNC_FILE_RANGE_WRITE |
573
0
             SYNC_FILE_RANGE_WAIT_AFTER);
574
0
#endif
575
576
#ifdef fsync_no_flush
577
    return fsync_no_flush(fd);
578
#endif
579
580
0
    errno = ENOSYS;
581
0
    return -1;
582
583
0
  case FSYNC_HARDWARE_FLUSH:
584
0
    trace2_counter_add(TRACE2_COUNTER_ID_FSYNC_HARDWARE_FLUSH, 1);
585
586
    /*
587
     * On macOS, a special fcntl is required to really flush the
588
     * caches within the storage controller. As of this writing,
589
     * this is a very expensive operation on Apple SSDs.
590
     */
591
#ifdef __APPLE__
592
    return fcntl(fd, F_FULLFSYNC);
593
#else
594
0
    return fsync_loop(fd);
595
0
#endif
596
0
  default:
597
0
    BUG("unexpected git_fsync(%d) call", action);
598
0
  }
599
0
}
600
601
static int warn_if_unremovable(const char *op, const char *file, int rc)
602
0
{
603
0
  int err;
604
0
  if (!rc || errno == ENOENT)
605
0
    return 0;
606
0
  err = errno;
607
0
  warning_errno("unable to %s '%s'", op, file);
608
0
  errno = err;
609
0
  return rc;
610
0
}
611
612
int unlink_or_msg(const char *file, struct strbuf *err)
613
0
{
614
0
  int rc = unlink(file);
615
616
0
  assert(err);
617
618
0
  if (!rc || errno == ENOENT)
619
0
    return 0;
620
621
0
  strbuf_addf(err, "unable to unlink '%s': %s",
622
0
        file, strerror(errno));
623
0
  return -1;
624
0
}
625
626
int unlink_or_warn(const char *file)
627
0
{
628
0
  return warn_if_unremovable("unlink", file, unlink(file));
629
0
}
630
631
int rmdir_or_warn(const char *file)
632
0
{
633
0
  return warn_if_unremovable("rmdir", file, rmdir(file));
634
0
}
635
636
static int access_error_is_ok(int err, unsigned flag)
637
0
{
638
0
  return (is_missing_file_error(err) ||
639
0
    ((flag & ACCESS_EACCES_OK) && err == EACCES));
640
0
}
641
642
int access_or_warn(const char *path, int mode, unsigned flag)
643
0
{
644
0
  int ret = access(path, mode);
645
0
  if (ret && !access_error_is_ok(errno, flag))
646
0
    warn_on_inaccessible(path);
647
0
  return ret;
648
0
}
649
650
int access_or_die(const char *path, int mode, unsigned flag)
651
0
{
652
0
  int ret = access(path, mode);
653
0
  if (ret && !access_error_is_ok(errno, flag))
654
0
    die_errno(_("unable to access '%s'"), path);
655
0
  return ret;
656
0
}
657
658
char *xgetcwd(void)
659
0
{
660
0
  struct strbuf sb = STRBUF_INIT;
661
0
  if (strbuf_getcwd(&sb))
662
0
    die_errno(_("unable to get current working directory"));
663
0
  return strbuf_detach(&sb, NULL);
664
0
}
665
666
int xsnprintf(char *dst, size_t max, const char *fmt, ...)
667
0
{
668
0
  va_list ap;
669
0
  int len;
670
671
0
  va_start(ap, fmt);
672
0
  len = vsnprintf(dst, max, fmt, ap);
673
0
  va_end(ap);
674
675
0
  if (len < 0)
676
0
    die(_("unable to format message: %s"), fmt);
677
0
  if (len >= max)
678
0
    BUG("attempt to snprintf into too-small buffer");
679
0
  return len;
680
0
}
681
682
void write_file_buf(const char *path, const char *buf, size_t len)
683
0
{
684
0
  int fd = xopen(path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
685
0
  if (write_in_full(fd, buf, len) < 0)
686
0
    die_errno(_("could not write to '%s'"), path);
687
0
  if (close(fd))
688
0
    die_errno(_("could not close '%s'"), path);
689
0
}
690
691
void write_file(const char *path, const char *fmt, ...)
692
0
{
693
0
  va_list params;
694
0
  struct strbuf sb = STRBUF_INIT;
695
696
0
  va_start(params, fmt);
697
0
  strbuf_vaddf(&sb, fmt, params);
698
0
  va_end(params);
699
700
0
  strbuf_complete_line(&sb);
701
702
0
  write_file_buf(path, sb.buf, sb.len);
703
0
  strbuf_release(&sb);
704
0
}
705
706
void sleep_millisec(int millisec)
707
0
{
708
0
  poll(NULL, 0, millisec);
709
0
}
710
711
int xgethostname(char *buf, size_t len)
712
0
{
713
  /*
714
   * If the full hostname doesn't fit in buf, POSIX does not
715
   * specify whether the buffer will be null-terminated, so to
716
   * be safe, do it ourselves.
717
   */
718
0
  int ret = gethostname(buf, len);
719
0
  if (!ret)
720
0
    buf[len - 1] = 0;
721
0
  return ret;
722
0
}
723
724
int is_missing_file(const char *filename)
725
0
{
726
0
  struct stat st;
727
728
0
  if (stat(filename, &st) < 0) {
729
0
    if (errno == ENOENT)
730
0
      return 1;
731
0
    die_errno(_("could not stat %s"), filename);
732
0
  }
733
734
0
  return 0;
735
0
}
736
737
int is_empty_or_missing_file(const char *filename)
738
0
{
739
0
  struct stat st;
740
741
0
  if (stat(filename, &st) < 0) {
742
0
    if (errno == ENOENT)
743
0
      return 1;
744
0
    die_errno(_("could not stat %s"), filename);
745
0
  }
746
747
0
  return !st.st_size;
748
0
}
749
750
int open_nofollow(const char *path, int flags)
751
0
{
752
0
#ifdef O_NOFOLLOW
753
0
  int ret = open(path, flags | O_NOFOLLOW);
754
  /*
755
   * NetBSD sets errno to EFTYPE when path is a symlink. The only other
756
   * time this errno occurs when O_REGULAR is used. Since we don't use
757
   * it anywhere we can avoid an lstat here. FreeBSD does the same with
758
   * EMLINK.
759
   */
760
# ifdef __NetBSD__
761
#  define SYMLINK_ERRNO EFTYPE
762
# elif defined(__FreeBSD__)
763
#  define SYMLINK_ERRNO EMLINK
764
# endif
765
# if SYMLINK_ERRNO
766
  if (ret < 0 && errno == SYMLINK_ERRNO) {
767
    errno = ELOOP;
768
    return -1;
769
  }
770
#  undef SYMLINK_ERRNO
771
# endif
772
0
  return ret;
773
#else
774
  struct stat st;
775
  if (lstat(path, &st) < 0)
776
    return -1;
777
  if (S_ISLNK(st.st_mode)) {
778
    errno = ELOOP;
779
    return -1;
780
  }
781
  return open(path, flags);
782
#endif
783
0
}
784
785
int csprng_bytes(void *buf, size_t len, MAYBE_UNUSED unsigned flags)
786
0
{
787
#if defined(HAVE_ARC4RANDOM) || defined(HAVE_ARC4RANDOM_LIBBSD)
788
  /* This function never returns an error. */
789
  arc4random_buf(buf, len);
790
  return 0;
791
#elif defined(HAVE_GETRANDOM)
792
  ssize_t res;
793
0
  char *p = buf;
794
0
  while (len) {
795
0
    res = getrandom(p, len, 0);
796
0
    if (res < 0)
797
0
      return -1;
798
0
    len -= res;
799
0
    p += res;
800
0
  }
801
0
  return 0;
802
#elif defined(HAVE_GETENTROPY)
803
  int res;
804
  char *p = buf;
805
  while (len) {
806
    /* getentropy has a maximum size of 256 bytes. */
807
    size_t chunk = len < 256 ? len : 256;
808
    res = getentropy(p, chunk);
809
    if (res < 0)
810
      return -1;
811
    len -= chunk;
812
    p += chunk;
813
  }
814
  return 0;
815
#elif defined(HAVE_RTLGENRANDOM)
816
  if (!RtlGenRandom(buf, len))
817
    return -1;
818
  return 0;
819
#elif defined(HAVE_OPENSSL_CSPRNG)
820
  switch (RAND_pseudo_bytes(buf, len)) {
821
  case 1:
822
    return 0;
823
  case 0:
824
    if (flags & CSPRNG_BYTES_INSECURE)
825
      return 0;
826
    errno = EIO;
827
    return -1;
828
  default:
829
    errno = ENOTSUP;
830
    return -1;
831
  }
832
#else
833
  ssize_t res;
834
  char *p = buf;
835
  int fd, err;
836
  fd = open("/dev/urandom", O_RDONLY);
837
  if (fd < 0)
838
    return -1;
839
  while (len) {
840
    res = xread(fd, p, len);
841
    if (res < 0) {
842
      err = errno;
843
      close(fd);
844
      errno = err;
845
      return -1;
846
    }
847
    len -= res;
848
    p += res;
849
  }
850
  close(fd);
851
  return 0;
852
#endif
853
0
}
854
855
uint32_t git_rand(unsigned flags)
856
0
{
857
0
  uint32_t result;
858
859
0
  if (csprng_bytes(&result, sizeof(result), flags) < 0)
860
0
    die(_("unable to get random bytes"));
861
862
0
  return result;
863
0
}
864
865
static void mmap_limit_check(size_t length)
866
0
{
867
0
  static size_t limit = 0;
868
0
  if (!limit) {
869
0
    limit = git_env_ulong("GIT_MMAP_LIMIT", 0);
870
0
    if (!limit)
871
0
      limit = SIZE_MAX;
872
0
  }
873
0
  if (length > limit)
874
0
    die(_("attempting to mmap %"PRIuMAX" over limit %"PRIuMAX),
875
0
        (uintmax_t)length, (uintmax_t)limit);
876
0
}
877
878
void *xmmap_gently(void *start, size_t length,
879
      int prot, int flags, int fd, off_t offset)
880
0
{
881
0
  void *ret;
882
883
0
  mmap_limit_check(length);
884
0
  ret = mmap(start, length, prot, flags, fd, offset);
885
0
  if (ret == MAP_FAILED && !length)
886
0
    ret = NULL;
887
0
  return ret;
888
0
}
889
890
const char *mmap_os_err(void)
891
0
{
892
0
  static const char blank[] = "";
893
0
#if defined(__linux__)
894
0
  if (errno == ENOMEM) {
895
    /* this continues an existing error message: */
896
0
    static const char enomem[] =
897
0
", check sys.vm.max_map_count and/or RLIMIT_DATA";
898
0
    return enomem;
899
0
  }
900
0
#endif /* OS-specific bits */
901
0
  return blank;
902
0
}
903
904
void *xmmap(void *start, size_t length,
905
  int prot, int flags, int fd, off_t offset)
906
0
{
907
0
  void *ret = xmmap_gently(start, length, prot, flags, fd, offset);
908
0
  if (ret == MAP_FAILED)
909
0
    die_errno(_("mmap failed%s"), mmap_os_err());
910
0
  return ret;
911
0
}