1#include "cache.h"2#include "run-command.h"34static void check_pipe(int err)5{6if (err == EPIPE) {7if (in_async())8async_exit(141);910signal(SIGPIPE, SIG_DFL);11raise(SIGPIPE);12/* Should never happen, but just in case... */13exit(141);14}15}1617/*18* Some cases use stdio, but want to flush after the write19* to get error handling (and to get better interactive20* behaviour - not buffering excessively).21*22* Of course, if the flush happened within the write itself,23* we've already lost the error code, and cannot report it any24* more. So we just ignore that case instead (and hope we get25* the right error code on the flush).26*27* If the file handle is stdout, and stdout is a file, then skip the28* flush entirely since it's not needed.29*/30void maybe_flush_or_die(FILE *f, const char *desc)31{32static int skip_stdout_flush = -1;33struct stat st;34char *cp;3536if (f == stdout) {37if (skip_stdout_flush < 0) {38cp = getenv("GIT_FLUSH");39if (cp)40skip_stdout_flush = (atoi(cp) == 0);41else if ((fstat(fileno(stdout), &st) == 0) &&42S_ISREG(st.st_mode))43skip_stdout_flush = 1;44else45skip_stdout_flush = 0;46}47if (skip_stdout_flush && !ferror(f))48return;49}50if (fflush(f)) {51check_pipe(errno);52die_errno("write failure on '%s'", desc);53}54}5556void fprintf_or_die(FILE *f, const char *fmt, ...)57{58va_list ap;59int ret;6061va_start(ap, fmt);62ret = vfprintf(f, fmt, ap);63va_end(ap);6465if (ret < 0) {66check_pipe(errno);67die_errno("write error");68}69}7071void fsync_or_die(int fd, const char *msg)72{73if (fsync(fd) < 0) {74die_errno("fsync error on '%s'", msg);75}76}7778void write_or_die(int fd, const void *buf, size_t count)79{80if (write_in_full(fd, buf, count) < 0) {81check_pipe(errno);82die_errno("write error");83}84}8586int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg)87{88if (write_in_full(fd, buf, count) < 0) {89check_pipe(errno);90fprintf(stderr, "%s: write error (%s)\n",91msg, strerror(errno));92return 0;93}9495return 1;96}