On Wed, Nov 11, 2009 at 09:41:29PM -0500, Chet Ramey wrote: > If your version of vsnprintf doesn't behave like that, I claim it's a > bug. The Posix and C standards explicitly allow the buffer to be NULL > if the size argument is 0, and guarantee that no data will be written > in this case.
Thanks for the explanation. HP-UX 10.20 has no manual page for vsnprintf (or for snprintf), and vsnprintf does not appear in any header file in /usr/include, at all. But vsnprintf _is_ defined in libc: imadev:~$ nm /usr/lib/libc.a | grep vsnprintf U _vsnprintf vsnprintf.o: 00000000 W vsnprintf 00000000 T _vsnprintf imadev:~$ nm /usr/lib/libc.sl | grep vsnprintf 00121db8 T vsnprintf 00121dd0 T vsnprintf 00121dd0 T _vsnprintf U _vsnprintf 00121da0 T _vsnprintf I wrote this test program: #include <stdio.h> #include <stdarg.h> void foo(const char *fmt, ...) { va_list args; va_start(args, fmt); vsnprintf(NULL, 0, fmt, args); va_end(args); } main() { foo("%s", ""); return 0; } HP-UX 10.20 dumps core: imadev:~$ uname -a HP-UX imadev B.10.20 A 9000/785 2008897791 two-user license imadev:~$ /net/appl/gcc-3.3/bin/gcc -o foo foo.c imadev:~$ ./foo Segmentation fault (core dumped) HP-UX 11.11 dumps core: bash-3.2# uname -a HP-UX dev3 B.11.11 U 9000/778 2005106987 unlimited-user license bash-3.2# gcc -o foo foo.c bash-3.2# ./foo Segmentation fault (core dumped) OpenBSD 4.6 and Debian GNU/Linux 3.1 (and unstable) seem to like it, though. At least they didn't dump core. HP-UX 11.11 has a man page for vsnprintf (same page as vsprintf), but all it says is: vprintf(), vfprintf(), vsprintf(), and vsnprintf() are the same as printf(), fprintf(), sprintf(), and snprintf() respectively, except that instead of being called with a variable number of arguments, they are called with an argument list as defined by <stdarg.h>. It doesn't mention a null pointer. The OpenBSD man page does explicitly say the null pointer is allowed if size is zero. The GNU/Linux man page says that SUSv2 and C99 disagree, but that the implementation follows C99 (allowing the null pointer when size is 0). Fun stuff. Maybe it needs an autoconf test for broken (or pre-C99) vsnprintf, with a wrapper function to test for size==0 and just return 0, to be used when autoconf detects the broken vsnprintf. You may use my test program (above) if you like, though I'm not an autoconf guru, so maybe a really-portable test program would need something more (like a setrlimit(RLIMIT_CORE, ...) call to stop actual core dumps?).