This patch detects the broken (v)snprintf functions on HP-UX and uses the replacement function provided in the bash source. Normally this function is only used if no (v)snprintf is discovered at all. To use: .../bash-4.0$ patch -p1 < ../bash-4.0-snprintf.diff .../bash-4.0$ autoconf .../bash-4.0$ ./configure [options] .../bash-4.0$ make --- bash-4.0/configure.in Fri Feb 6 12:03:44 2009 +++ bash-4.0-gw/configure.in Thu Nov 12 16:38:31 2009 @@ -725,7 +725,64 @@ setenv setlinebuf setlocale setvbuf siginterrupt strchr \ sysconf tcgetattr times ttyname tzset unsetenv) -AC_CHECK_FUNCS(vsnprintf snprintf vasprintf asprintf) +AC_CHECK_FUNCS(snprintf vsnprintf) +dnl HP-UX 10.20 and 11.11 (at least) have present-but-broken (v)snprintf. +dnl Among other undesirable behavior, it segfaults when the first argument +dnl is null and the second is 0. C99 says this is allowed. This test is +dnl not sufficient to find ALL the broken behaviors; just the segfault. +if test "x$ac_cv_func_snprintf" = "xyes"; then + AC_MSG_CHECKING([for working snprintf]) + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +main() { + struct rlimit r; + r.rlim_cur = r.rlim_max = 0; + setrlimit(RLIMIT_CORE, &r); + snprintf(NULL, 0, "%s", ""); + return 0; +} + ]])], + [AC_MSG_RESULT(yes)], + [ + AC_MSG_RESULT(no) + AC_DEFINE(SNPRINTF_BROKEN, 1, [Define if snprintf is broken]) + ], + [ AC_MSG_WARN([cross compiling: Assuming working snprintf]) ] + ) +fi +if test "x$ac_cv_func_vsnprintf" = "xyes"; then + AC_MSG_CHECKING([for working vsnprintf]) + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +void foo(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + vsnprintf(NULL, 0, fmt, args); + va_end(args); +} +main() { + struct rlimit r; + r.rlim_cur = r.rlim_max = 0; + setrlimit(RLIMIT_CORE, &r); + foo("%s", ""); + return 0; +} + ]])], + [AC_MSG_RESULT(yes)], + [ + AC_MSG_RESULT(no) + AC_DEFINE(VSNPRINTF_BROKEN, 1, [Define if vsnprintf is broken]) + ], + [ AC_MSG_WARN([cross compiling: Assuming working vsnprintf]) ] + ) +fi + +AC_CHECK_FUNCS(vasprintf asprintf) AC_CHECK_FUNCS(isascii isblank isgraph isprint isspace isxdigit) AC_CHECK_FUNCS(getpwent getpwnam getpwuid) AC_REPLACE_FUNCS(getcwd memset strcasecmp strerror strftime strnlen strpbrk strstr) --- bash-4.0/config.h.in Sun Feb 1 17:07:23 2009 +++ bash-4.0-gw/config.h.in Thu Nov 12 16:19:40 2009 @@ -1019,6 +1031,10 @@ #undef DUP2_BROKEN #undef GETCWD_BROKEN + +#undef SNPRINTF_BROKEN + +#undef VSNPRINTF_BROKEN /* Additional defines for configuring lib/intl, maintained by autoscan/autoheader */ --- bash-4.0/builtins/printf.def Sun Jan 18 18:37:07 2009 +++ bash-4.0-gw/builtins/printf.def Thu Nov 12 16:27:36 2009 @@ -170,7 +170,7 @@ extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3))); #endif -#ifndef HAVE_VSNPRINTF +#if !defined (HAVE_VSNPRINTF) || defined (VSNPRINTF_BROKEN) extern int vsnprintf __P((char *, size_t, const char *, ...)) __attribute__((__format__ (printf, 3, 4))); #endif --- bash-4.0/lib/sh/snprintf.c Tue Aug 12 12:02:14 2008 +++ bash-4.0-gw/lib/sh/snprintf.c Thu Nov 12 16:34:50 2009 @@ -82,7 +82,7 @@ #define intmax_t long #endif -#if !defined (HAVE_SNPRINTF) || !defined (HAVE_ASPRINTF) +#if !defined (HAVE_SNPRINTF) || !defined (HAVE_ASPRINTF) || defined (SNPRINTF_BROKEN) #include @@ -1640,7 +1640,7 @@ } #endif /* FLOATING_POINT */ -#ifndef HAVE_SNPRINTF +#if !defined (HAVE_SNPRINTF) || defined (SNPRINTF_BROKEN) int #if defined (__STDC__)