summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <gitster@pobox.com>2015-09-03 19:17:49 -0700
committerLibravatar Junio C Hamano <gitster@pobox.com>2015-09-03 19:17:49 -0700
commit6c0850f2dd994baaf64ef580e466706ce17a860f (patch)
tree4f4e8bc5af81c97e5aa9769c1e9975e59bb1340a
parentMerge branch 'cb/open-noatime-clear-errno' into maint (diff)
parentvreportf: avoid intermediate buffer (diff)
downloadtgif-6c0850f2dd994baaf64ef580e466706ce17a860f.tar.xz
Merge branch 'jk/long-error-messages' into maint
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.h2
-rw-r--r--run-command.c17
-rw-r--r--usage.c31
3 files changed, 21 insertions, 29 deletions
diff --git a/git-compat-util.h b/git-compat-util.h
index c6d391f864..076461e8c8 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 4d73e90fad..0d01671c1f 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]);
diff --git a/usage.c b/usage.c
index ed146453ca..82ff13163b 100644
--- a/usage.c
+++ b/usage.c
@@ -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;