{"thread":{"id":"10842","subject":"[PATCH] Handle broken vsnprintf implementations in strbuf","startedAt":"2007-11-13T08:22:44Z","lastAt":"2007-11-13T08:22:44Z","messageCount":1,"participants":["Shawn O. Pearce"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"59630","messageId":"20071113082244.GA12565@spearce.org","threadId":"10842","inReplyTo":null,"subject":"[PATCH] Handle broken vsnprintf implementations in strbuf","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-11-13T08:22:44Z","receivedAt":"2007-11-13T08:22:44Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Solaris 9's vsnprintf implementation returns -1 if we pass it a\nbuffer of length 0.  The only way to get it to give us the actual\nlength necessary for the formatted string is to grow the buffer\nout to have at least 1 byte available in the strbuf and then ask\nit to compute the length.\n\nIf the available space is 0 I'm growing it out by 64 to ensure\nwe will get an accurate length estimate from all implementations.\nSome callers may need to grow the strbuf again but 64 should be a\nreasonable enough initial growth.\n\nWe also no longer silently fail to append to the string when we are\nfaced with a broken vsnprintf implementation.  On Solaris 9 this\nsilent failure caused me to no longer be able to execute \"git clone\"\nas we tried to exec the empty string rather than \"git-clone\".\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n strbuf.c |    7 ++++---\n trace.c  |    4 ++--\n 2 files changed, 6 insertions(+), 5 deletions(-)\n\ndiff --git a/strbuf.c b/strbuf.c\nindex dbd8c4b..b9b194b 100644\n--- a/strbuf.c\n+++ b/strbuf.c\n@@ -118,12 +118,13 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...)\n \tint len;\n \tva_list ap;\n \n+\tif (!strbuf_avail(sb))\n+\t\tstrbuf_grow(sb, 64);\n \tva_start(ap, fmt);\n \tlen = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);\n \tva_end(ap);\n-\tif (len < 0) {\n-\t\tlen = 0;\n-\t}\n+\tif (len < 0)\n+\t\tdie(\"your vsnprintf is broken\");\n \tif (len > strbuf_avail(sb)) {\n \t\tstrbuf_grow(sb, len);\n \t\tva_start(ap, fmt);\ndiff --git a/trace.c b/trace.c\nindex 69fa05e..0d89dbe 100644\n--- a/trace.c\n+++ b/trace.c\n@@ -72,7 +72,7 @@ void trace_printf(const char *fmt, ...)\n \tif (!fd)\n \t\treturn;\n \n-\tstrbuf_init(&buf, 0);\n+\tstrbuf_init(&buf, 64);\n \tva_start(ap, fmt);\n \tlen = vsnprintf(buf.buf, strbuf_avail(&buf), fmt, ap);\n \tva_end(ap);\n@@ -103,7 +103,7 @@ void trace_argv_printf(const char **argv, int count, const char *fmt, ...)\n \tif (!fd)\n \t\treturn;\n \n-\tstrbuf_init(&buf, 0);\n+\tstrbuf_init(&buf, 64);\n \tva_start(ap, fmt);\n \tlen = vsnprintf(buf.buf, strbuf_avail(&buf), fmt, ap);\n \tva_end(ap);\n-- \n1.5.3.5.1661.gcbf0\n"}]}