/tests/plugin/mit-t
/tests/portable/asprintf-t
/tests/portable/mkstemp-t
+/tests/portable/reallocarray-t
/tests/portable/snprintf-t
/tests/portable/strndup-t
/tests/runtests
# Automake makefile for krb5-strength.
#
# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2016 Russ Allbery <eagle@eyrie.org>
# Copyright 2007, 2009, 2010, 2012, 2013, 2014
# The Board of Trustees of the Leland Stanford Junior University
#
# See LICENSE for licensing terms.
ACLOCAL_AMFLAGS = -I m4
-EXTRA_DIST = .gitignore LICENSE autogen cracklib/HISTORY cracklib/LICENCE \
- cracklib/README cracklib/genrules.pl cracklib/mkdict tests/HOWTO \
- tests/TESTS tests/data/krb5.conf tests/data/make-krb5-conf \
- tests/data/passwords tests/data/perl.conf tests/data/perlcriticrc \
- tests/data/perltidyrc tests/data/valgrind.supp tests/data/wordlist \
- tests/data/wordlist.cdb tests/data/wordlist.sqlite \
- tests/docs/pod-spelling-t tests/docs/pod-t tests/perl/critic-t \
- tests/perl/minimum-version-t tests/perl/strict-t \
- tests/tap/libtap.sh tests/tap/perl/Test/RRA.pm \
- tests/tap/perl/Test/RRA/Config.pm \
- tests/tap/perl/Test/RRA/Automake.pm tests/tools/heimdal-history-t \
- tests/tools/heimdal-strength-t tests/tools/wordlist-cdb-t \
- tests/tools/wordlist-sqlite-t tests/tools/wordlist-t \
+EXTRA_DIST = .gitignore LICENSE bootstrap cracklib/HISTORY cracklib/LICENCE \
+ cracklib/README cracklib/genrules.pl cracklib/mkdict tests/HOWTO \
+ tests/TESTS tests/data/krb5.conf tests/data/make-krb5-conf \
+ tests/data/passwords tests/data/perl.conf tests/data/perlcriticrc \
+ tests/data/perltidyrc tests/data/valgrind.supp tests/data/wordlist \
+ tests/data/wordlist.cdb tests/data/wordlist.sqlite \
+ tests/docs/pod-spelling-t tests/docs/pod-t tests/perl/critic-t \
+ tests/perl/minimum-version-t tests/perl/strict-t \
+ tests/tap/libtap.sh tests/tap/perl/Test/RRA.pm \
+ tests/tap/perl/Test/RRA/Config.pm \
+ tests/tap/perl/Test/RRA/Automake.pm tests/tools/heimdal-history-t \
+ tests/tools/heimdal-strength-t tests/tools/wordlist-cdb-t \
+ tests/tools/wordlist-sqlite-t tests/tools/wordlist-t \
tests/util/xmalloc-t tools/heimdal-strength.pod
# Do this globally. Everything needs to find the Kerberos headers and
maintainer-clean-local:
rm -f tests/data/passwords/*.c
-# 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)
-#
-# Last checked against gcc 4.7.2 (2013-04-22). -D_FORTIFY_SOURCE=2 enables
-# warn_unused_result attribute markings on glibc functions on Linux, which
-# catches a few more issues.
-WARNINGS = -g -O -D_FORTIFY_SOURCE=2 -Wall -Wextra -Wendif-labels \
- -Wformat=2 -Winit-self -Wswitch-enum -Wuninitialized -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
-
warnings:
- $(MAKE) V=0 CFLAGS='$(WARNINGS)'
- $(MAKE) V=0 CFLAGS='$(WARNINGS)' $(check_PROGRAMS)
+ $(MAKE) V=0 CFLAGS='$(WARNINGS_CFLAGS) $(AM_CFLAGS)' \
+ KRB5_CPPFLAGS='$(KRB5_CPPFLAGS_GCC)'
+ $(MAKE) V=0 CFLAGS='$(WARNINGS_CFLAGS) $(AM_CFLAGS)' \
+ KRB5_CPPFLAGS='$(KRB5_CPPFLAGS_GCC)' $(check_PROGRAMS)
# The bits below are for the test suite, not for the main package.
-check_PROGRAMS = tests/runtests tests/plugin/heimdal-t tests/plugin/mit-t \
- tests/portable/asprintf-t tests/portable/mkstemp-t \
- tests/portable/snprintf-t tests/portable/strndup-t \
- tests/util/messages-krb5-t tests/util/messages-t tests/util/xmalloc
+check_PROGRAMS = tests/runtests tests/plugin/heimdal-t tests/plugin/mit-t \
+ tests/portable/asprintf-t tests/portable/mkstemp-t \
+ tests/portable/reallocarray-t tests/portable/snprintf-t \
+ tests/portable/strndup-t tests/util/messages-krb5-t \
+ tests/util/messages-t tests/util/xmalloc
if EMBEDDED_CRACKLIB
check_PROGRAMS += cracklib/packer
endif
-tests_runtests_CPPFLAGS = -DSOURCE='"$(abs_top_srcdir)/tests"' \
- -DBUILD='"$(abs_top_builddir)/tests"'
+tests_runtests_CPPFLAGS = -DC_TAP_SOURCE='"$(abs_top_srcdir)/tests"' \
+ -DC_TAP_BUILD='"$(abs_top_builddir)/tests"'
check_LIBRARIES = tests/tap/libtap.a
tests_tap_libtap_a_CPPFLAGS = -I$(abs_top_srcdir)/tests $(KRB5_CPPFLAGS)
tests_tap_libtap_a_SOURCES = tests/tap/basic.c tests/tap/basic.h \
tests_portable_mkstemp_t_SOURCES = tests/portable/mkstemp-t.c \
tests/portable/mkstemp.c
tests_portable_mkstemp_t_LDADD = tests/tap/libtap.a portable/libportable.la
+tests_portable_reallocarray_t_SOURCES = tests/portable/reallocarray-t.c \
+ tests/portable/reallocarray.c
+tests_portable_reallocarray_t_LDADD = tests/tap/libtap.a \
+ portable/libportable.la
tests_portable_snprintf_t_SOURCES = tests/portable/snprintf-t.c \
tests/portable/snprintf.c
tests_portable_snprintf_t_LDADD = tests/tap/libtap.a portable/libportable.la
doesn't apply since all the GECOS manipulation code was removed from
the embedded CrackLib in this package.)
+ Update to rra-c-util 6.2:
+
+ * Use calloc in preference to malloc wherever appropriate.
+ * Use reallocarray in preference to realloc wherever appropriate.
+ * Suppress warnings from Kerberos headers under make warnings.
+ * Support the embedded Kerberos in Solaris 10 in library probes.
+ * Add missing va_end in xasprintf implementation.
+ * Fix logic in Test::RRA::Automake for new Automake dist checking.
+ * Fix all return-value checks for snprintf to avoid off-by-one error.
+ * Update warning flags for make warnings to GCC 6.1.0.
+ * Fix Test::RRA::Config for new "do" semantics in Perl 5.22.2.
+ * Add a new test for obsolete eyrie.org URLs.
+ * Require Test::Strict 0.25 or newer for Perl strictness checks.
+
+ Update to C TAP Harness 4.1:
+
+ * Replace all remaining uses of sprintf.
+ * Test lists may now have comments and blank lines.
+ * runtests -v will show the complete output from a test.
+ * Fix segfault in runtests when given an empty test list.
+ * Tests use C_TAP_SOURCE and C_TAP_BUILD instead of SOURCE and BUILD.
+
krb5-strength 3.0 (2014-03-25)
The krb5-strength plugin and heimdal-strength program now support a
The krb5-strength web page at:
- http://www.eyrie.org/~eagle/software/krb5-strength/
+ https://www.eyrie.org/~eagle/software/krb5-strength/
will always have the current version of this package, the current
documentation, and pointers to any additional resources.
or view the repository via the web at:
- http://git.eyrie.org/?p=kerberos/krb5-strength.git
+ https://git.eyrie.org/?p=kerberos/krb5-strength.git
When contributing modifications, either patches (possibly generated by
git format-patch) or Git pull requests are welcome.
dnl Process this file with autoconf to produce a configure script.
dnl
dnl Written by Russ Allbery <eagle@eyrie.org>
+dnl Copyright 2016 Russ Allbery <eagle@eyrie.org>
dnl Copyright 2006, 2007, 2009, 2010, 2012, 2013, 2014
dnl The Board of Trustees of the Leland Stanford Junior University
dnl
-Wall -Werror])
AM_MAINTAINER_MODE
+dnl Detect unexpanded macros.
+m4_pattern_forbid([^PKG_])
+m4_pattern_forbid([^_?RRA_])
+
dnl Probe for basic build system tools.
AC_PROG_CC
AC_USE_SYSTEM_EXTENSIONS
+RRA_PROG_CC_WARNINGS_FLAGS
AC_SYS_LARGEFILE
AM_PROG_CC_C_O
-AC_PROG_INSTALL
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+AC_PROG_INSTALL
AM_DISABLE_STATIC
LT_INIT
RRA_LIB_CRACKLIB_RESTORE])
RRA_LIB_KRB5
RRA_LIB_KRB5_SWITCH
-AC_CHECK_HEADERS([kadm5/kadm5-pwcheck.h kadm5/kadm5_err.h], [], [],
- [RRA_INCLUDES_KRB5])
AC_CHECK_HEADERS([krb5/pwqual_plugin.h], [], [], [RRA_INCLUDES_KRB5])
AC_CHECK_TYPES([krb5_realm], [], [], [RRA_INCLUDES_KRB5])
AC_CHECK_FUNCS([krb5_free_default_realm \
[RRA_FUNC_KRB5_GET_INIT_CREDS_OPT_FREE_ARGS])
AC_CHECK_DECLS([krb5_kt_free_entry], [], [], [RRA_INCLUDES_KRB5])
AC_LIBOBJ([krb5-extra])
+AC_CHECK_HEADERS([kadm5/kadm5-pwcheck.h kadm5/kadm5_err.h], [], [],
+ [RRA_INCLUDES_KRB5])
RRA_LIB_KRB5_RESTORE
RRA_LIB_SQLITE_OPTIONAL
dnl Checks for basic C functionality.
AC_HEADER_STDBOOL
-AC_CHECK_HEADERS([sys/bittypes.h sys/select.h syslog.h])
+AC_CHECK_HEADERS([sys/bittypes.h sys/select.h sys/time.h syslog.h])
AC_CHECK_DECLS([snprintf, vsnprintf])
RRA_C_C99_VAMACROS
RRA_C_GNU_VAMACROS
[#include <sys/types.h>])
RRA_FUNC_SNPRINTF
AC_CHECK_FUNCS([setrlimit])
-AC_REPLACE_FUNCS([asprintf mkstemp strndup])
+AC_REPLACE_FUNCS([asprintf mkstemp reallocarray strndup])
dnl Write out the results.
AC_CONFIG_FILES([Makefile])
* Set hidden visibility on all CrackLib symbols.
* Close the wfp file handle on PWClose if it's open.
* Applied various patches from distributions for security vulnerabilities.
+ * Changed the type of some variables to size_t to avoid truncation.
See the leading comments in each source file for a more detailed timeline
and list of changes.
* - Replaced MAXSTEP with allowing one increment per four characters.
* - Changed error for very short passwords to match current CrackLib.
* - Close the dictionary after each password lookup.
+ * 2016-11-06 Russ Allbery <eagle@eyrie.org>
+ * - Remove unused vers_id to silence GCC warnings
+ * - Changed some variables from int or unsigned int to size_t
*/
-static const char vers_id[] = "fascist.c : v2.3p3 Alec Muffett 14 dec 1997";
-
#include "packer.h"
#include <sys/types.h>
#include <pwd.h>
static const char *
FascistLook(PWDICT *pwp, const char *instring)
{
- int i, pw_len;
- unsigned int mindiff;
+ int i;
+ size_t pw_len, mindiff;
char *ptr;
char *jptr;
char junk[STRINGSIZE];
* - Remove last block optimization in GetPW and start fresh each time.
* 2013-12-13 Russ Allbery <eagle@eyrie.org>
* - Close the wfp file handle on PWClose if it's open.
+ * 2016-11-06 Russ Allbery <eagle@eyrie.org>
+ * - Remove unused vers_id to silence GCC warnings.
*/
#include <stdio.h>
#include "packer.h"
-static const char vers_id[] = "packlib.c : v2.3p2 Alec Muffett 18 May 1993";
-
PWDICT *
PWOpen(const char *prefix, const char *mode)
{
* - Make internal functions static.
* - Remove unused variables.
* - Changed a variable to unsigned to avoid gcc warnings.
+ * 2016-11-06 Russ Allbery <eagle@eyrie.org>
+ * - Remove unused vers_id to silence GCC warnings.
+ * - Added GCC __attribute__ marker on Debug() function.
*/
-static const char vers_id[] = "rules.c : v5.0p3 Alec Muffett 20 May 1993";
-
#include <stdarg.h>
#ifndef IN_CRACKLIB
#include "packer.h"
-static void
+static void __attribute__((__format__(printf, 2, 3)))
Debug(int val, const char *fmt, ...)
{
if (val < 2) {
* 2009-10-14 Russ Allbery <eagle@eyrie.org>
* - Add ANSI C protototypes for all functions.
* - Remove unused Clone function.
+ * 2016-11-06 Russ Allbery <eagle@eyrie.org>
+ * - Remove unused vers_id to silence GCC warnings.
*/
#include <string.h>
#include "packer.h"
-static const char vers_id[] = "stringlib.c : v2.3p2 Alec Muffett 18 May 1993";
-
char
Chop(char *string)
{
--- /dev/null
+dnl Check whether the compiler supports particular flags.
+dnl
+dnl Provides RRA_PROG_CC_FLAG, which checks whether a compiler supports a
+dnl given flag. If it does, the commands in the second argument are run. If
+dnl not, the commands in the third argument are run.
+dnl
+dnl Provides RRA_PROG_CC_WARNINGS_FLAGS, which checks whether a compiler
+dnl supports a large set of warning flags and sets the WARNINGS_CFLAGS
+dnl substitution variable to all of the supported warning flags. (Note that
+dnl this may be too aggressive for some people.)
+dnl
+dnl Depends on RRA_PROG_CC_CLANG.
+dnl
+dnl The canonical version of this file is maintained in the rra-c-util
+dnl package, available at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
+dnl
+dnl Copyright 2016 Russ Allbery <eagle@eyrie.org>
+dnl Copyright 2006, 2009, 2016
+dnl by Internet Systems Consortium, Inc. ("ISC")
+dnl
+dnl Permission to use, copy, modify, and distribute this software for any
+dnl purpose with or without fee is hereby granted, provided that the above
+dnl copyright notice and this permission notice appear in all copies.
+dnl
+dnl THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+dnl REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+dnl MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY
+dnl SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+dnl WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+dnl ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+dnl IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+dnl Used to build the result cache name.
+AC_DEFUN([_RRA_PROG_CC_FLAG_CACHE],
+[translit([rra_cv_compiler_c_$1], [-=], [__])])
+
+dnl Check whether a given flag is supported by the complier.
+AC_DEFUN([RRA_PROG_CC_FLAG],
+[AC_REQUIRE([AC_PROG_CC])
+ AC_MSG_CHECKING([if $CC supports $1])
+ AC_CACHE_VAL([_RRA_PROG_CC_FLAG_CACHE([$1])],
+ [save_CFLAGS=$CFLAGS
+ AS_CASE([$1],
+ [-Wno-*], [CFLAGS="$CFLAGS `echo "$1" | sed 's/-Wno-/-W/'`"],
+ [*], [CFLAGS="$CFLAGS $1"])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [int foo = 0;])],
+ [_RRA_PROG_CC_FLAG_CACHE([$1])=yes],
+ [_RRA_PROG_CC_FLAG_CACHE([$1])=no])
+ CFLAGS=$save_CFLAGS])
+ AC_MSG_RESULT([$_RRA_PROG_CC_FLAG_CACHE([$1])])
+ AS_IF([test x"$_RRA_PROG_CC_FLAG_CACHE([$1])" = xyes], [$2], [$3])])
+
+dnl Determine the full set of viable warning flags for the current compiler.
+dnl
+dnl This is based partly on personal preference and is a fairly aggressive set
+dnl of warnings. Desirable warnings that can't be turned on due to other
+dnl problems:
+dnl
+dnl -Wconversion http://bugs.debian.org/488884 (htons warnings)
+dnl -Wsign-conversion Too much noise from ssize_t and flag variables
+dnl -Wstack-protector Too many false positives from small buffers
+dnl
+dnl Last checked against gcc 6.1.0 (2016-09-25). -D_FORTIFY_SOURCE=2 enables
+dnl warn_unused_result attribute markings on glibc functions on Linux, which
+dnl catches a few more issues. Add -O2 because gcc won't find some warnings
+dnl without optimization turned on.
+dnl
+dnl The warnings here are listed in the same order they're listed in the
+dnl "Preprocessor Options" and "Warning Options" chapters of the GCC manual.
+dnl
+dnl Sets WARNINGS_CFLAGS as a substitution variable.
+AC_DEFUN([RRA_PROG_CC_WARNINGS_FLAGS],
+[AC_REQUIRE([RRA_PROG_CC_CLANG])
+ AS_IF([test x"$CLANG" = xyes],
+ [WARNINGS_CFLAGS="-Werror"
+ m4_foreach_w([flag],
+ [-Weverything -Wno-padded],
+ [RRA_PROG_CC_FLAG(flag,
+ [WARNINGS_CFLAGS="${WARNINGS_CFLAGS} flag"])])],
+ [WARNINGS_CFLAGS="-g -O2 -D_FORTIFY_SOURCE=2 -Werror"
+ m4_foreach_w([flag],
+ [-fstrict-overflow -fstrict-aliasing -Wcomments -Wendif-labels -Wall
+ -Wextra -Wformat=2 -Wformat-signedness -Wnull-dereference -Winit-self
+ -Wswitch-enum -Wuninitialized -Wstrict-overflow=5
+ -Wmissing-format-attribute -Wduplicated-cond -Wtrampolines
+ -Wfloat-equal -Wdeclaration-after-statement -Wshadow -Wpointer-arith
+ -Wbad-function-cast -Wcast-align -Wwrite-strings -Wdate-time
+ -Wjump-misses-init -Wfloat-conversion -Wlogical-op
+ -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes
+ -Wnormalized=nfc -Wpacked -Wredundant-decls -Wnested-externs -Winline
+ -Wvla],
+ [RRA_PROG_CC_FLAG(flag,
+ [WARNINGS_CFLAGS="${WARNINGS_CFLAGS} flag"])])])
+ AC_SUBST([WARNINGS_CFLAGS])])
--- /dev/null
+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 <https://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])])
dnl Depends on RRA_ENABLE_REDUCED_DEPENDS.
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 package, available at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
dnl Written by Russ Allbery <eagle@eyrie.org>
dnl Copyright 2011, 2012
dnl If KRB5_CPPFLAGS, KRB5_LDFLAGS, or KRB5_LIBS are set before calling these
dnl macros, their values will be added to whatever the macros discover.
dnl
+dnl KRB5_CPPFLAGS_GCC will be set to the same value as KRB5_CPPFLAGS but with
+dnl any occurrences of -I changed to -isystem. This may be useful to suppress
+dnl warnings from the Kerberos header files when building with GCC and
+dnl aggressive warning flags. Be aware that this change will change the
+dnl compiler header file search order as well.
+dnl
dnl Provides the RRA_LIB_KRB5_OPTIONAL macro, which should be used if Kerberos
dnl support is optional. In this case, Kerberos libraries are mandatory if
dnl --with-krb5 is given, and will not be probed for if --without-krb5 is
dnl probing the Kerberos library properties.
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 package, available at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
dnl Written by Russ Allbery <eagle@eyrie.org>
-dnl Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013
+dnl Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014
dnl The Board of Trustees of the Leland Stanford Junior University
dnl
dnl This file is free software; the authors give unlimited permission to copy
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
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.
[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], [],
[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
[$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], [],
[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
[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], [],
[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])])])
AC_DEFUN([_RRA_LIB_KRB5_INTERNAL],
[AC_REQUIRE([RRA_ENABLE_REDUCED_DEPENDS])
rra_krb5_incroot=
+ AC_SUBST([KRB5_CPPFLAGS])
+ AC_SUBST([KRB5_CPPFLAGS_GCC])
+ AC_SUBST([KRB5_LDFLAGS])
+ AC_SUBST([KRB5_LIBS])
AS_IF([test x"$rra_krb5_includedir" != x],
[rra_krb5_incroot="$rra_krb5_includedir"],
[AS_IF([test x"$rra_krb5_root" != x],
rra_krb5_uses_com_err=false
AS_CASE([$KRB5_LIBS], [*-lcom_err*], [rra_krb5_uses_com_err=true])
AM_CONDITIONAL([KRB5_USES_COM_ERR],
- [test x"$rra_krb5_uses_com_err" = xtrue])])
+ [test x"$rra_krb5_uses_com_err" = xtrue])
+ KRB5_CPPFLAGS_GCC=`echo "$KRB5_CPPFLAGS" | sed -e 's/-I/-isystem /g'`])
dnl The main macro for packages with mandatory Kerberos support.
AC_DEFUN([RRA_LIB_KRB5],
rra_krb5_libdir=
rra_krb5_includedir=
rra_use_KRB5=true
- AC_SUBST([KRB5_CPPFLAGS])
- AC_SUBST([KRB5_LDFLAGS])
- AC_SUBST([KRB5_LIBS])
AC_ARG_WITH([krb5],
[AS_HELP_STRING([--with-krb5=DIR],
rra_krb5_libdir=
rra_krb5_includedir=
rra_use_KRB5=
- AC_SUBST([KRB5_CPPFLAGS])
- AC_SUBST([KRB5_LDFLAGS])
- AC_SUBST([KRB5_LIBS])
AC_ARG_WITH([krb5],
[AS_HELP_STRING([--with-krb5@<:@=DIR@:>@],
dnl can require it with AC_REQUIRE.
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 package, available at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
dnl Written by Russ Allbery <eagle@eyrie.org>
dnl Copyright 2005, 2006, 2007
dnl Depends on RRA_SET_LDFLAGS.
dnl
dnl The canonical version of this file is maintained in the rra-c-util
-dnl package, available at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+dnl package, available at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
dnl Written by Russ Allbery <eagle@eyrie.org>
dnl Copyright 2011, 2013
dnl libdir variable to PREFIX/lib{,32,64} as appropriate.
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 package, available at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
dnl Written by Russ Allbery <eagle@eyrie.org>
dnl Copyright 2008, 2009
dnl fully working snprintf is found.
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 package, available at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
dnl Written by Russ Allbery <eagle@eyrie.org>
dnl Copyright 2006, 2008, 2009
dnl Depends on the lib-helper.m4 framework.
dnl
dnl The canonical version of this file is maintained in the rra-c-util
-dnl package, available at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+dnl package, available at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
dnl Written by Russ Allbery <eagle@eyrie.org>
dnl Copyright 2014
dnl Depends on the lib-helper.m4 framework.
dnl
dnl The canonical version of this file is maintained in the rra-c-util
-dnl package, available at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+dnl package, available at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
dnl Written by Russ Allbery <eagle@eyrie.org>
dnl Copyright 2013
dnl They set HAVE_C99_VAMACROS or HAVE_GNU_VAMACROS as appropriate.
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 package, available at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
dnl Written by Russ Allbery <eagle@eyrie.org>
dnl Copyright 2006, 2008, 2009
* message in the Kerberos context.
*
* Written by Russ Allbery <eagle@eyrie.org>
+ * Copyright 2016 Russ Allbery <eagle@eyrie.org>
* Copyright 2013
* The Board of Trustees of the Leland Stanford Junior University
*
* Internal helper function to set the Kerberos error message given a format,
* an error code, and a variable argument structure.
*/
-static void
+static void __attribute__((__format__(printf, 3, 0)))
set_error(krb5_context ctx, krb5_error_code code, const char *format,
va_list args)
{
*
* Written by Russ Allbery <eagle@eyrie.org>
* Based on work by David Mazières
+ * Copyright 2016 Russ Allbery <eagle@eyrie.org>
* Copyright 2014
* The Board of Trustees of the Leland Stanford Junior University
*
* context, and returns the generic KADM5_FAILURE code, since there doesn't
* appear to be anything better.
*/
-static krb5_error_code
+static krb5_error_code __attribute__((__format__(printf, 3, 4)))
error_sqlite(krb5_context ctx, krb5_pwqual_moddata data, const char *format,
...)
{
* asprintf and vasprintf for those platforms that don't have them.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
*/
#include <config.h>
+#include <portable/macros.h>
#include <portable/system.h>
#include <errno.h>
* with the system versions.
*/
#if TESTING
+# undef asprintf
+# undef vasprintf
# define asprintf test_asprintf
# define vasprintf test_vasprintf
int test_asprintf(char **, const char *, ...)
__attribute__((__format__(printf, 2, 3)));
-int test_vasprintf(char **, const char *, va_list);
+int test_vasprintf(char **, const char *, va_list)
+ __attribute__((__format__(printf, 2, 0)));
#endif
* arguments. Ensure that libportable always contains at least one symbol.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
* (favoring the Heimdal API as the exposed one).
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
# define KADM5_MISSING_KRB5_CONF_PARAMS KADM5_MISSING_CONF_PARAMS
#endif
-/*
- * Heimdal provides _ctx functions that take an existing context. MIT always
- * requires the context be passed in. Code should use the _ctx variant, and
- * the below will fix it up if built against MIT.
- *
- * MIT also doesn't have a const prototype for the server argument, so cast it
- * so that we can use the KADM5_ADMIN_SERVICE define.
- */
-#ifndef HAVE_KADM5_INIT_WITH_SKEY_CTX
-# define kadm5_init_with_skey_ctx(c, u, k, s, p, sv, av, h) \
- kadm5_init_with_skey((c), (u), (k), (char *) (s), (p), (sv), (av), NULL, \
- (h))
-#endif
-
#endif /* !PORTABLE_KADMIN_H */
* Kerberos libraries are fully capable, this file will be skipped.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
#include <config.h>
#include <portable/krb5.h>
+#include <portable/macros.h>
#include <portable/system.h>
#include <errno.h>
# 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
* This string is returned for unknown error messages. We use a static
* variable so that we can be sure not to free it.
*/
+#if !defined(HAVE_KRB5_GET_ERROR_MESSAGE) \
+ || !defined(HAVE_KRB5_FREE_ERROR_MESSAGE)
static const char error_unknown[] = "unknown error";
+#endif
#ifndef HAVE_KRB5_GET_ERROR_MESSAGE
* krb5_free_unparsed_name() for both APIs since it's the most specific call.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
#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
* Portability macros used in include files.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
* 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
* systems that don't have it.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
#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
--- /dev/null
+/*
+ * Replacement for a missing reallocarray.
+ *
+ * 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 <https://www.eyrie.org/~eagle/software/rra-c-util/>.
+ *
+ * Written by Russ Allbery <eagle@eyrie.org>
+ *
+ * The authors hereby relinquish any claim to any copyright that they may have
+ * in this work, whether granted under contract or by operation of law or
+ * international treaty, and hereby commit to the public, at large, that they
+ * shall not, at any time in the future, seek to enforce any copyright in this
+ * work against any person or entity, or prevent any person or entity from
+ * copying, publishing, distributing or creating derivative works of this
+ * work.
+ */
+
+#include <config.h>
+#include <portable/system.h>
+
+#include <errno.h>
+
+/*
+ * If we're running the test suite, rename reallocarray to avoid conflicts
+ * with the system version. #undef it first because some systems may define
+ * it to another name.
+ */
+#if TESTING
+# undef reallocarray
+# define reallocarray test_reallocarray
+void *test_reallocarray(void *, size_t, size_t);
+#endif
+
+/*
+ * nmemb * size cannot overflow if both are smaller than sqrt(SIZE_MAX). We
+ * can calculate that value statically by using 2^(sizeof(size_t) * 8) as the
+ * value of SIZE_MAX and then taking the square root, which gives
+ * 2^(sizeof(size_t) * 4). Compute the exponentiation with shift.
+ */
+#define CHECK_THRESHOLD (1UL << (sizeof(size_t) * 4))
+
+void *
+reallocarray(void *ptr, size_t nmemb, size_t size)
+{
+ if (nmemb >= CHECK_THRESHOLD || size >= CHECK_THRESHOLD)
+ if (nmemb > 0 && SIZE_MAX / nmemb <= size) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ return realloc(ptr, nmemb * size);
+}
* improvements should be sent back to the original author.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*/
/*
* conflicts with the system version.
*/
#if TESTING
+# undef snprintf
+# undef vsnprintf
# define snprintf test_snprintf
# define vsnprintf test_vsnprintf
#endif
* Russ Allbery <eagle@eyrie.org> 2000-08-26
* fixed return value to comply with C99
* fixed handling of snprintf(NULL, ...)
+ * added explicit casts for double to long long int conversion
*
* Hrvoje Niksic <hniksic@arsdigita.com> 2000-11-04
* include <stdio.h> for NULL.
char *strvalue;
int min;
int max;
- int state;
+ unsigned int state;
int flags;
int cflags;
int total;
return result;
}
-static LDOUBLE pow10_int (int exp)
+static LLONG pow10_int (int exp)
{
LDOUBLE result = 1;
exp--;
}
- return result;
+ return (LLONG) result;
}
static LLONG round_int (LDOUBLE value)
{
LLONG intpart;
- intpart = value;
+ intpart = (LLONG) value;
value = value - intpart;
if (value >= 0.5)
intpart++;
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
#endif
- intpart = ufvalue;
+ intpart = (LLONG) ufvalue;
/* With %g precision is the number of significant digits, which
includes the digits in intpart. */
* logic is based heavily on the example in the Autoconf manual.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
* Replacement for a missing strndup.
*
* The canonical version of this file is maintained in the rra-c-util package,
- * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
* file is the equivalent of including all of the following headers,
* portably:
*
- * #include <sys/types.h>
+ * #include <inttypes.h>
+ * #include <limits.h>
* #include <stdarg.h>
* #include <stdbool.h>
* #include <stddef.h>
* #include <stdint.h>
* #include <string.h>
* #include <strings.h>
+ * #include <sys/types.h>
* #include <unistd.h>
*
* Missing functions are provided via #define or prototyped if available from
* the portable helper library. Also provides some standard #defines.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
#if HAVE_INTTYPES_H
# include <inttypes.h>
#endif
+#include <limits.h>
#include <stdarg.h>
#include <stddef.h>
#if HAVE_STDINT_H
#if !HAVE_DECL_VSNPRINTF
extern int vsnprintf(char *, size_t, const char *, va_list);
#endif
+#if !HAVE_MKSTEMP
+extern int mkstemp(char *);
+#endif
+#if !HAVE_REALLOCARRAY
+extern void *reallocarray(void *, size_t, size_t);
+#endif
#if !HAVE_STRNDUP
extern char *strndup(const char *, size_t);
#endif
One of the special features of C TAP Harness is the environment that
it sets up for your test cases. If your test program is called under
- the runtests driver, the environment variables SOURCE and BUILD will
- be set to the top of the test directory in the source tree and the top
- of the build tree, respectively. You can use those environment
- variables to locate additional test data, programs and libraries built
- as part of your software build, and other supporting information
- needed by tests.
+ the runtests driver, the environment variables C_TAP_SOURCE and
+ C_TAP_BUILD will be set to the top of the test directory in the source
+ tree and the top of the build tree, respectively. You can use those
+ environment variables to locate additional test data, programs and
+ libraries built as part of your software build, and other supporting
+ information needed by tests.
The C and shell TAP libraries support a test_file_path() function,
which looks for a file under the build tree and then under the source
- tree, using the BUILD and SOURCE environment variables, and return the
- full path to the file. This can be used to locate supporting data
- files.
+ tree, using the C_TAP_BUILD and C_TAP_SOURCE environment variables,
+ and return the full path to the file. This can be used to locate
+ supporting data files. They also support a test_tmpdir() function
+ that returns a directory that can be used for temporary files during
+ tests.
Perl
Complete API documentation for the basic C TAP library that comes with
C TAP Harness is available at:
- <http://www.eyrie.org/~eagle/software/c-tap-harness/>
+ <https://www.eyrie.org/~eagle/software/c-tap-harness/>
It's common to need additional test functions and utility functions
for your C tests, particularly if you have to set up and tear down a
Libraries of additional useful TAP test functions are available in
rra-c-util at:
- <http://www.eyrie.org/~eagle/software/rra-c-util/>
+ <https://www.eyrie.org/~eagle/software/rra-c-util/>
Some of the code there is particularly useful when testing programs
that require Kerberos keys.
your test suite area. It can then be loaded by tests written in shell
using the environment set up by runtests with:
- . "$SOURCE"/tap/libtap.sh
+ . "$C_TAP_SOURCE"/tap/libtap.sh
Here is a complete test case written in shell which produces the same
output as the TAP sample above:
#!/bin/sh
- . "$SOURCE"/tap/libtap.sh
- cd "$BUILD"
+ . "$C_TAP_SOURCE"/tap/libtap.sh
+ cd "$C_TAP_BUILD"
plan 4
ok 'the first test' true
License
This file is part of the documentation of C TAP Harness, which can be
- found at <http://www.eyrie.org/~eagle/software/c-tap-harness/>.
+ found at <https://www.eyrie.org/~eagle/software/c-tap-harness/>.
- Copyright 2010 Russ Allbery <eagle@eyrie.org>
+ Copyright 2010, 2016 Russ Allbery <eagle@eyrie.org>
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
docs/pod
docs/pod-spelling
+docs/urls
plugin/heimdal
plugin/mit
perl/critic
# This file has been updated to match perlcritic 1.118.
#
# 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/>.
+# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2011, 2012, 2013
# Default options for perltidy for proper Perl code reformatting.
#
# 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/>.
+# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
-bbao # put line breaks before any operator
-nbbc # don't force blank lines before comments (bad for else blocks)
# and related software.
#
# 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/>.
+# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2011, 2012, 2013, 2014
# Checks all POD files in the tree for spelling errors using Test::Spelling.
#
# 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/>.
+# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2016 Russ Allbery <eagle@eyrie.org>
# Copyright 2012, 2013, 2014
# The Board of Trustees of the Leland Stanford Junior University
#
use strict;
use warnings;
-use lib "$ENV{SOURCE}/tap/perl";
+use lib "$ENV{C_TAP_SOURCE}/tap/perl";
use Test::More;
use Test::RRA qw(skip_unless_author use_prereq);
# distribution, for POD formatting errors.
#
# 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/>.
+# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2016 Russ Allbery <eagle@eyrie.org>
# Copyright 2012, 2013, 2014
# The Board of Trustees of the Leland Stanford Junior University
#
use strict;
use warnings;
-use lib "$ENV{SOURCE}/tap/perl";
+use lib "$ENV{C_TAP_SOURCE}/tap/perl";
use Test::More;
use Test::RRA qw(skip_unless_automated use_prereq);
--- /dev/null
+#!/usr/bin/perl
+#
+# Check URLs in source files.
+#
+# Examine all source files in a distribution for bad URL patterns and report
+# on files that fail this check. Currently, this just checks that all the
+# links to www.eyrie.org are https.
+#
+# The canonical version of this file is maintained in the rra-c-util package,
+# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
+#
+# Copyright 2016 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"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib "$ENV{C_TAP_SOURCE}/tap/perl";
+
+use File::Basename qw(basename);
+use Test::More;
+use Test::RRA qw(skip_unless_author);
+use Test::RRA::Automake qw(all_files automake_setup);
+
+# Bad patterns to search for.
+my @BAD_REGEXES = (qr{ http:// \S+ [.]eyrie[.]org }xms);
+my @BAD_STRINGS = qw(rra@stanford.edu);
+
+# Only run this test for the package author, since it doesn't indicate any
+# user-noticable flaw in the package itself.
+skip_unless_author('Documentation URL tests');
+
+# Set up Automake testing.
+automake_setup();
+
+# Check a single file for one of the bad patterns.
+#
+# $path - Path to the file
+#
+# Returns: undef
+sub check_file {
+ my ($path) = @_;
+ my $filename = basename($path);
+
+ # Ignore this check itself (or the Perl version of it) and binary files.
+ return if ($filename eq 'urls.t' || $filename eq 'urls-t');
+ return if !-T $path;
+
+ # Scan the file.
+ open(my $fh, '<', $path) or BAIL_OUT("Cannot open $path");
+ while (defined(my $line = <$fh>)) {
+ for my $regex (@BAD_REGEXES) {
+ if ($line =~ $regex) {
+ ok(0, "$path contains $regex");
+ close($fh) or BAIL_OUT("Cannot close $path");
+ return;
+ }
+ }
+ for my $string (@BAD_STRINGS) {
+ if (index($line, $string) != -1) {
+ ok(0, "$path contains $string");
+ close($fh) or BAIL_OUT("Cannot close $path");
+ return;
+ }
+ }
+ }
+ close($fh) or BAIL_OUT("Cannot close $path");
+ ok(1, $path);
+ return;
+}
+
+# Scan every file for any of the bad patterns or strings. We don't declare a
+# plan since we skip a lot of files and don't want to precalculate the file
+# list.
+my @paths = all_files();
+for my $path (@paths) {
+ check_file($path);
+}
+done_testing();
# Check for perlcritic errors in included Perl scripts.
#
# 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/>.
+# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2016 Russ Allbery <eagle@eyrie.org>
# Copyright 2012, 2013, 2014
# The Board of Trustees of the Leland Stanford Junior University
#
use strict;
use warnings;
-use lib "$ENV{SOURCE}/tap/perl";
+use lib "$ENV{C_TAP_SOURCE}/tap/perl";
use File::Spec;
use Test::More;
# required for internal tools than for public code.
#
# 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/>.
+# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2016 Russ Allbery <eagle@eyrie.org>
# Copyright 2012, 2013, 2014
# The Board of Trustees of the Leland Stanford Junior University
#
use strict;
use warnings;
-use lib "$ENV{SOURCE}/tap/perl";
+use lib "$ENV{C_TAP_SOURCE}/tap/perl";
use Test::More;
use Test::RRA qw(skip_unless_automated use_prereq);
# all pass a syntax check. Currently, test suite coverage is not checked.
#
# 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/>.
+# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2016 Russ Allbery <eagle@eyrie.org>
# Copyright 2012, 2013, 2014
# The Board of Trustees of the Leland Stanford Junior University
#
use strict;
use warnings;
-use lib "$ENV{SOURCE}/tap/perl";
+use lib "$ENV{C_TAP_SOURCE}/tap/perl";
use Test::More;
use Test::RRA qw(skip_unless_automated use_prereq);
skip_unless_automated('Strictness tests');
# Load prerequisite modules.
-use_prereq('Test::Strict');
+use_prereq('Test::Strict', '0.25');
# Check whether all prerequisites are available, and skip the test if any of
# them are not.
* asprintf and vasprintf test suite.
*
* The canonical version of this file is maintained in the rra-c-util package,
- * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
*/
#include <config.h>
+#include <portable/macros.h>
#include <portable/system.h>
#include <tests/tap/basic.h>
* mkstemp test suite.
*
* The canonical version of this file is maintained in the rra-c-util package,
- * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
--- /dev/null
+/*
+ * reallocarray test suite.
+ *
+ * This does some simple sanity checks and checks some of the overflow
+ * detection, but isn't particularly thorough.
+ *
+ * The canonical version of this file is maintained in the rra-c-util package,
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
+ *
+ * Written by Russ Allbery <eagle@eyrie.org>
+ *
+ * The authors hereby relinquish any claim to any copyright that they may have
+ * in this work, whether granted under contract or by operation of law or
+ * international treaty, and hereby commit to the public, at large, that they
+ * shall not, at any time in the future, seek to enforce any copyright in this
+ * work against any person or entity, or prevent any person or entity from
+ * copying, publishing, distributing or creating derivative works of this
+ * work.
+ */
+
+#include <config.h>
+#include <portable/system.h>
+
+#include <errno.h>
+
+#include <tests/tap/basic.h>
+
+void *test_reallocarray(void *, size_t, size_t);
+
+
+int
+main(void)
+{
+ char *p, *base;
+ size_t sqrt_max;
+ int oerrno;
+
+ plan(15);
+
+ /* Test success cases and write to the memory for valgrind checks. */
+ p = test_reallocarray(NULL, 2, 5);
+ memcpy(p, "123456789", 10);
+ is_string("123456789", p, "reallocarray of NULL");
+ p = test_reallocarray(p, 4, 5);
+ is_string("123456789", p, "reallocarray after resize");
+ memcpy(p + 9, "0123456789", 11);
+ is_string("1234567890123456789", p, "write to larger memory segment");
+ free(p);
+
+ /*
+ * If nmemb or size are 0, we should either get NULL or a pointer we can
+ * free. Make sure we don't get something weird, like division by zero.
+ */
+ p = test_reallocarray(NULL, 0, 100);
+ if (p != NULL)
+ free(p);
+ p = test_reallocarray(NULL, 100, 0);
+ if (p != NULL)
+ free(p);
+
+ /* Test the range-checking error cases. */
+ p = test_reallocarray(NULL, 2, SIZE_MAX / 2);
+ oerrno = errno;
+ ok(p == NULL, "reallocarray fails for 2, SIZE_MAX / 2");
+ is_int(ENOMEM, oerrno, "...with correct errno");
+ base = malloc(10);
+ p = test_reallocarray(base, 3, SIZE_MAX / 3);
+ oerrno = errno;
+ ok(p == NULL, "reallocarray fails for 3, SIZE_MAX / 3");
+ is_int(ENOMEM, oerrno, "...with correct errno");
+ sqrt_max = (1UL << (sizeof(size_t) * 4));
+ p = test_reallocarray(base, sqrt_max, sqrt_max);
+ oerrno = errno;
+ ok(p == NULL, "reallocarray fails for sqrt(SIZE_MAX), sqrt(SIZE_MAX)");
+ is_int(ENOMEM, oerrno, "...with correct errno");
+ p = test_reallocarray(base, 1, SIZE_MAX);
+ oerrno = errno;
+ ok(p == NULL, "reallocarray fails for 1, SIZE_MAX");
+ is_int(ENOMEM, oerrno, "...with correct errno");
+ p = test_reallocarray(base, SIZE_MAX, 1);
+ oerrno = errno;
+ ok(p == NULL, "reallocarray fails for SIZE_MAX, 1");
+ is_int(ENOMEM, oerrno, "...with correct errno");
+ p = test_reallocarray(base, 2, SIZE_MAX);
+ oerrno = errno;
+ ok(p == NULL, "reallocarray fails for 2, SIZE_MAX");
+ is_int(ENOMEM, oerrno, "...with correct errno");
+
+ /* Clean up and exit. */
+ free(base);
+ return 0;
+}
--- /dev/null
+#define TESTING 1
+#include <portable/reallocarray.c>
* snprintf test suite.
*
* The canonical version of this file is maintained in the rra-c-util package,
- * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006
* 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
* strndup test suite.
*
* The canonical version of this file is maintained in the rra-c-util package,
- * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
*
* 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>
* output. This is intended for use with failing tests so that the person
* running the test suite can get more details about what failed.
*
- * If built with the C preprocessor symbols SOURCE and BUILD defined, C TAP
- * Harness will export those values in the environment so that tests can find
- * the source and build directory and will look for tests under both
- * directories. These paths can also be set with the -b and -s command-line
- * options, which will override anything set at build time.
+ * If built with the C preprocessor symbols C_TAP_SOURCE and C_TAP_BUILD
+ * defined, C TAP Harness will export those values in the environment so that
+ * tests can find the source and build directory and will look for tests under
+ * both 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/>.
+ * Harness <https://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, 2016 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"),
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
+#include <limits.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
/*
* The source and build versions of the tests directory. This is used to set
- * the SOURCE and BUILD environment variables and find test programs, if set.
- * Normally, this should be set as part of the build process to the test
- * subdirectories of $(abs_top_srcdir) and $(abs_top_builddir) respectively.
+ * the C_TAP_SOURCE and C_TAP_BUILD environment variables (and the SOURCE and
+ * BUILD environment variables set for backward compatibility) and find test
+ * programs, if set. Normally, this should be set as part of the build
+ * process to the test subdirectories of $(abs_top_srcdir) and
+ * $(abs_top_builddir) respectively.
*/
-#ifndef SOURCE
-# define SOURCE NULL
+#ifndef C_TAP_SOURCE
+# define C_TAP_SOURCE NULL
#endif
-#ifndef BUILD
-# define BUILD NULL
+#ifndef C_TAP_BUILD
+# define C_TAP_BUILD NULL
#endif
/* Test status codes. */
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. */
* 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\
-------------------------- -------------- ---- ---- ------------------------";
/* Include the file name and line number in malloc failures. */
-#define xcalloc(n, size) x_calloc((n), (size), __FILE__, __LINE__)
-#define xmalloc(size) x_malloc((size), __FILE__, __LINE__)
-#define xrealloc(p, size) x_realloc((p), (size), __FILE__, __LINE__)
-#define xstrdup(p) x_strdup((p), __FILE__, __LINE__)
+#define xcalloc(n, size) x_calloc((n), (size), __FILE__, __LINE__)
+#define xmalloc(size) x_malloc((size), __FILE__, __LINE__)
+#define xstrdup(p) x_strdup((p), __FILE__, __LINE__)
+#define xreallocarray(p, n, size) \
+ x_reallocarray((p), (n), (size), __FILE__, __LINE__)
/*
* __attribute__ is available in gcc 2.5 and later, but only with gcc 2.7
* 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
__attribute__((__alloc_size__(1, 2), __malloc__, __nonnull__));
static void *x_malloc(size_t, const char *, int)
__attribute__((__alloc_size__(1), __malloc__, __nonnull__));
-static void *x_realloc(void *, size_t, const char *, int)
- __attribute__((__alloc_size__(2), __malloc__, __nonnull__(3)));
+static void *x_reallocarray(void *, size_t, size_t, const char *, int)
+ __attribute__((__alloc_size__(2, 3), __malloc__, __nonnull__(4)));
static char *x_strdup(const char *, const char *, int)
__attribute__((__malloc__, __nonnull__));
/*
* Reallocate memory, reporting a fatal error and exiting on failure.
+ *
+ * We should technically use SIZE_MAX here for the overflow check, but
+ * SIZE_MAX is C99 and we're only assuming C89 + SUSv3, which does not
+ * guarantee that it exists. They do guarantee that UINT_MAX exists, and we
+ * can assume that UINT_MAX <= SIZE_MAX. And we should not be allocating
+ * anything anywhere near that large.
+ *
+ * (In theory, C89 and C99 permit size_t to be smaller than unsigned int, but
+ * I disbelieve in the existence of such systems and they will have to cope
+ * without overflow checks.)
*/
static void *
-x_realloc(void *p, size_t size, const char *file, int line)
+x_reallocarray(void *p, size_t n, size_t size, const char *file, int line)
{
- p = realloc(p, size);
+ if (n > 0 && UINT_MAX / n <= size)
+ sysdie("realloc too large at %s line %d", file, line);
+ p = realloc(p, n * size);
if (p == NULL)
sysdie("failed to realloc %lu bytes at %s line %d",
- (unsigned long) size, file, line);
+ (unsigned long) (n * size), file, line);
return p;
}
}
+/*
+ * Form a new string by concatenating multiple strings. The arguments must be
+ * terminated by (const char *) 0.
+ *
+ * This function only exists because we can't assume asprintf. We can't
+ * simulate asprintf with snprintf because we're only assuming SUSv3, which
+ * does not require that snprintf with a NULL buffer return the required
+ * length. When those constraints are relaxed, this should be ripped out and
+ * replaced with asprintf or a more trivial replacement with snprintf.
+ */
+static char *
+concat(const char *first, ...)
+{
+ va_list args;
+ char *result;
+ const char *string;
+ size_t offset;
+ size_t length = 0;
+
+ /*
+ * Find the total memory required. Ensure we don't overflow length. We
+ * aren't guaranteed to have SIZE_MAX, so use UINT_MAX as an acceptable
+ * substitute (see the x_nrealloc comments).
+ */
+ va_start(args, first);
+ for (string = first; string != NULL; string = va_arg(args, const char *)) {
+ if (length >= UINT_MAX - strlen(string)) {
+ errno = EINVAL;
+ sysdie("strings too long in concat");
+ }
+ length += strlen(string);
+ }
+ va_end(args);
+ length++;
+
+ /* Create the string. */
+ result = xmalloc(length);
+ va_start(args, first);
+ offset = 0;
+ for (string = first; string != NULL; string = va_arg(args, const char *)) {
+ memcpy(result + offset, string, strlen(string));
+ offset += strlen(string);
+ }
+ va_end(args);
+ result[offset] = '\0';
+ return result;
+}
+
+
/*
* Given a struct timeval, return the number of seconds it represents as a
* double. Use difftime() to convert a time_t to a double.
}
+/*
+ * Allocate or resize the array of test results to be large enough to contain
+ * the test number in.
+ */
+static void
+resize_results(struct testset *ts, unsigned long n)
+{
+ unsigned long i;
+ size_t s;
+
+ /* If there's already enough space, return quickly. */
+ if (n <= ts->allocated)
+ return;
+
+ /*
+ * If no space has been allocated, do the initial allocation. Otherwise,
+ * resize. Start with 32 test cases and then add 1024 with each resize to
+ * try to reduce the number of reallocations.
+ */
+ if (ts->allocated == 0) {
+ s = (n > 32) ? n : 32;
+ ts->results = xcalloc(s, sizeof(enum test_status));
+ } else {
+ s = (n > ts->allocated + 1024) ? n : ts->allocated + 1024;
+ ts->results = xreallocarray(ts->results, s, sizeof(enum test_status));
+ }
+
+ /* Set the results for the newly-allocated test array. */
+ for (i = ts->allocated; i < s; i++)
+ ts->results[i] = TEST_INVALID;
+ ts->allocated = s;
+}
+
+
+/*
+ * 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
* 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)
{
- unsigned long i;
long n;
/*
line += 3;
/*
- * Get the count, check it for validity, and initialize the struct. If we
- * have something of the form "1..0 # skip foo", the whole file was
+ * Get the count and check it for validity.
+ *
+ * If we have something of the form "1..0 # skip foo", the whole file was
* skipped; record that. If we do skip the whole file, zero out all of
- * our statistics, since they're no longer relevant. strtol is called
- * with a second argument to advance the line pointer past the count to
- * make it simpler to detect the # skip case.
+ * our statistics, since they're no longer relevant.
+ *
+ * strtol is called with a second argument to advance the line pointer
+ * past the count to make it simpler to detect the # skip case.
*/
n = strtol(line, (char **) &line, 10);
if (n == 0) {
ts->reported = 1;
return 0;
}
- if (ts->plan == PLAN_INIT && ts->allocated == 0) {
- ts->count = n;
- ts->allocated = n;
+
+ /*
+ * If we are doing lazy planning, check the plan against the largest test
+ * number that we saw and fail now if we saw a check outside the plan
+ * range.
+ */
+ if (ts->plan == PLAN_PENDING && (unsigned long) n < ts->count) {
+ invalid_test_number(ts, (long) ts->count, verbose);
+ return 0;
+ }
+
+ /*
+ * Otherwise, allocated or resize the results if needed and update count,
+ * and then record that we've seen a plan.
+ */
+ resize_results(ts, (unsigned long) n);
+ ts->count = (unsigned long) n;
+ if (ts->plan == PLAN_INIT)
ts->plan = PLAN_FIRST;
- ts->results = xmalloc(ts->count * sizeof(enum test_status));
- for (i = 0; i < ts->count; i++)
- ts->results[i] = TEST_INVALID;
- } else if (ts->plan == PLAN_PENDING) {
- if ((unsigned long) n < ts->count) {
- test_backspace(ts);
- printf("ABORTED (invalid test number %lu)\n", ts->count);
- ts->aborted = 1;
- ts->reported = 1;
- return 0;
- }
- ts->count = n;
- if ((unsigned long) n > ts->allocated) {
- ts->results = xrealloc(ts->results, n * sizeof(enum test_status));
- for (i = ts->allocated; i < ts->count; i++)
- ts->results[i] = TEST_INVALID;
- ts->allocated = n;
- }
+ else if (ts->plan == PLAN_PENDING)
ts->plan = PLAN_FINAL;
- }
return 1;
}
* 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;
char *end;
long number;
- unsigned long i, current;
+ unsigned long current;
int outlen;
/* Before anything, check for a test abort. */
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;
}
/* 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;
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;
}
/* We have a valid test result. Tweak the results array if needed. */
if (ts->plan == PLAN_INIT || ts->plan == PLAN_PENDING) {
ts->plan = PLAN_PENDING;
+ resize_results(ts, current);
if (current > ts->count)
ts->count = current;
- if (current > ts->allocated) {
- unsigned long n;
-
- n = (ts->allocated == 0) ? 32 : ts->allocated * 2;
- if (n < current)
- n = current;
- ts->results = xrealloc(ts->results, n * sizeof(enum test_status));
- for (i = ts->allocated; i < n; i++)
- ts->results[i] = TEST_INVALID;
- ts->allocated = n;
- }
}
/*
/* 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;
}
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);
}
}
* 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;
* 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;
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,
* 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) {
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", "" };
base = bases[j];
if (base == NULL)
continue;
- path = xmalloc(strlen(base) + strlen(name) + strlen(suffix) + 2);
- sprintf(path, "%s/%s%s", base, name, suffix);
+ path = concat(base, "/", name, suffix, (const char *) 0);
if (is_valid_test(path))
return path;
free(path);
/*
* 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 *
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. */
- listhead = xmalloc(sizeof(struct testlist));
- listhead->ts = NULL;
- listhead->next = NULL;
+ listhead = xcalloc(1, sizeof(struct testlist));
current = NULL;
/*
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 {
- current->next = xmalloc(sizeof(struct testlist));
+ current->next = xcalloc(1, sizeof(struct testlist));
current = current->next;
- current->next = NULL;
}
current->ts = xcalloc(1, sizeof(struct testset));
current->ts->plan = PLAN_INIT;
- current->ts->file = xstrdup(buffer);
- current->ts->reason = NULL;
+ 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;
}
/*
* 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)
struct testlist *listhead, *current;
/* Create the initial container list that will hold our results. */
- listhead = xmalloc(sizeof(struct testlist));
- listhead->ts = NULL;
- listhead->next = NULL;
+ listhead = xcalloc(1, sizeof(struct testlist));
current = NULL;
/* Walk the list of arguments and create test sets for them. */
if (current == NULL)
current = listhead;
else {
- current->next = xmalloc(sizeof(struct testlist));
+ current->next = xcalloc(1, sizeof(struct testlist));
current = current->next;
- current->next = NULL;
}
current->ts = xcalloc(1, sizeof(struct testset));
current->ts->plan = PLAN_INIT;
current->ts->file = xstrdup(argv[i]);
- current->ts->reason = NULL;
+ }
+
+ /* If there were no tests, current is still NULL. */
+ if (current == NULL) {
+ free(listhead);
+ return NULL;
}
/* Return the results. */
* 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;
/* 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;
/*
- * Main routine. Set the SOURCE and BUILD environment variables and then,
- * given a file listing tests, run each test listed.
+ * Main routine. Set the C_TAP_SOURCE, C_TAP_BUILD, SOURCE, and BUILD
+ * environment variables and then, given a file listing tests, run each test
+ * listed.
*/
int
main(int argc, char *argv[])
int option;
int status = 0;
int single = 0;
+ enum test_verbose verbose = CONCISE;
+ char *c_tap_source_env = NULL;
+ char *c_tap_build_env = NULL;
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;
+ const char *source = C_TAP_SOURCE;
+ const char *build = C_TAP_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;
case 's':
source = optarg;
break;
+ case 'v':
+ verbose = VERBOSE;
+ break;
default:
exit(1);
}
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);
}
- /* Set SOURCE and BUILD environment variables. */
+ /*
+ * If C_TAP_VERBOSE is set in the environment, that also turns on verbose
+ * mode.
+ */
+ if (getenv("C_TAP_VERBOSE") != NULL)
+ verbose = VERBOSE;
+
+ /*
+ * Set C_TAP_SOURCE and C_TAP_BUILD environment variables. Also set
+ * SOURCE and BUILD for backward compatibility, although we're trying to
+ * migrate to the ones with a C_TAP_* prefix.
+ */
if (source != NULL) {
- source_env = xmalloc(strlen("SOURCE=") + strlen(source) + 1);
- sprintf(source_env, "SOURCE=%s", source);
+ c_tap_source_env = concat("C_TAP_SOURCE=", source, (const char *) 0);
+ if (putenv(c_tap_source_env) != 0)
+ sysdie("cannot set C_TAP_SOURCE in the environment");
+ source_env = concat("SOURCE=", source, (const char *) 0);
if (putenv(source_env) != 0)
sysdie("cannot set SOURCE in the environment");
}
if (build != NULL) {
- build_env = xmalloc(strlen("BUILD=") + strlen(build) + 1);
- sprintf(build_env, "BUILD=%s", build);
+ c_tap_build_env = concat("C_TAP_BUILD=", build, (const char *) 0);
+ if (putenv(c_tap_build_env) != 0)
+ sysdie("cannot set C_TAP_BUILD in the environment");
+ build_env = concat("BUILD=", build, (const char *) 0);
if (putenv(build_env) != 0)
sysdie("cannot set BUILD in the environment");
}
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. */
if (source_env != NULL) {
+ putenv((char *) "C_TAP_SOURCE=");
putenv((char *) "SOURCE=");
+ free(c_tap_source_env);
free(source_env);
}
if (build_env != NULL) {
+ putenv((char *) "C_TAP_BUILD=");
putenv((char *) "BUILD=");
+ free(c_tap_build_env);
free(build_env);
}
exit(status);
* up the TAP output format, or finding things in the test environment.
*
* 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/>.
+ * documentation is at <https://www.eyrie.org/~eagle/software/c-tap-harness/>.
*
- * Copyright 2009, 2010, 2011, 2012, 2013 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016
+ * 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
*
*/
#include <errno.h>
+#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
/*
* 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 {
} while (0)
+/*
+ * Form a new string by concatenating multiple strings. The arguments must be
+ * terminated by (const char *) 0.
+ *
+ * This function only exists because we can't assume asprintf. We can't
+ * simulate asprintf with snprintf because we're only assuming SUSv3, which
+ * does not require that snprintf with a NULL buffer return the required
+ * length. When those constraints are relaxed, this should be ripped out and
+ * replaced with asprintf or a more trivial replacement with snprintf.
+ */
+static char *
+concat(const char *first, ...)
+{
+ va_list args;
+ char *result;
+ const char *string;
+ size_t offset;
+ size_t length = 0;
+
+ /*
+ * Find the total memory required. Ensure we don't overflow length. See
+ * the comment for breallocarray for why we're using UINT_MAX here.
+ */
+ va_start(args, first);
+ for (string = first; string != NULL; string = va_arg(args, const char *)) {
+ if (length >= UINT_MAX - strlen(string))
+ bail("strings too long in concat");
+ length += strlen(string);
+ }
+ va_end(args);
+ length++;
+
+ /* Create the string. */
+ result = bmalloc(length);
+ va_start(args, first);
+ offset = 0;
+ for (string = first; string != NULL; string = va_arg(args, const char *)) {
+ memcpy(result + offset, string, strlen(string));
+ offset += strlen(string);
+ }
+ va_end(args);
+ result[offset] = '\0';
+ return result;
+}
+
+
/*
* Check all registered diag_files for any output. We only print out the
* output if we see a complete line; otherwise, we wait for the next newline.
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
/* 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;
/*
* See if the line ends in a newline. If not, see which error
- * case we have.
+ * case we have. Use UINT_MAX as a substitute for SIZE_MAX (see
+ * the comment for breallocarray).
*/
length = strlen(file->buffer);
if (file->buffer[length - 1] != '\n') {
if (length < file->bufsize - 1)
incomplete = 1;
else {
+ if (file->bufsize >= UINT_MAX - BUFSIZ)
+ sysbail("line too long in %s", file->name);
file->bufsize += BUFSIZ;
file->buffer = brealloc(file->buffer, file->bufsize);
}
* Takes a boolean success value and assumes the test passes if that value
* is true and fails if that value is false.
*/
-void
+int
ok(int success, const char *format, ...)
{
fflush(stderr);
_failed++;
PRINT_DESC(" - ", format);
putchar('\n');
+ return success;
}
/*
* Same as ok(), but takes the format arguments as a va_list.
*/
-void
+int
okv(int success, const char *format, va_list args)
{
fflush(stderr);
vprintf(format, args);
}
putchar('\n');
+ return success;
}
/*
* Report the same status on the next count tests.
*/
-void
-ok_block(unsigned long count, int status, const char *format, ...)
+int
+ok_block(unsigned long count, int success, const char *format, ...)
{
unsigned long i;
fflush(stderr);
check_diag_files();
for (i = 0; i < count; i++) {
- printf("%sok %lu", status ? "" : "not ", testnum++);
- if (!status)
+ printf("%sok %lu", success ? "" : "not ", testnum++);
+ if (!success)
_failed++;
PRINT_DESC(" - ", format);
putchar('\n');
}
+ return success;
}
* Takes an expected integer and a seen integer and assumes the test passes
* if those two numbers match.
*/
-void
+int
is_int(long wanted, long seen, const char *format, ...)
{
+ int success;
+
fflush(stderr);
check_diag_files();
- if (wanted == seen)
+ success = (wanted == seen);
+ if (success)
printf("ok %lu", testnum++);
else {
diag("wanted: %ld", wanted);
}
PRINT_DESC(" - ", format);
putchar('\n');
+ return success;
}
* Takes a string and what the string should be, and assumes the test passes
* if those strings match (using strcmp).
*/
-void
+int
is_string(const char *wanted, const char *seen, const char *format, ...)
{
+ int success;
+
if (wanted == NULL)
wanted = "(null)";
if (seen == NULL)
seen = "(null)";
fflush(stderr);
check_diag_files();
- if (strcmp(wanted, seen) == 0)
+ success = (strcmp(wanted, seen) == 0);
+ if (success)
printf("ok %lu", testnum++);
else {
diag("wanted: %s", wanted);
}
PRINT_DESC(" - ", format);
putchar('\n');
+ return success;
}
* Takes an expected unsigned long and a seen unsigned long and assumes the
* test passes if the two numbers match. Otherwise, reports them in hex.
*/
-void
+int
is_hex(unsigned long wanted, unsigned long seen, const char *format, ...)
{
+ int success;
+
fflush(stderr);
check_diag_files();
- if (wanted == seen)
+ success = (wanted == seen);
+ if (success)
printf("ok %lu", testnum++);
else {
diag("wanted: %lx", (unsigned long) wanted);
}
PRINT_DESC(" - ", format);
putchar('\n');
+ return success;
}
/*
- * Report a diagnostic to stderr.
+ * Report a diagnostic to stderr. Always returns 1 to allow embedding in
+ * compound statements.
*/
-void
+int
diag(const char *format, ...)
{
va_list args;
vprintf(format, args);
va_end(args);
printf("\n");
+ return 1;
}
/*
- * Report a diagnostic to stderr, appending strerror(errno).
+ * Report a diagnostic to stderr, appending strerror(errno). Always returns 1
+ * to allow embedding in compound statements.
*/
-void
+int
sysdiag(const char *format, ...)
{
va_list args;
vprintf(format, args);
va_end(args);
printf(": %s\n", strerror(oerrno));
+ return 1;
}
}
+/*
+ * The same as brealloc, but determine the size by multiplying an element
+ * count by a size, similar to calloc. The multiplication is checked for
+ * integer overflow.
+ *
+ * We should technically use SIZE_MAX here for the overflow check, but
+ * SIZE_MAX is C99 and we're only assuming C89 + SUSv3, which does not
+ * guarantee that it exists. They do guarantee that UINT_MAX exists, and we
+ * can assume that UINT_MAX <= SIZE_MAX.
+ *
+ * (In theory, C89 and C99 permit size_t to be smaller than unsigned int, but
+ * I disbelieve in the existence of such systems and they will have to cope
+ * without overflow checks.)
+ */
+void *
+breallocarray(void *p, size_t n, size_t size)
+{
+ if (n > 0 && UINT_MAX / n <= size)
+ bail("reallocarray too large");
+ p = realloc(p, n * size);
+ if (p == NULL)
+ sysbail("failed to realloc %lu bytes", (unsigned long) (n * size));
+ return p;
+}
+
+
/*
* Copy a string, reporting a fatal error with bail on failure.
*/
/* 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);
/*
- * Locate a test file. Given the partial path to a file, look under BUILD and
- * then SOURCE for the file and return the full path to the file. Returns
- * NULL if the file doesn't exist. A non-NULL return should be freed with
- * test_file_path_free().
- *
- * This function uses sprintf because it attempts to be independent of all
- * other portability layers. The use immediately after a memory allocation
- * should be safe without using snprintf or strlcpy/strlcat.
+ * Locate a test file. Given the partial path to a file, look under
+ * C_TAP_BUILD and then C_TAP_SOURCE for the file and return the full path to
+ * the file. Returns NULL if the file doesn't exist. A non-NULL return
+ * should be freed with test_file_path_free().
*/
char *
test_file_path(const char *file)
{
char *base;
char *path = NULL;
- size_t length;
- const char *envs[] = { "BUILD", "SOURCE", NULL };
+ const char *envs[] = { "C_TAP_BUILD", "C_TAP_SOURCE", NULL };
int i;
for (i = 0; envs[i] != NULL; i++) {
base = getenv(envs[i]);
if (base == NULL)
continue;
- length = strlen(base) + 1 + strlen(file) + 1;
- path = bmalloc(length);
- sprintf(path, "%s/%s", base, file);
+ path = concat(base, "/", file, (const char *) 0);
if (access(path, R_OK) == 0)
break;
free(path);
/*
- * Create a temporary directory, tmp, under BUILD if set and the current
+ * Create a temporary directory, tmp, under C_TAP_BUILD if set and the current
* directory if it does not. Returns the path to the temporary directory in
* newly allocated memory, and calls bail on any failure. The return value
* should be freed with test_tmpdir_free.
{
const char *build;
char *path = NULL;
- size_t length;
- build = getenv("BUILD");
+ build = getenv("C_TAP_BUILD");
if (build == NULL)
build = ".";
- length = strlen(build) + strlen("/tmp") + 1;
- path = bmalloc(length);
- sprintf(path, "%s/tmp", build);
+ path = concat(build, "/tmp", (const char *) 0);
if (access(path, X_OK) < 0)
if (mkdir(path, 0777) < 0)
sysbail("error creating temporary directory %s", path);
* Basic utility routines for the TAP protocol.
*
* 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/>.
+ * documentation is at <https://www.eyrie.org/~eagle/software/c-tap-harness/>.
*
- * Copyright 2009, 2010, 2011, 2012, 2013 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016
+ * 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
*
/*
* Basic reporting functions. The okv() function is the same as ok() but
* takes the test description as a va_list to make it easier to reuse the
- * reporting infrastructure when writing new tests.
+ * reporting infrastructure when writing new tests. ok() and okv() return the
+ * value of the success argument.
*/
-void ok(int success, const char *format, ...)
+int ok(int success, const char *format, ...)
__attribute__((__format__(printf, 2, 3)));
-void 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)));
-/* Report the same status on, or skip, the next count tests. */
-void ok_block(unsigned long count, int success, const char *format, ...)
+/*
+ * Report the same status on, or skip, the next count tests. ok_block()
+ * returns the value of the success argument.
+ */
+int ok_block(unsigned long count, int success, const char *format, ...)
__attribute__((__format__(printf, 3, 4)));
void skip_block(unsigned long count, const char *reason, ...)
__attribute__((__format__(printf, 2, 3)));
-/* Check an expected value against a seen value. */
-void is_int(long wanted, long seen, const char *format, ...)
+/*
+ * Check an expected value against a seen value. Returns true if the test
+ * passes and false if it fails.
+ */
+int is_int(long wanted, long seen, const char *format, ...)
__attribute__((__format__(printf, 3, 4)));
-void is_string(const char *wanted, const char *seen, const char *format, ...)
+int is_string(const char *wanted, const char *seen, const char *format, ...)
__attribute__((__format__(printf, 3, 4)));
-void is_hex(unsigned long wanted, unsigned long seen, const char *format, ...)
+int is_hex(unsigned long wanted, unsigned long seen, const char *format, ...)
__attribute__((__format__(printf, 3, 4)));
/* Bail out with an error. sysbail appends strerror(errno). */
__attribute__((__noreturn__, __nonnull__, __format__(printf, 1, 2)));
/* Report a diagnostic to stderr prefixed with #. */
-void diag(const char *format, ...)
+int diag(const char *format, ...)
__attribute__((__nonnull__, __format__(printf, 1, 2)));
-void sysdiag(const char *format, ...)
+int sysdiag(const char *format, ...)
__attribute__((__nonnull__, __format__(printf, 1, 2)));
/*
__attribute__((__alloc_size__(1, 2), __malloc__, __warn_unused_result__));
void *bmalloc(size_t)
__attribute__((__alloc_size__(1), __malloc__, __warn_unused_result__));
+void *breallocarray(void *, size_t, size_t)
+ __attribute__((__alloc_size__(2, 3), __malloc__, __warn_unused_result__));
void *brealloc(void *, size_t)
__attribute__((__alloc_size__(2), __malloc__, __warn_unused_result__));
char *bstrdup(const char *)
__attribute__((__malloc__, __nonnull__, __warn_unused_result__));
/*
- * Find a test file under BUILD or SOURCE, returning the full path. The
- * returned path should be freed with test_file_path_free().
+ * Find a test file under C_TAP_BUILD or C_TAP_SOURCE, returning the full
+ * path. The returned path should be freed with test_file_path_free().
*/
char *test_file_path(const char *file)
__attribute__((__malloc__, __nonnull__, __warn_unused_result__));
void test_file_path_free(char *path);
/*
- * Create a temporary directory relative to BUILD and return the path. The
- * returned path should be freed with test_tmpdir_free.
+ * Create a temporary directory relative to C_TAP_BUILD and return the path.
+ * The returned path should be freed with test_tmpdir_free().
*/
char *test_tmpdir(void)
__attribute__((__malloc__, __warn_unused_result__));
* 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.
* are available.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2006, 2007, 2009, 2010, 2011, 2012, 2013, 2014
* 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
/*
free(config->userprinc);
free(config->username);
free(config->password);
+ free(config->pkinit_principal);
+ free(config->pkinit_cert);
free(config);
config = NULL;
}
}
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.
* Utility functions for tests that use Kerberos.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2006, 2007, 2009, 2011, 2012, 2013, 2014
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
/* Bail out with an error, appending the Kerberos error message. */
void bail_krb5(krb5_context, krb5_error_code, const char *format, ...)
- __attribute__((__noreturn__, __nonnull__, __format__(printf, 3, 4)));
+ __attribute__((__noreturn__, __nonnull__(3), __format__(printf, 3, 4)));
/* Report a diagnostic with Kerberos error to stderr prefixed with #. */
void diag_krb5(krb5_context, krb5_error_code, const char *format, ...)
- __attribute__((__nonnull__, __format__(printf, 3, 4)));
+ __attribute__((__nonnull__(3), __format__(printf, 3, 4)));
/*
* Given a Kerberos context and the path to a keytab, retrieve the principal
#
# This file provides a TAP-compatible shell function library useful for
# writing test cases. It is part of C TAP Harness, which can be found at
-# <http://www.eyrie.org/~eagle/software/c-tap-harness/>.
+# <https://www.eyrie.org/~eagle/software/c-tap-harness/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
-# Copyright 2009, 2010, 2011, 2012 Russ Allbery <eagle@eyrie.org>
+# Copyright 2009, 2010, 2011, 2012, 2016 Russ Allbery <eagle@eyrie.org>
# Copyright 2006, 2007, 2008, 2013
# The Board of Trustees of the Leland Stanford Junior University
#
echo '#' "$@"
}
-# Search for the given file first in $BUILD and then in $SOURCE and echo the
-# path where the file was found, or the empty string if the file wasn't
-# found.
+# Search for the given file first in $C_TAP_BUILD and then in $C_TAP_SOURCE
+# and echo the path where the file was found, or the empty string if the file
+# wasn't found.
#
# This macro uses puts, so don't run it using backticks inside double quotes
# or bizarre quoting behavior will happen with Solaris sh.
test_file_path () {
- if [ -n "$BUILD" ] && [ -f "$BUILD/$1" ] ; then
- puts "$BUILD/$1"
- elif [ -n "$SOURCE" ] && [ -f "$SOURCE/$1" ] ; then
- puts "$SOURCE/$1"
+ if [ -n "$C_TAP_BUILD" ] && [ -f "$C_TAP_BUILD/$1" ] ; then
+ puts "$C_TAP_BUILD/$1"
+ elif [ -n "$C_TAP_SOURCE" ] && [ -f "$C_TAP_SOURCE/$1" ] ; then
+ puts "$C_TAP_SOURCE/$1"
else
echo ''
fi
}
-# Create $BUILD/tmp for use by tests for storing temporary files and return
-# the path (via standard output).
+# Create $C_TAP_BUILD/tmp for use by tests for storing temporary files and
+# return the path (via standard output).
#
# This macro uses puts, so don't run it using backticks inside double quotes
# or bizarre quoting behavior will happen with Solaris sh.
test_tmpdir () {
- if [ -z "$BUILD" ] ; then
+ if [ -z "$C_TAP_BUILD" ] ; then
tap_tmpdir="./tmp"
else
- tap_tmpdir="$BUILD"/tmp
+ tap_tmpdir="$C_TAP_BUILD"/tmp
fi
if [ ! -d "$tap_tmpdir" ] ; then
mkdir "$tap_tmpdir" || bail "Error creating $tap_tmpdir"
* everyone can pull them in.
*
* 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/>.
+ * documentation is at <https://www.eyrie.org/~eagle/software/c-tap-harness/>.
*
- * Copyright 2008, 2012, 2013 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2008, 2012, 2013, 2015 Russ Allbery <eagle@eyrie.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* variadic macro support.
*/
#if !defined(__attribute__) && !defined(__alloc_size__)
-# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)
-# define __alloc_size__(spec, args...) /* empty */
+# if defined(__GNUC__) && !defined(__clang__)
+# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)
+# define __alloc_size__(spec, args...) /* empty */
+# endif
# endif
#endif
# by both C packages with Automake and by stand-alone Perl modules. See
# Test::RRA::Automake for additional functions specifically for C Automake
# distributions.
-#
-# The canonical version of this file is maintained in the rra-c-util package,
-# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
-#
-# Written by Russ Allbery <eagle@eyrie.org>
-# Copyright 2013, 2014
-# The Board of Trustees of the Leland Stanford Junior University
-#
-# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the "Software"),
-# to deal in the Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish, distribute, sublicense,
-# and/or sell copies of the Software, and to permit persons to whom the
-# Software is furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-# DEALINGS IN THE SOFTWARE.
package Test::RRA;
use warnings;
use Exporter;
+use File::Temp;
use Test::More;
# For Perl 5.006 compatibility.
# consistency is good).
BEGIN {
@ISA = qw(Exporter);
- @EXPORT_OK = qw(skip_unless_author skip_unless_automated use_prereq);
+ @EXPORT_OK = qw(
+ is_file_contents skip_unless_author skip_unless_automated use_prereq
+ );
# This version should match the corresponding rra-c-util release, but with
# two digits for the minor version, including a leading zero if necessary,
# so that it will sort properly.
- $VERSION = '5.04';
+ $VERSION = '6.02';
+}
+
+# Compare a string to the contents of a file, similar to the standard is()
+# function, but to show the line-based unified diff between them if they
+# differ.
+#
+# $got - The output that we received
+# $expected - The path to the file containing the expected output
+# $message - The message to use when reporting the test results
+#
+# Returns: undef
+# Throws: Exception on failure to read or write files or run diff
+sub is_file_contents {
+ my ($got, $expected, $message) = @_;
+
+ # If they're equal, this is simple.
+ open(my $fh, '<', $expected) or BAIL_OUT("Cannot open $expected: $!\n");
+ my $data = do { local $/ = undef; <$fh> };
+ close($fh) or BAIL_OUT("Cannot close $expected: $!\n");
+ if ($got eq $data) {
+ is($got, $data, $message);
+ return;
+ }
+
+ # Otherwise, we show a diff, but only if we have IPC::System::Simple.
+ eval { require IPC::System::Simple };
+ if ($@) {
+ ok(0, $message);
+ return;
+ }
+
+ # They're not equal. Write out what we got so that we can run diff.
+ my $tmp = File::Temp->new();
+ my $tmpname = $tmp->filename;
+ print {$tmp} $got or BAIL_OUT("Cannot write to $tmpname: $!\n");
+ my @command = ('diff', '-u', $expected, $tmpname);
+ my $diff = IPC::System::Simple::capturex([0 .. 1], @command);
+ diag($diff);
+
+ # Remove the temporary file and report failure.
+ ok(0, $message);
+ return;
}
# Skip this test unless author tests are requested. Takes a short description
=for stopwords
Allbery Allbery's DESC bareword sublicense MERCHANTABILITY NONINFRINGEMENT
-rra-c-util
+rra-c-util CPAN
=head1 NAME
=head1 DESCRIPTION
-This module collects utility functions that are useful for Perl test
-scripts. It assumes Russ Allbery's Perl module layout and test
-conventions and will only be useful for other people if they use the
-same conventions.
+This module collects utility functions that are useful for Perl test scripts.
+It assumes Russ Allbery's Perl module layout and test conventions and will
+only be useful for other people if they use the same conventions.
=head1 FUNCTIONS
-None of these functions are imported by default. The ones used by a
-script should be explicitly imported.
+None of these functions are imported by default. The ones used by a script
+should be explicitly imported.
=over 4
=item skip_unless_author(DESC)
-Checks whether AUTHOR_TESTING is set in the environment and skips the
-whole test (by calling C<plan skip_all> from Test::More) if it is not.
-DESC is a description of the tests being skipped. A space and C<only run
-for author> will be appended to it and used as the skip reason.
+Checks whether AUTHOR_TESTING is set in the environment and skips the whole
+test (by calling C<plan skip_all> from Test::More) if it is not. DESC is a
+description of the tests being skipped. A space and C<only run for author>
+will be appended to it and used as the skip reason.
=item skip_unless_automated(DESC)
-Checks whether AUTHOR_TESTING, AUTOMATED_TESTING, or RELEASE_TESTING are
-set in the environment and skips the whole test (by calling C<plan
-skip_all> from Test::More) if they are not. This should be used by tests
-that should not run during end-user installs of the module, but which
-should run as part of CPAN smoke testing and release testing.
+Checks whether AUTHOR_TESTING, AUTOMATED_TESTING, or RELEASE_TESTING are set
+in the environment and skips the whole test (by calling C<plan skip_all> from
+Test::More) if they are not. This should be used by tests that should not run
+during end-user installs of the module, but which should run as part of CPAN
+smoke testing and release testing.
DESC is a description of the tests being skipped. A space and C<normally
skipped> will be appended to it and used as the skip reason.
=item use_prereq(MODULE[, VERSION][, IMPORT ...])
-Attempts to load MODULE with the given VERSION and import arguments. If
-this fails for any reason, the test will be skipped (by calling C<plan
-skip_all> from Test::More) with a skip reason saying that MODULE is
-required for the test.
+Attempts to load MODULE with the given VERSION and import arguments. If this
+fails for any reason, the test will be skipped (by calling C<plan skip_all>
+from Test::More) with a skip reason saying that MODULE is required for the
+test.
VERSION will be passed to C<use> as a version bareword if it looks like a
-version number. The remaining IMPORT arguments will be passed as the
-value of an array.
+version number. The remaining IMPORT arguments will be passed as the value of
+an array.
=back
Copyright 2013, 2014 The Board of Trustees of the Leland Stanford Junior
University
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
=head1 SEE ALSO
Test::More(3), Test::RRA::Automake(3), Test::RRA::Config(3)
-This module is maintained in the rra-c-util package. The current version
-is available from L<http://www.eyrie.org/~eagle/software/rra-c-util/>.
+This module is maintained in the rra-c-util package. The current version is
+available from L<https://www.eyrie.org/~eagle/software/rra-c-util/>.
-The functions to control when tests are run use environment variables
-defined by the L<Lancaster
+The functions to control when tests are run use environment variables defined
+by the L<Lancaster
Consensus|https://github.com/Perl-Toolchain-Gang/toolchain-site/blob/master/lancaster-consensus.md>.
=cut
# require closely following the conventions implemented by the rra-c-util
# utility collection.
#
-# All the functions here assume that BUILD and SOURCE are set in the
-# environment. This is normally done via the C TAP Harness runtests wrapper.
-#
-# The canonical version of this file is maintained in the rra-c-util package,
-# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
-#
-# Written by Russ Allbery <eagle@eyrie.org>
-# Copyright 2013
-# The Board of Trustees of the Leland Stanford Junior University
-#
-# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the "Software"),
-# to deal in the Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish, distribute, sublicense,
-# and/or sell copies of the Software, and to permit persons to whom the
-# Software is furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-# DEALINGS IN THE SOFTWARE.
+# All the functions here assume that C_TAP_BUILD and C_TAP_SOURCE are set in
+# the environment. This is normally done via the C TAP Harness runtests
+# wrapper.
package Test::RRA::Automake;
## no critic (ClassHierarchies::ProhibitExplicitISA)
use Exporter;
+use File::Find qw(find);
use File::Spec;
use Test::More;
use Test::RRA::Config qw($LIBRARY_PATH);
$PERL_BLIB_ARCH = File::Spec->catdir(qw(perl blib arch));
$PERL_BLIB_LIB = File::Spec->catdir(qw(perl blib lib));
- # If BUILD is set, we can come up with better values.
- if (defined($ENV{BUILD})) {
- my ($vol, $dirs) = File::Spec->splitpath($ENV{BUILD}, 1);
+ # If C_TAP_BUILD is set, we can come up with better values.
+ if (defined($ENV{C_TAP_BUILD})) {
+ my ($vol, $dirs) = File::Spec->splitpath($ENV{C_TAP_BUILD}, 1);
my @dirs = File::Spec->splitdir($dirs);
pop(@dirs);
$PERL_BLIB_ARCH = File::Spec->catdir(@dirs, qw(perl blib arch));
# consistency is good).
BEGIN {
@ISA = qw(Exporter);
- @EXPORT_OK = qw(automake_setup perl_dirs test_file_path test_tmpdir);
+ @EXPORT_OK = qw(
+ all_files automake_setup perl_dirs test_file_path test_tmpdir
+ );
# This version should match the corresponding rra-c-util release, but with
# two digits for the minor version, including a leading zero if necessary,
# so that it will sort properly.
- $VERSION = '5.04';
+ $VERSION = '6.02';
}
-# Perl directories to skip globally for perl_dirs. We ignore the perl
-# directory if it exists since, in my packages, it is treated as a Perl module
-# distribution and has its own standalone test suite.
-my @GLOBAL_SKIP = qw(.git perl);
+# Directories to skip globally when looking for all files, or for directories
+# that could contain Perl files.
+my @GLOBAL_SKIP = qw(.git _build autom4te.cache build-aux);
+
+# Additional paths to skip when building a list of all files in the
+# distribution. This primarily skips build artifacts that aren't interesting
+# to any of the tests. These match any path component.
+my @FILES_SKIP = qw(.deps .dirstamp .libs config.h.in~ configure);
# The temporary directory created by test_tmpdir, if any. If this is set,
# attempt to remove the directory stored here on program exit (but ignore
# failure to do so).
my $TMPDIR;
+# Returns a list of all files in the distribution.
+#
+# Returns: List of files
+sub all_files {
+ my @files;
+
+ # Turn the skip lists into hashes for ease of querying.
+ my %skip = map { $_ => 1 } @GLOBAL_SKIP;
+ my %files_skip = map { $_ => 1 } @FILES_SKIP;
+
+ # Wanted function for find. Prune anything matching either of the skip
+ # lists, or *.lo files, and then add all regular files to the list.
+ my $wanted = sub {
+ my $file = $_;
+ my $path = $File::Find::name;
+ $path =~ s{ \A [.]/ }{}xms;
+ if ($skip{$path} or $files_skip{$file} or $file =~ m{ [.] lo \z }xms) {
+ $File::Find::prune = 1;
+ return;
+ }
+ if (-f $file) {
+ push(@files, $path);
+ }
+ };
+
+ # Do the recursive search and return the results.
+ find($wanted, q{.});
+ return @files;
+}
+
# Perform initial test setup for running a Perl test in an Automake package.
-# This verifies that BUILD and SOURCE are set and then changes directory to
-# the SOURCE directory by default. Sets LD_LIBRARY_PATH if the $LIBRARY_PATH
-# configuration option is set. Calls BAIL_OUT if BUILD or SOURCE are missing
-# or if anything else fails.
+# This verifies that C_TAP_BUILD and C_TAP_SOURCE are set and then changes
+# directory to the C_TAP_SOURCE directory by default. Sets LD_LIBRARY_PATH if
+# the $LIBRARY_PATH configuration option is set. Calls BAIL_OUT if
+# C_TAP_BUILD or C_TAP_SOURCE are missing or if anything else fails.
#
# $args_ref - Reference to a hash of arguments to configure behavior:
-# chdir_build - If set to a true value, changes to BUILD instead of SOURCE
+# chdir_build - If set to a true value, changes to C_TAP_BUILD instead of
+# C_TAP_SOURCE
#
# Returns: undef
sub automake_setup {
my ($args_ref) = @_;
- # Bail if BUILD or SOURCE are not set.
- if (!$ENV{BUILD}) {
- BAIL_OUT('BUILD not defined (run under runtests)');
+ # Bail if C_TAP_BUILD or C_TAP_SOURCE are not set.
+ if (!$ENV{C_TAP_BUILD}) {
+ BAIL_OUT('C_TAP_BUILD not defined (run under runtests)');
}
- if (!$ENV{SOURCE}) {
- BAIL_OUT('SOURCE not defined (run under runtests)');
+ if (!$ENV{C_TAP_SOURCE}) {
+ BAIL_OUT('C_TAP_SOURCE not defined (run under runtests)');
}
- # BUILD or SOURCE will be the test directory. Change to the parent.
- my $start = $args_ref->{chdir_build} ? $ENV{BUILD} : $ENV{SOURCE};
+ # C_TAP_BUILD or C_TAP_SOURCE will be the test directory. Change to the
+ # parent.
+ my $start;
+ if ($args_ref->{chdir_build}) {
+ $start = $ENV{C_TAP_BUILD};
+ } else {
+ $start = $ENV{C_TAP_SOURCE};
+ }
my ($vol, $dirs) = File::Spec->splitpath($start, 1);
my @dirs = File::Spec->splitdir($dirs);
pop(@dirs);
- if ($dirs[-1] eq File::Spec->updir) {
+
+ # Simplify relative paths at the end of the directory.
+ my $ups = 0;
+ my $i = $#dirs;
+ while ($i > 2 && $dirs[$i] eq File::Spec->updir) {
+ $ups++;
+ $i--;
+ }
+ for (1 .. $ups) {
pop(@dirs);
pop(@dirs);
}
my $root = File::Spec->catpath($vol, File::Spec->catdir(@dirs), q{});
chdir($root) or BAIL_OUT("cannot chdir to $root: $!");
- # If BUILD is a subdirectory of SOURCE, add it to the global ignore list.
- my ($buildvol, $builddirs) = File::Spec->splitpath($ENV{BUILD}, 1);
+ # If C_TAP_BUILD is a subdirectory of C_TAP_SOURCE, add it to the global
+ # ignore list.
+ my ($buildvol, $builddirs) = File::Spec->splitpath($ENV{C_TAP_BUILD}, 1);
my @builddirs = File::Spec->splitdir($builddirs);
pop(@builddirs);
if ($buildvol eq $vol && @builddirs == @dirs + 1) {
sub perl_dirs {
my ($args_ref) = @_;
- # Add the global skip list.
+ # Add the global skip list. We also ignore the perl directory if it
+ # exists since, in my packages, it is treated as a Perl module
+ # distribution and has its own standalone test suite.
my @skip = $args_ref->{skip} ? @{ $args_ref->{skip} } : ();
- push(@skip, @GLOBAL_SKIP);
+ push(@skip, @GLOBAL_SKIP, 'perl');
# Separate directories to skip under tests from top-level directories.
my @skip_tests = grep { m{ \A tests/ }xms } @skip;
# Build the list of top-level directories to test.
opendir(my $rootdir, q{.}) or BAIL_OUT("cannot open .: $!");
- my @dirs = grep { -d $_ && !$skip{$_} } readdir($rootdir);
+ my @dirs = grep { -d && !$skip{$_} } readdir($rootdir);
closedir($rootdir);
@dirs = File::Spec->no_upwards(@dirs);
return @dirs;
}
-# Find a configuration file for the test suite. Searches relative to BUILD
-# first and then SOURCE and returns whichever is found first. Calls BAIL_OUT
-# if the file could not be found.
+# Find a configuration file for the test suite. Searches relative to
+# C_TAP_BUILD first and then C_TAP_SOURCE and returns whichever is found
+# first. Calls BAIL_OUT if the file could not be found.
#
# $file - Partial path to the file
#
sub test_file_path {
my ($file) = @_;
BASE:
- for my $base ($ENV{BUILD}, $ENV{SOURCE}) {
+ for my $base ($ENV{C_TAP_BUILD}, $ENV{C_TAP_SOURCE}) {
next if !defined($base);
if (-f "$base/$file") {
return "$base/$file";
my $path;
# If we already figured out what directory to use, reuse the same path.
- # Otherwise, create a directory relative to BUILD if set.
+ # Otherwise, create a directory relative to C_TAP_BUILD if set.
if (defined($TMPDIR)) {
$path = $TMPDIR;
} else {
- my $base = defined($ENV{BUILD}) ? $ENV{BUILD} : File::Spec->curdir;
+ my $base;
+ if (defined($ENV{C_TAP_BUILD})) {
+ $base = $ENV{C_TAP_BUILD};
+ } else {
+ $base = File::Spec->curdir;
+ }
$path = File::Spec->catdir($base, 'tmp');
}
__END__
=for stopwords
-Allbery Automake Automake-aware Automake-based rra-c-util ARGS
-subdirectories sublicense MERCHANTABILITY NONINFRINGEMENT umask
+Allbery Automake Automake-aware Automake-based rra-c-util ARGS subdirectories
+sublicense MERCHANTABILITY NONINFRINGEMENT umask
=head1 NAME
=head1 DESCRIPTION
This module collects utility functions that are useful for test scripts
-written in Perl and included in a C Automake-based package. They assume
-the layout of a package that uses rra-c-util and C TAP Harness for the
-test structure.
+written in Perl and included in a C Automake-based package. They assume the
+layout of a package that uses rra-c-util and C TAP Harness for the test
+structure.
Loading this module will also add the directories C<perl/blib/arch> and
-C<perl/blib/lib> to the Perl library search path, relative to BUILD if
-that environment variable is set. This is harmless for C Automake
-projects that don't contain an embedded Perl module, and for those
-projects that do, this will allow subsequent C<use> calls to find modules
-that are built as part of the package build process.
+C<perl/blib/lib> to the Perl library search path, relative to C_TAP_BUILD if
+that environment variable is set. This is harmless for C Automake projects
+that don't contain an embedded Perl module, and for those projects that do,
+this will allow subsequent C<use> calls to find modules that are built as part
+of the package build process.
The automake_setup() function should be called before calling any other
functions provided by this module.
=head1 FUNCTIONS
-None of these functions are imported by default. The ones used by a
-script should be explicitly imported. On failure, all of these functions
-call BAIL_OUT (from Test::More).
+None of these functions are imported by default. The ones used by a script
+should be explicitly imported. On failure, all of these functions call
+BAIL_OUT (from Test::More).
=over 4
+=item all_files()
+
+Returns a list of all "interesting" files in the distribution that a test
+suite may want to look at. This excludes various products of the build system,
+the build directory if it's under the source directory, and a few other
+uninteresting directories like F<.git>. The returned paths will be paths
+relative to the root of the package.
+
=item automake_setup([ARGS])
-Verifies that the BUILD and SOURCE environment variables are set and
-then changes directory to the top of the source tree (which is one
-directory up from the SOURCE path, since SOURCE points to the top of
-the tests directory).
+Verifies that the C_TAP_BUILD and C_TAP_SOURCE environment variables are set
+and then changes directory to the top of the source tree (which is one
+directory up from the C_TAP_SOURCE path, since C_TAP_SOURCE points to the top
+of the tests directory).
-If ARGS is given, it should be a reference to a hash of configuration
-options. Only one option is supported: C<chdir_build>. If it is set
-to a true value, automake_setup() changes directories to the top of
-the build tree instead.
+If ARGS is given, it should be a reference to a hash of configuration options.
+Only one option is supported: C<chdir_build>. If it is set to a true value,
+automake_setup() changes directories to the top of the build tree instead.
=item perl_dirs([ARGS])
Returns a list of directories that may contain Perl scripts that should be
-tested by test scripts that test all Perl in the source tree (such as
-syntax or coding style checks). The paths will be simple directory names
-relative to the current directory or two-part directory names under the
-F<tests> directory. (Directories under F<tests> are broken out separately
-since it's common to want to apply different policies to different
-subdirectories of F<tests>.)
-
-If ARGS is given, it should be a reference to a hash of configuration
-options. Only one option is supported: C<skip>, whose value should be a
-reference to an array of additional top-level directories or directories
-starting with C<tests/> that should be skipped.
+tested by test scripts that test all Perl in the source tree (such as syntax
+or coding style checks). The paths will be simple directory names relative to
+the current directory or two-part directory names under the F<tests>
+directory. (Directories under F<tests> are broken out separately since it's
+common to want to apply different policies to different subdirectories of
+F<tests>.)
+
+If ARGS is given, it should be a reference to a hash of configuration options.
+Only one option is supported: C<skip>, whose value should be a reference to an
+array of additional top-level directories or directories starting with
+C<tests/> that should be skipped.
=item test_file_path(FILE)
-Given FILE, which should be a relative path, locates that file relative to
-the test directory in either the source or build tree. FILE will be
-checked for relative to the environment variable BUILD first, and then
-relative to SOURCE. test_file_path() returns the full path to FILE or
-calls BAIL_OUT if FILE could not be found.
+Given FILE, which should be a relative path, locates that file relative to the
+test directory in either the source or build tree. FILE will be checked for
+relative to the environment variable C_TAP_BUILD first, and then relative to
+C_TAP_SOURCE. test_file_path() returns the full path to FILE or calls
+BAIL_OUT if FILE could not be found.
=item test_tmpdir()
-Create a temporary directory for tests to use for transient files and
-return the path to that directory. The directory is created relative to
-the BUILD environment variable, which must be set. Permissions on the
+Create a temporary directory for tests to use for transient files and return
+the path to that directory. The directory is created relative to the
+C_TAP_BUILD environment variable, which must be set. Permissions on the
directory are set using the current umask. test_tmpdir() returns the full
-path to the temporary directory or calls BAIL_OUT if it could not be
-created.
+path to the temporary directory or calls BAIL_OUT if it could not be created.
+
+The directory is automatically removed if possible on program exit. Failure
+to remove the directory on exit is reported with diag() and otherwise ignored.
+
+=back
+
+=head1 ENVIRONMENT
-The directory is automatically removed if possible on program exit.
-Failure to remove the directory on exit is reported with diag() and
-otherwise ignored.
+=over 4
+
+=item C_TAP_BUILD
+
+The root of the tests directory in Automake build directory for this package,
+used to find files as documented above.
+
+=item C_TAP_SOURCE
+
+The root of the tests directory in the source tree for this package, used to
+find files as documented above.
=back
=head1 COPYRIGHT AND LICENSE
-Copyright 2013 The Board of Trustees of the Leland Stanford Junior
-University
+Copyright 2014, 2015 Russ Allbery <eagle@eyrie.org>
+
+Copyright 2013 The Board of Trustees of the Leland Stanford Junior University
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
=head1 SEE ALSO
Test::More(3), Test::RRA(3), Test::RRA::Config(3)
-The C TAP Harness test driver and libraries for TAP-based C testing are
-available from L<http://www.eyrie.org/~eagle/software/c-tap-harness/>.
+This module is maintained in the rra-c-util package. The current version is
+available from L<https://www.eyrie.org/~eagle/software/rra-c-util/>.
-This module is maintained in the rra-c-util package. The current version
-is available from L<http://www.eyrie.org/~eagle/software/rra-c-util/>.
+The C TAP Harness test driver and libraries for TAP-based C testing are
+available from L<https://www.eyrie.org/~eagle/software/c-tap-harness/>.
=cut
# configuration file to store some package-specific data. This module loads
# that configuration and provides the namespace for the configuration
# settings.
-#
-# 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/>.
package Test::RRA::Config;
@ISA = qw(Exporter);
@EXPORT_OK = qw(
$COVERAGE_LEVEL @COVERAGE_SKIP_TESTS @CRITIC_IGNORE $LIBRARY_PATH
- $MINIMUM_VERSION %MINIMUM_VERSION @POD_COVERAGE_EXCLUDE @STRICT_IGNORE
- @STRICT_PREREQ
+ $MINIMUM_VERSION %MINIMUM_VERSION @MODULE_VERSION_IGNORE
+ @POD_COVERAGE_EXCLUDE @STRICT_IGNORE @STRICT_PREREQ
);
# This version should match the corresponding rra-c-util release, but with
# two digits for the minor version, including a leading zero if necessary,
# so that it will sort properly.
- $VERSION = '5.04';
+ $VERSION = '6.02';
}
-# If BUILD or SOURCE are set in the environment, look for data/perl.conf under
-# those paths for a C Automake package. Otherwise, look in t/data/perl.conf
-# for a standalone Perl module. Don't use Test::RRA::Automake since it may
-# not exist.
+# If C_TAP_BUILD or C_TAP_SOURCE are set in the environment, look for
+# data/perl.conf under those paths for a C Automake package. Otherwise, look
+# in t/data/perl.conf for a standalone Perl module or tests/data/perl.conf for
+# Perl tests embedded in a larger distribution. Don't use Test::RRA::Automake
+# since it may not exist.
our $PATH;
-for my $base ($ENV{BUILD}, $ENV{SOURCE}, 't') {
+for my $base ($ENV{C_TAP_BUILD}, $ENV{C_TAP_SOURCE}, './t', './tests') {
next if !defined($base);
my $path = "$base/data/perl.conf";
if (-r $path) {
our $LIBRARY_PATH;
our $MINIMUM_VERSION = '5.008';
our %MINIMUM_VERSION;
+our @MODULE_VERSION_IGNORE;
our @POD_COVERAGE_EXCLUDE;
our @STRICT_IGNORE;
our @STRICT_PREREQ;
# Load the configuration.
if (!do($PATH)) {
my $error = $@ || $! || 'loading file did not return true';
- BAIL_OUT("cannot load data/perl.conf: $error");
+ BAIL_OUT("cannot load $PATH: $error");
}
1;
__END__
=for stopwords
-Allbery rra-c-util Automake perlcritic .libs namespace subdirectory
-sublicense MERCHANTABILITY NONINFRINGEMENT
+Allbery rra-c-util Automake perlcritic .libs namespace subdirectory sublicense
+MERCHANTABILITY NONINFRINGEMENT regexes
=head1 NAME
=head1 DESCRIPTION
-Test::RRA::Config encapsulates per-package configuration for generic Perl
-test programs that are shared between multiple packages using the
-rra-c-util infrastructure. It handles locating and loading the test
-configuration file for both C Automake packages and stand-alone Perl
-modules.
+Test::RRA::Config encapsulates per-package configuration for generic Perl test
+programs that are shared between multiple packages using the rra-c-util
+infrastructure. It handles locating and loading the test configuration file
+for both C Automake packages and stand-alone Perl modules.
Test::RRA::Config looks for a file named F<data/perl.conf> relative to the
-root of the test directory. That root is taken from the environment
-variables BUILD or SOURCE (in that order) if set, which will be the case
-for C Automake packages using C TAP Harness. If neither is set, it
-expects the root of the test directory to be a directory named F<t>
-relative to the current directory, which will be the case for stand-alone
-Perl modules.
+root of the test directory. That root is taken from the environment variables
+C_TAP_BUILD or C_TAP_SOURCE (in that order) if set, which will be the case for
+C Automake packages using C TAP Harness. If neither is set, it expects the
+root of the test directory to be a directory named F<t> relative to the
+current directory, which will be the case for stand-alone Perl modules.
The following variables are supported:
=item $COVERAGE_LEVEL
-The coverage level achieved by the test suite for Perl test coverage
-testing using Test::Strict, as a percentage. The test will fail if test
-coverage less than this percentage is achieved. If not given, defaults
-to 100.
+The coverage level achieved by the test suite for Perl test coverage testing
+using Test::Strict, as a percentage. The test will fail if test coverage less
+than this percentage is achieved. If not given, defaults to 100.
=item @COVERAGE_SKIP_TESTS
Directories under F<t> whose tests should be skipped when doing coverage
-testing. This can be tests that won't contribute to coverage or tests
-that don't run properly under Devel::Cover for some reason (such as ones
-that use taint checking). F<docs> and F<style> will always be skipped
-regardless of this setting.
+testing. This can be tests that won't contribute to coverage or tests that
+don't run properly under Devel::Cover for some reason (such as ones that use
+taint checking). F<docs> and F<style> will always be skipped regardless of
+this setting.
=item @CRITIC_IGNORE
-Additional directories to ignore when doing recursive perlcritic testing.
-The contents of this directory must be either top-level directory names or
+Additional directories to ignore when doing recursive perlcritic testing. The
+contents of this directory must be either top-level directory names or
directory names starting with F<tests/>.
=item $LIBRARY_PATH
Add this directory (or a F<.libs> subdirectory) relative to the top of the
-source tree to LD_LIBRARY_PATH when checking the syntax of Perl modules.
-This may be required to pick up libraries that are used by in-tree Perl
-modules so that Perl scripts can pass a syntax check.
+source tree to LD_LIBRARY_PATH when checking the syntax of Perl modules. This
+may be required to pick up libraries that are used by in-tree Perl modules so
+that Perl scripts can pass a syntax check.
=item $MINIMUM_VERSION
-Default minimum version requirement for included Perl scripts. If not
-given, defaults to 5.008.
+Default minimum version requirement for included Perl scripts. If not given,
+defaults to 5.008.
=item %MINIMUM_VERSION
Minimum version exceptions for specific directories. The keys should be
minimum versions of Perl to enforce. The value for each key should be a
-reference to an array of either top-level directory names or directory
-names starting with F<tests/>. All files in those directories will have
-that minimum Perl version constraint imposed instead of $MINIMUM_VERSION.
+reference to an array of either top-level directory names or directory names
+starting with F<tests/>. All files in those directories will have that
+minimum Perl version constraint imposed instead of $MINIMUM_VERSION.
+
+=item @MODULE_VERSION_IGNORE
+
+File names to ignore when checking that all modules in a distribution have the
+same version. Sometimes, some specific modules need separate, special version
+handling, such as modules defining database schemata for DBIx::Class, and
+can't follow the version of the larger package.
=item @POD_COVERAGE_EXCLUDE
Regexes that match method names that should be excluded from POD coverage
-testing. Normally, all methods have to be documented in the POD for a
-Perl module, but methods matching any of these regexes will be considered
-private and won't require documentation.
+testing. Normally, all methods have to be documented in the POD for a Perl
+module, but methods matching any of these regexes will be considered private
+and won't require documentation.
=item @STRICT_IGNORE
-Additional directories to ignore when doing recursive Test::Strict testing
-for C<use strict> and C<use warnings>. The contents of this directory
-must be either top-level directory names or directory names starting with
-F<tests/>.
+Additional directories to ignore when doing recursive Test::Strict testing for
+C<use strict> and C<use warnings>. The contents of this directory must be
+either top-level directory names or directory names starting with F<tests/>.
=item @STRICT_PREREQ
A list of Perl modules that have to be available in order to do meaningful
Test::Strict testing. If any of the modules cannot be loaded via C<use>,
-Test::Strict checking will be skipped. There is currently no way to
-require specific versions of the modules.
+Test::Strict checking will be skipped. There is currently no way to require
+specific versions of the modules.
=back
-No variables are exported by default, but the variables can be imported
-into the local namespace to avoid long variable names.
+No variables are exported by default, but the variables can be imported into
+the local namespace to avoid long variable names.
=head1 AUTHOR
=head1 COPYRIGHT AND LICENSE
+Copyright 2015, 2016 Russ Allbery <eagle@eyrie.org>
+
Copyright 2013, 2014 The Board of Trustees of the Leland Stanford Junior
University
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
=head1 SEE ALSO
-perlcritic(1), Test::MinimumVersion(3), Test::RRA(3),
-Test::RRA::Automake(3), Test::Strict(3)
+perlcritic(1), Test::MinimumVersion(3), Test::RRA(3), Test::RRA::Automake(3),
+Test::Strict(3)
-This module is maintained in the rra-c-util package. The current version
-is available from L<http://www.eyrie.org/~eagle/software/rra-c-util/>.
+This module is maintained in the rra-c-util package. The current version is
+available from L<https://www.eyrie.org/~eagle/software/rra-c-util/>.
The C TAP Harness test driver and libraries for TAP-based C testing are
-available from L<http://www.eyrie.org/~eagle/software/c-tap-harness/>.
+available from L<https://www.eyrie.org/~eagle/software/c-tap-harness/>.
=cut
* mkstemp.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
- * Copyright 2002, 2004, 2005, 2013 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2002, 2004, 2005, 2013, 2016 Russ Allbery <eagle@eyrie.org>
* Copyright 2009, 2010, 2011, 2013, 2014
* The Board of Trustees of the Leland Stanford Junior University
*
# 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>
count = 0;
do {
ret = read(fds[0], buf + count, buflen - count - 1);
+ if (SSIZE_MAX - count <= ret)
+ bail("maximum output size exceeded in run_child_function");
if (ret > 0)
count += ret;
if (count >= buflen - 1) {
buf = brealloc(buf, buflen);
}
} while (ret > 0);
- buf[count < 0 ? 0 : count] = '\0';
+ buf[count] = '\0';
if (waitpid(child, &rval, 0) == (pid_t) -1)
sysbail("waitpid failed");
close(fds[0]);
{
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)
process_start_internal(const char *const argv[], const char *pidfile,
bool fakeroot)
{
- size_t i, size;
+ size_t i;
int log_fd;
const char *name;
struct timeval tv;
if (fakeroot) {
for (i = 0; argv[i] != NULL; i++)
;
- size = 2 + i + 1;
- fakeroot_argv = bmalloc(size * sizeof(const char *));
+ fakeroot_argv = bcalloc(2 + i + 1, sizeof(const char *));
fakeroot_argv[0] = path_fakeroot;
fakeroot_argv[1] = "--";
for (i = 0; argv[i] != NULL; i++)
* Utility functions for tests that use subprocesses.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2009, 2010, 2013
* because they rely on additional portability code from rra-c-util.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Copyright 2011, 2012 Russ Allbery <eagle@eyrie.org>
*
* because they rely on additional portability code from rra-c-util.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Copyright 2011, 2012 Russ Allbery <eagle@eyrie.org>
*
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
* Test suite for Kerberos error handling routines.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
- * Copyright 2010, 2011, 2013
+ * Copyright 2010, 2011, 2013, 2014
* The Board of Trustees of the Leland Stanford Junior University
*
* Permission is hereby granted, free of charge, to any person obtaining a
*/
#include <config.h>
-#include <portable/krb5.h>
+#ifdef HAVE_KRB5
+# include <portable/krb5.h>
+#endif
#include <portable/system.h>
#include <tests/tap/basic.h>
#include <tests/tap/process.h>
#include <util/macros.h>
-#include <util/messages-krb5.h>
+#ifdef HAVE_KRB5
+# include <util/messages-krb5.h>
+#endif
#include <util/messages.h>
#include <util/xmalloc.h>
+/* Skip the whole test if not built with Kerberos support. */
+#ifndef HAVE_KRB5
+int
+main(void)
+{
+ skip_all("not built with Kerberos support");
+ return 0;
+}
+#else
+
/*
* Test functions.
*/
krb5_free_context(ctx);
return 0;
}
+
+#endif /* HAVE_KRB5 */
* Test suite for error handling routines.
*
* 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/>.
+ * which can be found at <https://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
*
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");
# Test suite for xmalloc and friends.
#
# 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/>.
+# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
-# Copyright 2000, 2001, 2006, 2014 Russ Allbery <eagle@eyrie.org>
+# Copyright 2000, 2001, 2006, 2014, 2016 Russ Allbery <eagle@eyrie.org>
# Copyright 2008, 2009, 2010, 2012
# The Board of Trustees of the Leland Stanford Junior University
#
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
-. "$SOURCE/tap/libtap.sh"
-cd "$BUILD/util"
+. "$C_TAP_SOURCE/tap/libtap.sh"
+cd "$C_TAP_BUILD/util"
# Run an xmalloc test. Takes the description, the expectd exit status, the
# output, and the arguments.
fi
# Total tests.
-plan 36
+plan 41
# First run the tests expected to succeed.
-ok_xmalloc "malloc small" 0 "" "m" "21" "0"
-ok_xmalloc "malloc large" 0 "" "m" "5500000" "0"
-ok_xmalloc "malloc zero" 0 "" "m" "0" "0"
-ok_xmalloc "realloc small" 0 "" "r" "21" "0"
-ok_xmalloc "realloc large" 0 "" "r" "5500000" "0"
-ok_xmalloc "strdup small" 0 "" "s" "21" "0"
-ok_xmalloc "strdup large" 0 "" "s" "5500000" "0"
-ok_xmalloc "strndup small" 0 "" "n" "21" "0"
-ok_xmalloc "strndup large" 0 "" "n" "5500000" "0"
-ok_xmalloc "calloc small" 0 "" "c" "24" "0"
-ok_xmalloc "calloc large" 0 "" "c" "5500000" "0"
-ok_xmalloc "asprintf small" 0 "" "a" "24" "0"
-ok_xmalloc "asprintf large" 0 "" "a" "5500000" "0"
-ok_xmalloc "vasprintf small" 0 "" "v" "24" "0"
-ok_xmalloc "vasprintf large" 0 "" "v" "5500000" "0"
+ok_xmalloc "malloc small" 0 "" "m" "21" "0"
+ok_xmalloc "malloc large" 0 "" "m" "30000000" "0"
+ok_xmalloc "malloc zero" 0 "" "m" "0" "0"
+ok_xmalloc "realloc small" 0 "" "r" "21" "0"
+ok_xmalloc "realloc large" 0 "" "r" "30000000" "0"
+ok_xmalloc "reallocarray small" 0 "" "y" "20" "0"
+ok_xmalloc "reallocarray large" 0 "" "y" "30000000" "0"
+ok_xmalloc "strdup small" 0 "" "s" "21" "0"
+ok_xmalloc "strdup large" 0 "" "s" "30000000" "0"
+ok_xmalloc "strndup small" 0 "" "n" "21" "0"
+ok_xmalloc "strndup large" 0 "" "n" "30000000" "0"
+ok_xmalloc "calloc small" 0 "" "c" "24" "0"
+ok_xmalloc "calloc large" 0 "" "c" "30000000" "0"
+ok_xmalloc "asprintf small" 0 "" "a" "24" "0"
+ok_xmalloc "asprintf large" 0 "" "a" "30000000" "0"
+ok_xmalloc "vasprintf small" 0 "" "v" "24" "0"
+ok_xmalloc "vasprintf large" 0 "" "v" "30000000" "0"
-# Now limit our memory to 5.5MB and then try the large ones again, all of
+# Now limit our memory to 30MB and then try the large ones again, all of
# which should fail.
#
# The exact memory limits used here are essentially black magic. They need to
# but not so large that we can't reasonably expect to allocate that much
# memory normally. The amount of memory required varies a lot based on what
# shared libraries are loaded, and if it's too small, all memory allocations
-# fail. 5.5MB seems to work reasonably well on both Solaris and Linux.
+# fail. 30MB seems to work reasonably well on both Solaris and Linux, even
+# when the program is linked with additional libraries.
#
# 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 5500000 bytes at xmalloc.c line 38" \
- "m" "5500000" "5500000"
+ "failed to malloc 30000000 bytes at xmalloc.c line 41" \
+ "m" "30000000" "30000000"
ok_xmalloc "realloc fail" 1 \
- "failed to realloc 5500000 bytes at xmalloc.c line 66" \
- "r" "5500000" "5500000"
+ "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 99" \
+ "y" "30000000" "30000000"
ok_xmalloc "strdup fail" 1 \
- "failed to strdup 5500000 bytes at xmalloc.c line 97" \
- "s" "5500000" "5500000"
+ "failed to strdup 30000000 bytes at xmalloc.c line 130" \
+ "s" "30000000" "30000000"
ok_xmalloc "strndup fail" 1 \
- "failed to strndup 5500000 bytes at xmalloc.c line 143" \
- "n" "5500000" "5500000"
+ "failed to strndup 30000000 bytes at xmalloc.c line 176" \
+ "n" "30000000" "30000000"
ok_xmalloc "calloc fail" 1 \
- "failed to calloc 5500000 bytes at xmalloc.c line 167" \
- "c" "5500000" "5500000"
+ "failed to calloc 30000000 bytes at xmalloc.c line 200" \
+ "c" "30000000" "30000000"
ok_xmalloc "asprintf fail" 1 \
- "failed to asprintf 5500000 bytes at xmalloc.c line 191" \
- "a" "5500000" "5500000"
+ "failed to asprintf 30000000 bytes at xmalloc.c line 224" \
+ "a" "30000000" "30000000"
ok_xmalloc "vasprintf fail" 1 \
- "failed to vasprintf 5500000 bytes at xmalloc.c line 210" \
- "v" "5500000" "5500000"
+ "failed to vasprintf 30000000 bytes at xmalloc.c line 243" \
+ "v" "30000000" "30000000"
# Check our custom error handler.
-ok_xmalloc "malloc custom" 1 "malloc 5500000 xmalloc.c 38" \
- "M" "5500000" "5500000"
-ok_xmalloc "realloc custom" 1 "realloc 5500000 xmalloc.c 66" \
- "R" "5500000" "5500000"
-ok_xmalloc "strdup custom" 1 "strdup 5500000 xmalloc.c 97" \
- "S" "5500000" "5500000"
-ok_xmalloc "strndup custom" 1 "strndup 5500000 xmalloc.c 143" \
- "N" "5500000" "5500000"
-ok_xmalloc "calloc custom" 1 "calloc 5500000 xmalloc.c 167" \
- "C" "5500000" "5500000"
-ok_xmalloc "asprintf custom" 1 "asprintf 5500000 xmalloc.c 191" \
- "A" "5500000" "5500000"
-ok_xmalloc "vasprintf custom" 1 "vasprintf 5500000 xmalloc.c 210" \
- "V" "5500000" "5500000"
+ok_xmalloc "malloc custom" 1 "malloc 30000000 xmalloc.c 41" \
+ "M" "30000000" "30000000"
+ok_xmalloc "realloc custom" 1 "realloc 30000000 xmalloc.c 69" \
+ "R" "30000000" "30000000"
+ok_xmalloc "reallocarray custom" 1 "reallocarray 30000000 xmalloc.c 99" \
+ "Y" "30000000" "30000000"
+ok_xmalloc "strdup custom" 1 "strdup 30000000 xmalloc.c 130" \
+ "S" "30000000" "30000000"
+ok_xmalloc "strndup custom" 1 "strndup 30000000 xmalloc.c 176" \
+ "N" "30000000" "30000000"
+ok_xmalloc "calloc custom" 1 "calloc 30000000 xmalloc.c 200" \
+ "C" "30000000" "30000000"
+ok_xmalloc "asprintf custom" 1 "asprintf 30000000 xmalloc.c 224" \
+ "A" "30000000" "30000000"
+ok_xmalloc "vasprintf custom" 1 "vasprintf 30000000 xmalloc.c 243" \
+ "V" "30000000" "30000000"
# Check the smaller ones again just for grins.
-ok_xmalloc "malloc retry" 0 "" "m" "21" "5500000"
-ok_xmalloc "realloc retry" 0 "" "r" "32" "5500000"
-ok_xmalloc "strdup retry" 0 "" "s" "64" "5500000"
-ok_xmalloc "strndup retry" 0 "" "n" "20" "5500000"
-ok_xmalloc "calloc retry" 0 "" "c" "24" "5500000"
-ok_xmalloc "asprintf retry" 0 "" "a" "30" "5500000"
-ok_xmalloc "vasprintf retry" 0 "" "v" "35" "5500000"
+ok_xmalloc "malloc retry" 0 "" "m" "21" "30000000"
+ok_xmalloc "realloc retry" 0 "" "r" "32" "30000000"
+ok_xmalloc "reallocarray retry" 0 "" "y" "32" "30000000"
+ok_xmalloc "strdup retry" 0 "" "s" "64" "30000000"
+ok_xmalloc "strndup retry" 0 "" "n" "20" "30000000"
+ok_xmalloc "calloc retry" 0 "" "c" "24" "30000000"
+ok_xmalloc "asprintf retry" 0 "" "a" "30" "30000000"
+ok_xmalloc "vasprintf retry" 0 "" "v" "35" "30000000"
* Test suite for xmalloc and family.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Copyright 2000, 2001, 2006 Russ Allbery <eagle@eyrie.org>
- * Copyright 2008, 2012, 2013
+ * Copyright 2008, 2012, 2013, 2014
* The Board of Trustees of the Leland Stanford Junior University
*
* Permission is hereby granted, free of charge, to any person obtaining a
#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>
}
+/*
+ * Like test_realloc, but test allocating an array instead. Returns true on
+ * success, false on any failure.
+ */
+static int
+test_reallocarray(size_t n, size_t size)
+{
+ char *buffer;
+ size_t i;
+
+ buffer = xmalloc(10);
+ if (buffer == NULL)
+ return 0;
+ memset(buffer, 1, 10);
+ buffer = xreallocarray(buffer, n, size);
+ if (buffer == NULL)
+ return 0;
+ if (n > 0 && size > 0)
+ memset(buffer + 10, 2, (n * size) - 10);
+ for (i = 0; i < 10; i++)
+ if (buffer[i] != 1)
+ return 0;
+ for (i = 10; i < n * size; i++)
+ if (buffer[i] != 2)
+ return 0;
+ free(buffer);
+ return 1;
+}
+
+
/*
* Generate a string of the size indicated, call xstrdup on it, and then
* ensure the result matches. Returns true on success, false on any failure.
/* 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;
syswarn("Can't set data limit to %lu", (unsigned long) limit);
exit(2);
}
- if (size < limit || code == 'r') {
- test_size = code == 'r' ? 10 : size;
+ if (size < limit || code == 'r' || code == 'y') {
+ test_size = (code == 'r' || code == 'y') ? 10 : size;
if (test_size == 0)
test_size = 1;
tmp = malloc(test_size);
case 'c': exit(test_calloc(size) ? willfail : 1);
case 'm': exit(test_malloc(size) ? willfail : 1);
case 'r': exit(test_realloc(size) ? willfail : 1);
+ case 'y': exit(test_reallocarray(4, size / 4) ? willfail : 1);
case 's': exit(test_strdup(size) ? willfail : 1);
case 'n': exit(test_strndup(size) ? willfail : 1);
case 'a': exit(test_asprintf(size) ? willfail : 1);
Heimdal to use it.
The current version of this program is available from its web page at
-L<http://www.eyrie.org/~eagle/software/krb5-strength/> as part of the
+L<https://www.eyrie.org/~eagle/software/krb5-strength/> as part of the
krb5-strength package.
=head1 AUTHOR
=head1 COPYRIGHT AND LICENSE
+Copyright 2016 Russ Allbery <eagle@eyrie.org>
+
Copyright 2010, 2013, 2014 The Board of Trustees of the Leland Stanford
Junior University
=head1 COPYRIGHT AND LICENSE
+Copyright 2016 Russ Allbery <eagle@eyrie.org>
+
Copyright 2013, 2014 The Board of Trustees of the Leland Stanford Junior
University
The cdb file format is defined at L<http://cr.yp.to/cdb.html>.
The current version of this program is available from its web page at
-L<http://www.eyrie.org/~eagle/software/krb5-strength/> as part of the
+L<https://www.eyrie.org/~eagle/software/krb5-strength/> as part of the
krb5-strength package.
=cut
* Some standard helpful macros.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
*
#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__))
* formatted message.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2006, 2007, 2008, 2009, 2010, 2013
* Prototypes for error handling for Kerberos.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2006, 2007, 2008, 2009, 2010, 2013
* an error code to get the Kerberos error.
*/
void die_krb5(krb5_context, krb5_error_code, const char *, ...)
- __attribute__((__nonnull__, __noreturn__, __format__(printf, 3, 4)));
+ __attribute__((__nonnull__(3), __noreturn__, __format__(printf, 3, 4)));
void warn_krb5(krb5_context, krb5_error_code, const char *, ...)
- __attribute__((__nonnull__, __format__(printf, 3, 4)));
+ __attribute__((__nonnull__(3), __format__(printf, 3, 4)));
/* Undo default visibility change. */
#pragma GCC visibility pop
* va_list, and the applicable errno value (if any).
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
- * Copyright 2008, 2009, 2010, 2013
+ * Copyright 2015, 2016 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2008, 2009, 2010, 2013, 2014
* The Board of Trustees of the Leland Stanford Junior University
* Copyright (c) 2004, 2005, 2006
* by Internet Systems Consortium, Inc. ("ISC")
if (*list != stdout_handlers && *list != stderr_handlers)
free(*list);
- *list = xmalloc(sizeof(message_handler_func) * (count + 1));
+ *list = xcalloc(count + 1, sizeof(message_handler_func));
for (i = 0; i < count; i++)
(*list)[i] = (message_handler_func) va_arg(args, message_handler_func);
(*list)[count] = NULL;
* 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;
exit(message_fatal_cleanup ? (*message_fatal_cleanup)() : 1);
}
status = vsnprintf(buffer, len + 1, fmt, args);
- if (status < 0) {
+ if (status < 0 || (size_t) status >= len + 1) {
warn("failed to format output with vsnprintf in syslog handler");
free(buffer);
return;
* Prototypes for message and error reporting (possibly fatal).
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
+ * Written by Russ Allbery <eagle@eyrie.org>
+ * Copyright 2015 Russ Allbery <eagle@eyrie.org>
* Copyright 2008, 2010, 2013, 2014
* The Board of Trustees of the Leland Stanford Junior University
* Copyright (c) 2004, 2005, 2006
* 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);
* buffer = xmalloc(1024);
* xrealloc(buffer, 2048);
* free(buffer);
- * buffer = xcalloc(1024);
+ * buffer = xcalloc(1, 1024);
* free(buffer);
* buffer = xstrdup(string);
* free(buffer);
* allocation function will try its allocation again (calling the handler
* again if it still fails).
*
+ * xreallocarray behaves the same as the OpenBSD reallocarray function but for
+ * the same error checking, which in turn is the same as realloc but with
+ * calloc-style arguments and size overflow checking.
+ *
* xstrndup behaves like xstrdup but only copies the given number of
* characters. It allocates an additional byte over its second argument and
* always nul-terminates the string.
* line number to these functions.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Copyright 2012, 2013
+ * 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
* by Internet Systems Consortium, Inc. ("ISC")
}
+void *
+x_reallocarray(void *p, size_t n, size_t size, const char *file, int line)
+{
+ void *newp;
+
+ newp = reallocarray(p, n, size);
+ while (newp == NULL && size > 0 && n > 0) {
+ (*xmalloc_error_handler)("reallocarray", n * size, file, line);
+ newp = reallocarray(p, n, size);
+ }
+ return newp;
+}
+
+
char *
x_strdup(const char *s, const char *file, int line)
{
status = vasprintf(strp, fmt, args_copy);
va_end(args_copy);
}
+ va_end(args);
}
#else /* !(HAVE_C99_VAMACROS || HAVE_GNU_VAMACROS) */
void
status = vasprintf(strp, fmt, args_copy);
va_end(args_copy);
}
+ va_end(args);
}
#endif /* !(HAVE_C99_VAMACROS || HAVE_GNU_VAMACROS) */
* Prototypes for malloc routines with failure handling.
*
* 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/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Copyright 2010, 2012, 2013
+ * Copyright 2010, 2012, 2013, 2014
* The Board of Trustees of the Leland Stanford Junior University
* Copyright (c) 2004, 2005, 2006
* by Internet Systems Consortium, Inc. ("ISC")
#define xstrdup(p) x_strdup((p), __FILE__, __LINE__)
#define xstrndup(p, size) x_strndup((p), (size), __FILE__, __LINE__)
#define xvasprintf(p, f, a) x_vasprintf((p), (f), (a), __FILE__, __LINE__)
+#define xreallocarray(p, n, size) \
+ x_reallocarray((p), (n), (size), __FILE__, __LINE__)
/*
* asprintf is a special case since it takes variable arguments. If we have
__attribute__((__alloc_size__(1), __malloc__, __nonnull__));
void *x_realloc(void *, size_t, const char *, int)
__attribute__((__alloc_size__(2), __malloc__, __nonnull__(3)));
+void *x_reallocarray(void *, size_t, size_t, const char *, int)
+ __attribute__((__alloc_size__(2, 3), __malloc__, __nonnull__(4)));
char *x_strdup(const char *, const char *, int)
__attribute__((__malloc__, __nonnull__));
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