Synchronize support/ infrastructure with master

This commit updates the support/ subdirectory to
commit 2714c5f3c9
on the master branch and modifies Makeconfig,
Rules, and extra-lib.mk accordingly.
This commit is contained in:
Arjun Shankar 2017-06-07 11:46:24 +02:00
parent a29331702f
commit 4c5785aa12
119 changed files with 7306 additions and 3 deletions

View File

@ -394,6 +394,9 @@ ifndef after-link
after-link =
endif
# Additional libraries to link into every test.
link-extra-libs-tests = $(libsupport)
# Command for linking PIE programs with the C library.
ifndef +link-pie
+link-pie-before-libc = $(CC) -pie -Wl,-O1 -nostdlib -nostartfiles -o $@ \
@ -503,7 +506,7 @@ link-libc = $(link-libc-rpath-link) $(link-libc-before-gnulib) $(gnulib)
link-libc-tests = $(link-libc-tests-rpath-link) \
$(link-libc-before-gnulib) $(gnulib-tests)
# This is how to find at build-time things that will be installed there.
rpath-dirs = math elf dlfcn nss nis rt resolv crypt mathvec
rpath-dirs = math elf dlfcn nss nis rt resolv crypt mathvec support
rpath-link = \
$(common-objdir):$(subst $(empty) ,:,$(patsubst ../$(subdir),.,$(rpath-dirs:%=$(common-objpfx)%)))
else
@ -850,7 +853,7 @@ libio-include = -I$(..)libio
# List of non-library modules that we build.
built-modules = iconvprogs iconvdata ldconfig lddlibc4 libmemusage \
libSegFault libpcprofile librpcsvc locale-programs \
memusagestat nonlib nscd extramodules libnldbl
memusagestat nonlib nscd extramodules libnldbl libsupport
in-module = $(subst -,_,$(firstword $(libof-$(basename $(@F))) \
$(libof-$(<F)) \
@ -1089,6 +1092,12 @@ libm = $(common-objpfx)math/libm.a
libmvec = $(common-objpfx)mathvec/libmvec.a
endif
ifeq ($(build-shared),yes)
libsupport = $(common-objpfx)support/libsupport_nonshared.a
else
libsupport = $(common-objpfx)support/libsupport.a
endif
# These are the subdirectories containing the library source. The order
# is more or less arbitrary. The sorting step will take care of the
# dependencies.
@ -1096,7 +1105,7 @@ all-subdirs = csu assert ctype locale intl catgets math setjmp signal \
stdlib stdio-common libio malloc string wcsmbs time dirent \
grp pwd posix io termios resource misc socket sysvipc gmon \
gnulib iconv iconvdata wctype manual shadow gshadow po argp \
crypt localedata timezone rt conform debug mathvec \
crypt localedata timezone rt conform debug mathvec support \
$(add-on-subdirs) dlfcn elf
ifndef avoid-generated

3
Rules
View File

@ -149,6 +149,7 @@ endif
ifneq "$(strip $(binaries-shared-tests))" ""
$(addprefix $(objpfx),$(binaries-shared-tests)): %: %.o \
$(link-extra-libs-tests) \
$(sort $(filter $(common-objpfx)lib%,$(link-libc))) \
$(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
$(+link-tests)
@ -156,6 +157,7 @@ endif
ifneq "$(strip $(binaries-pie-tests))" ""
$(addprefix $(objpfx),$(binaries-pie-tests)): %: %.o \
$(link-extra-libs-tests) \
$(sort $(filter $(common-objpfx)lib%,$(link-libc))) \
$(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
$(+link-pie-tests)
@ -177,6 +179,7 @@ endif
ifneq "$(strip $(binaries-static-tests))" ""
$(addprefix $(objpfx),$(binaries-static-tests)): %: %.o \
$(link-extra-libs-tests) \
$(sort $(filter $(common-objpfx)lib%,$(link-libc-static-tests))) \
$(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
$(+link-static-tests)

View File

@ -5,6 +5,9 @@
# The variable $($(lib)-routines) defines the list of modules
# to be included in that library. A sysdep Makefile can add to
# $(lib)-sysdep_routines to include additional modules.
#
# Libraries listed in $(extra-libs-noinstall) are built, but not
# installed.
lib := $(firstword $(extra-libs-left))
extra-libs-left := $(filter-out $(lib),$(extra-libs-left))
@ -28,7 +31,9 @@ extra-objs := $(extra-objs)
all-$(lib)-routines := $($(lib)-routines) $($(lib)-sysdep_routines)
# Add each flavor of library to the lists of things to build and install.
ifeq (,$(filter $(lib), $(extra-libs-noinstall)))
install-lib += $(foreach o,$(object-suffixes-$(lib)),$(lib:lib%=$(libtype$o)))
endif
extra-objs += $(foreach o,$(filter-out .os .oS,$(object-suffixes-$(lib))),\
$(patsubst %,%$o,$(filter-out \
$($(lib)-shared-only-routines),\

110
scripts/backport-support.sh Normal file
View File

@ -0,0 +1,110 @@
#!/bin/bash
# Create a patch which backports the support/ subdirectory.
# Copyright (C) 2017 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# The GNU C Library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with the GNU C Library; if not, see
# <http://www.gnu.org/licenses/>.
# This script does not backport the Makefile tweaks outside the
# support/ directory (which need to be backported separately), or the
# changes to test-skeleton.c (which should not be backported).
set -e
export LC_ALL=C
export GIT_CONFIG=/dev/null
export GTT_CONFIG_NOSYSTEM=0
export GIT_PAGER=
usage () {
cat >&2 <<EOF
usage: $0 {patch|commit}
EOF
exit 1
}
if test $# -ne 1 ; then
usage
fi
command="$1"
case "$command" in
patch|commit)
;;
*)
usage
;;
esac
# The upstream branch to work on.
branch=origin/master
# The commit which added the support/ directory.
initial_commit=c23de0aacbeaa7a091609b35764bed931475a16d
# We backport the support directory and this script. Directories need
# to end in a /.
patch_targets="support/ scripts/backport-support.sh"
latest_commit="$(git log --max-count=1 --pretty=format:%H "$branch" -- \
$patch_targets)"
# Simplify the branch name somewhat for reporting.
branch_name="$(echo "$branch" | sed s,^origin/,,)"
command_patch () {
cat <<EOF
This patch creates the contents of the support/ directory up to this
upstream commit on the $branch_name branch:
EOF
git log --max-count=1 "$latest_commit"
echo
git diff "$initial_commit"^.."$latest_commit" $patch_targets
echo "# Before applying the patch, run this command:" >&2
echo "# rm -rf $patch_targets" >&2
}
command_commit () {
git status --porcelain | while read line ; do
echo "error: working copy is not clean, cannot commit" >&2
exit 1
done
for path in $patch_targets; do
echo "# Processing $path" >&2
case "$path" in
[a-zA-Z0-9]*/)
# Directory.
git rm --cached --ignore-unmatch -r "$path"
rm -rf "$path"
git read-tree --prefix="$path" "$latest_commit":"$path"
git checkout "$path"
;;
*)
# File.
git show "$latest_commit":"$path" > "$path"
git add "$path"
esac
done
git commit -m "Synchronize support/ infrastructure with $branch_name
This commit updates the support/ subdirectory to
commit $latest_commit
on the $branch_name branch.
"
}
command_$command

146
support/Makefile Normal file
View File

@ -0,0 +1,146 @@
# Makefile for support library, used only at build and test time
# Copyright (C) 2016-2017 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# The GNU C Library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with the GNU C Library; if not, see
# <http://www.gnu.org/licenses/>.
subdir := support
include ../Makeconfig
extra-libs := libsupport
extra-libs-others = $(extra-libs)
extra-libs-noinstall := $(extra-libs)
libsupport-routines = \
check \
check_addrinfo \
check_dns_packet \
check_hostent \
check_netent \
delayed_exit \
ignore_stderr \
oom_error \
resolv_test \
set_fortify_handler \
support-xstat \
support_become_root \
support_can_chroot \
support_capture_subprocess \
support_capture_subprocess_check \
support_enter_network_namespace \
support_format_address_family \
support_format_addrinfo \
support_format_dns_packet \
support_format_herrno \
support_format_hostent \
support_format_netent \
support_isolate_in_subprocess \
support_record_failure \
support_run_diff \
support_shared_allocate \
support_write_file_string \
support_test_main \
support_test_verify_impl \
temp_file \
write_message \
xaccept \
xaccept4 \
xasprintf \
xbind \
xcalloc \
xchroot \
xclose \
xconnect \
xdup2 \
xfclose \
xfopen \
xfork \
xgetsockname \
xlisten \
xmalloc \
xmemstream \
xmkdir \
xmmap \
xmunmap \
xopen \
xpipe \
xpoll \
xpthread_attr_destroy \
xpthread_attr_init \
xpthread_attr_setdetachstate \
xpthread_attr_setstacksize \
xpthread_barrier_destroy \
xpthread_barrier_init \
xpthread_barrier_wait \
xpthread_cancel \
xpthread_check_return \
xpthread_cond_wait \
xpthread_create \
xpthread_detach \
xpthread_join \
xpthread_mutex_consistent \
xpthread_mutex_destroy \
xpthread_mutex_init \
xpthread_mutex_lock \
xpthread_mutex_unlock \
xpthread_mutexattr_destroy \
xpthread_mutexattr_init \
xpthread_mutexattr_setprotocol \
xpthread_mutexattr_setpshared \
xpthread_mutexattr_setrobust \
xpthread_mutexattr_settype \
xpthread_once \
xpthread_sigmask \
xpthread_spin_lock \
xpthread_spin_unlock \
xrealloc \
xrecvfrom \
xsendto \
xsetsockopt \
xsocket \
xstrdup \
xwaitpid \
xwrite \
libsupport-static-only-routines := $(libsupport-routines)
# Only build one variant of the library.
libsupport-inhibit-o := .os
ifeq ($(build-shared),yes)
libsupport-inhibit-o += .o
endif
tests = \
README-testing \
tst-support-namespace \
tst-support_capture_subprocess \
tst-support_format_dns_packet \
tst-support_record_failure \
ifeq ($(run-built-tests),yes)
tests-special = \
$(objpfx)tst-support_record_failure-2.out
$(objpfx)tst-support_record_failure-2.out: tst-support_record_failure-2.sh \
$(objpfx)tst-support_record_failure
$(SHELL) $< $(common-objpfx) '$(test-program-prefix-before-env)' \
'$(run-program-env)' '$(test-program-prefix-after-env)' \
> $@; \
$(evaluate-test)
endif
$(objpfx)tst-support_format_dns_packet: $(common-objpfx)resolv/libresolv.so
include ../Rules

29
support/README Normal file
View File

@ -0,0 +1,29 @@
This subdirectory contains infrastructure which is not put into
installed libraries, but may be linked into programs (installed or
not) and tests.
# Error-checking wrappers
These wrappers test for error return codes an terminate the process on
error. They are declared in these header files:
* support.h
* xsignal.h
* xthread.h
In general, new wrappers should be added to support.h if possible.
However, support.h must remain fully compatible with C90 and therefore
cannot include headers which use identifers not reserved in C90. If
the wrappers need additional types, additional headers such as
signal.h need to be introduced.
# Test framework
The test framework provides a main program for tests, including a
timeout for hanging tests. See README-testing.c for a minimal
example, and test-driver.c for details how to use it. The following
header files provide related declarations:
* check.h
* temp_file.h
* test-driver.h

19
support/README-testing.c Normal file
View File

@ -0,0 +1,19 @@
/* This file contains an example test case which shows minimal use of
the test framework. Additional testing hooks are described in
<support/test-driver.c>. */
/* This function will be called from the test driver. */
static int
do_test (void)
{
if (3 == 5)
/* Indicate failure. */
return 1;
else
/* Indicate success. */
return 0;
}
/* This file references do_test above and contains the definition of
the main function. */
#include <support/test-driver.c>

View File

@ -0,0 +1,61 @@
/* Capture output from a subprocess.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef SUPPORT_CAPTURE_SUBPROCESS_H
#define SUPPORT_CAPTURE_SUBPROCESS_H
#include <support/xmemstream.h>
struct support_capture_subprocess
{
struct xmemstream out;
struct xmemstream err;
int status;
};
/* Invoke CALLBACK (CLOSURE) in a subprocess and capture standard
output, standard error, and the exit status. The out.buffer and
err.buffer members in the result are null-terminated strings which
can be examined by the caller (out.out and err.out are NULL). */
struct support_capture_subprocess support_capture_subprocess
(void (*callback) (void *), void *closure);
/* Deallocate the subprocess data captured by
support_capture_subprocess. */
void support_capture_subprocess_free (struct support_capture_subprocess *);
enum support_capture_allow
{
/* No output is allowed. */
sc_allow_none = 0x01,
/* Output to stdout is permitted. */
sc_allow_stdout = 0x02,
/* Output to standard error is permitted. */
sc_allow_stderr = 0x04,
};
/* Check that the subprocess exited with STATUS and that only the
allowed outputs happened. ALLOWED is a combination of
support_capture_allow flags. Report errors under the CONTEXT
message. */
void support_capture_subprocess_check (struct support_capture_subprocess *,
const char *context, int status,
int allowed)
__attribute__ ((nonnull (1, 2)));
#endif /* SUPPORT_CAPTURE_SUBPROCESS_H */

57
support/check.c Normal file
View File

@ -0,0 +1,57 @@
/* Support code for reporting test results.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/check.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/test-driver.h>
static void
print_failure (const char *file, int line, const char *format, va_list ap)
{
printf ("error: %s:%d: ", file, line);
vprintf (format, ap);
puts ("");
}
int
support_print_failure_impl (const char *file, int line,
const char *format, ...)
{
support_record_failure ();
va_list ap;
va_start (ap, format);
print_failure (file, line, format, ap);
va_end (ap);
return 1;
}
void
support_exit_failure_impl (int status, const char *file, int line,
const char *format, ...)
{
if (status != EXIT_SUCCESS && status != EXIT_UNSUPPORTED)
support_record_failure ();
va_list ap;
va_start (ap, format);
print_failure (file, line, format, ap);
va_end (ap);
exit (status);
}

94
support/check.h Normal file
View File

@ -0,0 +1,94 @@
/* Functionality for reporting test results.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef SUPPORT_CHECK_H
#define SUPPORT_CHECK_H
#include <sys/cdefs.h>
__BEGIN_DECLS
/* Record a test failure, print the failure message to standard output
and return 1. */
#define FAIL_RET(...) \
return support_print_failure_impl (__FILE__, __LINE__, __VA_ARGS__)
/* Print the failure message and terminate the process with STATUS.
Record a the process as failed if STATUS is neither EXIT_SUCCESS
nor EXIT_UNSUPPORTED. */
#define FAIL_EXIT(status, ...) \
support_exit_failure_impl (status, __FILE__, __LINE__, __VA_ARGS__)
/* Record a test failure, print the failure message and terminate with
exit status 1. */
#define FAIL_EXIT1(...) \
support_exit_failure_impl (1, __FILE__, __LINE__, __VA_ARGS__)
/* Print failure message and terminate with as unsupported test (exit
status of 77). */
#define FAIL_UNSUPPORTED(...) \
support_exit_failure_impl (77, __FILE__, __LINE__, __VA_ARGS__)
/* Record a test failure (but continue executing) if EXPR evaluates to
false. */
#define TEST_VERIFY(expr) \
({ \
if (expr) \
; \
else \
support_test_verify_impl (-1, __FILE__, __LINE__, #expr); \
})
/* Record a test failure and exit if EXPR evaluates to false. */
#define TEST_VERIFY_EXIT(expr) \
({ \
if (expr) \
; \
else \
support_test_verify_impl (1, __FILE__, __LINE__, #expr); \
})
int support_print_failure_impl (const char *file, int line,
const char *format, ...)
__attribute__ ((nonnull (1), format (printf, 3, 4)));
void support_exit_failure_impl (int exit_status,
const char *file, int line,
const char *format, ...)
__attribute__ ((noreturn, nonnull (2), format (printf, 4, 5)));
void support_test_verify_impl (int status, const char *file, int line,
const char *expr);
/* Record a test failure. This function returns and does not
terminate the process. The failure counter is stored in a shared
memory mapping, so that failures reported in child processes are
visible to the parent process and test driver. This function
depends on initialization by an ELF constructor, so it can only be
invoked after the test driver has run. Note that this function
does not support reporting failures from a DSO. */
void support_record_failure (void);
/* Internal function called by the test driver. */
int support_report_failure (int status)
__attribute__ ((weak, warn_unused_result));
/* Internal function used to test the failure recording framework. */
void support_record_failure_reset (void);
__END_DECLS
#endif /* SUPPORT_CHECK_H */

42
support/check_addrinfo.c Normal file
View File

@ -0,0 +1,42 @@
/* Compare struct addrinfo values against a formatted string.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/check_nss.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/check.h>
#include <support/format_nss.h>
#include <support/run_diff.h>
void
check_addrinfo (const char *query_description, struct addrinfo *ai, int ret,
const char *expected)
{
char *formatted = support_format_addrinfo (ai, ret);
if (strcmp (formatted, expected) != 0)
{
support_record_failure ();
printf ("error: addrinfo comparison failure\n");
if (query_description != NULL)
printf ("query: %s\n", query_description);
support_run_diff ("expected", expected,
"actual", formatted);
}
free (formatted);
}

View File

@ -0,0 +1,42 @@
/* Check that a DNS packet buffer has the expected contents.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/check_nss.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/check.h>
#include <support/format_nss.h>
#include <support/run_diff.h>
void
check_dns_packet (const char *query_description,
const unsigned char *buffer, size_t length,
const char *expected)
{
char *formatted = support_format_dns_packet (buffer, length);
if (strcmp (formatted, expected) != 0)
{
support_record_failure ();
printf ("error: packet comparison failure\n");
if (query_description != NULL)
printf ("query: %s\n", query_description);
support_run_diff ("expected", expected, "actual", formatted);
}
free (formatted);
}

42
support/check_hostent.c Normal file
View File

@ -0,0 +1,42 @@
/* Compare struct hostent values against a formatted string.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/check_nss.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/check.h>
#include <support/format_nss.h>
#include <support/run_diff.h>
void
check_hostent (const char *query_description, struct hostent *h,
const char *expected)
{
char *formatted = support_format_hostent (h);
if (strcmp (formatted, expected) != 0)
{
support_record_failure ();
printf ("error: hostent comparison failure\n");
if (query_description != NULL)
printf ("query: %s\n", query_description);
support_run_diff ("expected", expected,
"actual", formatted);
}
free (formatted);
}

42
support/check_netent.c Normal file
View File

@ -0,0 +1,42 @@
/* Compare struct netent values against a formatted string.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/check_nss.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/check.h>
#include <support/format_nss.h>
#include <support/run_diff.h>
void
check_netent (const char *query_description, struct netent *e,
const char *expected)
{
char *formatted = support_format_netent (e);
if (strcmp (formatted, expected) != 0)
{
support_record_failure ();
printf ("error: netent comparison failure\n");
if (query_description != NULL)
printf ("query: %s\n", query_description);
support_run_diff ("expected", expected,
"actual", formatted);
}
free (formatted);
}

42
support/check_nss.h Normal file
View File

@ -0,0 +1,42 @@
/* Test verification functions for NSS- and DNS-related data.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef SUPPORT_CHECK_NSS_H
#define SUPPORT_CHECK_NSS_H
#include <netdb.h>
#include <sys/cdefs.h>
__BEGIN_DECLS
/* Compare the data structures against the expected values (which have
to be formatted according to the support_format_* functions in
<support/format_nss.h>). If there is a difference, a delayed test
failure is recorded, and a diff is written to standard output. */
void check_addrinfo (const char *query_description,
struct addrinfo *, int ret, const char *expected);
void check_dns_packet (const char *query_description,
const unsigned char *, size_t, const char *expected);
void check_hostent (const char *query_description,
struct hostent *, const char *expected);
void check_netent (const char *query_description,
struct netent *, const char *expected);
__END_DECLS
#endif /* SUPPORT_CHECK_NSS_H */

55
support/delayed_exit.c Normal file
View File

@ -0,0 +1,55 @@
/* Time-triggered process termination.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
#include <support/xsignal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/check.h>
#include <time.h>
static void *
delayed_exit_thread (void *seconds_as_ptr)
{
int seconds = (uintptr_t) seconds_as_ptr;
struct timespec delay = { seconds, 0 };
struct timespec remaining = { 0 };
if (nanosleep (&delay, &remaining) != 0)
FAIL_EXIT1 ("nanosleep: %m");
/* Exit the process sucessfully. */
exit (0);
return NULL;
}
void
delayed_exit (int seconds)
{
/* Create the new thread with all signals blocked. */
sigset_t all_blocked;
sigfillset (&all_blocked);
sigset_t old_set;
xpthread_sigmask (SIG_SETMASK, &all_blocked, &old_set);
/* Create a detached thread. */
pthread_t thr = xpthread_create
(NULL, delayed_exit_thread, (void *) (uintptr_t) seconds);
xpthread_detach (thr);
/* Restore the original signal mask. */
xpthread_sigmask (SIG_SETMASK, &old_set, NULL);
}

41
support/format_nss.h Normal file
View File

@ -0,0 +1,41 @@
/* String formatting functions for NSS- and DNS-related data.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef SUPPORT_FORMAT_NSS_H
#define SUPPORT_FORMAT_NSS_H
#include <netdb.h>
#include <sys/cdefs.h>
__BEGIN_DECLS
/* The following functions format their arguments as human-readable
strings (which can span multiple lines). The caller must free the
returned buffer. For NULL pointers or failure status arguments,
error variables such as h_errno and errno are included in the
result. */
char *support_format_address_family (int);
char *support_format_addrinfo (struct addrinfo *, int ret);
char *support_format_dns_packet (const unsigned char *buffer, size_t length);
char *support_format_herrno (int);
char *support_format_hostent (struct hostent *);
char *support_format_netent (struct netent *);
__END_DECLS
#endif /* SUPPORT_FORMAT_NSS_H */

38
support/ignore_stderr.c Normal file
View File

@ -0,0 +1,38 @@
/* Avoid all the buffer overflow messages on stderr.
Copyright (C) 2015-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/support.h>
#include <fcntl.h>
#include <paths.h>
#include <stdlib.h>
#include <unistd.h>
void
ignore_stderr (void)
{
int fd = open (_PATH_DEVNULL, O_WRONLY);
if (fd == -1)
close (STDERR_FILENO);
else
{
dup2 (fd, STDERR_FILENO);
close (fd);
}
setenv ("LIBC_FATAL_STDERR_", "1", 1);
}

65
support/namespace.h Normal file
View File

@ -0,0 +1,65 @@
/* Entering namespaces for test case isolation.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef SUPPORT_NAMESPACE_H
#define SUPPORT_NAMESPACE_H
#include <stdbool.h>
#include <sys/cdefs.h>
__BEGIN_DECLS
/* Attempts to become root (or acquire root-like privileges), possibly
with the help of user namespaces. Return true if (restricted) root
privileges could be attained in some way. Print diagnostics to
standard output.
Note that this function generally has to be called before a process
becomes multi-threaded, otherwise it may fail with insufficient
privileges on systems which would support this operation for
single-threaded processes. */
bool support_become_root (void);
/* Return true if this process can perform a chroot operation. In
general, this is only possible if support_become_root has been
called. Note that the actual test is performed in a subprocess,
after fork, so that the file system root of the original process is
not changed. */
bool support_can_chroot (void);
/* Enter a network namespace (and a UTS namespace if possible) and
configure the loopback interface. Return true if a network
namespace could be created. Print diagnostics to standard output.
If a network namespace could be created, but networking in it could
not be configured, terminate the process. It is recommended to
call support_become_root before this function so that the process
has sufficient privileges. */
bool support_enter_network_namespace (void);
/* Return true if support_enter_network_namespace managed to enter a
UTS namespace. */
bool support_in_uts_namespace (void);
/* Invoke CALLBACK (CLOSURE) in a subprocess created using fork.
Terminate the calling process if the subprocess exits with a
non-zero exit status. */
void support_isolate_in_subprocess (void (*callback) (void *), void *closure);
__END_DECLS
#endif

29
support/oom_error.c Normal file
View File

@ -0,0 +1,29 @@
/* Reporting out-of-memory errors.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/support.h>
#include <stdio.h>
#include <stdlib.h>
void
oom_error (const char *function, size_t size)
{
printf ("%s: unable to allocate %zu bytes: %m\n", function, size);
exit (1);
}

1202
support/resolv_test.c Normal file

File diff suppressed because it is too large Load Diff

180
support/resolv_test.h Normal file
View File

@ -0,0 +1,180 @@
/* DNS test framework and libresolv redirection.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef SUPPORT_RESOLV_TEST_H
#define SUPPORT_RESOLV_TEST_H
#include <arpa/nameser.h>
#include <stdbool.h>
#include <sys/cdefs.h>
__BEGIN_DECLS
/* Information about EDNS properties of a DNS query. */
struct resolv_edns_info
{
bool active;
uint8_t extended_rcode;
uint8_t version;
uint16_t flags;
uint16_t payload_size;
};
/* This struct provides context information when the response callback
specified in struct resolv_redirect_config is invoked. */
struct resolv_response_context
{
const unsigned char *query_buffer;
size_t query_length;
int server_index;
bool tcp;
struct resolv_edns_info edns;
};
/* This opaque struct is used to construct responses from within the
response callback function. */
struct resolv_response_builder;
/* This opaque struct collects information about the resolver testing
currently in progress. */
struct resolv_test;
enum
{
/* Maximum number of test servers supported by the framework. */
resolv_max_test_servers = 3,
};
/* Configuration settings specific to individual test servers. */
struct resolv_redirect_server_config
{
bool disable_tcp; /* If true, no TCP server is listening. */
bool disable_udp; /* If true, no UDP server is listening. */
};
/* Instructions for setting up the libresolv redirection. */
struct resolv_redirect_config
{
/* The response_callback function is called for every incoming DNS
packet, over UDP or TCP. It must be specified, the other
configuration settings are optional. */
void (*response_callback) (const struct resolv_response_context *,
struct resolv_response_builder *,
const char *qname,
uint16_t qclass, uint16_t qtype);
/* Per-server configuration. */
struct resolv_redirect_server_config servers[resolv_max_test_servers];
/* Search path entries. The first entry serves as the default
domain name as well. */
const char *search[7];
/* Number of servers to activate in resolv. 0 means the default,
resolv_max_test_servers. */
int nscount;
/* If true, use a single thread to process all UDP queries. This
may results in more predictable ordering of queries and
responses. */
bool single_thread_udp;
};
/* Configure NSS to use, nss_dns only for aplicable databases, and try
to put the process into a network namespace for better isolation.
This may have to be called before resolv_test_start, before the
process creates any threads. Otherwise, initialization is
performed by resolv_test_start implicitly. */
void resolv_test_init (void);
/* Initiate resolver testing. This updates the _res variable as
needed. As a side effect, NSS is reconfigured to use nss_dns only
for aplicable databases, and the process may enter a network
namespace for better isolation. */
struct resolv_test *resolv_test_start (struct resolv_redirect_config);
/* Call this function at the end of resolver testing, to free
resources and report pending errors (if any). */
void resolv_test_end (struct resolv_test *);
/* The remaining facilities in this file are used for constructing
response packets from the response_callback function. */
/* Special settings for constructing responses from the callback. */
struct resolv_response_flags
{
/* 4-bit response code to incorporate into the response. */
unsigned char rcode;
/* If true, the TC (truncation) flag will be set. */
bool tc;
/* Initial section count values. Can be used to artificially
increase the counts, for malformed packet testing.*/
unsigned short qdcount;
unsigned short ancount;
unsigned short nscount;
unsigned short adcount;
};
/* Begin a new response with the requested flags. Must be called
first. */
void resolv_response_init (struct resolv_response_builder *,
struct resolv_response_flags);
/* Switches to the section in the response packet. Only forward
movement is supported. */
void resolv_response_section (struct resolv_response_builder *, ns_sect);
/* Add a question record to the question section. */
void resolv_response_add_question (struct resolv_response_builder *,
const char *name, uint16_t class,
uint16_t type);
/* Starts a new resource record with the specified owner name, class,
type, and TTL. Data is supplied with resolv_response_add_data or
resolv_response_add_name. */
void resolv_response_open_record (struct resolv_response_builder *,
const char *name, uint16_t class,
uint16_t type, uint32_t ttl);
/* Add unstructed bytes to the RDATA part of a resource record. */
void resolv_response_add_data (struct resolv_response_builder *,
const void *, size_t);
/* Add a compressed domain name to the RDATA part of a resource
record. */
void resolv_response_add_name (struct resolv_response_builder *,
const char *name);
/* Mark the end of the constructed record. Must be called last. */
void resolv_response_close_record (struct resolv_response_builder *);
/* Drop this query packet (that is, do not send a response, not even
an empty packet). */
void resolv_response_drop (struct resolv_response_builder *);
/* In TCP mode, close the connection after this packet (if a response
is sent). */
void resolv_response_close (struct resolv_response_builder *);
/* The size of the response packet built so far. */
size_t resolv_response_length (const struct resolv_response_builder *);
__END_DECLS
#endif /* SUPPORT_RESOLV_TEST_H */

31
support/run_diff.h Normal file
View File

@ -0,0 +1,31 @@
/* Invoke the system diff tool to compare two strings.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef SUPPORT_RUN_DIFF_H
#define SUPPORT_RUN_DIFF_H
/* Compare the two NUL-terminated strings LEFT and RIGHT using the
diff tool. Label the sides of the diff with LEFT_LABEL and
RIGHT_LABEL, respectively.
This function assumes that LEFT and RIGHT are different
strings. */
void support_run_diff (const char *left_label, const char *left,
const char *right_label, const char *right);
#endif /* SUPPORT_RUN_DIFF_H */

View File

@ -0,0 +1,34 @@
/* Set signal handler for use in fortify tests.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/support.h>
#include <signal.h>
void
set_fortify_handler (void (*handler) (int sig))
{
struct sigaction sa;
sa.sa_handler = handler;
sa.sa_flags = 0;
sigemptyset (&sa.sa_mask);
sigaction (SIGABRT, &sa, NULL);
ignore_stderr ();
}

30
support/support-xstat.c Normal file
View File

@ -0,0 +1,30 @@
/* stat64 with error checking.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* NB: Non-standard file name to avoid sysdeps override for xstat. */
#include <support/check.h>
#include <support/xunistd.h>
#include <sys/stat.h>
void
xstat (const char *path, struct stat64 *result)
{
if (stat64 (path, result) != 0)
FAIL_EXIT1 ("stat64 (\"%s\"): %m", path);
}

74
support/support.h Normal file
View File

@ -0,0 +1,74 @@
/* Common extra functions.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* This header file should only contain definitions compatible with
C90. (Using __attribute__ is fine because <features.h> provides a
fallback.) */
#ifndef SUPPORT_H
#define SUPPORT_H
#include <stddef.h>
#include <sys/cdefs.h>
__BEGIN_DECLS
/* Write a message to standard output. Can be used in signal
handlers. */
void write_message (const char *message) __attribute__ ((nonnull (1)));
/* Avoid all the buffer overflow messages on stderr. */
void ignore_stderr (void);
/* Set fortification error handler. Used when tests want to verify that bad
code is caught by the library. */
void set_fortify_handler (void (*handler) (int sig));
/* Report an out-of-memory error for the allocation of SIZE bytes in
FUNCTION, terminating the process. */
void oom_error (const char *function, size_t size)
__attribute__ ((nonnull (1)));
/* Return a pointer to a memory region of SIZE bytes. The memory is
initialized to zero and will be shared with subprocesses (across
fork). The returned pointer must be freed using
support_shared_free; it is not compatible with the malloc
functions. */
void *support_shared_allocate (size_t size);
/* Deallocate a pointer returned by support_shared_allocate. */
void support_shared_free (void *);
/* Write CONTENTS to the file PATH. Create or truncate the file as
needed. The file mode is 0666 masked by the umask. Terminate the
process on error. */
void support_write_file_string (const char *path, const char *contents);
/* Error-checking wrapper functions which terminate the process on
error. */
void *xmalloc (size_t) __attribute__ ((malloc));
void *xcalloc (size_t n, size_t s) __attribute__ ((malloc));
void *xrealloc (void *p, size_t n);
char *xasprintf (const char *format, ...)
__attribute__ ((format (printf, 1, 2), malloc));
char *xstrdup (const char *);
__END_DECLS
#endif /* SUPPORT_H */

View File

@ -0,0 +1,40 @@
/* Acquire root privileges.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/namespace.h>
#include <sched.h>
#include <stdio.h>
#include <unistd.h>
bool
support_become_root (void)
{
#ifdef CLONE_NEWUSER
if (unshare (CLONE_NEWUSER | CLONE_NEWNS) == 0)
/* Even if we do not have UID zero, we have extended privileges at
this point. */
return true;
#endif
if (setuid (0) != 0)
{
printf ("warning: could not become root outside namespace (%m)\n");
return false;
}
return true;
}

View File

@ -0,0 +1,65 @@
/* Return true if the process can perform a chroot operation.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <errno.h>
#include <stdio.h>
#include <support/check.h>
#include <support/namespace.h>
#include <support/support.h>
#include <sys/stat.h>
#include <unistd.h>
#include <xunistd.h>
static void
callback (void *closure)
{
int *result = closure;
struct stat64 before;
xstat ("/dev", &before);
if (chroot ("/dev") != 0)
{
*result = errno;
return;
}
struct stat64 after;
xstat ("/", &after);
TEST_VERIFY (before.st_dev == after.st_dev);
TEST_VERIFY (before.st_ino == after.st_ino);
*result = 0;
}
bool
support_can_chroot (void)
{
int *result = support_shared_allocate (sizeof (*result));
*result = 0;
support_isolate_in_subprocess (callback, result);
bool ok = *result == 0;
if (!ok)
{
static bool already_warned;
if (!already_warned)
{
already_warned = true;
errno = *result;
printf ("warning: this process does not support chroot: %m\n");
}
}
support_shared_free (result);
return ok;
}

View File

@ -0,0 +1,108 @@
/* Capture output from a subprocess.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/capture_subprocess.h>
#include <errno.h>
#include <stdlib.h>
#include <support/check.h>
#include <support/xunistd.h>
#include <support/xsocket.h>
static void
transfer (const char *what, struct pollfd *pfd, struct xmemstream *stream)
{
if (pfd->revents != 0)
{
char buf[1024];
ssize_t ret = TEMP_FAILURE_RETRY (read (pfd->fd, buf, sizeof (buf)));
if (ret < 0)
{
support_record_failure ();
printf ("error: reading from subprocess %s: %m", what);
pfd->events = 0;
pfd->revents = 0;
}
else if (ret == 0)
{
/* EOF reached. Stop listening. */
pfd->events = 0;
pfd->revents = 0;
}
else
/* Store the data just read. */
TEST_VERIFY (fwrite (buf, ret, 1, stream->out) == 1);
}
}
struct support_capture_subprocess
support_capture_subprocess (void (*callback) (void *), void *closure)
{
struct support_capture_subprocess result;
xopen_memstream (&result.out);
xopen_memstream (&result.err);
int stdout_pipe[2];
xpipe (stdout_pipe);
int stderr_pipe[2];
xpipe (stderr_pipe);
TEST_VERIFY (fflush (stdout) == 0);
TEST_VERIFY (fflush (stderr) == 0);
pid_t pid = xfork ();
if (pid == 0)
{
xclose (stdout_pipe[0]);
xclose (stderr_pipe[0]);
xdup2 (stdout_pipe[1], STDOUT_FILENO);
xdup2 (stderr_pipe[1], STDERR_FILENO);
callback (closure);
_exit (0);
}
xclose (stdout_pipe[1]);
xclose (stderr_pipe[1]);
struct pollfd fds[2] =
{
{ .fd = stdout_pipe[0], .events = POLLIN },
{ .fd = stderr_pipe[0], .events = POLLIN },
};
do
{
xpoll (fds, 2, -1);
transfer ("stdout", &fds[0], &result.out);
transfer ("stderr", &fds[1], &result.err);
}
while (fds[0].events != 0 || fds[1].events != 0);
xclose (stdout_pipe[0]);
xclose (stderr_pipe[0]);
xfclose_memstream (&result.out);
xfclose_memstream (&result.err);
xwaitpid (pid, &result.status, 0);
return result;
}
void
support_capture_subprocess_free (struct support_capture_subprocess *p)
{
free (p->out.buffer);
free (p->err.buffer);
}

View File

@ -0,0 +1,67 @@
/* Verify capture output from a subprocess.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <stdbool.h>
#include <stdio.h>
#include <support/capture_subprocess.h>
#include <support/check.h>
static void
print_context (const char *context, bool *failed)
{
if (*failed)
/* Do not duplicate message. */
return;
support_record_failure ();
printf ("error: subprocess failed: %s\n", context);
}
void
support_capture_subprocess_check (struct support_capture_subprocess *proc,
const char *context, int status,
int allowed)
{
TEST_VERIFY ((allowed & sc_allow_none)
|| (allowed & sc_allow_stdout)
|| (allowed & sc_allow_stderr));
TEST_VERIFY (!((allowed & sc_allow_none)
&& ((allowed & sc_allow_stdout)
|| (allowed & sc_allow_stderr))));
bool failed = false;
if (proc->status != status)
{
print_context (context, &failed);
printf ("error: expected exit status: %d\n", status);
printf ("error: actual exit status: %d\n", status);
}
if (!(allowed & sc_allow_stdout) && proc->out.length != 0)
{
print_context (context, &failed);
printf ("error: unexpected output from subprocess\n");
fwrite (proc->out.buffer, proc->out.length, 1, stdout);
puts ("\n");
}
if (!(allowed & sc_allow_stderr) && proc->err.length != 0)
{
print_context (context, &failed);
printf ("error: unexpected error output from subprocess\n");
fwrite (proc->err.buffer, proc->err.length, 1, stdout);
puts ("\n");
}
}

View File

@ -0,0 +1,75 @@
/* Enter a network namespace.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/namespace.h>
#include <net/if.h>
#include <sched.h>
#include <stdio.h>
#include <string.h>
#include <support/check.h>
#include <support/xsocket.h>
#include <support/xunistd.h>
#include <sys/ioctl.h>
#include <unistd.h>
static bool in_uts_namespace;
bool
support_enter_network_namespace (void)
{
#ifdef CLONE_NEWUTS
if (unshare (CLONE_NEWUTS) == 0)
in_uts_namespace = true;
else
printf ("warning: unshare (CLONE_NEWUTS) failed: %m\n");
#endif
#ifdef CLONE_NEWNET
if (unshare (CLONE_NEWNET) == 0)
{
/* Bring up the loopback interface. */
int fd = xsocket (AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
struct ifreq req;
strcpy (req.ifr_name, "lo");
TEST_VERIFY_EXIT (ioctl (fd, SIOCGIFFLAGS, &req) == 0);
bool already_up = req.ifr_flags & IFF_UP;
if (already_up)
/* This means that we likely have not achieved isolation from
the parent namespace. */
printf ("warning: loopback interface already exists"
" in new network namespace\n");
else
{
req.ifr_flags |= IFF_UP | IFF_RUNNING;
TEST_VERIFY_EXIT (ioctl (fd, SIOCSIFFLAGS, &req) == 0);
}
xclose (fd);
return !already_up;
}
#endif
printf ("warning: could not enter network namespace\n");
return false;
}
bool
support_in_uts_namespace (void)
{
return in_uts_namespace;
}

View File

@ -0,0 +1,35 @@
/* Convert an address family to a string.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/format_nss.h>
#include <support/support.h>
char *
support_format_address_family (int family)
{
switch (family)
{
case AF_INET:
return xstrdup ("INET");
case AF_INET6:
return xstrdup ("INET6");
default:
return xasprintf ("<unknown address family %d>", family);
}
}

View File

@ -0,0 +1,239 @@
/* Convert struct addrinfo values to a string.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/format_nss.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>
#include <support/support.h>
#include <support/xmemstream.h>
static size_t
socket_address_length (int family)
{
switch (family)
{
case AF_INET:
return sizeof (struct sockaddr_in);
case AF_INET6:
return sizeof (struct sockaddr_in6);
default:
return -1;
}
}
static void
format_ai_flags_1 (FILE *out, struct addrinfo *ai, int flag, const char *name,
int * flags_printed)
{
if ((ai->ai_flags & flag) != 0)
fprintf (out, " %s", name);
*flags_printed |= flag;
}
static void
format_ai_flags (FILE *out, struct addrinfo *ai)
{
if (ai == NULL)
return;
if (ai->ai_flags != 0)
{
fprintf (out, "flags:");
int flags_printed = 0;
#define FLAG(flag) format_ai_flags_1 (out, ai, flag, #flag, &flags_printed)
FLAG (AI_PASSIVE);
FLAG (AI_CANONNAME);
FLAG (AI_NUMERICHOST);
FLAG (AI_V4MAPPED);
FLAG (AI_ALL);
FLAG (AI_ADDRCONFIG);
FLAG (AI_IDN);
FLAG (AI_CANONIDN);
FLAG (AI_IDN_ALLOW_UNASSIGNED);
FLAG (AI_IDN_USE_STD3_ASCII_RULES);
FLAG (AI_NUMERICSERV);
#undef FLAG
int remaining = ai->ai_flags & ~flags_printed;
if (remaining != 0)
fprintf (out, " %08x", remaining);
fprintf (out, "\n");
}
/* Report flag mismatches within the list. */
int flags = ai->ai_flags;
int index = 1;
ai = ai->ai_next;
while (ai != NULL)
{
if (ai->ai_flags != flags)
fprintf (out, "error: flags at %d: 0x%x expected, 0x%x actual\n",
index, flags, ai->ai_flags);
ai = ai->ai_next;
++index;
}
}
static void
format_ai_canonname (FILE *out, struct addrinfo *ai)
{
if (ai == NULL)
return;
if (ai->ai_canonname != NULL)
fprintf (out, "canonname: %s\n", ai->ai_canonname);
/* Report incorrectly set ai_canonname fields on subsequent list
entries. */
int index = 1;
ai = ai->ai_next;
while (ai != NULL)
{
if (ai->ai_canonname != NULL)
fprintf (out, "error: canonname set at %d: %s\n",
index, ai->ai_canonname);
ai = ai->ai_next;
++index;
}
}
static void
format_ai_one (FILE *out, struct addrinfo *ai)
{
{
char type_buf[32];
const char *type_str;
char proto_buf[32];
const char *proto_str;
/* ai_socktype */
switch (ai->ai_socktype)
{
case SOCK_RAW:
type_str = "RAW";
break;
case SOCK_DGRAM:
type_str = "DGRAM";
break;
case SOCK_STREAM:
type_str = "STREAM";
break;
default:
snprintf (type_buf, sizeof (type_buf), "%d", ai->ai_socktype);
type_str = type_buf;
}
/* ai_protocol */
switch (ai->ai_protocol)
{
case IPPROTO_IP:
proto_str = "IP";
break;
case IPPROTO_UDP:
proto_str = "UDP";
break;
case IPPROTO_TCP:
proto_str = "TCP";
break;
default:
snprintf (proto_buf, sizeof (proto_buf), "%d", ai->ai_protocol);
proto_str = proto_buf;
}
fprintf (out, "address: %s/%s", type_str, proto_str);
}
/* ai_addrlen */
if (ai->ai_addrlen != socket_address_length (ai->ai_family))
{
char *family = support_format_address_family (ai->ai_family);
fprintf (out, "error: invalid address length %d for %s\n",
ai->ai_addrlen, family);
free (family);
}
/* ai_addr */
{
char buf[128];
uint16_t port;
const char *ret;
switch (ai->ai_family)
{
case AF_INET:
{
struct sockaddr_in *sin = (struct sockaddr_in *) ai->ai_addr;
ret = inet_ntop (AF_INET, &sin->sin_addr, buf, sizeof (buf));
port = sin->sin_port;
}
break;
case AF_INET6:
{
struct sockaddr_in6 *sin = (struct sockaddr_in6 *) ai->ai_addr;
ret = inet_ntop (AF_INET6, &sin->sin6_addr, buf, sizeof (buf));
port = sin->sin6_port;
}
break;
default:
errno = EAFNOSUPPORT;
ret = NULL;
}
if (ret == NULL)
fprintf (out, "error: inet_top failed: %m\n");
else
fprintf (out, " %s %u\n", buf, ntohs (port));
}
}
/* Format all the addresses in one address family. */
static void
format_ai_family (FILE *out, struct addrinfo *ai, int family)
{
while (ai)
{
if (ai->ai_family == family)
format_ai_one (out, ai);
ai = ai->ai_next;
}
}
char *
support_format_addrinfo (struct addrinfo *ai, int ret)
{
int errno_copy = errno;
struct xmemstream mem;
xopen_memstream (&mem);
if (ret != 0)
{
fprintf (mem.out, "error: %s\n", gai_strerror (ret));
if (ret == EAI_SYSTEM)
{
errno = errno_copy;
fprintf (mem.out, "error: %m\n");
}
}
else
{
format_ai_flags (mem.out, ai);
format_ai_canonname (mem.out, ai);
format_ai_family (mem.out, ai, AF_INET);
format_ai_family (mem.out, ai, AF_INET6);
}
xfclose_memstream (&mem);
return mem.buffer;
}

View File

@ -0,0 +1,222 @@
/* Convert a DNS packet to a human-readable representation.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/format_nss.h>
#include <arpa/inet.h>
#include <resolv.h>
#include <support/check.h>
#include <support/support.h>
#include <support/xmemstream.h>
struct in_buffer
{
const unsigned char *data;
size_t size;
};
static inline bool
extract_8 (struct in_buffer *in, unsigned char *value)
{
if (in->size == 0)
return false;
*value = in->data[0];
++in->data;
--in->size;
return true;
}
static inline bool
extract_16 (struct in_buffer *in, unsigned short *value)
{
if (in->size < 2)
return false;
*value = (in->data[0] << 8) | in->data[1];
in->data += 2;
in->size -= 2;
return true;
}
static inline bool
extract_32 (struct in_buffer *in, unsigned *value)
{
if (in->size < 4)
return false;
unsigned a = in->data[0];
unsigned b = in->data[1];
unsigned c = in->data[2];
unsigned d = in->data[3];
*value = (a << 24) | (b << 16) | (c << 8) | d;
in->data += 4;
in->size -= 4;
return true;
}
static inline bool
extract_bytes (struct in_buffer *in, size_t length, struct in_buffer *value)
{
if (in->size < length)
return false;
*value = (struct in_buffer) {in->data, length};
in->data += length;
in->size -= length;
return true;
}
struct dname
{
char name[MAXDNAME + 1];
};
static bool
extract_name (struct in_buffer full, struct in_buffer *in, struct dname *value)
{
const unsigned char *full_end = full.data + full.size;
/* Sanity checks; these indicate buffer misuse. */
TEST_VERIFY_EXIT
(!(in->data < full.data || in->data > full_end
|| in->size > (size_t) (full_end - in->data)));
int ret = dn_expand (full.data, full_end, in->data,
value->name, sizeof (value->name));
if (ret < 0)
return false;
in->data += ret;
in->size -= ret;
return true;
}
char *
support_format_dns_packet (const unsigned char *buffer, size_t length)
{
struct in_buffer full = { buffer, length };
struct in_buffer in = full;
struct xmemstream mem;
xopen_memstream (&mem);
unsigned short txnid;
unsigned short flags;
unsigned short qdcount;
unsigned short ancount;
unsigned short nscount;
unsigned short adcount;
if (!(extract_16 (&in, &txnid)
&& extract_16 (&in, &flags)
&& extract_16 (&in, &qdcount)
&& extract_16 (&in, &ancount)
&& extract_16 (&in, &nscount)
&& extract_16 (&in, &adcount)))
{
fprintf (mem.out, "error: could not parse DNS header\n");
goto out;
}
if (qdcount != 1)
{
fprintf (mem.out, "error: question count is %d, not 1\n", qdcount);
goto out;
}
struct dname qname;
if (!extract_name (full, &in, &qname))
{
fprintf (mem.out, "error: malformed QNAME\n");
goto out;
}
unsigned short qtype;
unsigned short qclass;
if (!(extract_16 (&in, &qtype)
&& extract_16 (&in, &qclass)))
{
fprintf (mem.out, "error: malformed question\n");
goto out;
}
if (qtype != T_A && qtype != T_AAAA && qtype != T_PTR)
{
fprintf (mem.out, "error: unsupported QTYPE %d\n", qtype);
goto out;
}
fprintf (mem.out, "name: %s\n", qname.name);
for (int i = 0; i < ancount; ++i)
{
struct dname rname;
if (!extract_name (full, &in, &rname))
{
fprintf (mem.out, "error: malformed record name\n");
goto out;
}
unsigned short rtype;
unsigned short rclass;
unsigned ttl;
unsigned short rdlen;
struct in_buffer rdata;
if (!(extract_16 (&in, &rtype)
&& extract_16 (&in, &rclass)
&& extract_32 (&in, &ttl)
&& extract_16 (&in, &rdlen)
&& extract_bytes (&in, rdlen, &rdata)))
{
fprintf (mem.out, "error: malformed record header\n");
goto out;
}
/* Skip non-matching record types. */
if ((rtype != qtype && rtype != T_CNAME) || rclass != qclass)
continue;
switch (rtype)
{
case T_A:
if (rdlen == 4)
fprintf (mem.out, "address: %d.%d.%d.%d\n",
rdata.data[0],
rdata.data[1],
rdata.data[2],
rdata.data[3]);
else
fprintf (mem.out, "error: A record of size %d: %s\n",
rdlen, rname.name);
break;
case T_AAAA:
{
if (rdlen == 16)
{
char buf[100];
if (inet_ntop (AF_INET6, rdata.data, buf, sizeof (buf)) == NULL)
fprintf (mem.out, "error: AAAA record decoding failed: %m\n");
else
fprintf (mem.out, "address: %s\n", buf);
}
else
fprintf (mem.out, "error: AAAA record of size %d: %s\n",
rdlen, rname.name);
}
break;
case T_CNAME:
case T_PTR:
{
struct dname name;
if (extract_name (full, &rdata, &name))
fprintf (mem.out, "name: %s\n", name.name);
else
fprintf (mem.out, "error: malformed CNAME/PTR record\n");
}
}
}
out:
xfclose_memstream (&mem);
return mem.buffer;
}

View File

@ -0,0 +1,45 @@
/* Convert a h_errno error code to a string.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/format_nss.h>
#include <support/support.h>
char *
support_format_herrno (int code)
{
const char *errstr;
switch (code)
{
case HOST_NOT_FOUND:
errstr = "HOST_NOT_FOUND";
break;
case NO_ADDRESS:
errstr = "NO_ADDRESS";
break;
case NO_RECOVERY:
errstr = "NO_RECOVERY";
break;
case TRY_AGAIN:
errstr = "TRY_AGAIN";
break;
default:
return xasprintf ("<invalid h_errno value %d>\n", code);
}
return xstrdup (errstr);
}

View File

@ -0,0 +1,75 @@
/* Convert a struct hostent object to a string.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/format_nss.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <support/support.h>
#include <support/xmemstream.h>
static int
address_length (int family)
{
switch (family)
{
case AF_INET:
return 4;
case AF_INET6:
return 16;
}
return -1;
}
char *
support_format_hostent (struct hostent *h)
{
if (h == NULL)
{
char *value = support_format_herrno (h_errno);
char *result = xasprintf ("error: %s\n", value);
free (value);
return result;
}
struct xmemstream mem;
xopen_memstream (&mem);
fprintf (mem.out, "name: %s\n", h->h_name);
for (char **alias = h->h_aliases; *alias != NULL; ++alias)
fprintf (mem.out, "alias: %s\n", *alias);
for (unsigned i = 0; h->h_addr_list[i] != NULL; ++i)
{
char buf[128];
if (inet_ntop (h->h_addrtype, h->h_addr_list[i],
buf, sizeof (buf)) == NULL)
fprintf (mem.out, "error: inet_ntop failed: %m\n");
else
fprintf (mem.out, "address: %s\n", buf);
}
if (h->h_length != address_length (h->h_addrtype))
{
char *family = support_format_address_family (h->h_addrtype);
fprintf (mem.out, "error: invalid address length %d for %s\n",
h->h_length, family);
free (family);
}
xfclose_memstream (&mem);
return mem.buffer;
}

View File

@ -0,0 +1,52 @@
/* Convert a struct netent object to a string.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/format_nss.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <support/support.h>
#include <support/xmemstream.h>
char *
support_format_netent (struct netent *e)
{
if (e == NULL)
{
char *value = support_format_herrno (h_errno);
char *result = xasprintf ("error: %s\n", value);
free (value);
return result;
}
struct xmemstream mem;
xopen_memstream (&mem);
if (e->n_name != NULL)
fprintf (mem.out, "name: %s\n", e->n_name);
for (char **ap = e->n_aliases; *ap != NULL; ++ap)
fprintf (mem.out, "alias: %s\n", *ap);
if (e->n_addrtype != AF_INET)
fprintf (mem.out, "addrtype: %d\n", e->n_addrtype);
/* On alpha, e->n_net is an unsigned long. */
unsigned int n_net = e->n_net;
fprintf (mem.out, "net: 0x%08x\n", n_net);
xfclose_memstream (&mem);
return mem.buffer;
}

View File

@ -0,0 +1,38 @@
/* Run a function in a subprocess.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/check.h>
#include <support/xunistd.h>
void
support_isolate_in_subprocess (void (*callback) (void *), void *closure)
{
pid_t pid = xfork ();
if (pid == 0)
{
/* Child process. */
callback (closure);
_exit (0);
}
/* Parent process. */
int status;
xwaitpid (pid, &status, 0);
if (status != 0)
FAIL_EXIT1 ("child process exited with status %d", status);
}

View File

@ -0,0 +1,106 @@
/* Global test failure counter.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/check.h>
#include <support/support.h>
#include <support/test-driver.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
/* This structure keeps track of test failures. The counter is
incremented on each failure. The failed member is set to true if a
failure is detected, so that even if the counter wraps around to
zero, the failure of a test can be detected.
The init constructor function below puts *state on a shared
annonymous mapping, so that failure reports from subprocesses
propagate to the parent process. */
struct test_failures
{
unsigned int counter;
unsigned int failed;
};
static struct test_failures *state;
static __attribute__ ((constructor)) void
init (void)
{
void *ptr = mmap (NULL, sizeof (*state), PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_SHARED, -1, 0);
if (ptr == MAP_FAILED)
{
printf ("error: could not map %zu bytes: %m\n", sizeof (*state));
exit (1);
}
/* Zero-initialization of the struct is sufficient. */
state = ptr;
}
void
support_record_failure (void)
{
if (state == NULL)
{
write_message
("error: support_record_failure called without initialization\n");
_exit (1);
}
/* Relaxed MO is sufficient because we are only interested in the
values themselves, in isolation. */
__atomic_store_n (&state->failed, 1, __ATOMIC_RELEASE);
__atomic_add_fetch (&state->counter, 1, __ATOMIC_RELEASE);
}
int
support_report_failure (int status)
{
if (state == NULL)
{
write_message
("error: support_report_failure called without initialization\n");
return 1;
}
/* Relaxed MO is sufficient because acquire test result reporting
assumes that exiting from the main thread happens before the
error reporting via support_record_failure, which requires some
form of external synchronization. */
bool failed = __atomic_load_n (&state->failed, __ATOMIC_RELAXED);
if (failed)
printf ("error: %u test failures\n",
__atomic_load_n (&state->counter, __ATOMIC_RELAXED));
if ((status == 0 || status == EXIT_UNSUPPORTED) && failed)
/* If we have a recorded failure, it overrides a non-failure
report from the test function. */
status = 1;
return status;
}
void
support_record_failure_reset (void)
{
/* Only used for testing the test framework, with external
synchronization, but use release MO for consistency. */
__atomic_store_n (&state->failed, 0, __ATOMIC_RELAXED);
__atomic_add_fetch (&state->counter, 0, __ATOMIC_RELAXED);
}

View File

@ -0,0 +1,76 @@
/* Invoke the system diff tool to compare two strings.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/run_diff.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <support/check.h>
#include <support/support.h>
#include <support/temp_file.h>
#include <support/xunistd.h>
#include <sys/wait.h>
static char *
write_to_temp_file (const char *prefix, const char *str)
{
char *template = xasprintf ("run_diff-%s", prefix);
char *name = NULL;
int fd = create_temp_file (template, &name);
TEST_VERIFY_EXIT (fd >= 0);
free (template);
xwrite (fd, str, strlen (str));
xclose (fd);
return name;
}
void
support_run_diff (const char *left_label, const char *left,
const char *right_label, const char *right)
{
/* Ensure that the diff command output is ordered properly with
standard output. */
TEST_VERIFY_EXIT (fflush (stdout) == 0);
char *left_path = write_to_temp_file ("left-diff", left);
char *right_path = write_to_temp_file ("right-diff", right);
pid_t pid = xfork ();
if (pid == 0)
{
execlp ("diff", "diff", "-u",
"--label", left_label, "--label", right_label,
"--", left_path, right_path,
NULL);
_exit (17);
}
else
{
int status;
xwaitpid (pid, &status, 0);
if (!WIFEXITED (status) || WEXITSTATUS (status) != 1)
printf ("warning: could not run diff, exit status: %d\n"
"*** %s ***\n%s\n"
"*** %s ***\n%s\n",
status, left_label, left, right_label, right);
}
free (right_path);
free (left_path);
}

View File

@ -0,0 +1,57 @@
/* Allocate a memory region shared across processes.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <errno.h>
#include <stddef.h>
#include <support/support.h>
#include <support/xunistd.h>
#include <sys/mman.h>
/* Header for the allocation. It contains the size of the allocation
for subsequent unmapping. */
struct header
{
size_t total_size;
char data[] __attribute__ ((aligned (__alignof__ (max_align_t))));
};
void *
support_shared_allocate (size_t size)
{
size_t total_size = size + offsetof (struct header, data);
if (total_size < size)
{
errno = ENOMEM;
oom_error (__func__, size);
return NULL;
}
else
{
struct header *result = xmmap (NULL, total_size, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_SHARED, -1);
result->total_size = total_size;
return &result->data;
}
}
void
support_shared_free (void *data)
{
struct header *header = data - offsetof (struct header, data);
xmunmap (header, header->total_size);
}

423
support/support_test_main.c Normal file
View File

@ -0,0 +1,423 @@
/* Main worker function for the test driver.
Copyright (C) 1998-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/test-driver.h>
#include <support/check.h>
#include <support/temp_file-internal.h>
#include <assert.h>
#include <errno.h>
#include <getopt.h>
#include <malloc.h>
#include <signal.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
static const struct option default_options[] =
{
TEST_DEFAULT_OPTIONS
{ NULL, 0, NULL, 0 }
};
/* Show people how to run the program. */
static void
usage (const struct option *options)
{
size_t i;
printf ("Usage: %s [options]\n"
"\n"
"Environment Variables:\n"
" TIMEOUTFACTOR An integer used to scale the timeout\n"
" TMPDIR Where to place temporary files\n"
" TEST_COREDUMPS Do not disable coredumps if set\n"
"\n",
program_invocation_short_name);
printf ("Options:\n");
for (i = 0; options[i].name; ++i)
{
int indent;
indent = printf (" --%s", options[i].name);
if (options[i].has_arg == required_argument)
indent += printf (" <arg>");
printf ("%*s", 25 - indent, "");
switch (options[i].val)
{
case 'v':
printf ("Increase the output verbosity");
break;
case OPT_DIRECT:
printf ("Run the test directly (instead of forking & monitoring)");
break;
case OPT_TESTDIR:
printf ("Override the TMPDIR env var");
break;
}
printf ("\n");
}
}
/* The PID of the test process. */
static pid_t test_pid;
/* The cleanup handler passed to test_main. */
static void (*cleanup_function) (void);
/* Timeout handler. We kill the child and exit with an error. */
static void
__attribute__ ((noreturn))
signal_handler (int sig)
{
int killed;
int status;
assert (test_pid > 1);
/* Kill the whole process group. */
kill (-test_pid, SIGKILL);
/* In case setpgid failed in the child, kill it individually too. */
kill (test_pid, SIGKILL);
/* Wait for it to terminate. */
int i;
for (i = 0; i < 5; ++i)
{
killed = waitpid (test_pid, &status, WNOHANG|WUNTRACED);
if (killed != 0)
break;
/* Delay, give the system time to process the kill. If the
nanosleep() call return prematurely, all the better. We
won't restart it since this probably means the child process
finally died. */
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 100000000;
nanosleep (&ts, NULL);
}
if (killed != 0 && killed != test_pid)
{
printf ("Failed to kill test process: %m\n");
exit (1);
}
if (cleanup_function != NULL)
cleanup_function ();
if (sig == SIGINT)
{
signal (sig, SIG_DFL);
raise (sig);
}
if (killed == 0 || (WIFSIGNALED (status) && WTERMSIG (status) == SIGKILL))
puts ("Timed out: killed the child process");
else if (WIFSTOPPED (status))
printf ("Timed out: the child process was %s\n",
strsignal (WSTOPSIG (status)));
else if (WIFSIGNALED (status))
printf ("Timed out: the child process got signal %s\n",
strsignal (WTERMSIG (status)));
else
printf ("Timed out: killed the child process but it exited %d\n",
WEXITSTATUS (status));
/* Exit with an error. */
exit (1);
}
/* Run test_function or test_function_argv. */
static int
run_test_function (int argc, char **argv, const struct test_config *config)
{
if (config->test_function != NULL)
return config->test_function ();
else if (config->test_function_argv != NULL)
return config->test_function_argv (argc, argv);
else
{
printf ("error: no test function defined\n");
exit (1);
}
}
static bool test_main_called;
const char *test_dir = NULL;
unsigned int test_verbose = 0;
/* If test failure reporting has been linked in, it may contribute
additional test failures. */
static int
adjust_exit_status (int status)
{
if (support_report_failure != NULL)
return support_report_failure (status);
return status;
}
int
support_test_main (int argc, char **argv, const struct test_config *config)
{
if (test_main_called)
{
printf ("error: test_main called for a second time\n");
exit (1);
}
test_main_called = true;
const struct option *options;
if (config->options != NULL)
options = config->options;
else
options = default_options;
cleanup_function = config->cleanup_function;
int direct = 0; /* Directly call the test function? */
int status;
int opt;
unsigned int timeoutfactor = 1;
pid_t termpid;
if (!config->no_mallopt)
{
/* Make uses of freed and uninitialized memory known. Do not
pull in a definition for mallopt if it has not been defined
already. */
extern __typeof__ (mallopt) mallopt __attribute__ ((weak));
if (mallopt != NULL)
mallopt (M_PERTURB, 42);
}
while ((opt = getopt_long (argc, argv, "+", options, NULL)) != -1)
switch (opt)
{
case '?':
usage (options);
exit (1);
case 'v':
++test_verbose;
break;
case OPT_DIRECT:
direct = 1;
break;
case OPT_TESTDIR:
test_dir = optarg;
break;
default:
if (config->cmdline_function != NULL)
config->cmdline_function (opt);
}
/* If set, read the test TIMEOUTFACTOR value from the environment.
This value is used to scale the default test timeout values. */
char *envstr_timeoutfactor = getenv ("TIMEOUTFACTOR");
if (envstr_timeoutfactor != NULL)
{
char *envstr_conv = envstr_timeoutfactor;
unsigned long int env_fact;
env_fact = strtoul (envstr_timeoutfactor, &envstr_conv, 0);
if (*envstr_conv == '\0' && envstr_conv != envstr_timeoutfactor)
timeoutfactor = MAX (env_fact, 1);
}
/* Set TMPDIR to specified test directory. */
if (test_dir != NULL)
{
setenv ("TMPDIR", test_dir, 1);
if (chdir (test_dir) < 0)
{
printf ("chdir: %m\n");
exit (1);
}
}
else
{
test_dir = getenv ("TMPDIR");
if (test_dir == NULL || test_dir[0] == '\0')
test_dir = "/tmp";
}
if (support_set_test_dir != NULL)
support_set_test_dir (test_dir);
int timeout = config->timeout;
if (timeout == 0)
timeout = DEFAULT_TIMEOUT;
/* Make sure we see all message, even those on stdout. */
setvbuf (stdout, NULL, _IONBF, 0);
/* Make sure temporary files are deleted. */
if (support_delete_temp_files != NULL)
atexit (support_delete_temp_files);
/* Correct for the possible parameters. */
argv[optind - 1] = argv[0];
argv += optind - 1;
argc -= optind - 1;
/* Call the initializing function, if one is available. */
if (config->prepare_function != NULL)
config->prepare_function (argc, argv);
const char *envstr_direct = getenv ("TEST_DIRECT");
if (envstr_direct != NULL)
{
FILE *f = fopen (envstr_direct, "w");
if (f == NULL)
{
printf ("cannot open TEST_DIRECT output file '%s': %m\n",
envstr_direct);
exit (1);
}
fprintf (f, "timeout=%u\ntimeoutfactor=%u\n",
config->timeout, timeoutfactor);
if (config->expected_status != 0)
fprintf (f, "exit=%u\n", config->expected_status);
if (config->expected_signal != 0)
fprintf (f, "signal=%s\n", strsignal (config->expected_signal));
if (support_print_temp_files != NULL)
support_print_temp_files (f);
fclose (f);
direct = 1;
}
bool disable_coredumps;
{
const char *coredumps = getenv ("TEST_COREDUMPS");
disable_coredumps = coredumps == NULL || coredumps[0] == '\0';
}
/* If we are not expected to fork run the function immediately. */
if (direct)
return adjust_exit_status (run_test_function (argc, argv, config));
/* Set up the test environment:
- prevent core dumps
- set up the timer
- fork and execute the function. */
test_pid = fork ();
if (test_pid == 0)
{
/* This is the child. */
if (disable_coredumps)
{
/* Try to avoid dumping core. This is necessary because we
run the test from the source tree, and the coredumps
would end up there (and not in the build tree). */
struct rlimit core_limit;
core_limit.rlim_cur = 0;
core_limit.rlim_max = 0;
setrlimit (RLIMIT_CORE, &core_limit);
}
/* We put the test process in its own pgrp so that if it bogusly
generates any job control signals, they won't hit the whole build. */
if (setpgid (0, 0) != 0)
printf ("Failed to set the process group ID: %m\n");
/* Execute the test function and exit with the return value. */
exit (run_test_function (argc, argv, config));
}
else if (test_pid < 0)
{
printf ("Cannot fork test program: %m\n");
exit (1);
}
/* Set timeout. */
signal (SIGALRM, signal_handler);
alarm (timeout * timeoutfactor);
/* Make sure we clean up if the wrapper gets interrupted. */
signal (SIGINT, signal_handler);
/* Wait for the regular termination. */
termpid = TEMP_FAILURE_RETRY (waitpid (test_pid, &status, 0));
if (termpid == -1)
{
printf ("Waiting for test program failed: %m\n");
exit (1);
}
if (termpid != test_pid)
{
printf ("Oops, wrong test program terminated: expected %ld, got %ld\n",
(long int) test_pid, (long int) termpid);
exit (1);
}
/* Process terminated normaly without timeout etc. */
if (WIFEXITED (status))
{
if (config->expected_status == 0)
{
if (config->expected_signal == 0)
/* Exit with the return value of the test. */
return adjust_exit_status (WEXITSTATUS (status));
else
{
printf ("Expected signal '%s' from child, got none\n",
strsignal (config->expected_signal));
exit (1);
}
}
else
{
/* Non-zero exit status is expected */
if (WEXITSTATUS (status) != config->expected_status)
{
printf ("Expected status %d, got %d\n",
config->expected_status, WEXITSTATUS (status));
exit (1);
}
}
return adjust_exit_status (0);
}
/* Process was killed by timer or other signal. */
else
{
if (config->expected_signal == 0)
{
printf ("Didn't expect signal from child: got `%s'\n",
strsignal (WTERMSIG (status)));
exit (1);
}
else if (WTERMSIG (status) != config->expected_signal)
{
printf ("Incorrect signal from child: got `%s', need `%s'\n",
strsignal (WTERMSIG (status)),
strsignal (config->expected_signal));
exit (1);
}
return adjust_exit_status (0);
}
}

View File

@ -0,0 +1,33 @@
/* Implementation of the TEST_VERIFY and TEST_VERIFY_EXIT macros.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/check.h>
#include <stdio.h>
#include <stdlib.h>
void
support_test_verify_impl (int status, const char *file, int line,
const char *expr)
{
support_record_failure ();
printf ("error: %s:%d: not true: %s\n", file, line, expr);
if (status >= 0)
exit (status);
}

View File

@ -0,0 +1,39 @@
/* Write a string to a file.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <fcntl.h>
#include <string.h>
#include <support/check.h>
#include <xunistd.h>
void
support_write_file_string (const char *path, const char *contents)
{
int fd = xopen (path, O_CREAT | O_TRUNC | O_WRONLY, 0666);
const char *end = contents + strlen (contents);
for (const char *p = contents; p < end; )
{
ssize_t ret = write (fd, p, end - p);
if (ret < 0)
FAIL_EXIT1 ("cannot write to \"%s\": %m", path);
if (ret == 0)
FAIL_EXIT1 ("zero-length write to \"%s\"", path);
p += ret;
}
xclose (fd);
}

View File

@ -0,0 +1,31 @@
/* Internal weak declarations for temporary file handling.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef SUPPORT_TEMP_FILE_INTERNAL_H
#define SUPPORT_TEMP_FILE_INTERNAL_H
/* These functions are called by the test driver if they are
defined. Tests should not call them directly. */
#include <stdio.h>
void support_set_test_dir (const char *name) __attribute__ ((weak));
void support_delete_temp_files (void) __attribute__ ((weak));
void support_print_temp_files (FILE *) __attribute__ ((weak));
#endif /* SUPPORT_TEMP_FILE_INTERNAL_H */

132
support/temp_file.c Normal file
View File

@ -0,0 +1,132 @@
/* Temporary file handling for tests.
Copyright (C) 1998-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* This is required to get an mkstemp which can create large files on
some 32-bit platforms. */
#define _FILE_OFFSET_BITS 64
#include <support/temp_file.h>
#include <support/temp_file-internal.h>
#include <support/support.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/* List of temporary files. */
static struct temp_name_list
{
struct temp_name_list *next;
char *name;
pid_t owner;
} *temp_name_list;
/* Location of the temporary files. Set by the test skeleton via
support_set_test_dir. The string is not be freed. */
static const char *test_dir = _PATH_TMP;
void
add_temp_file (const char *name)
{
struct temp_name_list *newp
= (struct temp_name_list *) xcalloc (sizeof (*newp), 1);
char *newname = strdup (name);
if (newname != NULL)
{
newp->name = newname;
newp->next = temp_name_list;
newp->owner = getpid ();
temp_name_list = newp;
}
else
free (newp);
}
int
create_temp_file (const char *base, char **filename)
{
char *fname;
int fd;
fname = (char *) xmalloc (strlen (test_dir) + 1 + strlen (base)
+ sizeof ("XXXXXX"));
strcpy (stpcpy (stpcpy (stpcpy (fname, test_dir), "/"), base), "XXXXXX");
fd = mkstemp (fname);
if (fd == -1)
{
printf ("cannot open temporary file '%s': %m\n", fname);
free (fname);
return -1;
}
add_temp_file (fname);
if (filename != NULL)
*filename = fname;
else
free (fname);
return fd;
}
/* Helper functions called by the test skeleton follow. */
void
support_set_test_dir (const char *path)
{
test_dir = path;
}
void
support_delete_temp_files (void)
{
pid_t pid = getpid ();
while (temp_name_list != NULL)
{
/* Only perform the removal if the path was registed in the same
process, as identified by the PID. (This assumes that the
parent process which registered the temporary file sticks
around, to prevent PID reuse.) */
if (temp_name_list->owner == pid)
{
if (remove (temp_name_list->name) != 0)
printf ("warning: could not remove temporary file: %s: %m\n",
temp_name_list->name);
}
free (temp_name_list->name);
struct temp_name_list *next = temp_name_list->next;
free (temp_name_list);
temp_name_list = next;
}
}
void
support_print_temp_files (FILE *f)
{
if (temp_name_list != NULL)
{
struct temp_name_list *n;
fprintf (f, "temp_files=(\n");
for (n = temp_name_list; n != NULL; n = n->next)
fprintf (f, " '%s'\n", n->name);
fprintf (f, ")\n");
}
}

37
support/temp_file.h Normal file
View File

@ -0,0 +1,37 @@
/* Declarations for temporary file handling.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef SUPPORT_TEMP_FILE_H
#define SUPPORT_TEMP_FILE_H
#include <sys/cdefs.h>
__BEGIN_DECLS
/* Schedule a temporary file for deletion on exit. */
void add_temp_file (const char *name);
/* Create a temporary file. Return the opened file descriptor on
success, or -1 on failure. Write the file name to *FILENAME if
FILENAME is not NULL. In this case, the caller is expected to free
*FILENAME. */
int create_temp_file (const char *base, char **filename);
__END_DECLS
#endif /* SUPPORT_TEMP_FILE_H */

156
support/test-driver.c Normal file
View File

@ -0,0 +1,156 @@
/* Main function for test programs.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* This file should be included from test cases. It will define a
main function which provides the test wrapper.
It assumes that the test case defines a function
int do_test (void);
and arranges for that function being called under the test wrapper.
The do_test function should return 0 to indicate a passing test, 1
to indicate a failing test, or 77 to indicate an unsupported test.
Other result values could be used to indicate a failing test, but
the result of the expression is passed to exit and exit only
returns the lower 8 bits of its input. A non-zero return with some
values could cause a test to incorrectly be considered passing when
it really failed. For this reason, the function should always
return 0 (EXIT_SUCCESS), 1 (EXIT_FAILURE), or 77
(EXIT_UNSUPPORTED).
The test function may print out diagnostic or warning messages as well
as messages about failures. These messages should be printed to stdout
and not stderr so that the output is properly ordered with respect to
the rest of the glibc testsuite run output.
Several preprocessors macros can be defined before including this
file.
The name of the do_test function can be changed with the
TEST_FUNCTION macro. It must expand to the desired function name.
If the test case needs access to command line parameters, it must
define the TEST_FUNCTION_ARGV macro with the name of the test
function. It must have the following type:
int TEST_FUNCTION_ARGV (int argc, char **argv);
This overrides the do_test default function and is incompatible
with the TEST_FUNCTION macro.
If PREPARE is defined, it must expand to the name of a function of
the type
void PREPARE (int argc, char **);
This function will be called early, after parsing the command line,
but before running the test, in the parent process which acts as
the test supervisor.
If CLEANUP_HANDLER is defined, it must expand to the name of a
function of the type
void CLEANUP_HANDLER (void);
This function will be called from the timeout (SIGALRM) signal
handler.
If EXPECTED_SIGNAL is defined, it must expanded to a constant which
denotes the expected signal number.
If EXPECTED_STATUS is defined, it must expand to the expected exit
status.
If TIMEOUT is defined, it must be positive constant. It overrides
the default test timeout and is measured in seconds.
If TEST_NO_MALLOPT is defined, the test wrapper will not call
mallopt.
Custom command line handling can be implemented by defining the
CMDLINE_OPTION macro (after including the <getopt.h> header; this
requires _GNU_SOURCE to be defined). This macro must expand to a
to a comma-separated list of braced initializers for struct option
from <getopt.h>, with a trailing comma. CMDLINE_PROCESS can be
defined as the name of a function which is called to process these
options. The function is passed the option character/number and
has this type:
void CMDLINE_PROCESS (int);
*/
#include <support/test-driver.h>
#include <string.h>
int
main (int argc, char **argv)
{
struct test_config test_config;
memset (&test_config, 0, sizeof (test_config));
#ifdef PREPARE
test_config.prepare_function = (PREPARE);
#endif
#if defined (TEST_FUNCTION) && defined (TEST_FUNCTON_ARGV)
# error TEST_FUNCTION and TEST_FUNCTION_ARGV cannot be defined at the same time
#endif
#if defined (TEST_FUNCTION)
test_config.test_function = TEST_FUNCTION;
#elif defined (TEST_FUNCTION_ARGV)
test_config.test_function_argv = TEST_FUNCTION_ARGV;
#else
test_config.test_function = do_test;
#endif
#ifdef CLEANUP_HANDLER
test_config.cleanup_function = CLEANUP_HANDLER;
#endif
#ifdef EXPECTED_SIGNAL
test_config.expected_signal = (EXPECTED_SIGNAL);
#endif
#ifdef EXPECTED_STATUS
test_config.expected_status = (EXPECTED_STATUS);
#endif
#ifdef TEST_NO_MALLOPT
test_config.no_mallopt = 1;
#endif
#ifdef TIMEOUT
test_config.timeout = TIMEOUT;
#endif
#ifdef CMDLINE_OPTIONS
struct option options[] =
{
CMDLINE_OPTIONS
TEST_DEFAULT_OPTIONS
};
test_config.options = &options;
#endif
#ifdef CMDLINE_PROCESS
test_config.cmdline_function = CMDLINE_PROCESS;
#endif
return support_test_main (argc, argv, &test_config);
}

74
support/test-driver.h Normal file
View File

@ -0,0 +1,74 @@
/* Interfaces for the test driver.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef SUPPORT_TEST_DRIVER_H
#define SUPPORT_TEST_DRIVER_H
#include <sys/cdefs.h>
__BEGIN_DECLS
struct test_config
{
void (*prepare_function) (int argc, char **argv);
int (*test_function) (void);
int (*test_function_argv) (int argc, char **argv);
void (*cleanup_function) (void);
void (*cmdline_function) (int);
const void *options; /* Custom options if not NULL. */
int timeout; /* Test timeout in seconds. */
int expected_status; /* Expected exit status. */
int expected_signal; /* If non-zero, expect termination by signal. */
char no_mallopt; /* Boolean flag to disable mallopt. */
};
enum
{
/* Test exit status which indicates that the feature is
unsupported. */
EXIT_UNSUPPORTED = 77,
/* Default timeout is twenty seconds. Tests should normally
complete faster than this, but if they don't, that's abnormal
(a bug) anyways. */
DEFAULT_TIMEOUT = 20,
/* Used for command line argument parsing. */
OPT_DIRECT = 1000,
OPT_TESTDIR,
};
/* Options provided by the test driver. */
#define TEST_DEFAULT_OPTIONS \
{ "verbose", no_argument, NULL, 'v' }, \
{ "direct", no_argument, NULL, OPT_DIRECT }, \
{ "test-dir", required_argument, NULL, OPT_TESTDIR }, \
/* The directory the test should use for temporary files. */
extern const char *test_dir;
/* The number of --verbose arguments specified during program
invocation. This variable can be used to control the verbosity of
tests. */
extern unsigned int test_verbose;
int support_test_main (int argc, char **argv, const struct test_config *);
__END_DECLS
#endif /* SUPPORT_TEST_DRIVER_H */

View File

@ -0,0 +1,34 @@
/* Test entering namespaces.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <stdio.h>
#include <support/namespace.h>
static int
do_test (void)
{
if (support_become_root ())
printf ("info: acquired root-like privileges\n");
if (support_enter_network_namespace ())
printf ("info: entered network namespace\n");
if (support_in_uts_namespace ())
printf ("info: also entered UTS namespace\n");
return 0;
}
#include <support/test-driver.c>

View File

@ -0,0 +1,188 @@
/* Test capturing output from a subprocess.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <support/capture_subprocess.h>
#include <support/check.h>
#include <support/support.h>
#include <sys/wait.h>
#include <unistd.h>
/* Write one byte at *P to FD and advance *P. Do nothing if *P is
'\0'. */
static void
transfer (const unsigned char **p, int fd)
{
if (**p != '\0')
{
TEST_VERIFY (write (fd, *p, 1) == 1);
++*p;
}
}
/* Determine the order in which stdout and stderr are written. */
enum write_mode { out_first, err_first, interleave,
write_mode_last = interleave };
/* Describe what to write in the subprocess. */
struct test
{
char *out;
char *err;
enum write_mode write_mode;
int signal;
int status;
};
/* For use with support_capture_subprocess. */
static void
callback (void *closure)
{
const struct test *test = closure;
bool mode_ok = false;
switch (test->write_mode)
{
case out_first:
TEST_VERIFY (fputs (test->out, stdout) >= 0);
TEST_VERIFY (fflush (stdout) == 0);
TEST_VERIFY (fputs (test->err, stderr) >= 0);
TEST_VERIFY (fflush (stderr) == 0);
mode_ok = true;
break;
case err_first:
TEST_VERIFY (fputs (test->err, stderr) >= 0);
TEST_VERIFY (fflush (stderr) == 0);
TEST_VERIFY (fputs (test->out, stdout) >= 0);
TEST_VERIFY (fflush (stdout) == 0);
mode_ok = true;
break;
case interleave:
{
const unsigned char *pout = (const unsigned char *) test->out;
const unsigned char *perr = (const unsigned char *) test->err;
do
{
transfer (&pout, STDOUT_FILENO);
transfer (&perr, STDERR_FILENO);
}
while (*pout != '\0' || *perr != '\0');
}
mode_ok = true;
break;
}
TEST_VERIFY (mode_ok);
if (test->signal != 0)
raise (test->signal);
exit (test->status);
}
/* Create a heap-allocated random string of letters. */
static char *
random_string (size_t length)
{
char *result = xmalloc (length + 1);
for (size_t i = 0; i < length; ++i)
result[i] = 'a' + (rand () % 26);
result[length] = '\0';
return result;
}
/* Check that the specific stream from the captured subprocess matches
expectations. */
static void
check_stream (const char *what, const struct xmemstream *stream,
const char *expected)
{
if (strcmp (stream->buffer, expected) != 0)
{
support_record_failure ();
printf ("error: captured %s data incorrect\n"
" expected: %s\n"
" actual: %s\n",
what, expected, stream->buffer);
}
if (stream->length != strlen (expected))
{
support_record_failure ();
printf ("error: captured %s data length incorrect\n"
" expected: %zu\n"
" actual: %zu\n",
what, strlen (expected), stream->length);
}
}
static int
do_test (void)
{
const int lengths[] = {0, 1, 17, 512, 20000, -1};
/* Test multiple combinations of support_capture_subprocess.
length_idx_stdout: Index into the lengths array above,
controls how many bytes are written by the subprocess to
standard output.
length_idx_stderr: Same for standard error.
write_mode: How standard output and standard error writes are
ordered.
signal: Exit with no signal if zero, with SIGTERM if one.
status: Process exit status: 0 if zero, 3 if one. */
for (int length_idx_stdout = 0; lengths[length_idx_stdout] >= 0;
++length_idx_stdout)
for (int length_idx_stderr = 0; lengths[length_idx_stderr] >= 0;
++length_idx_stderr)
for (int write_mode = 0; write_mode < write_mode_last; ++write_mode)
for (int signal = 0; signal < 2; ++signal)
for (int status = 0; status < 2; ++status)
{
struct test test =
{
.out = random_string (lengths[length_idx_stdout]),
.err = random_string (lengths[length_idx_stderr]),
.write_mode = write_mode,
.signal = signal * SIGTERM, /* 0 or SIGTERM. */
.status = status * 3, /* 0 or 3. */
};
TEST_VERIFY (strlen (test.out) == lengths[length_idx_stdout]);
TEST_VERIFY (strlen (test.err) == lengths[length_idx_stderr]);
struct support_capture_subprocess result
= support_capture_subprocess (callback, &test);
check_stream ("stdout", &result.out, test.out);
check_stream ("stderr", &result.err, test.err);
if (test.signal != 0)
{
TEST_VERIFY (WIFSIGNALED (result.status));
TEST_VERIFY (WTERMSIG (result.status) == test.signal);
}
else
{
TEST_VERIFY (WIFEXITED (result.status));
TEST_VERIFY (WEXITSTATUS (result.status) == test.status);
}
support_capture_subprocess_free (&result);
free (test.out);
free (test.err);
}
return 0;
}
#include <support/test-driver.c>

View File

@ -0,0 +1,101 @@
/* Tests for the support_format_dns_packet function.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/check.h>
#include <support/format_nss.h>
#include <support/run_diff.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void
check_packet (const void *buffer, size_t length,
const char *name, const char *expected)
{
char *actual = support_format_dns_packet (buffer, length);
if (strcmp (actual, expected) != 0)
{
support_record_failure ();
printf ("error: formatted packet does not match: %s\n", name);
support_run_diff ("expected", expected,
"actual", actual);
}
free (actual);
}
static void
test_aaaa_length (void)
{
static const char packet[] =
/* Header: Response with two records. */
"\x12\x34\x80\x00\x00\x01\x00\x02\x00\x00\x00\x00"
/* Question section. www.example/IN/AAAA. */
"\x03www\x07""example\x00\x00\x1c\x00\x01"
/* Answer section. www.example AAAA [corrupted]. */
"\xc0\x0c"
"\x00\x1c\x00\x01\x00\x00\x00\x00\x00\x10"
"\x20\x01\x0d\xb8\x05\x06\x07\x08"
"\x11\x12\x13\x14\x15\x16\x17\x18"
/* www.example AAAA [corrupted]. */
"\xc0\x0c"
"\x00\x1c\x00\x01\x00\x00\x00\x00\x00\x11"
"\x01\x02\x03\x04\x05\x06\x07\x08"
"\x11\x12\x13\x14\x15\x16\x17\x18" "\xff";
check_packet (packet, sizeof (packet) - 1, __func__,
"name: www.example\n"
"address: 2001:db8:506:708:1112:1314:1516:1718\n"
"error: AAAA record of size 17: www.example\n");
}
static void
test_multiple_cnames (void)
{
static const char packet[] =
/* Header: Response with three records. */
"\x12\x34\x80\x00\x00\x01\x00\x03\x00\x00\x00\x00"
/* Question section. www.example/IN/A. */
"\x03www\x07""example\x00\x00\x01\x00\x01"
/* Answer section. www.example CNAME www1.example. */
"\xc0\x0c"
"\x00\x05\x00\x01\x00\x00\x00\x00\x00\x07"
"\x04www1\xc0\x10"
/* www1 CNAME www2. */
"\x04www1\xc0\x10"
"\x00\x05\x00\x01\x00\x00\x00\x00\x00\x07"
"\x04www2\xc0\x10"
/* www2 A 192.0.2.1. */
"\x04www2\xc0\x10"
"\x00\x01\x00\x01\x00\x00\x00\x00\x00\x04"
"\xc0\x00\x02\x01";
check_packet (packet, sizeof (packet) - 1, __func__,
"name: www.example\n"
"name: www1.example\n"
"name: www2.example\n"
"address: 192.0.2.1\n");
}
static int
do_test (void)
{
test_aaaa_length ();
test_multiple_cnames ();
return 0;
}
#include <support/test-driver.c>

View File

@ -0,0 +1,69 @@
#!/bin/sh
# Test failure recording (with and without --direct).
# Copyright (C) 2016-2017 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# The GNU C Library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with the GNU C Library; if not, see
# <http://www.gnu.org/licenses/>. */
set -e
common_objpfx=$1; shift
test_program_prefix_before_env=$1; shift
run_program_env=$1; shift
test_program_prefix_after_env=$1; shift
run_test () {
expected_status="$1"
expected_output="$2"
shift 2
args="${common_objpfx}support/tst-support_record_failure $*"
echo "running: $args"
set +e
output="$(${test_program_prefix_before_env} \
${run_program} ${test_program_prefix_after_env} $args)"
status=$?
set -e
echo " exit status: $status"
if test "$output" != "$expected_output" ; then
echo "error: unexpected output: $output"
exit 1
fi
if test "$status" -ne "$expected_status" ; then
echo "error: exit status $expected_status expected"
exit 1
fi
}
different_status () {
direct="$1"
run_test 1 "error: 1 test failures" $direct --status=0
run_test 1 "error: 1 test failures" $direct --status=1
run_test 2 "error: 1 test failures" $direct --status=2
run_test 1 "error: 1 test failures" $direct --status=77
run_test 2 "error: tst-support_record_failure.c:109: not true: false
error: 1 test failures" $direct --test-verify
run_test 2 "error: tst-support_record_failure.c:109: not true: false
info: execution passed failed TEST_VERIFY
error: 1 test failures" $direct --test-verify --verbose
}
different_status
different_status --direct
run_test 1 "error: tst-support_record_failure.c:116: not true: false
error: 1 test failures" --test-verify-exit
# --direct does not print the summary error message if exit is called.
run_test 1 "error: tst-support_record_failure.c:116: not true: false" \
--direct --test-verify-exit

View File

@ -0,0 +1,153 @@
/* Test support_record_failure state sharing.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/check.h>
#include <support/support.h>
#include <support/test-driver.h>
#include <support/xunistd.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static int exit_status_with_failure = -1;
static bool test_verify;
static bool test_verify_exit;
enum
{
OPT_STATUS = 10001,
OPT_TEST_VERIFY,
OPT_TEST_VERIFY_EXIT,
};
#define CMDLINE_OPTIONS \
{ "status", required_argument, NULL, OPT_STATUS }, \
{ "test-verify", no_argument, NULL, OPT_TEST_VERIFY }, \
{ "test-verify-exit", no_argument, NULL, OPT_TEST_VERIFY_EXIT },
static void
cmdline_process (int c)
{
switch (c)
{
case OPT_STATUS:
exit_status_with_failure = atoi (optarg);
break;
case OPT_TEST_VERIFY:
test_verify = true;
break;
case OPT_TEST_VERIFY_EXIT:
test_verify_exit = true;
break;
}
}
#define CMDLINE_PROCESS cmdline_process
static void
check_failure_reporting (int phase, int zero, int unsupported)
{
int status = support_report_failure (0);
if (status != zero)
{
printf ("real-error (phase %d): support_report_failure (0) == %d\n",
phase, status);
exit (1);
}
status = support_report_failure (1);
if (status != 1)
{
printf ("real-error (phase %d): support_report_failure (1) == %d\n",
phase, status);
exit (1);
}
status = support_report_failure (2);
if (status != 2)
{
printf ("real-error (phase %d): support_report_failure (2) == %d\n",
phase, status);
exit (1);
}
status = support_report_failure (EXIT_UNSUPPORTED);
if (status != unsupported)
{
printf ("real-error (phase %d): "
"support_report_failure (EXIT_UNSUPPORTED) == %d\n",
phase, status);
exit (1);
}
}
static int
do_test (void)
{
if (exit_status_with_failure >= 0)
{
/* External invocation with requested error status. Used by
tst-support_report_failure-2.sh. */
support_record_failure ();
return exit_status_with_failure;
}
TEST_VERIFY (true);
TEST_VERIFY_EXIT (true);
if (test_verify)
{
TEST_VERIFY (false);
if (test_verbose)
printf ("info: execution passed failed TEST_VERIFY\n");
return 2; /* Expected exit status. */
}
if (test_verify_exit)
{
TEST_VERIFY_EXIT (false);
return 3; /* Not reached. Expected exit status is 1. */
}
printf ("info: This test tests the test framework.\n"
"info: It reports some expected errors on stdout.\n");
/* Check that the status is passed through unchanged. */
check_failure_reporting (1, 0, EXIT_UNSUPPORTED);
/* Check state propagation from a subprocess. */
pid_t pid = xfork ();
if (pid == 0)
{
support_record_failure ();
_exit (0);
}
int status;
xwaitpid (pid, &status, 0);
if (status != 0)
{
printf ("real-error: incorrect status from subprocess: %d\n", status);
return 1;
}
check_failure_reporting (2, 1, 1);
/* Also test directly in the parent process. */
support_record_failure_reset ();
check_failure_reporting (3, 0, EXIT_UNSUPPORTED);
support_record_failure ();
check_failure_reporting (4, 1, 1);
/* We need to mask the failure above. */
support_record_failure_reset ();
return 0;
}
#include <support/test-driver.c>

29
support/write_message.c Normal file
View File

@ -0,0 +1,29 @@
/* Write a message to standard output.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/support.h>
#include <string.h>
#include <unistd.h>
void
write_message (const char *message)
{
ssize_t unused __attribute__ ((unused));
unused = write (STDOUT_FILENO, message, strlen (message));
}

32
support/xaccept.c Normal file
View File

@ -0,0 +1,32 @@
/* accept with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xsocket.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/check.h>
int
xaccept (int fd, struct sockaddr *sa, socklen_t *salen)
{
int clientfd = accept (fd, sa, salen);
if (clientfd < 0)
FAIL_EXIT1 ("accept (%d): %m", fd);
return clientfd;
}

32
support/xaccept4.c Normal file
View File

@ -0,0 +1,32 @@
/* accept4 with error checking.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xsocket.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/check.h>
int
xaccept4 (int fd, struct sockaddr *sa, socklen_t *salen, int flags)
{
int clientfd = accept4 (fd, sa, salen, flags);
if (clientfd < 0)
FAIL_EXIT1 ("accept4 (%d, 0x%x): %m", fd, flags);
return clientfd;
}

36
support/xasprintf.c Normal file
View File

@ -0,0 +1,36 @@
/* Error-checking wrapper for asprintf.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/support.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/check.h>
char *
xasprintf (const char *format, ...)
{
va_list ap;
va_start (ap, format);
char *result;
if (vasprintf (&result, format, ap) < 0)
FAIL_EXIT1 ("asprintf: %m");
va_end (ap);
return result;
}

30
support/xbind.c Normal file
View File

@ -0,0 +1,30 @@
/* bind with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xsocket.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/check.h>
void
xbind (int fd, const struct sockaddr *sa, socklen_t sa_len)
{
if (bind (fd, sa, sa_len) != 0)
FAIL_EXIT1 ("bind (%d), family %d: %m", fd, sa->sa_family);
}

34
support/xcalloc.c Normal file
View File

@ -0,0 +1,34 @@
/* Error-checking wrapper for calloc.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/support.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
void *
xcalloc (size_t n, size_t s)
{
void *p;
p = calloc (n, s);
if (p == NULL)
oom_error ("calloc", n * s);
return p;
}

28
support/xchroot.c Normal file
View File

@ -0,0 +1,28 @@
/* chroot with error checking.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/check.h>
#include <support/xunistd.h>
#include <sys/stat.h>
void
xchroot (const char *path)
{
if (chroot (path) != 0)
FAIL_EXIT1 ("chroot (\"%s\"): %m", path);
}

28
support/xclose.c Normal file
View File

@ -0,0 +1,28 @@
/* close with error checking.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xunistd.h>
#include <support/check.h>
#include <errno.h>
void
xclose (int fd)
{
if (close (fd) < 0 && errno != EINTR)
FAIL_EXIT1 ("close of descriptor %d failed: %m", fd);
}

30
support/xconnect.c Normal file
View File

@ -0,0 +1,30 @@
/* connect with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xsocket.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/check.h>
void
xconnect (int fd, const struct sockaddr *sa, socklen_t sa_len)
{
if (connect (fd, sa, sa_len) != 0)
FAIL_EXIT1 ("connect (%d), family %d: %m", fd, sa->sa_family);
}

28
support/xdup2.c Normal file
View File

@ -0,0 +1,28 @@
/* dup2 with error checking.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xunistd.h>
#include <support/check.h>
void
xdup2 (int from, int to)
{
if (dup2 (from, to) < 0)
FAIL_EXIT1 ("dup2 (%d, %d): %m", from, to);
}

33
support/xfclose.c Normal file
View File

@ -0,0 +1,33 @@
/* fclose with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xstdio.h>
#include <support/check.h>
#include <stdlib.h>
void
xfclose (FILE *fp)
{
if (ferror (fp))
FAIL_EXIT1 ("stdio stream closed with pending errors");
if (fflush (fp) != 0)
FAIL_EXIT1 ("fflush: %m");
if (fclose (fp) != 0)
FAIL_EXIT1 ("fclose: %m");
}

31
support/xfopen.c Normal file
View File

@ -0,0 +1,31 @@
/* fopen with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xstdio.h>
#include <support/check.h>
#include <stdlib.h>
FILE *
xfopen (const char *path, const char *mode)
{
FILE *fp = fopen (path, mode);
if (fp == NULL)
FAIL_EXIT1 ("could not open %s (mode \"%s\"): %m", path, mode);
return fp;
}

32
support/xfork.c Normal file
View File

@ -0,0 +1,32 @@
/* fork with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xunistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/check.h>
pid_t
xfork (void)
{
pid_t result = fork ();
if (result < 0)
FAIL_EXIT1 ("fork: %m");
return result;
}

30
support/xgetsockname.c Normal file
View File

@ -0,0 +1,30 @@
/* getsockname with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xsocket.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/check.h>
void
xgetsockname (int fd, struct sockaddr *sa, socklen_t *plen)
{
if (getsockname (fd, sa, plen) != 0)
FAIL_EXIT1 ("setsockopt (%d): %m", fd);
}

30
support/xlisten.c Normal file
View File

@ -0,0 +1,30 @@
/* listen with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xsocket.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/check.h>
void
xlisten (int fd, int backlog)
{
if (listen (fd, backlog) != 0)
FAIL_EXIT1 ("listen (%d, %d): %m", fd, backlog);
}

34
support/xmalloc.c Normal file
View File

@ -0,0 +1,34 @@
/* Error-checking wrapper for malloc.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/support.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
void *
xmalloc (size_t n)
{
void *p;
p = malloc (n);
if (p == NULL)
oom_error ("malloc", n);
return p;
}

42
support/xmemstream.c Normal file
View File

@ -0,0 +1,42 @@
/* Error-checking wrappers for memstream functions.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xmemstream.h>
#include <errno.h>
#include <stdlib.h>
#include <support/check.h>
#include <support/xstdio.h>
void
xopen_memstream (struct xmemstream *stream)
{
int old_errno = errno;
*stream = (struct xmemstream) {};
stream->out = open_memstream (&stream->buffer, &stream->length);
if (stream->out == NULL)
FAIL_EXIT1 ("open_memstream: %m");
errno = old_errno;
}
void
xfclose_memstream (struct xmemstream *stream)
{
xfclose (stream->out);
stream->out = NULL;
}

49
support/xmemstream.h Normal file
View File

@ -0,0 +1,49 @@
/* Error-checking wrappers for memstream functions.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef SUPPORT_XMEMSTREAM_H
#define SUPPORT_XMEMSTREAM_H
#include <stdio.h>
#include <sys/cdefs.h>
__BEGIN_DECLS
/* Wrappers for other libc functions. */
struct xmemstream
{
FILE *out;
char *buffer;
size_t length;
};
/* Create a new in-memory stream. Initializes *STREAM. After this
function returns, STREAM->out is a file descriptor open for
writing. errno is preserved, so that the %m format specifier can
be used for writing to STREAM->out. */
void xopen_memstream (struct xmemstream *stream);
/* Closes STREAM->OUT. After this function returns, STREAM->buffer
and STREAM->length denote a memory range which contains the bytes
written to the output stream. The caller should free
STREAM->buffer. */
void xfclose_memstream (struct xmemstream *stream);
__END_DECLS
#endif /* SUPPORT_XMEMSTREAM_H */

28
support/xmkdir.c Normal file
View File

@ -0,0 +1,28 @@
/* mkdir with error checking.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/check.h>
#include <support/xunistd.h>
#include <sys/stat.h>
void
xmkdir (const char *path, mode_t mode)
{
if (mkdir (path, mode) != 0)
FAIL_EXIT1 ("mkdir (\"%s\", 0%o): %m", path, mode);
}

31
support/xmmap.c Normal file
View File

@ -0,0 +1,31 @@
/* mmap with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/check.h>
#include <support/xunistd.h>
#include <sys/mman.h>
void *
xmmap (void *addr, size_t length, int prot, int flags, int fd)
{
void *result = mmap (addr, length, prot, flags, fd, 0);
if (result == MAP_FAILED)
FAIL_EXIT1 ("mmap of %zu bytes, prot=0x%x, flags=0x%x: %m",
length, prot, flags);
return result;
}

28
support/xmunmap.c Normal file
View File

@ -0,0 +1,28 @@
/* munmap with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/check.h>
#include <support/xunistd.h>
#include <sys/mman.h>
void
xmunmap (void *addr, size_t length)
{
if (munmap (addr, length) != 0)
FAIL_EXIT1 ("munmap of %zu bytes: %m", length);
}

30
support/xopen.c Normal file
View File

@ -0,0 +1,30 @@
/* open64 with error checking.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/check.h>
#include <support/xunistd.h>
#include <fcntl.h>
int
xopen (const char *path, int flags, mode_t mode)
{
int ret = open64 (path, flags, mode);
if (ret < 0)
FAIL_EXIT1 ("open64 (\"%s\", 0x%x, 0%o): %m", path, flags, mode);
return ret;
}

28
support/xpipe.c Normal file
View File

@ -0,0 +1,28 @@
/* pipe with error checking.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xunistd.h>
#include <support/check.h>
void
xpipe (int fds[2])
{
if (pipe (fds) < 0)
FAIL_EXIT1 ("pipe: %m");
}

32
support/xpoll.c Normal file
View File

@ -0,0 +1,32 @@
/* poll with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xsocket.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/check.h>
int
xpoll (struct pollfd *fds, nfds_t nfds, int timeout)
{
int ret = poll (fds, nfds, timeout);
if (ret < 0)
FAIL_EXIT1 ("poll: %m");
return ret;
}

View File

@ -0,0 +1,26 @@
/* pthread_attr_destroy with error checking.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_attr_destroy (pthread_attr_t *attr)
{
xpthread_check_return ("pthread_attr_destroy",
pthread_attr_destroy (attr));
}

View File

@ -0,0 +1,25 @@
/* pthread_attr_init with error checking.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_attr_init (pthread_attr_t *attr)
{
xpthread_check_return ("pthread_attr_init", pthread_attr_init (attr));
}

View File

@ -0,0 +1,27 @@
/* pthread_attr_setdetachstate with error checking.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate)
{
xpthread_check_return ("pthread_attr_setdetachstate",
pthread_attr_setdetachstate (attr,
detachstate));
}

View File

@ -0,0 +1,26 @@
/* pthread_attr_setstacksize with error checking.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize)
{
xpthread_check_return ("pthread_attr_setstacksize",
pthread_attr_setstacksize (attr, stacksize));
}

View File

@ -0,0 +1,26 @@
/* pthread_barrier_destroy with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_barrier_destroy (pthread_barrier_t *barrier)
{
xpthread_check_return ("pthread_barrier_destroy",
pthread_barrier_destroy (barrier));
}

View File

@ -0,0 +1,27 @@
/* pthread_barrier_init with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_barrier_init (pthread_barrier_t *barrier,
pthread_barrierattr_t *attr, unsigned int count)
{
xpthread_check_return ("pthread_barrier_init",
pthread_barrier_init (barrier, attr, count));
}

View File

@ -0,0 +1,28 @@
/* pthread_barrier_wait with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
int
xpthread_barrier_wait (pthread_barrier_t *barrier)
{
int ret = pthread_barrier_wait (barrier);
if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD)
xpthread_check_return ("pthread_barrier_wait", ret);
return ret == PTHREAD_BARRIER_SERIAL_THREAD;
}

25
support/xpthread_cancel.c Normal file
View File

@ -0,0 +1,25 @@
/* pthread_cancel with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_cancel (pthread_t thr)
{
xpthread_check_return ("pthread_cancel", pthread_cancel (thr));
}

View File

@ -0,0 +1,34 @@
/* Return value checking for pthread functions, exit variant.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/check.h>
void
xpthread_check_return (const char *function, int value)
{
if (value != 0)
{
errno = value;
FAIL_EXIT1 ("%s: %m", function);
}
}

View File

@ -0,0 +1,26 @@
/* pthread_cond_wait with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
{
xpthread_check_return
("pthread_cond_wait", pthread_cond_wait (cond, mutex));
}

29
support/xpthread_create.c Normal file
View File

@ -0,0 +1,29 @@
/* pthread_create with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
pthread_t
xpthread_create (pthread_attr_t *attr,
void *(*thread_func) (void *), void *closure)
{
pthread_t thr;
xpthread_check_return
("pthread_create", pthread_create (&thr, attr, thread_func, closure));
return thr;
}

25
support/xpthread_detach.c Normal file
View File

@ -0,0 +1,25 @@
/* pthread_detach with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_detach (pthread_t thr)
{
xpthread_check_return ("pthread_detach", pthread_detach (thr));
}

27
support/xpthread_join.c Normal file
View File

@ -0,0 +1,27 @@
/* pthread_join with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void *
xpthread_join (pthread_t thr)
{
void *result;
xpthread_check_return ("pthread_join", pthread_join (thr, &result));
return result;
}

View File

@ -0,0 +1,26 @@
/* pthread_mutex_consistent with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_mutex_consistent (pthread_mutex_t *mutex)
{
xpthread_check_return ("pthread_mutex_consistent",
pthread_mutex_consistent (mutex));
}

View File

@ -0,0 +1,26 @@
/* pthread_mutex_destroy with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_mutex_destroy (pthread_mutex_t *mutex)
{
xpthread_check_return ("pthread_mutex_destroy",
pthread_mutex_destroy (mutex));
}

View File

@ -0,0 +1,26 @@
/* pthread_mutex_init with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
{
xpthread_check_return ("pthread_mutex_init",
pthread_mutex_init (mutex, attr));
}

View File

@ -0,0 +1,25 @@
/* pthread_mutex_lock with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_mutex_lock (pthread_mutex_t *mutex)
{
xpthread_check_return ("pthread_mutex_lock", pthread_mutex_lock (mutex));
}

View File

@ -0,0 +1,25 @@
/* pthread_mutex_unlock with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_mutex_unlock (pthread_mutex_t *mutex)
{
xpthread_check_return ("pthread_mutex_unlock", pthread_mutex_unlock (mutex));
}

View File

@ -0,0 +1,26 @@
/* pthread_mutexattr_destroy with error checking.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_mutexattr_destroy (pthread_mutexattr_t *attr)
{
xpthread_check_return ("pthread_mutexattr_destroy",
pthread_mutexattr_destroy (attr));
}

View File

@ -0,0 +1,25 @@
/* pthread_mutexattr_init with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_mutexattr_init (pthread_mutexattr_t *attr)
{
xpthread_check_return ("pthread_mutexattr_init", pthread_mutexattr_init (attr));
}

View File

@ -0,0 +1,26 @@
/* pthread_mutexattr_setprotocol with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_mutexattr_setprotocol (pthread_mutexattr_t *attr, int flag)
{
xpthread_check_return ("pthread_mutexattr_setprotocol",
pthread_mutexattr_setprotocol (attr, flag));
}

View File

@ -0,0 +1,26 @@
/* pthread_mutexattr_setpshared with error checking.
Copyright (C) 2016-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_mutexattr_setpshared (pthread_mutexattr_t *attr, int flag)
{
xpthread_check_return ("pthread_mutexattr_setpshared",
pthread_mutexattr_setpshared (attr, flag));
}

Some files were not shown because too many files have changed in this diff Show More