summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Allbery <eagle@eyrie.org>2016-01-17 14:30:53 -0800
committerRuss Allbery <eagle@eyrie.org>2016-01-17 14:30:53 -0800
commit57a5a0095c3fe0f22dcbb9d99a82cc94f2b608c7 (patch)
treed7ab6169e2c5af79d97711964c34fbc1f5bbab13
parent884297fc439a4c3eba2365cdb810214dfc4f5799 (diff)
Update to rra-c-util 5.10 and C TAP Harness 3.4
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.
-rw-r--r--Makefile.am27
-rw-r--r--NEWS14
-rw-r--r--configure.ac8
-rw-r--r--m4/clang.m426
-rw-r--r--m4/krb5.m440
-rw-r--r--portable/asprintf.c6
-rw-r--r--portable/krb5-extra.c3
-rw-r--r--portable/krb5.h4
-rw-r--r--portable/macros.h3
-rw-r--r--portable/mkstemp.c5
-rw-r--r--portable/reallocarray.c8
-rw-r--r--portable/setenv.c24
-rw-r--r--portable/snprintf.c2
-rw-r--r--portable/strlcat.c1
-rw-r--r--portable/strlcpy.c1
-rw-r--r--portable/system.h4
-rw-r--r--tests/portable/asprintf-t.c1
-rw-r--r--tests/portable/snprintf-t.c4
-rw-r--r--tests/runtests.c204
-rw-r--r--tests/tap/basic.c12
-rw-r--r--tests/tap/basic.h8
-rw-r--r--tests/tap/kerberos.c31
-rw-r--r--tests/tap/kerberos.h8
-rw-r--r--tests/tap/macros.h8
-rw-r--r--tests/tap/messages.c4
-rw-r--r--tests/tap/process.c9
-rw-r--r--tests/tap/string.h2
-rw-r--r--tests/util/messages-t.c5
-rwxr-xr-xtests/util/xmalloc-t32
-rw-r--r--tests/util/xmalloc.c7
-rw-r--r--util/macros.h4
-rw-r--r--util/messages.c2
-rw-r--r--util/messages.h19
-rw-r--r--util/xmalloc.c5
-rw-r--r--util/xmalloc.h2
35 files changed, 380 insertions, 163 deletions
diff --git a/Makefile.am b/Makefile.am
index ccbaed0..5c87639 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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 fe4429d..e493200 100644
--- 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
diff --git a/configure.ac b/configure.ac
index 4efc5d7..f4541e2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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
index 0000000..0659d82
--- /dev/null
+++ b/m4/clang.m4
@@ -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])])
diff --git a/m4/krb5.m4 b/m4/krb5.m4
index 79ef961..683e30b 100644
--- a/m4/krb5.m4
+++ b/m4/krb5.m4
@@ -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])])])
diff --git a/portable/asprintf.c b/portable/asprintf.c
index eb2b713..9693842 100644
--- a/portable/asprintf.c
+++ b/portable/asprintf.c
@@ -19,6 +19,7 @@
*/
#include <config.h>
+#include <portable/macros.h>
#include <portable/system.h>
#include <errno.h>
@@ -28,11 +29,14 @@
* 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
diff --git a/portable/krb5-extra.c b/portable/krb5-extra.c
index b1c8b8d..c8309a4 100644
--- a/portable/krb5-extra.c
+++ b/portable/krb5-extra.c
@@ -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
diff --git a/portable/krb5.h b/portable/krb5.h
index 6dfffd5..34f960e 100644
--- a/portable/krb5.h
+++ b/portable/krb5.h
@@ -42,8 +42,10 @@
#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
diff --git a/portable/macros.h b/portable/macros.h
index b5093f5..d4cc2cc 100644
--- a/portable/macros.h
+++ b/portable/macros.h
@@ -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
diff --git a/portable/mkstemp.c b/portable/mkstemp.c
index 2cbfe08..7c733a4 100644
--- a/portable/mkstemp.c
+++ b/portable/mkstemp.c
@@ -23,7 +23,10 @@
#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
diff --git a/portable/reallocarray.c b/portable/reallocarray.c
index 7d40a7a..e9404e9 100644
--- a/portable/reallocarray.c
+++ b/portable/reallocarray.c
@@ -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/>.
diff --git a/portable/setenv.c b/portable/setenv.c
index 472282a..f1f6db4 100644
--- a/portable/setenv.c
+++ b/portable/setenv.c
@@ -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);
/*
diff --git a/portable/snprintf.c b/portable/snprintf.c
index c35ad80..9818acd 100644
--- a/portable/snprintf.c
+++ b/portable/snprintf.c
@@ -19,6 +19,8 @@
* conflicts with the system version.
*/
#if TESTING
+# undef snprintf
+# undef vsnprintf
# define snprintf test_snprintf
# define vsnprintf test_vsnprintf
#endif
diff --git a/portable/strlcat.c b/portable/strlcat.c
index 9c8686d..613d3f2 100644
--- a/portable/strlcat.c
+++ b/portable/strlcat.c
@@ -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
diff --git a/portable/strlcpy.c b/portable/strlcpy.c
index 592e3ee..60fdab3 100644
--- a/portable/strlcpy.c
+++ b/portable/strlcpy.c
@@ -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
diff --git a/portable/system.h b/portable/system.h
index 544b2de..581e46c 100644
--- a/portable/system.h
+++ b/portable/system.h
@@ -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
diff --git a/tests/portable/asprintf-t.c b/tests/portable/asprintf-t.c
index c61c14a..e556d95 100644
--- a/tests/portable/asprintf-t.c
+++ b/tests/portable/asprintf-t.c
@@ -16,6 +16,7 @@
*/
#include <config.h>
+#include <portable/macros.h>
#include <portable/system.h>
#include <tests/tap/basic.h>
diff --git a/tests/portable/snprintf-t.c b/tests/portable/snprintf-t.c
index 270d2e1..cc8cf00 100644
--- a/tests/portable/snprintf-t.c
+++ b/tests/portable/snprintf-t.c
@@ -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
diff --git a/tests/runtests.c b/tests/runtests.c
index a9d2373..42a73ea 100644
--- a/tests/runtests.c
+++ b/tests/runtests.c
@@ -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>
@@ -50,12 +54,16 @@
* 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
@@ -591,13 +609,28 @@ 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
* seen a test. Return true if initialization succeeded and the test should
* 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. */
diff --git a/tests/tap/basic.c b/tests/tap/basic.c
index 92a749b..4f8be04 100644
--- a/tests/tap/basic.c
+++ b/tests/tap/basic.c
@@ -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);
diff --git a/tests/tap/basic.h b/tests/tap/basic.h
index c002df9..4ecaaec 100644
--- a/tests/tap/basic.h
+++ b/tests/tap/basic.h
@@ -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.
diff --git a/tests/tap/kerberos.c b/tests/tap/kerberos.c
index 578a858..6a5025a 100644
--- a/tests/tap/kerberos.c
+++ b/tests/tap/kerberos.c
@@ -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;
}
@@ -351,6 +355,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.
*/
diff --git a/tests/tap/kerberos.h b/tests/tap/kerberos.h
index 8be0add..26f45f9 100644
--- a/tests/tap/kerberos.h
+++ b/tests/tap/kerberos.h
@@ -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
diff --git a/tests/tap/macros.h b/tests/tap/macros.h
index 04cc420..139cff0 100644
--- a/tests/tap/macros.h
+++ b/tests/tap/macros.h
@@ -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"),
@@ -53,8 +53,10 @@
* 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
diff --git a/tests/tap/messages.c b/tests/tap/messages.c
index 45b0566..9c28789 100644
--- a/tests/tap/messages.c
+++ b/tests/tap/messages.c
@@ -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)
{
diff --git a/tests/tap/process.c b/tests/tap/process.c
index 6461fb4..8c22324 100644
--- a/tests/tap/process.c
+++ b/tests/tap/process.c
@@ -47,8 +47,11 @@
# 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)
diff --git a/tests/tap/string.h b/tests/tap/string.h
index cc51945..d58f75d 100644
--- a/tests/tap/string.h
+++ b/tests/tap/string.h
@@ -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
diff --git a/tests/util/messages-t.c b/tests/util/messages-t.c
index f60fa6a..1098314 100644
--- a/tests/util/messages-t.c
+++ b/tests/util/messages-t.c
@@ -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");
diff --git a/tests/util/xmalloc-t b/tests/util/xmalloc-t
index d52c448..af604ed 100755
--- a/tests/util/xmalloc-t
+++ b/tests/util/xmalloc-t
@@ -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.
diff --git a/tests/util/xmalloc.c b/tests/util/xmalloc.c
index e222612..84ba081 100644
--- a/tests/util/xmalloc.c
+++ b/tests/util/xmalloc.c
@@ -34,7 +34,10 @@
#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;
diff --git a/util/macros.h b/util/macros.h
index d071793..4a773a2 100644
--- a/util/macros.h
+++ b/util/macros.h
@@ -29,6 +29,10 @@
#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__))
diff --git a/util/messages.c b/util/messages.c
index a43d962..b5c2dba 100644
--- a/util/messages.c
+++ b/util/messages.c
@@ -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;
diff --git a/util/messages.h b/util/messages.h
index 8c731b7..cf91ba7 100644
--- a/util/messages.h
+++ b/util/messages.h
@@ -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);
diff --git a/util/xmalloc.c b/util/xmalloc.c
index 721447a..7fb0405 100644
--- a/util/xmalloc.c
+++ b/util/xmalloc.c
@@ -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) */
diff --git a/util/xmalloc.h b/util/xmalloc.h
index a4b4686..6aa9b93 100644
--- a/util/xmalloc.h
+++ b/util/xmalloc.h
@@ -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