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