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:
parent
7504fc886e
commit
4bab85fdc2
1 changed files with 11 additions and 3 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue