]> eyrie.org Git - kerberos/krb5-strength.git/commitdiff
Update to rra-c-util 4.12 and C TAP Harness 2.3
authorRuss Allbery <eagle@eyrie.org>
Mon, 16 Dec 2013 21:35:00 +0000 (13:35 -0800)
committerRuss Allbery <eagle@eyrie.org>
Mon, 16 Dec 2013 21:35:00 +0000 (13:35 -0800)
Update to rra-c-util 4.12:

* Properly check the return status of snprintf and friends.

Update to C TAP Harness 2.3:

* Suppress lazy plans and test summaries if the test failed with bail.
* Add warn_unused_result gcc attributes to relevant functions.

27 files changed:
.gitignore
Makefile.am
NEWS
configure.ac
m4/krb5.m4
m4/lib-helper.m4
m4/tinycdb.m4
portable/asprintf.c
portable/snprintf.c
portable/strndup.c [new file with mode: 0644]
portable/system.h
tests/TESTS
tests/portable/strndup-t.c [new file with mode: 0644]
tests/portable/strndup.c [new file with mode: 0644]
tests/runtests.c
tests/tap/basic.c
tests/tap/basic.h
tests/tap/kerberos.c
tests/tap/kerberos.h
tests/tap/macros.h
tests/tap/perl/Test/RRA.pm
tests/tap/perl/Test/RRA/Automake.pm
tests/tap/perl/Test/RRA/Config.pm
tests/tap/process.c
util/messages.c
util/xmalloc.c
util/xmalloc.h

index 02ec31664edcbcd7104987c6b2f462088e070853..9d75f42ea1cc9e0f81adc522aed5d879c91f52ee 100644 (file)
@@ -25,6 +25,7 @@
 /tests/plugin/mit-t
 /tests/portable/asprintf-t
 /tests/portable/snprintf-t
+/tests/portable/strndup-t
 /tests/runtests
 /tests/tap/libtap.a
 /tests/util/messages-krb5-t
index 22f2107ec09e6842b52cc9a3ca3c800524add855..341634a1583cc3eab7f482f7a0a84bcb824f01db 100644 (file)
@@ -121,9 +121,10 @@ warnings:
        $(MAKE) V=0 CFLAGS='$(WARNINGS)' $(check_PROGRAMS)
 
 # The bits below are for the test suite, not for the main package.
-check_PROGRAMS = tests/runtests tests/plugin/heimdal-t tests/plugin/mit-t   \
-       tests/portable/asprintf-t tests/portable/snprintf-t                 \
-       tests/util/messages-krb5-t tests/util/messages-t tests/util/xmalloc
+check_PROGRAMS = tests/runtests tests/plugin/heimdal-t tests/plugin/mit-t \
+       tests/portable/asprintf-t tests/portable/snprintf-t               \
+       tests/portable/strndup-t tests/util/messages-krb5-t               \
+       tests/util/messages-t tests/util/xmalloc
 if EMBEDDED_CRACKLIB
     check_PROGRAMS += cracklib/packer
 endif
@@ -149,6 +150,9 @@ tests_portable_asprintf_t_LDADD = tests/tap/libtap.a portable/libportable.la
 tests_portable_snprintf_t_SOURCES = tests/portable/snprintf-t.c \
        tests/portable/snprintf.c
 tests_portable_snprintf_t_LDADD = tests/tap/libtap.a portable/libportable.la
+tests_portable_strndup_t_SOURCES = tests/portable/strndup-t.c \
+       tests/portable/strndup.c
+tests_portable_strndup_t_LDADD = tests/tap/libtap.a portable/libportable.la
 tests_util_messages_t_LDADD = tests/tap/libtap.a util/libutil.a \
        portable/libportable.la
 tests_util_messages_krb5_t_LDADD = tests/tap/libtap.a util/libutil.a \
diff --git a/NEWS b/NEWS
index d8bdeb64b063f05dc71c2aaf7e1af7f5e7711c0a..8735effb841548ae3c3d429da9cb7c8f914a7a71 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,15 @@ krb5-strength 2.2 (unreleased)
     Close a file descriptor and memory leak in the included version of
     CrackLib.  This problem was already fixed in CrackLib 2.9.0.
 
+    Update to rra-c-util 4.12:
+
+    * Properly check the return status of snprintf and friends.
+
+    Update to C TAP Harness 2.3:
+
+    * Suppress lazy plans and test summaries if the test failed with bail.
+    * Add warn_unused_result gcc attributes to relevant functions.
+
 krb5-strength 2.1 (2013-10-10)
 
     Fix the package build when CDB support is disabled or TinyCDB was not
index aa8bb9a3eaca6a5111d2fc4135bcf0c22c708dfc..5d11d4d437ab2a44c13920281f22e18731a2a289 100644 (file)
@@ -71,7 +71,7 @@ AC_CHECK_TYPES([ssize_t], [], [],
     [#include <sys/types.h>])
 RRA_FUNC_SNPRINTF
 AC_CHECK_FUNCS([setrlimit])
-AC_REPLACE_FUNCS([asprintf])
+AC_REPLACE_FUNCS([asprintf strndup])
 
 dnl Write out the results.
 AC_CONFIG_FILES([Makefile])
index 2556425ec91060678875b914e109b56b5908feb7..950524f4069f28c62c51ecaaae8e68966f93a7bb 100644 (file)
@@ -11,23 +11,27 @@ dnl KRB5_CPPFLAGS, KRB5_LDFLAGS, and KRB5_LIBS.  Also provides
 dnl RRA_LIB_KRB5_SWITCH to set CPPFLAGS, LDFLAGS, and LIBS to include the
 dnl Kerberos libraries, saving the current values first, and
 dnl RRA_LIB_KRB5_RESTORE to restore those settings to before the last
-dnl RRA_LIB_KRB5_SWITCH.  HAVE_KERBEROS will always be defined if RRA_LIB_KRB5
-dnl is used.
+dnl RRA_LIB_KRB5_SWITCH.  HAVE_KRB5 will always be defined if RRA_LIB_KRB5 is
+dnl used.
 dnl
 dnl If KRB5_CPPFLAGS, KRB5_LDFLAGS, or KRB5_LIBS are set before calling these
 dnl macros, their values will be added to whatever the macros discover.
 dnl
 dnl Provides the RRA_LIB_KRB5_OPTIONAL macro, which should be used if Kerberos
-dnl support is optional.  This macro will still always set the substitution
-dnl variables, but they'll be empty unless --with-krb5 is given.  Also,
-dnl HAVE_KERBEROS will be defined if --with-krb5 is given and
-dnl $rra_use_kerberos will be set to "true".
+dnl support is optional.  In this case, Kerberos libraries are mandatory if
+dnl --with-krb5 is given, and will not be probed for if --without-krb5 is
+dnl given.  Otherwise, they'll be probed for but will not be required.
+dnl Defines HAVE_KRB5 and sets rra_use_KRB5 to true if the libraries are
+dnl found.  The substitution variables will always be set, but they will be
+dnl empty unless Kerberos libraries are found and the user did not disable
+dnl Kerberos support.
 dnl
 dnl Sets the Automake conditional KRB5_USES_COM_ERR saying whether we use
 dnl com_err, since if we're also linking with AFS libraries, we may have to
 dnl change library ordering in that case.
 dnl
-dnl Depends on RRA_ENABLE_REDUCED_DEPENDS and RRA_SET_LDFLAGS.
+dnl Depends on RRA_KRB5_CONFIG, RRA_ENABLE_REDUCED_DEPENDS, and
+dnl RRA_SET_LDFLAGS.
 dnl
 dnl Also provides RRA_FUNC_KRB5_GET_INIT_CREDS_OPT_FREE_ARGS, which checks
 dnl whether krb5_get_init_creds_opt_free takes one argument or two.  Defines
@@ -40,13 +44,16 @@ dnl The canonical version of this file is maintained in the rra-c-util
 dnl package, available at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
 dnl
 dnl Written by Russ Allbery <eagle@eyrie.org>
-dnl Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011
+dnl Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013
 dnl     The Board of Trustees of the Leland Stanford Junior University
 dnl
 dnl This file is free software; the authors give unlimited permission to copy
 dnl and/or distribute it, with or without modifications, as long as this
 dnl notice is preserved.
 
+dnl Ignore Automake conditionals if not using Automake.
+m4_define_default([AM_CONDITIONAL], [:])
+
 dnl Headers to include when probing for Kerberos library properties.
 AC_DEFUN([RRA_INCLUDES_KRB5], [[
 #if HAVE_KRB5_H
@@ -124,7 +131,9 @@ AC_DEFUN([_RRA_LIB_KRB5_REDUCED],
                      [RRA_INCLUDES_KRB5])],
                  [AC_CHECK_LIB([com_err], [com_err],
                      [KRB5_LIBS="$KRB5_LIBS -lcom_err"],
-                     [AC_MSG_ERROR([cannot find usable com_err library])])
+                     [AS_IF([test x"$1" = xtrue],
+                         [AC_MSG_ERROR([cannot find usable com_err library])],
+                         [KRB5_LIBS=""])])
                   AC_CHECK_HEADERS([et/com_err.h])])])])])
  RRA_LIB_KRB5_RESTORE])
 
@@ -242,15 +251,16 @@ AC_DEFUN([_RRA_LIB_KRB5_INTERNAL],
         [_RRA_LIB_KRB5_PATHS
          _RRA_LIB_KRB5_MANUAL([$1])])])
  rra_krb5_uses_com_err=false
- AS_CASE([$LIBS], [*-lcom_err*], [rra_krb5_uses_com_err=true])
- AM_CONDITIONAL([KRB5_USES_COM_ERR], [test x"$rra_krb5_uses_com_err" = xtrue])])
+ AS_CASE([$KRB5_LIBS], [*-lcom_err*], [rra_krb5_uses_com_err=true])
+ AM_CONDITIONAL([KRB5_USES_COM_ERR],
+    [test x"$rra_krb5_uses_com_err" = xtrue])])
 
 dnl The main macro for packages with mandatory Kerberos support.
 AC_DEFUN([RRA_LIB_KRB5],
 [rra_krb5_root=
  rra_krb5_libdir=
  rra_krb5_includedir=
- rra_use_kerberos=true
+ rra_use_KRB5=true
  AC_SUBST([KRB5_CPPFLAGS])
  AC_SUBST([KRB5_LDFLAGS])
  AC_SUBST([KRB5_LIBS])
@@ -271,14 +281,14 @@ AC_DEFUN([RRA_LIB_KRB5],
     [AS_IF([test x"$withval" != xyes && test x"$withval" != xno],
         [rra_krb5_libdir="$withval"])])
  _RRA_LIB_KRB5_INTERNAL([true])
- AC_DEFINE([HAVE_KERBEROS], 1, [Define to enable Kerberos features.])])
+ AC_DEFINE([HAVE_KRB5], 1, [Define to enable Kerberos features.])])
 
 dnl The main macro for packages with optional Kerberos support.
 AC_DEFUN([RRA_LIB_KRB5_OPTIONAL],
 [rra_krb5_root=
  rra_krb5_libdir=
  rra_krb5_includedir=
- rra_use_kerberos=
+ rra_use_KRB5=
  AC_SUBST([KRB5_CPPFLAGS])
  AC_SUBST([KRB5_LDFLAGS])
  AC_SUBST([KRB5_LIBS])
@@ -287,9 +297,9 @@ AC_DEFUN([RRA_LIB_KRB5_OPTIONAL],
     [AS_HELP_STRING([--with-krb5@<:@=DIR@:>@],
         [Location of Kerberos headers and libraries])],
     [AS_IF([test x"$withval" = xno],
-        [rra_use_kerberos=false],
+        [rra_use_KRB5=false],
         [AS_IF([test x"$withval" != xyes], [rra_krb5_root="$withval"])
-         rra_use_kerberos=true])])
+         rra_use_KRB5=true])])
  AC_ARG_WITH([krb5-include],
     [AS_HELP_STRING([--with-krb5-include=DIR],
         [Location of Kerberos headers])],
@@ -301,13 +311,14 @@ AC_DEFUN([RRA_LIB_KRB5_OPTIONAL],
     [AS_IF([test x"$withval" != xyes && test x"$withval" != xno],
         [rra_krb5_libdir="$withval"])])
 
- AS_IF([test x"$rra_use_kerberos" != xfalse],
-     [AS_IF([test x"$rra_use_kerberos" = xtrue],
+ AS_IF([test x"$rra_use_KRB5" != xfalse],
+     [AS_IF([test x"$rra_use_KRB5" = xtrue],
          [_RRA_LIB_KRB5_INTERNAL([true])],
          [_RRA_LIB_KRB5_INTERNAL([false])])],
      [AM_CONDITIONAL([KRB5_USES_COM_ERR], [false])])
  AS_IF([test x"$KRB5_LIBS" != x],
-    [AC_DEFINE([HAVE_KERBEROS], 1, [Define to enable Kerberos features.])])])
+    [rra_use_KRB5=true
+     AC_DEFINE([HAVE_KRB5], 1, [Define to enable Kerberos features.])])])
 
 dnl Source used by RRA_FUNC_KRB5_GET_INIT_CREDS_OPT_FREE_ARGS.
 AC_DEFUN([_RRA_FUNC_KRB5_OPT_FREE_ARGS_SOURCE], [RRA_INCLUDES_KRB5] [[
index c45a60ee91d7a572e9cccf8370368342288bf7ea..0b2e85ca99e650a27ba844563b751003e082566c 100644 (file)
@@ -6,7 +6,7 @@ dnl CPPFLAGS, LDFLAGS, and LIBS shell substitution variables.  Most of them
 dnl take as one of the arguments the prefix string to use for variables, which
 dnl is usually something like "KRB5" or "GSSAPI".
 dnl
-dnl Depends on RRA_ENABLE_REDUCED_DEPENDS and RRA_SET_LDFLAGS.
+dnl Depends on RRA_SET_LDFLAGS.
 dnl
 dnl The canonical version of this file is maintained in the rra-c-util
 dnl package, available at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
index 75a629da62a892bf98345d728a5a15fd71d4b840..d7fd22f4143a86db5b5cebc1cc90569bc76f391f 100644 (file)
@@ -7,15 +7,17 @@ dnl
 dnl Provides the macros RRA_LIB_CDB and RRA_LIB_CDB_OPTIONAL and sets the
 dnl substitution variables CDB_CPPFLAGS, CDB_LDFLAGS, and CDB_LIBS.  Also
 dnl provides RRA_LIB_CDB_SWITCH to set CPPFLAGS, LDFLAGS, and LIBS to include
-dnl the kadmin client libraries, saving the ecurrent values, and
-dnl RRA_LIB_CDB_RESTORE to restore those settings to before the last
-dnl RRA_LIB_CDB_SWITCH.  Defines HAVE_CDB and sets rra_use_CDB to true if the
-dnl library is found.
+dnl the TinyCDB libraries, saving the current values, and RRA_LIB_CDB_RESTORE
+dnl to restore those settings to before the last RRA_LIB_CDB_SWITCH.  Defines
+dnl HAVE_CDB and sets rra_use_CDB to true if the library is found.
 dnl
-dnl Depends on the lib-helper.m4 infrastructure.
+dnl Depends on the lib-helper.m4 framework.
+dnl
+dnl The canonical version of this file is maintained in the rra-c-util
+dnl package, available at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
 dnl
 dnl Written by Russ Allbery <eagle@eyrie.org>
-dnl Copyright 2010, 2013
+dnl Copyright 2013
 dnl     The Board of Trustees of the Leland Stanford Junior University
 dnl
 dnl This file is free software; the authors give unlimited permission to copy
@@ -36,26 +38,28 @@ dnl says to fail if the libcdb library could not be found.
 AC_DEFUN([_RRA_LIB_CDB_INTERNAL],
 [RRA_LIB_HELPER_PATHS([CDB])
  RRA_LIB_CDB_SWITCH
- AC_CHECK_LIB([cdb], [cdb_init],
-    [CDB_LIBS=-lcdb
-     AC_DEFINE([HAVE_CDB], 1, [Define if libcdb is available.])
-     rra_use_CDB=true],
+ AC_CHECK_LIB([cdb], [cdb_init], [CDB_LIBS=-lcdb],
     [AS_IF([test x"$1" = xtrue],
         [AC_MSG_ERROR([cannot find usable TinyCDB library])])])
  AC_CHECK_HEADERS([cdb.h])
  RRA_LIB_CDB_RESTORE])
 
-dnl The main macro for packages with mandatory kadmin client support.
+dnl The main macro for packages with mandatory TinyCDB support.
 AC_DEFUN([RRA_LIB_CDB],
 [RRA_LIB_HELPER_VAR_INIT([CDB])
  RRA_LIB_HELPER_WITH([tinycdb], [TinyCDB], [CDB])
- _RRA_LIB_CDB_INTERNAL([true])])
+ _RRA_LIB_CDB_INTERNAL([true])
+ rra_use_CDB=true
+ AC_DEFINE([HAVE_CDB], 1, [Define if libcdb is available.])])
 
-dnl The main macro for packages with optional kadmin client support.
+dnl The main macro for packages with optional TinyCDB support.
 AC_DEFUN([RRA_LIB_CDB_OPTIONAL],
 [RRA_LIB_HELPER_VAR_INIT([CDB])
  RRA_LIB_HELPER_WITH_OPTIONAL([tinycdb], [TinyCDB], [CDB])
  AS_IF([test x"$rra_use_CDB" != xfalse],
     [AS_IF([test x"$rra_use_CDB" = xtrue],
         [_RRA_LIB_CDB_INTERNAL([true])],
-        [_RRA_LIB_CDB_INTERNAL([false])])])])
+        [_RRA_LIB_CDB_INTERNAL([false])])])
+ AS_IF([test x"$CDB_LIBS" != x],
+    [rra_use_CDB=true
+     AC_DEFINE([HAVE_CDB], 1, [Define if libcdb is available.])])])
index 7bdfd0d547c25b0b405779e5f3285d7a22a8dc0f..eb2b713e55b3fd5f023f07c870aed588e813288f 100644 (file)
@@ -21,6 +21,8 @@
 #include <config.h>
 #include <portable/system.h>
 
+#include <errno.h>
+
 /*
  * If we're running the test suite, rename the functions to avoid conflicts
  * with the system versions.
@@ -33,6 +35,7 @@ int test_asprintf(char **, const char *, ...)
 int test_vasprintf(char **, const char *, va_list);
 #endif
 
+
 int
 asprintf(char **strp, const char *fmt, ...)
 {
@@ -45,11 +48,12 @@ asprintf(char **strp, const char *fmt, ...)
     return status;
 }
 
+
 int
 vasprintf(char **strp, const char *fmt, va_list args)
 {
     va_list args_copy;
-    int status, needed;
+    int status, needed, oerrno;
 
     va_copy(args_copy, args);
     needed = vsnprintf(NULL, 0, fmt, args_copy);
@@ -65,8 +69,10 @@ vasprintf(char **strp, const char *fmt, va_list args)
     if (status >= 0)
         return status;
     else {
+        oerrno = errno;
         free(*strp);
         *strp = NULL;
+        errno = oerrno;
         return status;
     }
 }
index e3754a36a4b54301a932b1c668ad20d4740c1fad..c35ad807671286144845be9cb9c4570bdbe86801 100644 (file)
@@ -2,8 +2,9 @@
  * Replacement for a missing snprintf or vsnprintf.
  *
  * The following implementation of snprintf was taken mostly verbatim from
- * <http://www.fiction.net/~blong/programs/>; it is the version of snprintf
- * used in Mutt.
+ * <http://www.fiction.net/blong/programs/>; it is the version of snprintf
+ * used in Mutt.  A possibly newer version is used in wget, found at
+ * <https://github.com/wertarbyte/wget/blob/master/src/snprintf.c>.
  *
  * Please do not reformat or otherwise change this file more than necessary so
  * that later merges with the original source are easy.  Bug fixes and
diff --git a/portable/strndup.c b/portable/strndup.c
new file mode 100644 (file)
index 0000000..e94d944
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Replacement for a missing strndup.
+ *
+ * The canonical version of this file is maintained in the rra-c-util package,
+ * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+ *
+ * Written by Russ Allbery <eagle@eyrie.org>
+ *
+ * The authors hereby relinquish any claim to any copyright that they may have
+ * in this work, whether granted under contract or by operation of law or
+ * international treaty, and hereby commit to the public, at large, that they
+ * shall not, at any time in the future, seek to enforce any copyright in this
+ * work against any person or entity, or prevent any person or entity from
+ * copying, publishing, distributing or creating derivative works of this
+ * work.
+ */
+
+#include <config.h>
+#include <portable/system.h>
+
+#include <errno.h>
+
+/*
+ * If we're running the test suite, rename the functions to avoid conflicts
+ * with the system versions.
+ */
+#if TESTING
+# undef strndup
+# define strndup test_strndup
+char *test_strndup(const char *, size_t);
+#endif
+
+char *
+strndup(const char *s, size_t n)
+{
+    const char *p;
+    size_t length;
+    char *copy;
+
+    if (s == NULL) {
+        errno = EINVAL;
+        return NULL;
+    }
+
+    /* Don't assume that the source string is nul-terminated. */
+    for (p = s; (size_t) (p - s) < n && *p != '\0'; p++)
+        ;
+    length = p - s;
+    copy = malloc(length + 1);
+    if (copy == NULL)
+        return NULL;
+    memcpy(copy, s, length);
+    copy[length] = '\0';
+    return copy;
+}
index c04d68e51aaa7732d03a6dd1042b45d85bab03d3..5345da360c4a6f921bd7e15b624d119542d1dd2e 100644 (file)
@@ -124,6 +124,9 @@ extern int snprintf(char *, size_t, const char *, ...)
 #if !HAVE_DECL_VSNPRINTF
 extern int vsnprintf(char *, size_t, const char *, va_list);
 #endif
+#if !HAVE_STRNDUP
+extern char *strndup(const char *, size_t);
+#endif
 
 /* Undo default visibility change. */
 #pragma GCC visibility pop
index 344e69850c87d303fd641579e17b8b6f49fc05cc..b85e43d61576931dc3f83b8e19323567b8eff50b 100644 (file)
@@ -7,6 +7,7 @@ perl/minimum-version
 perl/strict
 portable/asprintf
 portable/snprintf
+portable/strndup
 tools/cdbmake-wordlist
 tools/heimdal-strength
 util/messages
diff --git a/tests/portable/strndup-t.c b/tests/portable/strndup-t.c
new file mode 100644 (file)
index 0000000..0f923b7
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * strndup test suite.
+ *
+ * The canonical version of this file is maintained in the rra-c-util package,
+ * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+ *
+ * Written by Russ Allbery <eagle@eyrie.org>
+ *
+ * The authors hereby relinquish any claim to any copyright that they may have
+ * in this work, whether granted under contract or by operation of law or
+ * international treaty, and hereby commit to the public, at large, that they
+ * shall not, at any time in the future, seek to enforce any copyright in this
+ * work against any person or entity, or prevent any person or entity from
+ * copying, publishing, distributing or creating derivative works of this
+ * work.
+ */
+
+#include <config.h>
+#include <portable/system.h>
+
+#include <errno.h>
+
+#include <tests/tap/basic.h>
+
+char *test_strndup(const char *, size_t);
+
+
+int
+main(void)
+{
+    char buffer[3];
+    char *result = NULL;
+
+    plan(7);
+
+    result = test_strndup("foo", 8);
+    is_string("foo", result, "strndup longer than string");
+    free(result);
+    result = test_strndup("foo", 2);
+    is_string("fo", result, "strndup shorter than string");
+    free(result);
+    result = test_strndup("foo", 3);
+    is_string("foo", result, "strndup same size as string");
+    free(result);
+    result = test_strndup("foo", 0);
+    is_string("", result, "strndup of size 0");
+    free(result);
+    memcpy(buffer, "foo", 3);
+    result = test_strndup(buffer, 3);
+    is_string("foo", result, "strndup of non-nul-terminated string");
+    free(result);
+    errno = 0;
+    result = test_strndup(NULL, 0);
+    is_string(NULL, result, "strndup of NULL");
+    is_int(errno, EINVAL, "...and returns EINVAL");
+
+    return 0;
+}
diff --git a/tests/portable/strndup.c b/tests/portable/strndup.c
new file mode 100644 (file)
index 0000000..99c3bc1
--- /dev/null
@@ -0,0 +1,2 @@
+#define TESTING 1
+#include <portable/strndup.c>
index be34ab305703ce574cb74c1708872e3592d60150..2b7959bfc854d9751774b1d4d7c58966ea900904 100644 (file)
@@ -87,6 +87,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdarg.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 /* AIX doesn't have WCOREDUMP. */
 #ifndef WCOREDUMP
-# define WCOREDUMP(status)      ((unsigned)(status) & 0x80)
+# define WCOREDUMP(status) ((unsigned)(status) & 0x80)
 #endif
 
 /*
@@ -173,14 +174,16 @@ struct testlist {
 };
 
 /*
- * Usage message.  Should be used as a printf format with two arguments: the
- * path to runtests, given twice.
+ * Usage message.  Should be used as a printf format with four arguments: the
+ * path to runtests, given three times, and the usage_description.  This is
+ * split into variables to satisfy the pedantic ISO C90 limit on strings.
  */
 static const char usage_message[] = "\
 Usage: %s [-b <build-dir>] [-s <source-dir>] <test> ...\n\
        %s [-b <build-dir>] [-s <source-dir>] -l <test-list>\n\
        %s -o [-b <build-dir>] [-s <source-dir>] <test>\n\
-\n\
+\n%s";
+static const char usage_extra[] = "\
 Options:\n\
     -b <build-dir>      Set the build directory to <build-dir>\n\
     -l <list>           Take the list of tests to run from <test-list>\n\
@@ -1310,7 +1313,7 @@ main(int argc, char *argv[])
             build = optarg;
             break;
         case 'h':
-            printf(usage_message, argv[0], argv[0], argv[0]);
+            printf(usage_message, argv[0], argv[0], argv[0], usage_extra);
             exit(0);
             break;
         case 'l':
@@ -1329,7 +1332,7 @@ main(int argc, char *argv[])
     argv += optind;
     argc -= optind;
     if ((list == NULL && argc < 1) || (list != NULL && argc > 0)) {
-        fprintf(stderr, usage_message, argv[0], argv[0], argv[0]);
+        fprintf(stderr, usage_message, argv[0], argv[0], argv[0], usage_extra);
         exit(1);
     }
 
index 254c19f5a7367c6e6defa362e0625f674f45701a..bb51606b639b08350820bad6936386437b713c01 100644 (file)
@@ -12,7 +12,7 @@
  * This file is part of C TAP Harness.  The current version plus supporting
  * documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>.
  *
- * Copyright 2009, 2010, 2011, 2012 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2009, 2010, 2011, 2012, 2013 Russ Allbery <eagle@eyrie.org>
  * Copyright 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2011, 2012, 2013
  *     The Board of Trustees of the Leland Stanford Junior University
  *
@@ -58,7 +58,7 @@
 
 /*
  * The test count.  Always contains the number that will be used for the next
- * test status.
+ * test status.  This is exported to callers of the library.
  */
 unsigned long testnum = 1;
 
@@ -66,53 +66,133 @@ unsigned long testnum = 1;
  * Status information stored so that we can give a test summary at the end of
  * the test case.  We store the planned final test and the count of failures.
  * We can get the highest test count from testnum.
- *
- * We also store the PID of the process that called plan() and only summarize
- * results when that process exits, so as to not misreport results in forked
- * processes.
- *
- * If _lazy is true, we're doing lazy planning and will print out the plan
- * based on the last test number at the end of testing.
  */
 static unsigned long _planned = 0;
 static unsigned long _failed  = 0;
+
+/*
+ * Store the PID of the process that called plan() and only summarize
+ * results when that process exits, so as to not misreport results in forked
+ * processes.
+ */
 static pid_t _process = 0;
+
+/*
+ * If true, we're doing lazy planning and will print out the plan based on the
+ * last test number at the end of testing.
+ */
 static int _lazy = 0;
 
+/*
+ * If true, the test was aborted by calling bail().  Currently, this is only
+ * used to ensure that we pass a false value to any cleanup functions even if
+ * all tests to that point have passed.
+ */
+static int _aborted = 0;
+
+/*
+ * Registered cleanup functions.  These are stored as a linked list and run in
+ * registered order by finish when the test program exits.  Each function is
+ * passed a boolean value indicating whether all tests were successful.
+ */
+struct cleanup_func {
+    test_cleanup_func func;
+    struct cleanup_func *next;
+};
+static struct cleanup_func *cleanup_funcs = NULL;
+
+/*
+ * Print a specified prefix and then the test description.  Handles turning
+ * the argument list into a va_args structure suitable for passing to
+ * print_desc, which has to be done in a macro.  Assumes that format is the
+ * argument immediately before the variadic arguments.
+ */
+#define PRINT_DESC(prefix, format)              \
+    do {                                        \
+        if (format != NULL) {                   \
+            va_list args;                       \
+            if (prefix != NULL)                 \
+                printf("%s", prefix);           \
+            va_start(args, format);             \
+            vprintf(format, args);              \
+            va_end(args);                       \
+        }                                       \
+    } while (0)
+
 
 /*
  * Our exit handler.  Called on completion of the test to report a summary of
  * results provided we're still in the original process.  This also handles
  * printing out the plan if we used plan_lazy(), although that's suppressed if
- * we never ran a test (due to an early bail, for example).
+ * we never ran a test (due to an early bail, for example), and running any
+ * registered cleanup functions.
  */
 static void
 finish(void)
 {
+    int success;
+    struct cleanup_func *current;
     unsigned long highest = testnum - 1;
 
-    if (_planned == 0 && !_lazy)
-        return;
-    fflush(stderr);
-    if (_process != 0 && getpid() == _process) {
-        if (_lazy && highest > 0) {
-            printf("1..%lu\n", highest);
-            _planned = highest;
+    /*
+     * Don't do anything except free the cleanup functions if we aren't the
+     * primary process (the process in which plan or plan_lazy was called).
+     */
+    if (_process != 0 && getpid() != _process) {
+        while (cleanup_funcs != NULL) {
+            current = cleanup_funcs;
+            cleanup_funcs = cleanup_funcs->next;
+            free(current);
         }
-        if (_planned > highest)
-            printf("# Looks like you planned %lu test%s but only ran %lu\n",
-                   _planned, (_planned > 1 ? "s" : ""), highest);
-        else if (_planned < highest)
-            printf("# Looks like you planned %lu test%s but ran %lu extra\n",
-                   _planned, (_planned > 1 ? "s" : ""), highest - _planned);
-        else if (_failed > 0)
-            printf("# Looks like you failed %lu test%s of %lu\n", _failed,
-                   (_failed > 1 ? "s" : ""), _planned);
-        else if (_planned > 1)
-            printf("# All %lu tests successful or skipped\n", _planned);
-        else
-            printf("# %lu test successful or skipped\n", _planned);
+        return;
     }
+
+    /*
+     * Determine whether all tests were successful, which is needed before
+     * calling cleanup functions since we pass that fact to the functions.
+     */
+    if (_planned == 0 && _lazy)
+        _planned = highest;
+    success = (!_aborted && _planned == highest && _failed == 0);
+
+    /*
+     * If there are any registered cleanup functions, we run those first.  We
+     * always run them, even if we didn't run a test.
+     */
+    while (cleanup_funcs != NULL) {
+        cleanup_funcs->func(success);
+        current = cleanup_funcs;
+        cleanup_funcs = cleanup_funcs->next;
+        free(current);
+    }
+
+    /* Don't do anything further if we never planned a test. */
+    if (_planned == 0)
+        return;
+
+    /* If we're aborting due to bail, don't print summaries. */
+    if (_aborted)
+        return;
+
+    /* Print out the lazy plan if needed. */
+    fflush(stderr);
+    if (_lazy && _planned > 0)
+        printf("1..%lu\n", _planned);
+
+    /* Print out a summary of the results. */
+    if (_planned > highest)
+        diag("Looks like you planned %lu test%s but only ran %lu", _planned,
+             (_planned > 1 ? "s" : ""), highest);
+    else if (_planned < highest)
+        diag("Looks like you planned %lu test%s but ran %lu extra", _planned,
+             (_planned > 1 ? "s" : ""), highest - _planned);
+    else if (_failed > 0)
+        diag("Looks like you failed %lu test%s of %lu", _failed,
+             (_failed > 1 ? "s" : ""), _planned);
+    else if (_planned != 1)
+        diag("All %lu tests successful or skipped", _planned);
+    else
+        diag("%lu test successful or skipped", _planned);
 }
 
 
@@ -124,14 +204,16 @@ void
 plan(unsigned long count)
 {
     if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0)
-        fprintf(stderr, "# cannot set stdout to line buffered: %s\n",
-                strerror(errno));
+        sysdiag("cannot set stdout to line buffered");
     fflush(stderr);
     printf("1..%lu\n", count);
     testnum = 1;
     _planned = count;
     _process = getpid();
-    atexit(finish);
+    if (atexit(finish) != 0) {
+        sysdiag("cannot register exit handler");
+        diag("cleanups will not be run");
+    }
 }
 
 
@@ -143,12 +225,12 @@ void
 plan_lazy(void)
 {
     if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0)
-        fprintf(stderr, "# cannot set stdout to line buffered: %s\n",
-                strerror(errno));
+        sysdiag("cannot set stdout to line buffered");
     testnum = 1;
     _process = getpid();
     _lazy = 1;
-    atexit(finish);
+    if (atexit(finish) != 0)
+        sysbail("cannot register exit handler to display plan");
 }
 
 
@@ -161,30 +243,12 @@ skip_all(const char *format, ...)
 {
     fflush(stderr);
     printf("1..0 # skip");
-    if (format != NULL) {
-        va_list args;
-
-        putchar(' ');
-        va_start(args, format);
-        vprintf(format, args);
-        va_end(args);
-    }
+    PRINT_DESC(" ", format);
     putchar('\n');
     exit(0);
 }
 
 
-/*
- * Print the test description.
- */
-static void
-print_desc(const char *format, va_list args)
-{
-    printf(" - ");
-    vprintf(format, args);
-}
-
-
 /*
  * Takes a boolean success value and assumes the test passes if that value
  * is true and fails if that value is false.
@@ -196,13 +260,7 @@ ok(int success, const char *format, ...)
     printf("%sok %lu", success ? "" : "not ", testnum++);
     if (!success)
         _failed++;
-    if (format != NULL) {
-        va_list args;
-
-        va_start(args, format);
-        print_desc(format, args);
-        va_end(args);
-    }
+    PRINT_DESC(" - ", format);
     putchar('\n');
 }
 
@@ -217,8 +275,10 @@ okv(int success, const char *format, va_list args)
     printf("%sok %lu", success ? "" : "not ", testnum++);
     if (!success)
         _failed++;
-    if (format != NULL)
-        print_desc(format, args);
+    if (format != NULL) {
+        printf(" - ");
+        vprintf(format, args);
+    }
     putchar('\n');
 }
 
@@ -231,14 +291,7 @@ skip(const char *reason, ...)
 {
     fflush(stderr);
     printf("ok %lu # skip", testnum++);
-    if (reason != NULL) {
-        va_list args;
-
-        va_start(args, reason);
-        putchar(' ');
-        vprintf(reason, args);
-        va_end(args);
-    }
+    PRINT_DESC(" ", reason);
     putchar('\n');
 }
 
@@ -256,13 +309,7 @@ ok_block(unsigned long count, int status, const char *format, ...)
         printf("%sok %lu", status ? "" : "not ", testnum++);
         if (!status)
             _failed++;
-        if (format != NULL) {
-            va_list args;
-
-            va_start(args, format);
-            print_desc(format, args);
-            va_end(args);
-        }
+        PRINT_DESC(" - ", format);
         putchar('\n');
     }
 }
@@ -279,14 +326,7 @@ skip_block(unsigned long count, const char *reason, ...)
     fflush(stderr);
     for (i = 0; i < count; i++) {
         printf("ok %lu # skip", testnum++);
-        if (reason != NULL) {
-            va_list args;
-
-            va_start(args, reason);
-            putchar(' ');
-            vprintf(reason, args);
-            va_end(args);
-        }
+        PRINT_DESC(" ", reason);
         putchar('\n');
     }
 }
@@ -303,17 +343,12 @@ is_int(long wanted, long seen, const char *format, ...)
     if (wanted == seen)
         printf("ok %lu", testnum++);
     else {
-        printf("# wanted: %ld\n#   seen: %ld\n", wanted, seen);
+        diag("wanted: %ld", wanted);
+        diag("  seen: %ld", seen);
         printf("not ok %lu", testnum++);
         _failed++;
     }
-    if (format != NULL) {
-        va_list args;
-
-        va_start(args, format);
-        print_desc(format, args);
-        va_end(args);
-    }
+    PRINT_DESC(" - ", format);
     putchar('\n');
 }
 
@@ -333,17 +368,12 @@ is_string(const char *wanted, const char *seen, const char *format, ...)
     if (strcmp(wanted, seen) == 0)
         printf("ok %lu", testnum++);
     else {
-        printf("# wanted: %s\n#   seen: %s\n", wanted, seen);
+        diag("wanted: %s", wanted);
+        diag("  seen: %s", seen);
         printf("not ok %lu", testnum++);
         _failed++;
     }
-    if (format != NULL) {
-        va_list args;
-
-        va_start(args, format);
-        print_desc(format, args);
-        va_end(args);
-    }
+    PRINT_DESC(" - ", format);
     putchar('\n');
 }
 
@@ -359,18 +389,12 @@ is_hex(unsigned long wanted, unsigned long seen, const char *format, ...)
     if (wanted == seen)
         printf("ok %lu", testnum++);
     else {
-        printf("# wanted: %lx\n#   seen: %lx\n", (unsigned long) wanted,
-               (unsigned long) seen);
+        diag("wanted: %lx", (unsigned long) wanted);
+        diag("  seen: %lx", (unsigned long) seen);
         printf("not ok %lu", testnum++);
         _failed++;
     }
-    if (format != NULL) {
-        va_list args;
-
-        va_start(args, format);
-        print_desc(format, args);
-        va_end(args);
-    }
+    PRINT_DESC(" - ", format);
     putchar('\n');
 }
 
@@ -383,6 +407,7 @@ bail(const char *format, ...)
 {
     va_list args;
 
+    _aborted = 1;
     fflush(stderr);
     fflush(stdout);
     printf("Bail out! ");
@@ -403,6 +428,7 @@ sysbail(const char *format, ...)
     va_list args;
     int oerrno = errno;
 
+    _aborted = 1;
     fflush(stderr);
     fflush(stdout);
     printf("Bail out! ");
@@ -627,3 +653,22 @@ test_tmpdir_free(char *path)
     if (path != NULL)
         free(path);
 }
+
+
+/*
+ * Register a cleanup function that is called when testing ends.  All such
+ * registered functions will be run by finish.
+ */
+void
+test_cleanup_register(test_cleanup_func func)
+{
+    struct cleanup_func *cleanup, **last;
+
+    cleanup = bmalloc(sizeof(struct cleanup_func));
+    cleanup->func = func;
+    cleanup->next = NULL;
+    last = &cleanup_funcs;
+    while (*last != NULL)
+        last = &(*last)->next;
+    *last = cleanup;
+}
index c55f6621eaa7525fa5f0ba069187f0b97a72fa80..92d348a15a0c6af752e66d796b0cd57e331a44ad 100644 (file)
@@ -4,7 +4,7 @@
  * This file is part of C TAP Harness.  The current version plus supporting
  * documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>.
  *
- * Copyright 2009, 2010, 2011, 2012 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2009, 2010, 2011, 2012, 2013 Russ Allbery <eagle@eyrie.org>
  * Copyright 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2011, 2012
  *     The Board of Trustees of the Leland Stanford Junior University
  *
@@ -32,7 +32,7 @@
 
 #include <tests/tap/macros.h>
 #include <stdarg.h>             /* va_list */
-#include <sys/types.h>          /* size_t */
+#include <stddef.h>             /* size_t */
 
 /*
  * Used for iterating through arrays.  ARRAY_SIZE returns the number of
@@ -55,7 +55,7 @@ extern unsigned long testnum;
 void plan(unsigned long count);
 
 /*
- * Prepare for lazy planning, in which the plan will be  printed automatically
+ * Prepare for lazy planning, in which the plan will be printed automatically
  * at the end of the test program.
  */
 void plan_lazy(void);
@@ -103,22 +103,22 @@ void sysdiag(const char *format, ...)
 
 /* Allocate memory, reporting a fatal error with bail on failure. */
 void *bcalloc(size_t, size_t)
-    __attribute__((__alloc_size__(1, 2), __malloc__));
+    __attribute__((__alloc_size__(1, 2), __malloc__, __warn_unused_result__));
 void *bmalloc(size_t)
-    __attribute__((__alloc_size__(1), __malloc__));
+    __attribute__((__alloc_size__(1), __malloc__, __warn_unused_result__));
 void *brealloc(void *, size_t)
-    __attribute__((__alloc_size__(2), __malloc__));
+    __attribute__((__alloc_size__(2), __malloc__, __warn_unused_result__));
 char *bstrdup(const char *)
-    __attribute__((__malloc__, __nonnull__));
+    __attribute__((__malloc__, __nonnull__, __warn_unused_result__));
 char *bstrndup(const char *, size_t)
-    __attribute__((__malloc__, __nonnull__));
+    __attribute__((__malloc__, __nonnull__, __warn_unused_result__));
 
 /*
  * Find a test file under BUILD or SOURCE, returning the full path.  The
  * returned path should be freed with test_file_path_free().
  */
 char *test_file_path(const char *file)
-    __attribute__((__malloc__, __nonnull__));
+    __attribute__((__malloc__, __nonnull__, __warn_unused_result__));
 void test_file_path_free(char *path);
 
 /*
@@ -126,9 +126,20 @@ void test_file_path_free(char *path);
  * returned path should be freed with test_tmpdir_free.
  */
 char *test_tmpdir(void)
-    __attribute__((__malloc__));
+    __attribute__((__malloc__, __warn_unused_result__));
 void test_tmpdir_free(char *path);
 
+/*
+ * Register a cleanup function that is called when testing ends.  All such
+ * registered functions will be run during atexit handling (and are therefore
+ * subject to all the same constraints and caveats as atexit functions).  The
+ * function must return void and will be passed one argument, an int that will
+ * be true if the test completed successfully and false otherwise.
+ */
+typedef void (*test_cleanup_func)(int);
+void test_cleanup_register(test_cleanup_func)
+    __attribute__((__nonnull__));
+
 END_DECLS
 
 #endif /* TAP_BASIC_H */
index 6f593f86bc17538a111e1443988540de7f6d4ce9..58315ee2ca9c302d050134c0dbb99661163af761 100644 (file)
@@ -15,7 +15,7 @@
  * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
  *
  * Written by Russ Allbery <eagle@eyrie.org>
- * Copyright 2006, 2007, 2009, 2010, 2011, 2012
+ * Copyright 2006, 2007, 2009, 2010, 2011, 2012, 2013
  *     The Board of Trustees of the Leland Stanford Junior University
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -38,7 +38,7 @@
  */
 
 #include <config.h>
-#ifdef HAVE_KERBEROS
+#ifdef HAVE_KRB5
 # include <portable/krb5.h>
 #endif
 #include <portable/system.h>
@@ -79,7 +79,7 @@ static char *tmpdir_conf = NULL;
  * Kerberos libraries available and one if we don't.  Uses keytab to obtain
  * credentials, and fills in the cache member of the provided config struct.
  */
-#ifdef HAVE_KERBEROS
+#ifdef HAVE_KRB5
 
 static void
 kerberos_kinit(void)
@@ -147,7 +147,7 @@ kerberos_kinit(void)
     free(krbtgt);
 }
 
-#else /* !HAVE_KERBEROS */
+#else /* !HAVE_KRB5 */
 
 static void
 kerberos_kinit(void)
@@ -197,7 +197,7 @@ kerberos_kinit(void)
         bail("cannot get Kerberos tickets");
 }
 
-#endif /* !HAVE_KERBEROS */
+#endif /* !HAVE_KRB5 */
 
 
 /*
@@ -401,7 +401,7 @@ kerberos_generate_conf(const char *realm)
  * The remaining functions in this file are only available if Kerberos
  * libraries are available.
  */
-#ifdef HAVE_KERBEROS
+#ifdef HAVE_KRB5
 
 
 /*
@@ -485,4 +485,4 @@ kerberos_keytab_principal(krb5_context ctx, const char *path)
     return princ;
 }
 
-#endif /* HAVE_KERBEROS */
+#endif /* HAVE_KRB5 */
index ed2ef7bac92405c24899daf5ec7859f5bcd26d6a..c34f891005e2e5775f2d9ed41ae14ae93d76ab68 100644 (file)
@@ -33,7 +33,7 @@
 #include <config.h>
 #include <tests/tap/macros.h>
 
-#ifdef HAVE_KERBEROS
+#ifdef HAVE_KRB5
 # include <portable/krb5.h>
 #endif
 
@@ -100,7 +100,7 @@ void kerberos_generate_conf(const char *realm);
 void kerberos_cleanup_conf(void);
 
 /* Thes interfaces are only available with native Kerberos support. */
-#ifdef HAVE_KERBEROS
+#ifdef HAVE_KRB5
 
 /* Bail out with an error, appending the Kerberos error message. */
 void bail_krb5(krb5_context, krb5_error_code, const char *format, ...)
@@ -118,7 +118,7 @@ void diag_krb5(krb5_context, krb5_error_code, const char *format, ...)
 krb5_principal kerberos_keytab_principal(krb5_context, const char *path)
     __attribute__((__nonnull__));
 
-#endif /* HAVE_KERBEROS */
+#endif /* HAVE_KRB5 */
 
 END_DECLS
 
index 368f95e6d03f90bb7c4e7ccc61e8a339f2db3ba8..04cc420ddc76b7b08cd89fc00693251d8b9362d5 100644 (file)
@@ -8,7 +8,7 @@
  * This file is part of C TAP Harness.  The current version plus supporting
  * documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>.
  *
- * Copyright 2008, 2012 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2008, 2012, 2013 Russ Allbery <eagle@eyrie.org>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
 # endif
 #endif
 
+/* Suppress __warn_unused_result__ if gcc is too old. */
+#if !defined(__attribute__) && !defined(__warn_unused_result__)
+# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4)
+#  define __warn_unused_result__ /* empty */
+# endif
+#endif
+
 /*
  * LLVM and Clang pretend to be GCC but don't support all of the __attribute__
  * settings that GCC does.  For them, suppress warnings about unknown
index dc48ad8cf5f596fa64c572b230ca9a5211decc40..b252250e6a0623eb32a2bec5919ce8c36db0b761 100644 (file)
@@ -56,7 +56,7 @@ BEGIN {
     # This version should match the corresponding rra-c-util release, but with
     # two digits for the minor version, including a leading zero if necessary,
     # so that it will sort properly.
-    $VERSION = '4.09';
+    $VERSION = '4.12';
 }
 
 # Skip this test unless maintainer tests are requested.  Takes a short
index 3232bc8b883ba6f8dfb3429e9df09d9719f25680..b8ce0958b02c16e2a21968bf43b686221f5f0416 100644 (file)
@@ -82,12 +82,12 @@ our (@EXPORT_OK, @ISA, $VERSION);
 # consistency is good).
 BEGIN {
     @ISA       = qw(Exporter);
-    @EXPORT_OK = qw(automake_setup perl_dirs test_file_path);
+    @EXPORT_OK = qw(automake_setup perl_dirs test_file_path test_tmpdir);
 
     # This version should match the corresponding rra-c-util release, but with
     # two digits for the minor version, including a leading zero if necessary,
     # so that it will sort properly.
-    $VERSION = '4.09';
+    $VERSION = '4.12';
 }
 
 # Perl directories to skip globally for perl_dirs.  We ignore the perl
@@ -95,6 +95,11 @@ BEGIN {
 # distribution and has its own standalone test suite.
 my @GLOBAL_SKIP = qw(.git perl);
 
+# The temporary directory created by test_tmpdir, if any.  If this is set,
+# attempt to remove the directory stored here on program exit (but ignore
+# failure to do so).
+my $TMPDIR;
+
 # Perform initial test setup for running a Perl test in an Automake package.
 # This verifies that BUILD and SOURCE are set and then changes directory to
 # the SOURCE directory by default.  Sets LD_LIBRARY_PATH if the $LIBRARY_PATH
@@ -238,12 +243,53 @@ sub test_file_path {
     return;
 }
 
+# Create a temporary directory for tests to use for transient files and return
+# the path to that directory.  The directory is automatically removed on
+# program exit.  The directory permissions use the current umask.  Calls
+# BAIL_OUT if the directory could not be created.
+#
+# Returns: Path to a writable temporary directory
+sub test_tmpdir {
+    my $path;
+
+    # If we already figured out what directory to use, reuse the same path.
+    # Otherwise, create a directory relative to BUILD if set.
+    if (defined($TMPDIR)) {
+        $path = $TMPDIR;
+    } else {
+        my $base = defined($ENV{BUILD}) ? $ENV{BUILD} : File::Spec->curdir;
+        $path = File::Spec->catdir($base, 'tmp');
+    }
+
+    # Create the directory if it doesn't exist.
+    if (!-d $path) {
+        if (!mkdir($path, 0777)) {
+            BAIL_OUT("cannot create directory $path: $!");
+        }
+    }
+
+    # Store the directory name for cleanup and return it.
+    $TMPDIR = $path;
+    return $path;
+}
+
+# On program exit, remove $TMPDIR if set and if possible.  Report errors with
+# diag but otherwise ignore them.
+END {
+    if (defined($TMPDIR) && -d $TMPDIR) {
+        local $! = undef;
+        if (!rmdir($TMPDIR)) {
+            diag("cannot remove temporary directory $TMPDIR: $!");
+        }
+    }
+}
+
 1;
 __END__
 
 =for stopwords
 Allbery Automake Automake-aware Automake-based rra-c-util ARGS
-subdirectories sublicense MERCHANTABILITY NONINFRINGEMENT
+subdirectories sublicense MERCHANTABILITY NONINFRINGEMENT umask
 
 =head1 NAME
 
@@ -320,6 +366,19 @@ checked for relative to the environment variable BUILD first, and then
 relative to SOURCE.  test_file_path() returns the full path to FILE or
 calls BAIL_OUT if FILE could not be found.
 
+=item test_tmpdir()
+
+Create a temporary directory for tests to use for transient files and
+return the path to that directory.  The directory is created relative to
+the BUILD environment variable, which must be set.  Permissions on the
+directory are set using the current umask.  test_tmpdir() returns the full
+path to the temporary directory or calls BAIL_OUT if it could not be
+created.
+
+The directory is automatically removed if possible on program exit.
+Failure to remove the directory on exit is reported with diag() and
+otherwise ignored.
+
 =back
 
 =head1 AUTHOR
index 556df39f0ec7a9103ea4d62f34a9298c9a18cb06..106cc6eed3e21361fe52389c8ed1929cba3a14d7 100644 (file)
@@ -36,7 +36,7 @@ BEGIN {
     # This version should match the corresponding rra-c-util release, but with
     # two digits for the minor version, including a leading zero if necessary,
     # so that it will sort properly.
-    $VERSION = '4.09';
+    $VERSION = '4.12';
 }
 
 # If BUILD or SOURCE are set in the environment, look for data/perl.conf under
@@ -131,7 +131,7 @@ directory names starting with F<tests/>.
 
 =item $LIBRARY_PATH
 
-Add this directory (or a .libs subdirectory) relative to the top of the
+Add this directory (or a F<.libs> subdirectory) relative to the top of the
 source tree to LD_LIBRARY_PATH when checking the syntax of Perl modules.
 This may be required to pick up libraries that are used by in-tree Perl
 modules so that Perl scripts can pass a syntax check.
index ac60aae87b2cd96c347f096003068c6fbce6e63a..b8d6ff96dce2c5d9dbdf19be3a389c5b3a7ccdfb 100644 (file)
@@ -12,7 +12,7 @@
  *
  * Written by Russ Allbery <eagle@eyrie.org>
  * Copyright 2002, 2004, 2005 Russ Allbery <eagle@eyrie.org>
- * Copyright 2009, 2010, 2011
+ * Copyright 2009, 2010, 2011, 2013
  *     The Board of Trustees of the Leland Stanford Junior University
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -171,7 +171,10 @@ run_setup(const char *const argv[])
         p = strchr(output, '\n');
         if (p != NULL)
             *p = '\0';
-        bail("%s", output);
+        if (output[0] != '\0')
+            bail("%s", output);
+        else
+            bail("setup command failed with no output");
     }
     free(output);
 }
index 9ec3ba855860445c720e6aa36560e93a124108ce..769166fc4c01b4cd0cb33a13092ce129d0b205e4 100644 (file)
@@ -54,7 +54,7 @@
  * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
  *
  * Written by Russ Allbery <eagle@eyrie.org>
- * Copyright 2008, 2009, 2010
+ * Copyright 2008, 2009, 2010, 2013
  *     The Board of Trustees of the Leland Stanford Junior University
  * Copyright (c) 2004, 2005, 2006
  *     by Internet Systems Consortium, Inc. ("ISC")
@@ -204,6 +204,7 @@ static void
 message_log_syslog(int pri, size_t len, const char *fmt, va_list args, int err)
 {
     char *buffer;
+    int status;
 
     buffer = malloc(len + 1);
     if (buffer == NULL) {
@@ -211,7 +212,12 @@ message_log_syslog(int pri, size_t len, const char *fmt, va_list args, int err)
                 (unsigned long) len + 1, __FILE__, __LINE__, strerror(errno));
         exit(message_fatal_cleanup ? (*message_fatal_cleanup)() : 1);
     }
-    vsnprintf(buffer, len + 1, fmt, args);
+    status = vsnprintf(buffer, len + 1, fmt, args);
+    if (status < 0) {
+        warn("failed to format output with vsnprintf in syslog handler");
+        free(buffer);
+        return;
+    }
 #ifdef _WIN32
     {
         HANDLE eventlog;
index cffae803096a7f16b188305a40cd5bceca510ca0..5bfd5558589f2290a8c221a5747194a950dfac5c 100644 (file)
@@ -58,7 +58,7 @@
  * The canonical version of this file is maintained in the rra-c-util package,
  * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
  *
- * Copyright 2012
+ * Copyright 2012, 2013
  *     The Board of Trustees of the Leland Stanford Junior University
  * Copyright (c) 2004, 2005, 2006
  *     by Internet Systems Consortium, Inc. ("ISC")
 void
 xmalloc_fail(const char *function, size_t size, const char *file, int line)
 {
-    sysdie("failed to %s %lu bytes at %s line %d", function,
-           (unsigned long) size, file, line);
+    if (size == 0)
+        sysdie("failed to format output with %s at %s line %d", function,
+               file, line);
+    else
+        sysdie("failed to %s %lu bytes at %s line %d", function,
+               (unsigned long) size, file, line);
 }
 
 /* Assign to this variable to choose a handler other than the default. */
@@ -206,7 +210,8 @@ x_vasprintf(char **strp, const char *fmt, va_list args, const char *file,
         va_copy(args_copy, args);
         status = vsnprintf(NULL, 0, fmt, args_copy);
         va_end(args_copy);
-        (*xmalloc_error_handler)("vasprintf", status + 1, file, line);
+        status = (status < 0) ? 0 : status + 1;
+        (*xmalloc_error_handler)("vasprintf", status, file, line);
         va_copy(args_copy, args);
         status = vasprintf(strp, fmt, args_copy);
         va_end(args_copy);
@@ -229,7 +234,8 @@ x_asprintf(char **strp, const char *file, int line, const char *fmt, ...)
         va_copy(args_copy, args);
         status = vsnprintf(NULL, 0, fmt, args_copy);
         va_end(args_copy);
-        (*xmalloc_error_handler)("asprintf", status + 1, file, line);
+        status = (status < 0) ? 0 : status + 1;
+        (*xmalloc_error_handler)("asprintf", status, file, line);
         va_copy(args_copy, args);
         status = vasprintf(strp, fmt, args_copy);
         va_end(args_copy);
@@ -250,7 +256,8 @@ x_asprintf(char **strp, const char *fmt, ...)
         va_copy(args_copy, args);
         status = vsnprintf(NULL, 0, fmt, args_copy);
         va_end(args_copy);
-        (*xmalloc_error_handler)("asprintf", status + 1, __FILE__, __LINE__);
+        status = (status < 0) ? 0 : status + 1;
+        (*xmalloc_error_handler)("asprintf", status, __FILE__, __LINE__);
         va_copy(args_copy, args);
         status = vasprintf(strp, fmt, args_copy);
         va_end(args_copy);
index 3f680adff4b5b69a63713b8ebf89d74bf57dfd14..ac4d79629c0d302376ab01768b58526f1102a9a5 100644 (file)
@@ -97,7 +97,11 @@ void x_asprintf(char **, const char *, ...)
     __attribute__((__nonnull__, __format__(printf, 2, 3)));
 #endif
 
-/* Failure handler takes the function, the size, the file, and the line. */
+/*
+ * Failure handler takes the function, the size, the file, and the line.  The
+ * size will be zero if the failure was due to some failure in snprintf
+ * instead of a memory allocation failure.
+ */
 typedef void (*xmalloc_handler_type)(const char *, size_t, const char *, int);
 
 /* The default error handler. */