On Wed, Oct 24, 2007 at 04:59:48PM -0400, Kyle Moffett wrote:This seems unlikely to work reliably as the various "v*printf" functions modify the va_list argument they are passed. It may happen to work on your particular architecture depending on how that argument data is passed and stored, but you probably actually want to make a copy of the varargs list for the first vsnprintf call.
I based what I did on how printk works:
va_start(args, fmt);
r = vprintk(fmt, args);
va_end(args);
It doesn't call va_* anywhere else. I don't claim to be a varargs expert, but if I'm wrong, I'm at least wrong the same way that printk is, so not in any way that's significant for any other architecture Linux runs on.
va_list args;
va_start(args, fmt);
r1 = vprintk(fmt, args);
r2 = vprintk(fmt, args);
va_end(args);
va_list args;
va_start(args, fmt);
r1 = vprintk(fmt, args);
va_end(args);
va_start(args, fmt);
r2 = vprintk(fmt, args);
va_end(args);
va_list args, argscopy;
va_start(args, fmt);
va_copy(argscopy, args);
r1 = vprintk(fmt, argscopy);
va_end(argscopy);
r2 = vprintk(fmt, args);
va_end(args);
void func1(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
func2(fmt, ap);
va_end(ap);
}
void func2(const char *fmt, va_list ap)
{
va_list ap2;
va_copy(ap2, ap);
vprintk(fmt, ap2);
va_end(ap2);
vprintk(fmt, ap);
}