Git fork
at reftables-rust 109 lines 2.4 kB view raw
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 */ 19void maybe_flush_or_die(FILE *f, const char *desc) 20{ 21 if (f == stdout) { 22 static int force_flush_stdout = -1; 23 24 if (force_flush_stdout < 0) { 25 force_flush_stdout = git_env_bool("GIT_FLUSH", -1); 26 if (force_flush_stdout < 0) { 27 struct stat st; 28 if (fstat(fileno(stdout), &st)) 29 force_flush_stdout = 1; 30 else 31 force_flush_stdout = !S_ISREG(st.st_mode); 32 } 33 } 34 if (!force_flush_stdout && !ferror(f)) 35 return; 36 } 37 if (fflush(f)) { 38 check_pipe(errno); 39 die_errno("write failure on '%s'", desc); 40 } 41} 42 43void fprintf_or_die(FILE *f, const char *fmt, ...) 44{ 45 va_list ap; 46 int ret; 47 48 va_start(ap, fmt); 49 ret = vfprintf(f, fmt, ap); 50 va_end(ap); 51 52 if (ret < 0) { 53 check_pipe(errno); 54 die_errno("write error"); 55 } 56} 57 58static int maybe_fsync(int fd) 59{ 60 if (use_fsync < 0) 61 use_fsync = git_env_bool("GIT_TEST_FSYNC", 1); 62 if (!use_fsync) 63 return 0; 64 65 if (fsync_method == FSYNC_METHOD_WRITEOUT_ONLY && 66 git_fsync(fd, FSYNC_WRITEOUT_ONLY) >= 0) 67 return 0; 68 69 return git_fsync(fd, FSYNC_HARDWARE_FLUSH); 70} 71 72void fsync_or_die(int fd, const char *msg) 73{ 74 if (maybe_fsync(fd) < 0) 75 die_errno("fsync error on '%s'", msg); 76} 77 78int fsync_component(enum fsync_component component, int fd) 79{ 80 if (fsync_components & component) 81 return maybe_fsync(fd); 82 return 0; 83} 84 85void fsync_component_or_die(enum fsync_component component, int fd, const char *msg) 86{ 87 if (fsync_components & component) 88 fsync_or_die(fd, msg); 89} 90 91void write_or_die(int fd, const void *buf, size_t count) 92{ 93 if (write_in_full(fd, buf, count) < 0) { 94 check_pipe(errno); 95 die_errno("write error"); 96 } 97} 98 99void fwrite_or_die(FILE *f, const void *buf, size_t count) 100{ 101 if (fwrite(buf, 1, count, f) != count) 102 die_errno("fwrite error"); 103} 104 105void fflush_or_die(FILE *f) 106{ 107 if (fflush(f)) 108 die_errno("fflush error"); 109}