diff options
author | Russ Allbery <eagle@eyrie.org> | 2016-01-17 14:30:53 -0800 |
---|---|---|
committer | Russ Allbery <eagle@eyrie.org> | 2016-01-17 14:30:53 -0800 |
commit | 57a5a0095c3fe0f22dcbb9d99a82cc94f2b608c7 (patch) | |
tree | d7ab6169e2c5af79d97711964c34fbc1f5bbab13 | |
parent | 884297fc439a4c3eba2365cdb810214dfc4f5799 (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.
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)' @@ -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])]) @@ -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 |