I'm introducing a 3rd party protocol stack to on an old embeded platform where all va_* stuff are implemented except va_copy. The problem I face is, in the 3rd party stack, vsnprintf() is used:
int fun(char **buf, size_t buf_size, const char *fmt, va_list ap) {
va_list ap_copy;
int len;
/* first call*/
va_copy(ap_copy, ap);
len = vsnprintf(*buf, buf_size, fmt, ap_copy);
va_end(ap_copy);
if(len >= buf_size)
{
/* 2nd call*/
va_copy(ap_copy, ap);
len = vsnprintf(*buf, len + 1, fmt, ap_copy);
va_end(ap_copy);
}
}
Luckily the 3rd party stack provedes its own vsnprintf function(call it new_vsnprintf), but without va_copy, only the first call works, i.e, when the len is small than buf_size. Below is the way I call it:
#define vsnprintf new_vsnprintf
int fun(char **buf, size_t buf_size, const char *fmt, va_list ap) {
//va_list ap_copy;
int len;
/* first call*/
va_start(ap, fmt);
len = vsnprintf(*buf, buf_size, fmt, ap);
va_end(ap);
if(len >= buf_size)
{
/* 2nd call*/
va_start(ap, fmt);
len = vsnprintf(*buf, len + 1, fmt, ap); //new_vsnprintf()
va_end(ap);
}
}
Problem occurs in the 2nd call of new_vsnprintf(), when trying to get the actual value of placeholders by va_arg(). I assume the inner pointer of (va_list) ap points to wrong memory address.
Then how to correct it?