diff options
author | Junio C Hamano <gitster@pobox.com> | 2015-08-25 14:57:06 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2015-08-25 14:57:06 -0700 |
commit | 1302c9f514686e32065130ec9a80eb0db224e819 (patch) | |
tree | a9891d1a8906165ccabc6e005da5eb4fda1306d7 | |
parent | b590720f2cd3638930847f5abf646275caf8d334 (diff) | |
parent | f4c3edc0b156362a92bf9de4f0ec794e90a757fc (diff) | |
download | git-1302c9f514686e32065130ec9a80eb0db224e819.tar.gz |
Merge branch 'jk/long-error-messages'
The codepath to produce error messages had a hard-coded limit to
the size of the message, primarily to avoid memory allocation while
calling die().
* jk/long-error-messages:
vreportf: avoid intermediate buffer
vreportf: report to arbitrary filehandles
-rw-r--r-- | git-compat-util.h | 2 | ||||
-rw-r--r-- | run-command.c | 17 | ||||
-rw-r--r-- | usage.c | 31 |
3 files changed, 21 insertions, 29 deletions
diff --git a/git-compat-util.h b/git-compat-util.h index 392da79029..f649e81f11 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -389,7 +389,6 @@ struct strbuf; /* General helper functions */ extern void vreportf(const char *prefix, const char *err, va_list params); -extern void vwritef(int fd, const char *prefix, const char *err, va_list params); extern NORETURN void usage(const char *err); extern NORETURN void usagef(const char *err, ...) __attribute__((format (printf, 1, 2))); extern NORETURN void die(const char *err, ...) __attribute__((format (printf, 1, 2))); @@ -425,6 +424,7 @@ static inline int const_error(void) extern void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params)); extern void set_error_routine(void (*routine)(const char *err, va_list params)); extern void set_die_is_recursing_routine(int (*routine)(void)); +extern void set_error_handle(FILE *); extern int starts_with(const char *str, const char *prefix); diff --git a/run-command.c b/run-command.c index 28e1d55cb9..3277cf797e 100644 --- a/run-command.c +++ b/run-command.c @@ -200,7 +200,6 @@ static int execv_shell_cmd(const char **argv) #endif #ifndef GIT_WINDOWS_NATIVE -static int child_err = 2; static int child_notifier = -1; static void notify_parent(void) @@ -212,17 +211,6 @@ static void notify_parent(void) */ xwrite(child_notifier, "", 1); } - -static NORETURN void die_child(const char *err, va_list params) -{ - vwritef(child_err, "fatal: ", err, params); - exit(128); -} - -static void error_child(const char *err, va_list params) -{ - vwritef(child_err, "error: ", err, params); -} #endif static inline void set_cloexec(int fd) @@ -362,11 +350,10 @@ fail_pipe: * in subsequent call paths use the parent's stderr. */ if (cmd->no_stderr || need_err) { - child_err = dup(2); + int child_err = dup(2); set_cloexec(child_err); + set_error_handle(fdopen(child_err, "w")); } - set_die_routine(die_child); - set_error_routine(error_child); close(notify_pipe[0]); set_cloexec(notify_pipe[1]); @@ -6,23 +6,22 @@ #include "git-compat-util.h" #include "cache.h" +static FILE *error_handle; +static int tweaked_error_buffering; + void vreportf(const char *prefix, const char *err, va_list params) { - char msg[4096]; - vsnprintf(msg, sizeof(msg), err, params); - fprintf(stderr, "%s%s\n", prefix, msg); -} + FILE *fh = error_handle ? error_handle : stderr; -void vwritef(int fd, const char *prefix, const char *err, va_list params) -{ - char msg[4096]; - int len = vsnprintf(msg, sizeof(msg), err, params); - if (len > sizeof(msg)) - len = sizeof(msg); + fflush(fh); + if (!tweaked_error_buffering) { + setvbuf(fh, NULL, _IOLBF, 0); + tweaked_error_buffering = 1; + } - write_in_full(fd, prefix, strlen(prefix)); - write_in_full(fd, msg, len); - write_in_full(fd, "\n", 1); + fputs(prefix, fh); + vfprintf(fh, err, params); + fputc('\n', fh); } static NORETURN void usage_builtin(const char *err, va_list params) @@ -76,6 +75,12 @@ void set_die_is_recursing_routine(int (*routine)(void)) die_is_recursing = routine; } +void set_error_handle(FILE *fh) +{ + error_handle = fh; + tweaked_error_buffering = 0; +} + void NORETURN usagef(const char *err, ...) { va_list params; |