Coverage Report

Created: 2024-09-08 06:24

/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
3.89M
{
20
3.89M
  static size_t limit = 0;
21
3.89M
  if (!limit) {
22
1
    limit = git_env_ulong("GIT_ALLOC_LIMIT", 0);
23
1
    if (!limit)
24
1
      limit = SIZE_MAX;
25
1
  }
26
3.89M
  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
3.89M
  return 0;
36
3.89M
}
37
38
char *xstrdup(const char *str)
39
1.04M
{
40
1.04M
  char *ret = strdup(str);
41
1.04M
  if (!ret)
42
0
    die("Out of memory, strdup failed");
43
1.04M
  return ret;
44
1.04M
}
45
46
static void *do_xmalloc(size_t size, int gentle)
47
696k
{
48
696k
  void *ret;
49
50
696k
  if (memory_limit_check(size, gentle))
51
0
    return NULL;
52
696k
  ret = malloc(size);
53
696k
  if (!ret && !size)
54
0
    ret = malloc(1);
55
696k
  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
696k
  return ret;
69
696k
}
70
71
void *xmalloc(size_t size)
72
468k
{
73
468k
  return do_xmalloc(size, 0);
74
468k
}
75
76
static void *do_xmallocz(size_t size, int gentle)
77
228k
{
78
228k
  void *ret;
79
228k
  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
228k
  ret = do_xmalloc(size + 1, gentle);
87
228k
  if (ret)
88
228k
    ((char*)ret)[size] = 0;
89
228k
  return ret;
90
228k
}
91
92
void *xmallocz(size_t size)
93
220k
{
94
220k
  return do_xmallocz(size, 0);
95
220k
}
96
97
void *xmallocz_gently(size_t size)
98
7.69k
{
99
7.69k
  return do_xmallocz(size, 1);
100
7.69k
}
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
21.7k
{
110
21.7k
  return memcpy(xmallocz(len), data, len);
111
21.7k
}
112
113
char *xstrndup(const char *str, size_t len)
114
21.7k
{
115
21.7k
  char *p = memchr(str, '\0', len);
116
21.7k
  return xmemdupz(str, p ? p - str : len);
117
21.7k
}
118
119
int xstrncmpz(const char *s, const char *t, size_t len)
120
655k
{
121
655k
  int res = strncmp(s, t, len);
122
655k
  if (res)
123
570k
    return res;
124
85.2k
  return s[len] == '\0' ? 0 : 1;
125
655k
}
126
127
void *xrealloc(void *ptr, size_t size)
128
2.74M
{
129
2.74M
  void *ret;
130
131
2.74M
  if (!size) {
132
0
    free(ptr);
133
0
    return xmalloc(0);
134
0
  }
135
136
2.74M
  memory_limit_check(size, 0);
137
2.74M
  ret = realloc(ptr, size);
138
2.74M
  if (!ret)
139
0
    die("Out of memory, realloc failed");
140
2.74M
  return ret;
141
2.74M
}
142
143
void *xcalloc(size_t nmemb, size_t size)
144
457k
{
145
457k
  void *ret;
146
147
457k
  if (unsigned_mult_overflows(nmemb, size))
148
0
    die("data too large to fit into virtual memory space");
149
150
457k
  memory_limit_check(size * nmemb, 0);
151
457k
  ret = calloc(nmemb, size);
152
457k
  if (!ret && (!nmemb || !size))
153
0
    ret = calloc(1, 1);
154
457k
  if (!ret)
155
0
    die("Out of memory, calloc failed");
156
457k
  return ret;
157
457k
}
158
159
void xsetenv(const char *name, const char *value, int overwrite)
160
13.9k
{
161
13.9k
  if (setenv(name, value, overwrite))
162
0
    die_errno(_("could not setenv '%s'"), name ? name : "(null)");
163
13.9k
}
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
462k
{
227
462k
  ssize_t nr;
228
462k
  if (len > MAX_IO_SIZE)
229
0
    len = MAX_IO_SIZE;
230
462k
  while (1) {
231
462k
    nr = read(fd, buf, len);
232
462k
    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
462k
    return nr;
239
462k
  }
240
462k
}
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
112k
{
249
112k
  ssize_t nr;
250
112k
  if (len > MAX_IO_SIZE)
251
0
    len = MAX_IO_SIZE;
252
112k
  while (1) {
253
112k
    nr = write(fd, buf, len);
254
112k
    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
112k
    return nr;
262
112k
  }
263
112k
}
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
225k
{
285
225k
  char *p = buf;
286
225k
  ssize_t total = 0;
287
288
451k
  while (count > 0) {
289
401k
    ssize_t loaded = xread(fd, p, count);
290
401k
    if (loaded < 0)
291
0
      return -1;
292
401k
    if (loaded == 0)
293
175k
      return total;
294
225k
    count -= loaded;
295
225k
    p += loaded;
296
225k
    total += loaded;
297
225k
  }
298
299
50.1k
  return total;
300
225k
}
301
302
ssize_t write_in_full(int fd, const void *buf, size_t count)
303
112k
{
304
112k
  const char *p = buf;
305
112k
  ssize_t total = 0;
306
307
225k
  while (count > 0) {
308
112k
    ssize_t written = xwrite(fd, p, count);
309
112k
    if (written < 0)
310
0
      return -1;
311
112k
    if (!written) {
312
0
      errno = ENOSPC;
313
0
      return -1;
314
0
    }
315
112k
    count -= written;
316
112k
    p += written;
317
112k
    total += written;
318
112k
  }
319
320
112k
  return total;
321
112k
}
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
9.16k
{
382
9.16k
  FILE *ret = fopen(path, "w");
383
384
9.16k
  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
9.16k
  return ret;
391
9.16k
}
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
16.0k
{
400
16.0k
  if (errno != ENOENT && errno != ENOTDIR) {
401
0
    warn_on_inaccessible(path);
402
0
    return -1;
403
0
  }
404
405
16.0k
  return 0;
406
16.0k
}
407
408
FILE *fopen_or_warn(const char *path, const char *mode)
409
46.3k
{
410
46.3k
  FILE *fp = fopen(path, mode);
411
412
46.3k
  if (fp)
413
42.0k
    return fp;
414
415
4.31k
  warn_on_fopen_errors(path);
416
4.31k
  return NULL;
417
46.3k
}
418
419
int xmkstemp(char *filename_template)
420
1.39k
{
421
1.39k
  int fd;
422
1.39k
  char origtemplate[PATH_MAX];
423
1.39k
  strlcpy(origtemplate, filename_template, sizeof(origtemplate));
424
425
1.39k
  fd = mkstemp(filename_template);
426
1.39k
  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
1.39k
  return fd;
439
1.39k
}
440
441
/* Adapted from libiberty's mkstemp.c. */
442
443
#undef TMP_MAX
444
52.1k
#define TMP_MAX 16384
445
446
int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
447
52.1k
{
448
52.1k
  static const char letters[] =
449
52.1k
    "abcdefghijklmnopqrstuvwxyz"
450
52.1k
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
451
52.1k
    "0123456789";
452
52.1k
  static const int num_letters = ARRAY_SIZE(letters) - 1;
453
52.1k
  static const char x_pattern[] = "XXXXXX";
454
52.1k
  static const int num_x = ARRAY_SIZE(x_pattern) - 1;
455
52.1k
  char *filename_template;
456
52.1k
  size_t len;
457
52.1k
  int fd, count;
458
459
52.1k
  len = strlen(pattern);
460
461
52.1k
  if (len < num_x + suffix_len) {
462
0
    errno = EINVAL;
463
0
    return -1;
464
0
  }
465
466
52.1k
  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
52.1k
  filename_template = &pattern[len - num_x - suffix_len];
476
52.1k
  for (count = 0; count < TMP_MAX; ++count) {
477
52.1k
    int i;
478
52.1k
    uint64_t v;
479
52.1k
    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
364k
    for (i = 0; i < num_x; i++) {
484
312k
      filename_template[i] = letters[v % num_letters];
485
312k
      v /= num_letters;
486
312k
    }
487
488
52.1k
    fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);
489
52.1k
    if (fd >= 0)
490
26.8k
      return fd;
491
    /*
492
     * Fatal error (EPERM, ENOSPC etc).
493
     * It doesn't make sense to loop.
494
     */
495
25.2k
    if (errno != EEXIST)
496
25.2k
      break;
497
25.2k
  }
498
  /* We return the null string if we can't find a unique file name.  */
499
25.2k
  pattern[0] = '\0';
500
25.2k
  return -1;
501
52.1k
}
502
503
int git_mkstemp_mode(char *pattern, int mode)
504
52.1k
{
505
  /* mkstemp is just mkstemps with no suffix */
506
52.1k
  return git_mkstemps_mode(pattern, 0, mode);
507
52.1k
}
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
63.1k
{
600
63.1k
  int err;
601
63.1k
  if (!rc || errno == ENOENT)
602
63.1k
    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
63.1k
}
608
609
int unlink_or_msg(const char *file, struct strbuf *err)
610
9.08k
{
611
9.08k
  int rc = unlink(file);
612
613
9.08k
  assert(err);
614
615
9.08k
  if (!rc || errno == ENOENT)
616
9.08k
    return 0;
617
618
0
  strbuf_addf(err, "unable to unlink '%s': %s",
619
0
        file, strerror(errno));
620
0
  return -1;
621
9.08k
}
622
623
int unlink_or_warn(const char *file)
624
63.1k
{
625
63.1k
  return warn_if_unremovable("unlink", file, unlink(file));
626
63.1k
}
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
120k
{
635
120k
  return (is_missing_file_error(err) ||
636
120k
    ((flag & ACCESS_EACCES_OK) && err == EACCES));
637
120k
}
638
639
int access_or_warn(const char *path, int mode, unsigned flag)
640
56.1k
{
641
56.1k
  int ret = access(path, mode);
642
56.1k
  if (ret && !access_error_is_ok(errno, flag))
643
0
    warn_on_inaccessible(path);
644
56.1k
  return ret;
645
56.1k
}
646
647
int access_or_die(const char *path, int mode, unsigned flag)
648
90.7k
{
649
90.7k
  int ret = access(path, mode);
650
90.7k
  if (ret && !access_error_is_ok(errno, flag))
651
0
    die_errno(_("unable to access '%s'"), path);
652
90.7k
  return ret;
653
90.7k
}
654
655
char *xgetcwd(void)
656
4
{
657
4
  struct strbuf sb = STRBUF_INIT;
658
4
  if (strbuf_getcwd(&sb))
659
0
    die_errno(_("unable to get current working directory"));
660
4
  return strbuf_detach(&sb, NULL);
661
4
}
662
663
int xsnprintf(char *dst, size_t max, const char *fmt, ...)
664
48.3k
{
665
48.3k
  va_list ap;
666
48.3k
  int len;
667
668
48.3k
  va_start(ap, fmt);
669
48.3k
  len = vsnprintf(dst, max, fmt, ap);
670
48.3k
  va_end(ap);
671
672
48.3k
  if (len < 0)
673
0
    die(_("unable to format message: %s"), fmt);
674
48.3k
  if (len >= max)
675
0
    BUG("attempt to snprintf into too-small buffer");
676
48.3k
  return len;
677
48.3k
}
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
24
{
705
24
  poll(NULL, 0, millisec);
706
24
}
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
10.3k
{
736
10.3k
#ifdef O_NOFOLLOW
737
10.3k
  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
10.3k
}
749
750
int csprng_bytes(void *buf, size_t len)
751
52.1k
{
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
52.1k
  ssize_t res;
795
52.1k
  char *p = buf;
796
52.1k
  int fd, err;
797
52.1k
  fd = open("/dev/urandom", O_RDONLY);
798
52.1k
  if (fd < 0)
799
0
    return -1;
800
104k
  while (len) {
801
52.1k
    res = xread(fd, p, len);
802
52.1k
    if (res < 0) {
803
0
      err = errno;
804
0
      close(fd);
805
0
      errno = err;
806
0
      return -1;
807
0
    }
808
52.1k
    len -= res;
809
52.1k
    p += res;
810
52.1k
  }
811
52.1k
  close(fd);
812
52.1k
  return 0;
813
52.1k
#endif
814
52.1k
}
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
}