On x86_64, accessing varargs is destructive. For repeated calls to vsnprintf()

we have to create a copy with va_copy().


git-svn-id: https://shellinabox.googlecode.com/svn/trunk@34 0da03de8-d603-11dd-86c2-0f8696b7b6f9
This commit is contained in:
zodiac 2009-01-08 01:29:20 +00:00
parent 7504fc886e
commit 4bab85fdc2

View file

@ -143,10 +143,15 @@ char *vStringPrintf(char *buf, const char *fmt, va_list ap) {
int offset = buf ? strlen(buf) : 0; int offset = buf ? strlen(buf) : 0;
int len = 80; int len = 80;
check(buf = realloc(buf, offset + len)); check(buf = realloc(buf, offset + len));
int p = vsnprintf(buf + offset, len, fmt, ap); va_list aq;
va_copy(aq, ap);
int p = vsnprintf(buf + offset, len, fmt, aq);
va_end(aq);
if (p >= len) { if (p >= len) {
check(buf = realloc(buf, offset + p + 1)); check(buf = realloc(buf, offset + p + 1));
check(vsnprintf(buf + offset, p + 1, fmt, ap) == p); va_copy(aq, ap);
check(vsnprintf(buf + offset, p + 1, fmt, aq) == p);
va_end(aq);
} else if (p < 0) { } else if (p < 0) {
int inc = 256; int inc = 256;
do { do {
@ -156,7 +161,10 @@ char *vStringPrintf(char *buf, const char *fmt, va_list ap) {
inc <<= 1; inc <<= 1;
} }
check(buf = realloc(buf, offset + len)); check(buf = realloc(buf, offset + len));
} while (vsnprintf(buf + offset, len, fmt, ap) < 0); va_copy(aq, ap);
p = vsnprintf(buf + offset, len, fmt, ap);
va_end(aq);
} while (p < 0 || p >= len);
} }
return buf; return buf;
} }