]> eyrie.org Git - kerberos/wallet.git/commitdiff
Update to rra-c-util 5.10 and C TAP Harness 3.4
authorRuss Allbery <eagle@eyrie.org>
Sun, 17 Jan 2016 22:30:53 +0000 (14:30 -0800)
committerRuss Allbery <eagle@eyrie.org>
Sun, 17 Jan 2016 22:30:53 +0000 (14:30 -0800)
Update to rra-c-util 5.10:

* Add missing va_end to xasprintf implementation.
* Fix Perl test suite framework for new Automake relative paths.
* Improve portability to Kerberos included in Solaris 10.
* Use appropriate warning flags with Clang (currently not warning clean).

Update to C TAP Harness 3.4:

* Fix segfault in runtests with an empty test list.
* Display verbose test results with -v or C_TAP_VERBOSE.
* Test infrastructure builds cleanly with Clang warnings.
* Support comments and blank lines in test lists.

35 files changed:
Makefile.am
NEWS
configure.ac
m4/clang.m4 [new file with mode: 0644]
m4/krb5.m4
portable/asprintf.c
portable/krb5-extra.c
portable/krb5.h
portable/macros.h
portable/mkstemp.c
portable/reallocarray.c
portable/setenv.c
portable/snprintf.c
portable/strlcat.c
portable/strlcpy.c
portable/system.h
tests/portable/asprintf-t.c
tests/portable/snprintf-t.c
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/messages.c
tests/tap/process.c
tests/tap/string.h
tests/util/messages-t.c
tests/util/xmalloc-t
tests/util/xmalloc.c
util/macros.h
util/messages.c
util/messages.h
util/xmalloc.c
util/xmalloc.h

index ccbaed0223a46ccf716fe86a0431513591030378..5c876391d9e4f2be8a2887e4c763ce2ff0e2ca17 100644 (file)
@@ -1,6 +1,7 @@
 # Automake makefile for wallet.
 #
 # Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2016 Russ Allbery <eagle@eyrie.org>
 # Copyright 2006, 2007, 2008, 2010, 2013, 2014
 #     The Board of Trustees of the Leland Stanford Junior University
 #
@@ -173,22 +174,28 @@ dist_pkgdata_DATA = perl/sql/Wallet-Schema-0.07-0.08-MySQL.sql    \
        perl/sql/Wallet-Schema-0.09-PostgreSQL.sql              \
        perl/sql/Wallet-Schema-0.09-SQLite.sql
 
-# A set of flags for warnings. Add -O because gcc won't find some warnings
+# A set of flags for warnings.  Add -O because gcc won't find some warnings
 # without optimization turned on.  Desirable warnings that can't be turned
 # on due to other problems:
 #
-#     -Wconversion     http://bugs.debian.org/488884 (htons warnings)
+#     -Wconversion      http://bugs.debian.org/488884 (htons warnings)
 #
-# Last checked against gcc 4.8.2 (2014-04-12). -D_FORTIFY_SOURCE=2 enables
+# Last checked against gcc 4.8.2 (2014-04-12).  -D_FORTIFY_SOURCE=2 enables
 # warn_unused_result attribute markings on glibc functions on Linux, which
 # catches a few more issues.
-WARNINGS = -g -O -fstrict-overflow -fstrict-aliasing -D_FORTIFY_SOURCE=2    \
-       -Wall -Wextra -Wendif-labels -Wformat=2 -Winit-self -Wswitch-enum   \
-       -Wstrict-overflow=5 -Wfloat-equal -Wdeclaration-after-statement     \
-       -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align           \
-       -Wwrite-strings -Wjump-misses-init -Wlogical-op -Wstrict-prototypes \
-       -Wold-style-definition -Wmissing-prototypes -Wnormalized=nfc        \
-       -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wvla -Werror
+if WARNINGS_GCC
+    WARNINGS = -g -O -fstrict-overflow -fstrict-aliasing -D_FORTIFY_SOURCE=2 \
+        -Wall -Wextra -Wendif-labels -Wformat=2 -Winit-self -Wswitch-enum    \
+        -Wstrict-overflow=5 -Wmissing-format-attribute -Wfloat-equal         \
+        -Wdeclaration-after-statement -Wshadow -Wpointer-arith               \
+        -Wbad-function-cast -Wcast-align -Wwrite-strings -Wjump-misses-init  \
+        -Wlogical-op -Wstrict-prototypes -Wold-style-definition              \
+        -Wmissing-prototypes -Wnormalized=nfc -Wpacked -Wredundant-decls     \
+        -Wnested-externs -Winline -Wvla -Werror
+endif
+if WARNINGS_CLANG
+    WARNINGS = -Weverything -Wno-padded
+endif
 
 warnings:
        $(MAKE) V=0 CFLAGS='$(WARNINGS)' KRB5_CPPFLAGS='$(KRB5_CPPFLAGS_GCC)'
diff --git a/NEWS b/NEWS
index fe4429db72c3dfd98998caad3576488766d2aa1d..e4932004c0b1b3f0dd92b7d53e02015ff8a73424 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -79,6 +79,20 @@ wallet 1.3 (unreleased)
     package version except for Wallet::Schema, which is used to version
     the database schema.
 
+    Update to rra-c-util 5.10:
+
+    * Add missing va_end to xasprintf implementation.
+    * Fix Perl test suite framework for new Automake relative paths.
+    * Improve portability to Kerberos included in Solaris 10.
+    * Use appropriate warning flags with Clang (currently not warning clean).
+
+    Update to C TAP Harness 3.4:
+
+    * Fix segfault in runtests with an empty test list.
+    * Display verbose test results with -v or C_TAP_VERBOSE.
+    * Test infrastructure builds cleanly with Clang warnings.
+    * Support comments and blank lines in test lists.
+
 wallet 1.2 (2014-12-08)
 
     The duo object type has been split into several sub-types, each for a
index 4efc5d76989bc28c400330670b287499e9a77f46..f4541e275b9858ca16b192acc61cd0dc9c4c322d 100644 (file)
@@ -15,10 +15,14 @@ AM_INIT_AUTOMAKE([1.11 check-news dist-xz foreign silent-rules subdir-objects
     -Wall -Wno-override -Werror])
 AM_MAINTAINER_MODE
 
+dnl Detect unexpanded macros.
+m4_pattern_forbid([^_?RRA_])
+
 dnl AM_PROG_AR is required for Automake 1.12 by Libtool but not defined at all
 dnl (or needed) in Automake 1.11.  Work around this bug.
 AC_PROG_CC
 AC_USE_SYSTEM_EXTENSIONS
+RRA_PROG_CC_CLANG
 AC_SYS_LARGEFILE
 AM_PROG_CC_C_O
 m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
@@ -56,8 +60,8 @@ RRA_LIB_KRB5_RESTORE
 
 dnl Probe for properties of the C library.
 AC_HEADER_STDBOOL
-AC_CHECK_HEADERS([sys/bitypes.h sys/uio.h syslog.h])
-AC_CHECK_DECLS([snprintf, vsnprintf])
+AC_CHECK_HEADERS([sys/bitypes.h sys/uio.h sys/time.h syslog.h])
+AC_CHECK_DECLS([snprintf, strlcat, strlcpy, vsnprintf])
 RRA_C_C99_VAMACROS
 RRA_C_GNU_VAMACROS
 AC_TYPE_LONG_LONG_INT
diff --git a/m4/clang.m4 b/m4/clang.m4
new file mode 100644 (file)
index 0000000..0659d82
--- /dev/null
@@ -0,0 +1,26 @@
+dnl Determine whether the current compiler is Clang.
+dnl
+dnl If the current compiler is Clang, set the shell variable CLANG to yes.
+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 Copyright 2015 Russ Allbery <eagle@eyrie.org>
+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 Source used by RRA_PROG_CC_CLANG.
+AC_DEFUN([_RRA_PROG_CC_CLANG_SOURCE], [[
+#if ! __clang__
+#error
+#endif
+]])
+
+AC_DEFUN([RRA_PROG_CC_CLANG],
+[AC_CACHE_CHECK([if the compiler is Clang], [rra_cv_prog_cc_clang],
+    [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_RRA_PROG_CC_CLANG_SOURCE])],
+        [rra_cv_prog_cc_clang=yes],
+        [rra_cv_prog_cc_clang=no])])
+ AS_IF([test x"$rra_cv_prog_cc_clang" = xyes], [CLANG=yes])])
index 79ef961215658534c59a701a8543760ab648ee4e..683e30b3bde2d84795f2c139cec3872153562cc1 100644 (file)
@@ -64,6 +64,8 @@ dnl Headers to include when probing for Kerberos library properties.
 AC_DEFUN([RRA_INCLUDES_KRB5], [[
 #if HAVE_KRB5_H
 # include <krb5.h>
+#elif HAVE_KERBEROSV5_KRB5_H
+# include <kerberosv5/krb5.h>
 #else
 # include <krb5/krb5.h>
 #endif
@@ -113,6 +115,23 @@ AC_DEFUN([_RRA_LIB_KRB5_CHECK_HEADER],
      AC_MSG_RESULT([yes])],
     [AC_MSG_RESULT([no])])])
 
+dnl Check for the com_err header.  Internal helper macro since we need
+dnl to do the same checks in multiple places.
+AC_DEFUN([_RRA_LIB_KRB5_CHECK_HEADER_COM_ERR],
+[AS_IF([test x"$rra_krb5_incroot" = x],
+    [AC_CHECK_HEADERS([et/com_err.h kerberosv5/com_err.h])],
+        [_RRA_LIB_KRB5_CHECK_HEADER([et/com_err.h])
+         _RRA_LIB_KRB5_CHECK_HEADER([kerberosv5/com_err.h])])])
+
+dnl Check for the main Kerberos header.  Internal helper macro since we need
+dnl to do the same checks in multiple places.
+AC_DEFUN([_RRA_LIB_KRB5_CHECK_HEADER_KRB5],
+[AS_IF([test x"$rra_krb5_incroot" = x],
+     [AC_CHECK_HEADERS([krb5.h kerberosv5/krb5.h krb5/krb5.h])],
+     [_RRA_LIB_KRB5_CHECK_HEADER([krb5.h])
+      _RRA_LIB_KRB5_CHECK_HEADER([kerberosv5/krb5.h])
+      _RRA_LIB_KRB5_CHECK_HEADER([krb5/krb5.h])])])
+
 dnl Does the appropriate library checks for reduced-dependency Kerberos
 dnl linkage.  The single argument, if true, says to fail if Kerberos could not
 dnl be found.
@@ -122,10 +141,7 @@ AC_DEFUN([_RRA_LIB_KRB5_REDUCED],
      [AS_IF([test x"$1" = xtrue],
          [AC_MSG_ERROR([cannot find usable Kerberos library])])])
  LIBS="$KRB5_LIBS $LIBS"
- AS_IF([test x"$rra_krb5_incroot" = x],
-     [AC_CHECK_HEADERS([krb5.h krb5/krb5.h])],
-     [_RRA_LIB_KRB5_CHECK_HEADER([krb5.h])
-      _RRA_LIB_KRB5_CHECK_HEADER([krb5/krb5.h])])
+ _RRA_LIB_KRB5_CHECK_HEADER_KRB5
  AC_CHECK_FUNCS([krb5_get_error_message],
      [AC_CHECK_FUNCS([krb5_free_error_message])],
      [AC_CHECK_FUNCS([krb5_get_error_string], [],
@@ -140,7 +156,7 @@ AC_DEFUN([_RRA_LIB_KRB5_REDUCED],
                      [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_CHECK_HEADER_COM_ERR])])])])
  RRA_LIB_KRB5_RESTORE])
 
 dnl Does the appropriate library checks for Kerberos linkage when we don't
@@ -187,10 +203,7 @@ AC_DEFUN([_RRA_LIB_KRB5_MANUAL],
         [$rra_krb5_extra])],
     [-lasn1 -lcom_err -lcrypto $rra_krb5_extra])
  LIBS="$KRB5_LIBS $LIBS"
- AS_IF([test x"$rra_krb5_incroot" = x],
-     [AC_CHECK_HEADERS([krb5.h krb5/krb5.h])],
-     [_RRA_LIB_KRB5_CHECK_HEADER([krb5.h])
-      _RRA_LIB_KRB5_CHECK_HEADER([krb5/krb5.h])])
+ _RRA_LIB_KRB5_CHECK_HEADER_KRB5
  AC_CHECK_FUNCS([krb5_get_error_message],
      [AC_CHECK_FUNCS([krb5_free_error_message])],
      [AC_CHECK_FUNCS([krb5_get_error_string], [],
@@ -198,7 +211,7 @@ AC_DEFUN([_RRA_LIB_KRB5_MANUAL],
              [AC_CHECK_FUNCS([krb5_svc_get_msg],
                  [AC_CHECK_HEADERS([ibm_svc/krb5_svc.h], [], [],
                      [RRA_INCLUDES_KRB5])],
-                 [AC_CHECK_HEADERS([et/com_err.h])])])])])
+                 [_RRA_LIB_KRB5_CHECK_HEADER_COM_ERR])])])])
  RRA_LIB_KRB5_RESTORE])
 
 dnl Sanity-check the results of krb5-config and be sure we can really link a
@@ -222,10 +235,7 @@ AC_DEFUN([_RRA_LIB_KRB5_CONFIG],
 [RRA_KRB5_CONFIG([${rra_krb5_root}], [krb5], [KRB5],
     [_RRA_LIB_KRB5_CHECK([$1])
      RRA_LIB_KRB5_SWITCH
-     AS_IF([test x"$rra_krb5_incroot" = x],
-         [AC_CHECK_HEADERS([krb5.h krb5/krb5.h])],
-         [_RRA_LIB_KRB5_CHECK_HEADER([krb5.h])
-          _RRA_LIB_KRB5_CHECK_HEADER([krb5/krb5.h])])
+     _RRA_LIB_KRB5_CHECK_HEADER_KRB5
      AC_CHECK_FUNCS([krb5_get_error_message],
          [AC_CHECK_FUNCS([krb5_free_error_message])],
          [AC_CHECK_FUNCS([krb5_get_error_string], [],
@@ -233,7 +243,7 @@ AC_DEFUN([_RRA_LIB_KRB5_CONFIG],
                  [AC_CHECK_FUNCS([krb5_svc_get_msg],
                      [AC_CHECK_HEADERS([ibm_svc/krb5_svc.h], [], [],
                          [RRA_INCLUDES_KRB5])],
-                     [AC_CHECK_HEADERS([et/com_err.h])])])])])
+                     [_RRA_LIB_KRB5_CHECK_HEADER_COM_ERR])])])])
      RRA_LIB_KRB5_RESTORE],
     [_RRA_LIB_KRB5_PATHS
      _RRA_LIB_KRB5_MANUAL([$1])])])
index eb2b713e55b3fd5f023f07c870aed588e813288f..9693842d6c82cf773ae45010c279af35cce4e42e 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <config.h>
+#include <portable/macros.h>
 #include <portable/system.h>
 
 #include <errno.h>
  * with the system versions.
  */
 #if TESTING
+# undef asprintf
+# undef vasprintf
 # define asprintf test_asprintf
 # define vasprintf test_vasprintf
 int test_asprintf(char **, const char *, ...)
     __attribute__((__format__(printf, 2, 3)));
-int test_vasprintf(char **, const char *, va_list);
+int test_vasprintf(char **, const char *, va_list)
+    __attribute__((__format__(printf, 2, 0)));
 #endif
 
 
index b1c8b8d1f5b0aa2d05b26a6ee306513145c0b45b..c8309a4640e65e36948ecf91a32953ff4429ff2b 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <config.h>
 #include <portable/krb5.h>
+#include <portable/macros.h>
 #include <portable/system.h>
 
 #include <errno.h>
@@ -33,6 +34,8 @@
 #   include <ibm_svc/krb5_svc.h>
 #  elif defined(HAVE_ET_COM_ERR_H)
 #   include <et/com_err.h>
+#  elif defined(HAVE_KERBEROSV5_COM_ERR_H)
+#   include <kerberosv5/com_err.h>
 #  else
 #   include <com_err.h>
 #  endif
index 6dfffd55dd86f1e5842e3ba66b3ec18cc186909f..34f960e449d5fb99a51908e606017e5f1eec210a 100644 (file)
 #endif
 #include <portable/macros.h>
 
-#ifdef HAVE_KRB5_H
+#if defined(HAVE_KRB5_H)
 # include <krb5.h>
+#elif defined(HAVE_KERBEROSV5_KRB5_H)
+# include <kerberosv5/krb5.h>
 #else
 # include <krb5/krb5.h>
 #endif
index b5093f53bdd004843af5c0cb12523a32d9315596..d4cc2ccee0dcbb743068119d9589c4ceebe57876 100644 (file)
@@ -37,7 +37,8 @@
  * variadic macro support.
  */
 #if !defined(__attribute__) && !defined(__alloc_size__)
-# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)
+# if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)) \
+    && !defined(__clang__)
 #  define __alloc_size__(spec, args...) /* empty */
 # endif
 #endif
index 2cbfe081249ff735e7dd890f6492ca7d862179ac..7c733a48cf4cbd14e1118e831a996c3320945efc 100644 (file)
 
 #include <errno.h>
 #include <fcntl.h>
-#include <sys/time.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <time.h>
 
 /*
  * If we're running the test suite, rename mkstemp to avoid conflicts with the
index 7d40a7a25d1a0a575a9e17c878128a1d65375ee2..e9404e93fd6d659a063b79bf0703612837e4f090 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * Replacement for a missing reallocarray.
  *
- * Provides the same functionality as the OpenBSD library function reallocrray
- * for those systems that don't have it.  This function is the same as
- * realloc, but takes the size arguments in the same form as calloc and checks
- * for overflow so that the caller doesn't need to.
+ * Provides the same functionality as the OpenBSD library function
+ * reallocarray for those systems that don't have it.  This function is the
+ * same as realloc, but takes the size arguments in the same form as calloc
+ * and checks for overflow so that the caller doesn't need to.
  *
  * 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/>.
index 472282ac1b8794f7b51d88d373ff918d32a06ead..f1f6db4cd9649a9b91ab55a9e5b320dd2c877f26 100644 (file)
@@ -26,6 +26,7 @@
  * the system version.
  */
 #if TESTING
+# undef setenv
 # define setenv test_setenv
 int test_setenv(const char *, const char *, int);
 #endif
@@ -34,29 +35,22 @@ int
 setenv(const char *name, const char *value, int overwrite)
 {
     char *envstring;
-    size_t size;
 
+    /* Do nothing if not overwriting and the variable is already set. */
     if (!overwrite && getenv(name) != NULL)
         return 0;
 
-    /*
-     * Allocate memory for the environment string.  We intentionally don't use
-     * the xmalloc family of allocation routines here, since the intention is
-     * to provide a replacement for the standard library function that sets
-     * errno and returns in the event of a memory allocation failure.
-     */
-    size = strlen(name) + 1 + strlen(value) + 1;
-    envstring = malloc(size);
-    if (envstring == NULL)
-        return -1;
-
     /*
      * Build the environment string and add it to the environment using
      * putenv.  Systems without putenv lose, but XPG4 requires it.
+     *
+     * We intentionally don't use the xmalloc family of allocation routines
+     * here, since the intention is to provide a replacement for the standard
+     * library function that sets errno and returns in the event of a memory
+     * allocation failure.
      */
-    strlcpy(envstring, name, size);
-    strlcat(envstring, "=", size);
-    strlcat(envstring, value, size);
+    if (asprintf(&envstring, "%s=%s", name, value) < 0)
+        return -1;
     return putenv(envstring);
 
     /*
index c35ad807671286144845be9cb9c4570bdbe86801..9818acdd46a4f420b0734165e09dc1ee3ddd8694 100644 (file)
@@ -19,6 +19,8 @@
  * conflicts with the system version.
  */
 #if TESTING
+# undef snprintf
+# undef vsnprintf
 # define snprintf test_snprintf
 # define vsnprintf test_vsnprintf
 #endif
index 9c8686ded045aa887f85c525c621baf97a6d7316..613d3f2e9e28925ce09b88e2d79847dabe44864a 100644 (file)
@@ -31,6 +31,7 @@
  * the system version.
  */
 #if TESTING
+# undef strlcat
 # define strlcat test_strlcat
 size_t test_strlcat(char *, const char *, size_t);
 #endif
index 592e3ee8957bee3aa27979fa659471bc855836b4..60fdab3f0e68b36d9c0ea4a2b5e23624f7186a86 100644 (file)
@@ -30,6 +30,7 @@
  * the system version.
  */
 #if TESTING
+# undef strlcpy
 # define strlcpy test_strlcpy
 size_t test_strlcpy(char *, const char *, size_t);
 #endif
index 544b2deacc2eec1f034a58c461c39124aaeefa5d..581e46c08eb6bad0b977fb46e368961b22b110db 100644 (file)
@@ -136,10 +136,10 @@ extern void *reallocarray(void *, size_t, size_t);
 #if !HAVE_SETENV
 extern int setenv(const char *, const char *, int);
 #endif
-#if !HAVE_STRLCAT
+#if !HAVE_DECL_STRLCAT
 extern size_t strlcat(char *, const char *, size_t);
 #endif
-#if !HAVE_STRLCPY
+#if !HAVE_DECL_STRLCPY
 extern size_t strlcpy(char *, const char *, size_t);
 #endif
 
index c61c14aef1415c8b42892cb87568bc73080cc3dd..e556d956543213b2e2b5592d4b2af4d34876ca45 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <config.h>
+#include <portable/macros.h>
 #include <portable/system.h>
 
 #include <tests/tap/basic.h>
index 270d2e1831743b5366c66cf318ca7a38b317dddd..cc8cf00ee3f44040f5a7e619ac21dfa5c6c9be55 100644 (file)
@@ -26,7 +26,9 @@
  * Disable the requirement that format strings be literals.  We need variable
  * formats for easy testing.
  */
-#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2) || defined(__clang__)
+# pragma GCC diagnostic ignored "-Wformat-nonliteral"
+#endif
 
 /*
  * Intentionally don't add the printf attribute here since we pass a
index a9d237312c63c4d185b8832d0ed7f019a23353d2..42a73ea81a49a0be203c4bf1d02dbc0f3ad92363 100644 (file)
@@ -3,15 +3,19 @@
  *
  * Usage:
  *
- *      runtests [-b <build-dir>] [-s <source-dir>] <test-list>
- *      runtests -o [-b <build-dir>] [-s <source-dir>] <test>
+ *      runtests [-hv] [-b <build-dir>] [-s <source-dir>] -l <test-list>
+ *      runtests [-hv] [-b <build-dir>] [-s <source-dir>] <test> [<test> ...]
+ *      runtests -o [-h] [-b <build-dir>] [-s <source-dir>] <test>
  *
  * In the first case, expects a list of executables located in the given file,
  * one line per executable.  For each one, runs it as part of a test suite,
- * reporting results.  Test output should start with a line containing the
- * number of tests (numbered from 1 to this number), optionally preceded by
- * "1..", although that line may be given anywhere in the output.  Each
- * additional line should be in the following format:
+ * reporting results.  In the second case, use the same infrastructure, but
+ * run only the tests listed on the command line.
+ *
+ * Test output should start with a line containing the number of tests
+ * (numbered from 1 to this number), optionally preceded by "1..", although
+ * that line may be given anywhere in the output.  Each additional line should
+ * be in the following format:
  *
  *      ok <number>
  *      not ok <number>
  * directories.  These paths can also be set with the -b and -s command-line
  * options, which will override anything set at build time.
  *
+ * If the -v option is given, or the C_TAP_VERBOSE environment variable is set,
+ * display the full output of each test as it runs rather than showing a
+ * summary of the results of each test.
+ *
  * Any bug reports, bug fixes, and improvements are very much welcome and
  * should be sent to the e-mail address below.  This program is part of C TAP
  * Harness <http://www.eyrie.org/~eagle/software/c-tap-harness/>.
  *
  * Copyright 2000, 2001, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
- *     2014 Russ Allbery <eagle@eyrie.org>
+ *     2014, 2015 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"),
@@ -146,6 +154,12 @@ enum test_status {
     TEST_INVALID
 };
 
+/* Really, just a boolean, but this is more self-documenting. */
+enum test_verbose {
+    CONCISE = 0,
+    VERBOSE = 1
+};
+
 /* Indicates the state of our plan. */
 enum plan_status {
     PLAN_INIT,                  /* Nothing seen yet. */
@@ -192,16 +206,18 @@ struct testlist {
  * 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%s";
-static const char usage_extra[] = "\
+Usage: %s [-hv] [-b <build-dir>] [-s <source-dir>] <test> ...\n\
+       %s [-hv] [-b <build-dir>] [-s <source-dir>] -l <test-list>\n\
+       %s -o [-h] [-b <build-dir>] [-s <source-dir>] <test>\n\
+\n\
 Options:\n\
     -b <build-dir>      Set the build directory to <build-dir>\n\
+%s";
+static const char usage_extra[] = "\
     -l <list>           Take the list of tests to run from <test-list>\n\
     -o                  Run a single test rather than a list of tests\n\
     -s <source-dir>     Set the source directory to <source-dir>\n\
+    -v                  Show the full output of each test\n\
 \n\
 runtests normally runs each test listed on the command line.  With the -l\n\
 option, it instead runs every test listed in a file.  With the -o option,\n\
@@ -246,8 +262,10 @@ Failed Set                 Fail/Total (%) Skip Stat  Failing Tests\n\
  * variadic macro support.
  */
 #if !defined(__attribute__) && !defined(__alloc_size__)
-# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)
-#  define __alloc_size__(spec, args...) /* empty */
+# if defined(__GNUC__) && !defined(__clang__)
+#  if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)
+#   define __alloc_size__(spec, args...) /* empty */
+#  endif
 # endif
 #endif
 
@@ -590,6 +608,21 @@ resize_results(struct testset *ts, unsigned long n)
 }
 
 
+/*
+ * Report an invalid test number and set the appropriate flags.  Pulled into a
+ * separate function since we do this in several places.
+ */
+static void
+invalid_test_number(struct testset *ts, long n, enum test_verbose verbose)
+{
+    if (!verbose)
+        test_backspace(ts);
+    printf("ABORTED (invalid test number %ld)\n", n);
+    ts->aborted = 1;
+    ts->reported = 1;
+}
+
+
 /*
  * Read the plan line of test output, which should contain the range of test
  * numbers.  We may initialize the testset structure here if we haven't yet
@@ -597,7 +630,7 @@ resize_results(struct testset *ts, unsigned long n)
  * continue, false otherwise.
  */
 static int
-test_plan(const char *line, struct testset *ts)
+test_plan(const char *line, struct testset *ts, enum test_verbose verbose)
 {
     long n;
 
@@ -654,10 +687,7 @@ test_plan(const char *line, struct testset *ts)
      * range.
      */
     if (ts->plan == PLAN_PENDING && (unsigned long) n < ts->count) {
-        test_backspace(ts);
-        printf("ABORTED (invalid test number %lu)\n", ts->count);
-        ts->aborted = 1;
-        ts->reported = 1;
+        invalid_test_number(ts, (long) ts->count, verbose);
         return 0;
     }
 
@@ -665,8 +695,8 @@ test_plan(const char *line, struct testset *ts)
      * Otherwise, allocated or resize the results if needed and update count,
      * and then record that we've seen a plan.
      */
-    resize_results(ts, n);
-    ts->count = n;
+    resize_results(ts, (unsigned long) n);
+    ts->count = (unsigned long) n;
     if (ts->plan == PLAN_INIT)
         ts->plan = PLAN_FIRST;
     else if (ts->plan == PLAN_PENDING)
@@ -682,7 +712,8 @@ test_plan(const char *line, struct testset *ts)
  * reported status.
  */
 static void
-test_checkline(const char *line, struct testset *ts)
+test_checkline(const char *line, struct testset *ts,
+               enum test_verbose verbose)
 {
     enum test_status status = TEST_PASS;
     const char *bail;
@@ -701,7 +732,8 @@ test_checkline(const char *line, struct testset *ts)
             length = strlen(bail);
             if (bail[length - 1] == '\n')
                 length--;
-            test_backspace(ts);
+            if (!verbose)
+                test_backspace(ts);
             printf("ABORTED (%.*s)\n", (int) length, bail);
             ts->reported = 1;
         }
@@ -722,14 +754,15 @@ test_checkline(const char *line, struct testset *ts)
 
     /* If we haven't yet seen a plan, look for one. */
     if (ts->plan == PLAN_INIT && isdigit((unsigned char)(*line))) {
-        if (!test_plan(line, ts))
+        if (!test_plan(line, ts, verbose))
             return;
     } else if (strncmp(line, "1..", 3) == 0) {
         if (ts->plan == PLAN_PENDING) {
-            if (!test_plan(line, ts))
+            if (!test_plan(line, ts, verbose))
                 return;
         } else {
-            test_backspace(ts);
+            if (!verbose)
+                test_backspace(ts);
             puts("ABORTED (multiple plans)");
             ts->aborted = 1;
             ts->reported = 1;
@@ -748,13 +781,14 @@ test_checkline(const char *line, struct testset *ts)
     errno = 0;
     number = strtol(line, &end, 10);
     if (errno != 0 || end == line)
-        number = ts->current + 1;
-    current = number;
-    if (number <= 0 || (current > ts->count && ts->plan == PLAN_FIRST)) {
-        test_backspace(ts);
-        printf("ABORTED (invalid test number %lu)\n", current);
-        ts->aborted = 1;
-        ts->reported = 1;
+        current = ts->current + 1;
+    else if (number <= 0) {
+        invalid_test_number(ts, number, verbose);
+        return;
+    } else
+        current = (unsigned long) number;
+    if (current > ts->count && ts->plan == PLAN_FIRST) {
+        invalid_test_number(ts, (long) current, verbose);
         return;
     }
 
@@ -783,7 +817,8 @@ test_checkline(const char *line, struct testset *ts)
 
     /* Make sure that the test number is in range and not a duplicate. */
     if (ts->results[current - 1] != TEST_INVALID) {
-        test_backspace(ts);
+        if (!verbose)
+            test_backspace(ts);
         printf("ABORTED (duplicate test number %lu)\n", current);
         ts->aborted = 1;
         ts->reported = 1;
@@ -799,13 +834,13 @@ test_checkline(const char *line, struct testset *ts)
     }
     ts->current = current;
     ts->results[current - 1] = status;
-    if (isatty(STDOUT_FILENO)) {
+    if (!verbose && isatty(STDOUT_FILENO)) {
         test_backspace(ts);
         if (ts->plan == PLAN_PENDING)
             outlen = printf("%lu/?", current);
         else
             outlen = printf("%lu/%lu", current, ts->count);
-        ts->length = (outlen >= 0) ? outlen : 0;
+        ts->length = (outlen >= 0) ? (unsigned int) outlen : 0;
         fflush(stdout);
     }
 }
@@ -821,7 +856,7 @@ test_checkline(const char *line, struct testset *ts)
  * disable this).
  */
 static unsigned int
-test_print_range(unsigned long first, unsigned long last, unsigned int chars,
+test_print_range(unsigned long first, unsigned long last, unsigned long chars,
                  unsigned int limit)
 {
     unsigned int needed = 0;
@@ -991,7 +1026,7 @@ test_analyze(struct testset *ts)
  * false otherwise.
  */
 static int
-test_run(struct testset *ts)
+test_run(struct testset *ts, enum test_verbose verbose)
 {
     pid_t testpid, child;
     int outfd, status;
@@ -1008,12 +1043,19 @@ test_run(struct testset *ts)
         sysdie("fdopen failed");
     }
 
-    /* Pass each line of output to test_checkline(). */
-    while (!ts->aborted && fgets(buffer, sizeof(buffer), output))
-        test_checkline(buffer, ts);
+    /*
+     * Pass each line of output to test_checkline(), and print the line if
+     * verbosity is requested.
+     */
+    while (!ts->aborted && fgets(buffer, sizeof(buffer), output)) {
+        if (verbose)
+            printf("%s", buffer);
+        test_checkline(buffer, ts, verbose);
+    }
     if (ferror(output) || ts->plan == PLAN_INIT)
         ts->aborted = 1;
-    test_backspace(ts);
+    if (!verbose)
+        test_backspace(ts);
 
     /*
      * Consume the rest of the test output, close the output descriptor,
@@ -1021,7 +1063,8 @@ test_run(struct testset *ts)
      * for eventual output.
      */
     while (fgets(buffer, sizeof(buffer), output))
-        ;
+        if (verbose)
+            printf("%s", buffer);
     fclose(output);
     child = waitpid(testpid, &ts->status, 0);
     if (child == (pid_t) -1) {
@@ -1129,7 +1172,7 @@ is_valid_test(const char *path)
 static char *
 find_test(const char *name, const char *source, const char *build)
 {
-    char *path;
+    char *path = NULL;
     const char *bases[3], *suffix, *base;
     unsigned int i, j;
     const char *suffixes[3] = { "-t", ".t", "" };
@@ -1161,7 +1204,8 @@ find_test(const char *name, const char *source, const char *build)
 
 /*
  * Read a list of tests from a file, returning the list of tests as a struct
- * testlist.  Reports an error to standard error and exits if the list of
+ * testlist, or NULL if there were no tests (such as a file containing only
+ * comments).  Reports an error to standard error and exits if the list of
  * tests cannot be read.
  */
 static struct testlist *
@@ -1171,6 +1215,7 @@ read_test_list(const char *filename)
     unsigned int line;
     size_t length;
     char buffer[BUFSIZ];
+    const char *testname;
     struct testlist *listhead, *current;
 
     /* Create the initial container list that will hold our results. */
@@ -1193,6 +1238,15 @@ read_test_list(const char *filename)
             exit(1);
         }
         buffer[length] = '\0';
+
+        /* Skip comments, leading spaces, and blank lines. */
+        testname = skip_whitespace(buffer);
+        if (strlen(testname) == 0)
+            continue;
+        if (testname[0] == '#')
+            continue;
+
+        /* Allocate the new testset structure. */
         if (current == NULL)
             current = listhead;
         else {
@@ -1201,10 +1255,16 @@ read_test_list(const char *filename)
         }
         current->ts = xcalloc(1, sizeof(struct testset));
         current->ts->plan = PLAN_INIT;
-        current->ts->file = xstrdup(buffer);
+        current->ts->file = xstrdup(testname);
     }
     fclose(file);
 
+    /* If there were no tests, current is still NULL. */
+    if (current == NULL) {
+        free(listhead);
+        return NULL;
+    }
+
     /* Return the results. */
     return listhead;
 }
@@ -1213,7 +1273,8 @@ read_test_list(const char *filename)
 /*
  * Build a list of tests from command line arguments.  Takes the argv and argc
  * representing the command line arguments and returns a newly allocated test
- * list.  The caller is responsible for freeing.
+ * list, or NULL if there were no tests.  The caller is responsible for
+ * freeing.
  */
 static struct testlist *
 build_test_list(char *argv[], int argc)
@@ -1238,6 +1299,12 @@ build_test_list(char *argv[], int argc)
         current->ts->file = xstrdup(argv[i]);
     }
 
+    /* If there were no tests, current is still NULL. */
+    if (current == NULL) {
+        free(listhead);
+        return NULL;
+    }
+
     /* Return the results. */
     return listhead;
 }
@@ -1263,11 +1330,11 @@ free_testset(struct testset *ts)
  * frees the test list that's passed in.
  */
 static int
-test_batch(struct testlist *tests, const char *source, const char *build)
+test_batch(struct testlist *tests, const char *source, const char *build,
+           enum test_verbose verbose)
 {
-    size_t length;
-    unsigned int i;
-    unsigned int longest = 0;
+    size_t length, i;
+    size_t longest = 0;
     unsigned int count = 0;
     struct testset *ts;
     struct timeval start, end;
@@ -1306,15 +1373,20 @@ test_batch(struct testlist *tests, const char *source, const char *build)
 
         /* Print out the name of the test file. */
         fputs(ts->file, stdout);
-        for (i = strlen(ts->file); i < longest; i++)
-            putchar('.');
+        if (verbose)
+            fputs("\n\n", stdout);
+        else
+            for (i = strlen(ts->file); i < longest; i++)
+                putchar('.');
         if (isatty(STDOUT_FILENO))
             fflush(stdout);
 
         /* Run the test. */
         ts->path = find_test(ts->file, source, build);
-        succeeded = test_run(ts);
+        succeeded = test_run(ts, verbose);
         fflush(stdout);
+        if (verbose)
+            putchar('\n');
 
         /* Record cumulative statistics. */
         aborted += ts->aborted;
@@ -1416,23 +1488,25 @@ main(int argc, char *argv[])
     int option;
     int status = 0;
     int single = 0;
+    enum test_verbose verbose = CONCISE;
     char *source_env = NULL;
     char *build_env = NULL;
+    const char *program;
     const char *shortlist;
     const char *list = NULL;
     const char *source = SOURCE;
     const char *build = BUILD;
     struct testlist *tests;
 
-    while ((option = getopt(argc, argv, "b:hl:os:")) != EOF) {
+    program = argv[0];
+    while ((option = getopt(argc, argv, "b:hl:os:v")) != EOF) {
         switch (option) {
         case 'b':
             build = optarg;
             break;
         case 'h':
-            printf(usage_message, argv[0], argv[0], argv[0], usage_extra);
+            printf(usage_message, program, program, program, usage_extra);
             exit(0);
-            break;
         case 'l':
             list = optarg;
             break;
@@ -1442,6 +1516,9 @@ main(int argc, char *argv[])
         case 's':
             source = optarg;
             break;
+        case 'v':
+            verbose = VERBOSE;
+            break;
         default:
             exit(1);
         }
@@ -1449,10 +1526,17 @@ 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], usage_extra);
+        fprintf(stderr, usage_message, program, program, program, usage_extra);
         exit(1);
     }
 
+    /*
+     * If C_TAP_VERBOSE is set in the environment, that also turns on verbose
+     * mode.
+     */
+    if (getenv("C_TAP_VERBOSE") != NULL)
+        verbose = VERBOSE;
+
     /* Set SOURCE and BUILD environment variables. */
     if (source != NULL) {
         source_env = concat("SOURCE=", source, (const char *) 0);
@@ -1476,10 +1560,10 @@ main(int argc, char *argv[])
             shortlist++;
         printf(banner, shortlist);
         tests = read_test_list(list);
-        status = test_batch(tests, source, build) ? 0 : 1;
+        status = test_batch(tests, source, build, verbose) ? 0 : 1;
     } else {
         tests = build_test_list(argv, argc);
-        status = test_batch(tests, source, build) ? 0 : 1;
+        status = test_batch(tests, source, build, verbose) ? 0 : 1;
     }
 
     /* For valgrind cleanliness, free all our memory. */
index 92a749b235a953a2081361ddd6099ffad009fe77..4f8be04c4c7935c84139e1bd3180768536bfe525 100644 (file)
@@ -12,7 +12,8 @@
  * 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, 2013, 2014 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015
+ *     Russ Allbery <eagle@eyrie.org>
  * Copyright 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2011, 2012, 2013, 2014
  *     The Board of Trustees of the Leland Stanford Junior University
  *
@@ -105,7 +106,7 @@ static struct cleanup_func *cleanup_funcs = NULL;
 /*
  * Registered diag files.  Any output found in these files will be printed out
  * as if it were passed to diag() before any other output we do.  This allows
- * background processes to log to a file and have that output interleved with
+ * background processes to log to a file and have that output interleaved with
  * the test output.
  */
 struct diag_file {
@@ -192,7 +193,7 @@ check_diag_files(void)
     struct diag_file *file;
     fpos_t where;
     size_t length;
-    int incomplete;
+    int size, incomplete;
 
     /*
      * Walk through each file and read each line of output available.  The
@@ -216,7 +217,8 @@ check_diag_files(void)
         /* Continue until we get EOF or an incomplete line of data. */
         incomplete = 0;
         while (!feof(file->file) && !incomplete) {
-            if (fgets(file->buffer, file->bufsize, file->file) == NULL) {
+            size = file->bufsize > INT_MAX ? INT_MAX : (int) file->bufsize;
+            if (fgets(file->buffer, size, file->file) == NULL) {
                 if (ferror(file->file))
                     sysbail("cannot read from %s", file->name);
                 continue;
@@ -807,7 +809,7 @@ bstrndup(const char *s, size_t n)
     /* Don't assume that the source string is nul-terminated. */
     for (p = s; (size_t) (p - s) < n && *p != '\0'; p++)
         ;
-    length = p - s;
+    length = (size_t) (p - s);
     copy = malloc(length + 1);
     if (p == NULL)
         sysbail("failed to strndup %lu bytes", (unsigned long) length);
index c002df98aa80abc2d84c18be6df693866d34fc69..4ecaaec8e1e30a84d43d0fe79af35279f9290e10 100644 (file)
@@ -4,7 +4,8 @@
  * 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, 2013, 2014 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015
+ *     Russ Allbery <eagle@eyrie.org>
  * Copyright 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2011, 2012, 2014
  *     The Board of Trustees of the Leland Stanford Junior University
  *
@@ -72,7 +73,8 @@ void skip_all(const char *format, ...)
  */
 int ok(int success, const char *format, ...)
     __attribute__((__format__(printf, 2, 3)));
-int okv(int success, const char *format, va_list args);
+int okv(int success, const char *format, va_list args)
+    __attribute__((__format__(printf, 2, 0)));
 void skip(const char *reason, ...)
     __attribute__((__format__(printf, 1, 2)));
 
@@ -155,7 +157,7 @@ void test_tmpdir_free(char *path);
  * 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 two argument, an int that
+ * The function must return void and will be passed two arguments: an int that
  * will be true if the test completed successfully and false otherwise, and an
  * int that will be true if the cleanup function is run in the primary process
  * (the one that called plan or plan_lazy) and false otherwise.
index 578a8583cb50518310462fd228706a106973e956..6a5025a1804f74ee734f564ba47de946a87337eb 100644 (file)
@@ -55,7 +55,9 @@
  * Disable the requirement that format strings be literals, since it's easier
  * to handle the possible patterns for kinit commands as an array.
  */
-#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2) || defined(__clang__)
+# pragma GCC diagnostic ignored "-Wformat-nonliteral"
+#endif
 
 
 /*
@@ -219,6 +221,8 @@ kerberos_free(void)
         free(config->userprinc);
         free(config->username);
         free(config->password);
+        free(config->pkinit_principal);
+        free(config->pkinit_cert);
         free(config);
         config = NULL;
     }
@@ -350,6 +354,31 @@ kerberos_setup(enum kerberos_needs needs)
     }
     test_file_path_free(path);
 
+    /*
+     * If we have PKINIT configuration, read it and fill out the relevant
+     * members of our config struct.
+     */
+    path = test_file_path("config/pkinit-principal");
+    if (path != NULL)
+        file = fopen(path, "r");
+    if (file != NULL) {
+        if (fgets(buffer, sizeof(buffer), file) == NULL)
+            bail("cannot read %s", path);
+        if (buffer[strlen(buffer) - 1] != '\n')
+            bail("no newline in %s", path);
+        buffer[strlen(buffer) - 1] = '\0';
+        fclose(file);
+        test_file_path_free(path);
+        path = test_file_path("config/pkinit-cert");
+        if (path != NULL) {
+            config->pkinit_principal = bstrdup(buffer);
+            config->pkinit_cert = bstrdup(path);
+        }
+    }
+    test_file_path_free(path);
+    if (config->pkinit_cert == NULL && (needs & TAP_KRB_NEEDS_PKINIT) != 0)
+        skip_all("PKINIT tests not configured");
+
     /*
      * Register the cleanup function so that the caller doesn't have to do
      * explicit cleanup.
index 8be0add4c10cef80bcf2a99d7a02843b0623bc50..26f45f900143c12ae758ac96d6f28f1a31999eb8 100644 (file)
@@ -46,17 +46,21 @@ struct kerberos_config {
     char *username;             /* The local (non-realm) part of principal. */
     char *realm;                /* The realm part of the principal. */
     char *password;             /* The password. */
+    char *pkinit_principal;     /* Principal for PKINIT authentication. */
+    char *pkinit_cert;          /* Path to certificates for PKINIT. */
 };
 
 /*
  * Whether to skip all tests (by calling skip_all) in kerberos_setup if
- * certain configuration information isn't available.
+ * certain configuration information isn't available.  "_BOTH" means that the
+ * tests require both keytab and password, but PKINIT is not required.
  */
 enum kerberos_needs {
     TAP_KRB_NEEDS_NONE     = 0x00,
     TAP_KRB_NEEDS_KEYTAB   = 0x01,
     TAP_KRB_NEEDS_PASSWORD = 0x02,
-    TAP_KRB_NEEDS_BOTH     = 0x01 | 0x02
+    TAP_KRB_NEEDS_BOTH     = 0x01 | 0x02,
+    TAP_KRB_NEEDS_PKINIT   = 0x04
 };
 
 BEGIN_DECLS
index 04cc420ddc76b7b08cd89fc00693251d8b9362d5..139cff0af2d181da4fd88ed966e143ca3e91c521 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, 2013 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2008, 2012, 2013, 2015 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"),
  * variadic macro support.
  */
 #if !defined(__attribute__) && !defined(__alloc_size__)
-# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)
-#  define __alloc_size__(spec, args...) /* empty */
+# if defined(__GNUC__) && !defined(__clang__)
+#  if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)
+#   define __alloc_size__(spec, args...) /* empty */
+#  endif
 # endif
 #endif
 
index 45b05664c05988fffa80cbde706bc4a478c3930e..9c28789ba906340248ffc4aa08182040b932e44c 100644 (file)
@@ -8,7 +8,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 2002, 2004, 2005 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2002, 2004, 2005, 2015 Russ Allbery <eagle@eyrie.org>
  * Copyright 2006, 2007, 2009, 2012, 2014
  *     The Board of Trustees of the Leland Stanford Junior University
  *
@@ -47,7 +47,7 @@ char *errors = NULL;
  * An error handler that appends all errors to the errors global.  Used by
  * error_capture.
  */
-static void
+static void __attribute__((__format__(printf, 2, 0)))
 message_log_buffer(int len UNUSED, const char *fmt, va_list args,
                    int error UNUSED)
 {
index 6461fb456af2117d520b8df07eeabb80134083b9..8c22324c20632f7b1244f1a91e027baeb0532f2c 100644 (file)
 # include <sys/select.h>
 #endif
 #include <sys/stat.h>
-#include <sys/time.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
 #include <sys/wait.h>
+#include <time.h>
 
 #include <tests/tap/basic.h>
 #include <tests/tap/process.h>
@@ -229,6 +232,10 @@ process_free(struct process *process)
 {
     struct process **prev;
 
+    /* Do nothing if called with a NULL argument. */
+    if (process == NULL)
+        return;
+
     /* Remove the process from the global list. */
     prev = &processes;
     while (*prev != NULL && *prev != process)
index cc51945da6f27d06c25a292d18a9fb4afd82b6c3..d58f75d6f002a239e26b02191f6273ebcc7df8f5 100644 (file)
@@ -42,7 +42,7 @@ BEGIN_DECLS
 void basprintf(char **, const char *, ...)
     __attribute__((__nonnull__, __format__(printf, 2, 3)));
 void bvasprintf(char **, const char *, va_list)
-    __attribute__((__nonnull__));
+    __attribute__((__nonnull__, __format__(printf, 2, 0)));
 
 END_DECLS
 
index f60fa6a9698af051b0977903116bff426a407559..109831485ea068b07f7e19aa680dfefeb9c8c3f5 100644 (file)
@@ -5,7 +5,7 @@
  * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
  *
  * Written by Russ Allbery <eagle@eyrie.org>
- * Copyright 2002, 2004, 2005 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2002, 2004, 2005, 2015 Russ Allbery <eagle@eyrie.org>
  * Copyright 2009, 2010, 2011, 2012
  *     The Board of Trustees of the Leland Stanford Junior University
  *
@@ -92,7 +92,8 @@ static void test11(void *data UNUSED) {
     sysdie("fatal");
 }
 
-static void log_msg(size_t len, const char *format, va_list args, int error) {
+static void __attribute__((__format__(printf, 2, 0)))
+log_msg(size_t len, const char *format, va_list args, int error) {
     fprintf(stderr, "%lu %d ", (unsigned long) len, error);
     vfprintf(stderr, format, args);
     fprintf(stderr, "\n");
index d52c44873f33368fc041359d883dd53768bb0af8..af604edb84d1f606cb704a53c3a49e94ed40d65c 100755 (executable)
@@ -99,46 +99,46 @@ ok_xmalloc "vasprintf large"    0 "" "v" "30000000" "0"
 # We assume that there are enough miscellaneous allocations that an allocation
 # exactly as large as the limit will always fail.
 ok_xmalloc "malloc fail" 1 \
-    "failed to malloc 30000000 bytes at xmalloc.c line 38" \
+    "failed to malloc 30000000 bytes at xmalloc.c line 41" \
     "m" "30000000" "30000000"
 ok_xmalloc "realloc fail" 1 \
-    "failed to realloc 30000000 bytes at xmalloc.c line 66" \
+    "failed to realloc 30000000 bytes at xmalloc.c line 69" \
     "r" "30000000" "30000000"
 ok_xmalloc "reallocarray fail" 1 \
-    "failed to reallocarray 30000000 bytes at xmalloc.c line 96" \
+    "failed to reallocarray 30000000 bytes at xmalloc.c line 99" \
     "y" "30000000" "30000000"
 ok_xmalloc "strdup fail" 1 \
-    "failed to strdup 30000000 bytes at xmalloc.c line 127" \
+    "failed to strdup 30000000 bytes at xmalloc.c line 130" \
     "s" "30000000" "30000000"
 ok_xmalloc "strndup fail" 1 \
-    "failed to strndup 30000000 bytes at xmalloc.c line 173" \
+    "failed to strndup 30000000 bytes at xmalloc.c line 176" \
     "n" "30000000" "30000000"
 ok_xmalloc "calloc fail" 1 \
-    "failed to calloc 30000000 bytes at xmalloc.c line 197" \
+    "failed to calloc 30000000 bytes at xmalloc.c line 200" \
     "c" "30000000" "30000000"
 ok_xmalloc "asprintf fail" 1 \
-    "failed to asprintf 30000000 bytes at xmalloc.c line 221" \
+    "failed to asprintf 30000000 bytes at xmalloc.c line 224" \
     "a" "30000000" "30000000"
 ok_xmalloc "vasprintf fail" 1 \
-    "failed to vasprintf 30000000 bytes at xmalloc.c line 240" \
+    "failed to vasprintf 30000000 bytes at xmalloc.c line 243" \
     "v" "30000000" "30000000"
 
 # Check our custom error handler.
-ok_xmalloc "malloc custom"       1 "malloc 30000000 xmalloc.c 38" \
+ok_xmalloc "malloc custom"       1 "malloc 30000000 xmalloc.c 41" \
     "M" "30000000" "30000000"
-ok_xmalloc "realloc custom"      1 "realloc 30000000 xmalloc.c 66" \
+ok_xmalloc "realloc custom"      1 "realloc 30000000 xmalloc.c 69" \
     "R" "30000000" "30000000"
-ok_xmalloc "reallocarray custom" 1 "reallocarray 30000000 xmalloc.c 96" \
+ok_xmalloc "reallocarray custom" 1 "reallocarray 30000000 xmalloc.c 99" \
     "Y" "30000000" "30000000"
-ok_xmalloc "strdup custom"       1 "strdup 30000000 xmalloc.c 127" \
+ok_xmalloc "strdup custom"       1 "strdup 30000000 xmalloc.c 130" \
     "S" "30000000" "30000000"
-ok_xmalloc "strndup custom"      1 "strndup 30000000 xmalloc.c 173" \
+ok_xmalloc "strndup custom"      1 "strndup 30000000 xmalloc.c 176" \
     "N" "30000000" "30000000"
-ok_xmalloc "calloc custom"       1 "calloc 30000000 xmalloc.c 197" \
+ok_xmalloc "calloc custom"       1 "calloc 30000000 xmalloc.c 200" \
     "C" "30000000" "30000000"
-ok_xmalloc "asprintf custom"     1 "asprintf 30000000 xmalloc.c 221" \
+ok_xmalloc "asprintf custom"     1 "asprintf 30000000 xmalloc.c 224" \
     "A" "30000000" "30000000"
-ok_xmalloc "vasprintf custom"    1 "vasprintf 30000000 xmalloc.c 240" \
+ok_xmalloc "vasprintf custom"    1 "vasprintf 30000000 xmalloc.c 243" \
     "V" "30000000" "30000000"
 
 # Check the smaller ones again just for grins.
index e22261203ec9cf0f25081b70d0c54afb606edb3c..84ba0812aa21244ac6466b4bcccf7b6fd77fd31c 100644 (file)
 
 #include <ctype.h>
 #include <errno.h>
-#include <sys/time.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <time.h>
 
 /* Linux requires sys/time.h be included before sys/resource.h. */
 #include <sys/resource.h>
@@ -261,7 +264,7 @@ test_asprintf(size_t size)
 
 
 /* Wrapper around vasprintf to do the va_list stuff. */
-static void
+static void __attribute__((__format__(printf, 2, 3)))
 xvasprintf_wrapper(char **strp, const char *format, ...)
 {
     va_list args;
index d071793a807580cf2ecf190cc2ba3f86a5f9bd53..4a773a2dafe34f0e9ec296b3332f7feb4c6df69a 100644 (file)
 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
 #define ARRAY_END(array)  (&(array)[ARRAY_SIZE(array)])
 
+/* Used to name the elements of the array passed to pipe. */
+#define PIPE_READ  0
+#define PIPE_WRITE 1
+
 /* Used for unused parameters to silence gcc warnings. */
 #define UNUSED __attribute__((__unused__))
 
index a43d962ad63fb9c6ce7ae0f6b508f5c7dab82191..b5c2dbabcf8e7ba745465df66863fd407f345bb3 100644 (file)
@@ -225,7 +225,7 @@ message_log_stderr(size_t len UNUSED, const char *fmt, va_list args, int err)
  * This needs further attention on Windows.  For example, it currently doesn't
  * log the errno information.
  */
-static void
+static void __attribute__((__format__(printf, 3, 0)))
 message_log_syslog(int pri, size_t len, const char *fmt, va_list args, int err)
 {
     char *buffer;
index 8c731b7169aabe4058f0d089b61bbb2c46cdf29f..cf91ba75a6bed96d1db590c6c9bbb0b5404a2680 100644 (file)
@@ -84,24 +84,25 @@ void message_handlers_reset(void);
  * argument list, and the errno setting if any.
  */
 void message_log_stdout(size_t, const char *, va_list, int)
-    __attribute__((__nonnull__));
+    __attribute__((__format__(printf, 2, 0), __nonnull__));
 void message_log_stderr(size_t, const char *, va_list, int)
-    __attribute__((__nonnull__));
+    __attribute__((__format__(printf, 2, 0), __nonnull__));
 void message_log_syslog_debug(size_t, const char *, va_list, int)
-    __attribute__((__nonnull__));
+    __attribute__((__format__(printf, 2, 0), __nonnull__));
 void message_log_syslog_info(size_t, const char *, va_list, int)
-    __attribute__((__nonnull__));
+    __attribute__((__format__(printf, 2, 0), __nonnull__));
 void message_log_syslog_notice(size_t, const char *, va_list, int)
-    __attribute__((__nonnull__));
+    __attribute__((__format__(printf, 2, 0), __nonnull__));
 void message_log_syslog_warning(size_t, const char *, va_list, int)
-    __attribute__((__nonnull__));
+    __attribute__((__format__(printf, 2, 0), __nonnull__));
 void message_log_syslog_err(size_t, const char *, va_list, int)
-    __attribute__((__nonnull__));
+    __attribute__((__format__(printf, 2, 0), __nonnull__));
 void message_log_syslog_crit(size_t, const char *, va_list, int)
-    __attribute__((__nonnull__));
+    __attribute__((__format__(printf, 2, 0), __nonnull__));
 
 /* The type of a message handler. */
-typedef void (*message_handler_func)(size_t, const char *, va_list, int);
+typedef void (*message_handler_func)(size_t, const char *, va_list, int)
+    __attribute__((__format__(printf, 2, 0)));
 
 /* If non-NULL, called before exit and its return value passed to exit. */
 extern int (*message_fatal_cleanup)(void);
index 721447a9c99804b859e1f617d36ad8f32f4c4313..7fb040505415608de1da59692c112958a2f7ab8c 100644 (file)
@@ -12,7 +12,7 @@
  *      buffer = xmalloc(1024);
  *      xrealloc(buffer, 2048);
  *      free(buffer);
- *      buffer = xcalloc(1024);
+ *      buffer = xcalloc(1, 1024);
  *      free(buffer);
  *      buffer = xstrdup(string);
  *      free(buffer);
@@ -62,6 +62,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 2015 Russ Allbery <eagle@eyrie.org>
  * Copyright 2012, 2013, 2014
  *     The Board of Trustees of the Leland Stanford Junior University
  * Copyright (c) 2004, 2005, 2006
@@ -258,6 +259,7 @@ x_asprintf(char **strp, const char *file, int line, const char *fmt, ...)
         status = vasprintf(strp, fmt, args_copy);
         va_end(args_copy);
     }
+    va_end(args);
 }
 #else /* !(HAVE_C99_VAMACROS || HAVE_GNU_VAMACROS) */
 void
@@ -280,5 +282,6 @@ x_asprintf(char **strp, const char *fmt, ...)
         status = vasprintf(strp, fmt, args_copy);
         va_end(args_copy);
     }
+    va_end(args);
 }
 #endif /* !(HAVE_C99_VAMACROS || HAVE_GNU_VAMACROS) */
index a4b4686eb1efd9587edbe23820d5ee8782d2220d..6aa9b93c604b579cb126b87f1bdf2e43530fde06 100644 (file)
@@ -90,7 +90,7 @@ char *x_strdup(const char *, const char *, int)
 char *x_strndup(const char *, size_t, const char *, int)
     __attribute__((__malloc__, __nonnull__));
 void x_vasprintf(char **, const char *, va_list, const char *, int)
-    __attribute__((__nonnull__));
+    __attribute__((__nonnull__, __format__(printf, 2, 0)));
 
 /* asprintf special case. */
 #if HAVE_C99_VAMACROS || HAVE_GNU_VAMACROS