summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <gitster@pobox.com>2019-12-01 09:04:31 -0800
committerLibravatar Junio C Hamano <gitster@pobox.com>2019-12-01 09:04:31 -0800
commit5444d528662d7a64ec34486e63ffafced9005937 (patch)
treeaebdcc0b5f52023e7f198c52f062bb7d7c622071
parentMerge branch 'pb/no-recursive-reset-hard-in-worktree-add' (diff)
parentvreportf(): avoid relying on stdio buffering (diff)
downloadtgif-5444d528662d7a64ec34486e63ffafced9005937.tar.xz
Merge branch 'js/vreportf-wo-buffering'
Messages from die() etc. can be mixed up from multiple processes without even line buffering on Windows, which has been worked around. * js/vreportf-wo-buffering: vreportf(): avoid relying on stdio buffering
-rw-r--r--usage.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/usage.c b/usage.c
index 2fdb20086b..58fb5fff5f 100644
--- a/usage.c
+++ b/usage.c
@@ -9,14 +9,26 @@
void vreportf(const char *prefix, const char *err, va_list params)
{
char msg[4096];
- char *p;
+ char *p, *pend = msg + sizeof(msg);
+ size_t prefix_len = strlen(prefix);
- vsnprintf(msg, sizeof(msg), err, params);
- for (p = msg; *p; p++) {
+ if (sizeof(msg) <= prefix_len) {
+ fprintf(stderr, "BUG!!! too long a prefix '%s'\n", prefix);
+ abort();
+ }
+ memcpy(msg, prefix, prefix_len);
+ p = msg + prefix_len;
+ if (vsnprintf(p, pend - p, err, params) < 0)
+ *p = '\0'; /* vsnprintf() failed, clip at prefix */
+
+ for (; p != pend - 1 && *p; p++) {
if (iscntrl(*p) && *p != '\t' && *p != '\n')
*p = '?';
}
- fprintf(stderr, "%s%s\n", prefix, msg);
+
+ *(p++) = '\n'; /* we no longer need a NUL */
+ fflush(stderr);
+ write_in_full(2, msg, p - msg);
}
static NORETURN void usage_builtin(const char *err, va_list params)