Coverage Report

Created: 2024-09-16 06:10

/src/git/write-or-die.c
Line
Count
Source (jump to first uncovered line)
1
#include "git-compat-util.h"
2
#include "parse.h"
3
#include "run-command.h"
4
#include "write-or-die.h"
5
6
/*
7
 * Some cases use stdio, but want to flush after the write
8
 * to get error handling (and to get better interactive
9
 * behaviour - not buffering excessively).
10
 *
11
 * Of course, if the flush happened within the write itself,
12
 * we've already lost the error code, and cannot report it any
13
 * more. So we just ignore that case instead (and hope we get
14
 * the right error code on the flush).
15
 *
16
 * If the file handle is stdout, and stdout is a file, then skip the
17
 * flush entirely since it's not needed.
18
 */
19
void maybe_flush_or_die(FILE *f, const char *desc)
20
0
{
21
0
  if (f == stdout) {
22
0
    static int force_flush_stdout = -1;
23
24
0
    if (force_flush_stdout < 0) {
25
0
      force_flush_stdout = git_env_bool("GIT_FLUSH", -1);
26
0
      if (force_flush_stdout < 0) {
27
0
        struct stat st;
28
0
        if (fstat(fileno(stdout), &st))
29
0
          force_flush_stdout = 1;
30
0
        else
31
0
          force_flush_stdout = !S_ISREG(st.st_mode);
32
0
      }
33
0
    }
34
0
    if (!force_flush_stdout && !ferror(f))
35
0
      return;
36
0
  }
37
0
  if (fflush(f)) {
38
0
    check_pipe(errno);
39
0
    die_errno("write failure on '%s'", desc);
40
0
  }
41
0
}
42
43
void fprintf_or_die(FILE *f, const char *fmt, ...)
44
0
{
45
0
  va_list ap;
46
0
  int ret;
47
48
0
  va_start(ap, fmt);
49
0
  ret = vfprintf(f, fmt, ap);
50
0
  va_end(ap);
51
52
0
  if (ret < 0) {
53
0
    check_pipe(errno);
54
0
    die_errno("write error");
55
0
  }
56
0
}
57
58
static int maybe_fsync(int fd)
59
0
{
60
0
  if (use_fsync < 0)
61
0
    use_fsync = git_env_bool("GIT_TEST_FSYNC", 1);
62
0
  if (!use_fsync)
63
0
    return 0;
64
65
0
  if (fsync_method == FSYNC_METHOD_WRITEOUT_ONLY &&
66
0
      git_fsync(fd, FSYNC_WRITEOUT_ONLY) >= 0)
67
0
    return 0;
68
69
0
  return git_fsync(fd, FSYNC_HARDWARE_FLUSH);
70
0
}
71
72
void fsync_or_die(int fd, const char *msg)
73
0
{
74
0
  if (maybe_fsync(fd) < 0)
75
0
    die_errno("fsync error on '%s'", msg);
76
0
}
77
78
int fsync_component(enum fsync_component component, int fd)
79
0
{
80
0
  if (fsync_components & component)
81
0
    return maybe_fsync(fd);
82
0
  return 0;
83
0
}
84
85
void fsync_component_or_die(enum fsync_component component, int fd, const char *msg)
86
0
{
87
0
  if (fsync_components & component)
88
0
    fsync_or_die(fd, msg);
89
0
}
90
91
void write_or_die(int fd, const void *buf, size_t count)
92
0
{
93
0
  if (write_in_full(fd, buf, count) < 0) {
94
0
    check_pipe(errno);
95
0
    die_errno("write error");
96
0
  }
97
0
}
98
99
void fwrite_or_die(FILE *f, const void *buf, size_t count)
100
0
{
101
0
  if (fwrite(buf, 1, count, f) != count)
102
0
    die_errno("fwrite error");
103
0
}
104
105
void fflush_or_die(FILE *f)
106
0
{
107
0
  if (fflush(f))
108
0
    die_errno("fflush error");
109
0
}