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 | } |