mirror of
git://sourceware.org/git/glibc.git
synced 2025-02-17 13:00:43 +08:00
Synchronize support/ infrastructure with master
This commit updates the support/ subdirectory to
commit faf8c066df
on the master branch.
This commit is contained in:
parent
02aaa3c749
commit
92a0e0c617
110
scripts/backport-support.sh
Normal file
110
scripts/backport-support.sh
Normal 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
|
@ -35,7 +35,12 @@ libsupport-routines = \
|
||||
oom_error \
|
||||
resolv_test \
|
||||
set_fortify_handler \
|
||||
support-xstat \
|
||||
support_become_root \
|
||||
support_can_chroot \
|
||||
support_capture_subprocess \
|
||||
support_capture_subprocess_check \
|
||||
support_chroot \
|
||||
support_enter_network_namespace \
|
||||
support_format_address_family \
|
||||
support_format_addrinfo \
|
||||
@ -43,17 +48,24 @@ libsupport-routines = \
|
||||
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 \
|
||||
@ -61,13 +73,18 @@ libsupport-routines = \
|
||||
xlisten \
|
||||
xmalloc \
|
||||
xmemstream \
|
||||
xmkdir \
|
||||
xmmap \
|
||||
xmprotect \
|
||||
xmunmap \
|
||||
xopen \
|
||||
xpipe \
|
||||
xpoll \
|
||||
xpthread_attr_destroy \
|
||||
xpthread_attr_init \
|
||||
xpthread_attr_setdetachstate \
|
||||
xpthread_attr_setstacksize \
|
||||
xpthread_attr_setguardsize \
|
||||
xpthread_barrier_destroy \
|
||||
xpthread_barrier_init \
|
||||
xpthread_barrier_wait \
|
||||
@ -89,6 +106,12 @@ libsupport-routines = \
|
||||
xpthread_mutexattr_setrobust \
|
||||
xpthread_mutexattr_settype \
|
||||
xpthread_once \
|
||||
xpthread_rwlock_init \
|
||||
xpthread_rwlock_rdlock \
|
||||
xpthread_rwlock_wrlock \
|
||||
xpthread_rwlock_unlock \
|
||||
xpthread_rwlockattr_init \
|
||||
xpthread_rwlockattr_setkind_np \
|
||||
xpthread_sigmask \
|
||||
xpthread_spin_lock \
|
||||
xpthread_spin_unlock \
|
||||
@ -111,6 +134,8 @@ 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)
|
||||
@ -125,4 +150,6 @@ $(objpfx)tst-support_record_failure-2.out: tst-support_record_failure-2.sh \
|
||||
$(evaluate-test)
|
||||
endif
|
||||
|
||||
$(objpfx)tst-support_format_dns_packet: $(common-objpfx)resolv/libresolv.so
|
||||
|
||||
include ../Rules
|
||||
|
61
support/capture_subprocess.h
Normal file
61
support/capture_subprocess.h
Normal 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 */
|
@ -51,7 +51,7 @@ __BEGIN_DECLS
|
||||
if (expr) \
|
||||
; \
|
||||
else \
|
||||
support_test_verify_impl (-1, __FILE__, __LINE__, #expr); \
|
||||
support_test_verify_impl (__FILE__, __LINE__, #expr); \
|
||||
})
|
||||
|
||||
/* Record a test failure and exit if EXPR evaluates to false. */
|
||||
@ -60,7 +60,8 @@ __BEGIN_DECLS
|
||||
if (expr) \
|
||||
; \
|
||||
else \
|
||||
support_test_verify_impl (1, __FILE__, __LINE__, #expr); \
|
||||
support_test_verify_exit_impl \
|
||||
(1, __FILE__, __LINE__, #expr); \
|
||||
})
|
||||
|
||||
int support_print_failure_impl (const char *file, int line,
|
||||
@ -70,8 +71,11 @@ 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,
|
||||
void support_test_verify_impl (const char *file, int line,
|
||||
const char *expr);
|
||||
void support_test_verify_exit_impl (int status, const char *file, int line,
|
||||
const char *expr)
|
||||
__attribute__ ((noreturn));
|
||||
|
||||
/* Record a test failure. This function returns and does not
|
||||
terminate the process. The failure counter is stored in a shared
|
||||
|
@ -35,6 +35,13 @@ __BEGIN_DECLS
|
||||
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.
|
||||
@ -48,6 +55,43 @@ bool support_enter_network_namespace (void);
|
||||
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);
|
||||
|
||||
/* Describe the setup of a chroot environment, for
|
||||
support_chroot_create below. */
|
||||
struct support_chroot_configuration
|
||||
{
|
||||
/* File contents. The files are not created if the field is
|
||||
NULL. */
|
||||
const char *resolv_conf;
|
||||
};
|
||||
|
||||
/* The result of the creation of a chroot. */
|
||||
struct support_chroot
|
||||
{
|
||||
/* Path information. All these paths are relative to the parent
|
||||
chroot. */
|
||||
|
||||
/* Path to the chroot directory. */
|
||||
char *path_chroot;
|
||||
|
||||
/* Path to the /etc/resolv.conf file. */
|
||||
char *path_resolv_conf;
|
||||
};
|
||||
|
||||
/* Create a chroot environment. The returned data should be freed
|
||||
using support_chroot_free below. The files will be deleted when
|
||||
the process exits. This function does not enter the chroot. */
|
||||
struct support_chroot *support_chroot_create
|
||||
(struct support_chroot_configuration);
|
||||
|
||||
/* Deallocate the chroot information created by
|
||||
support_chroot_create. */
|
||||
void support_chroot_free (struct support_chroot *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
|
@ -32,9 +32,11 @@
|
||||
#include <support/test-driver.h>
|
||||
#include <support/xsocket.h>
|
||||
#include <support/xthread.h>
|
||||
#include <support/xunistd.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Response builder. */
|
||||
/* Response builder. */
|
||||
|
||||
enum
|
||||
{
|
||||
@ -910,7 +912,7 @@ server_thread_tcp_client (void *arg)
|
||||
break;
|
||||
}
|
||||
|
||||
close (closure->client_socket);
|
||||
xclose (closure->client_socket);
|
||||
free (closure);
|
||||
return NULL;
|
||||
}
|
||||
@ -931,7 +933,7 @@ server_thread_tcp (struct resolv_test *obj, int server_index)
|
||||
if (obj->termination_requested)
|
||||
{
|
||||
xpthread_mutex_unlock (&obj->lock);
|
||||
close (client_socket);
|
||||
xclose (client_socket);
|
||||
break;
|
||||
}
|
||||
xpthread_mutex_unlock (&obj->lock);
|
||||
@ -991,8 +993,8 @@ make_server_sockets (struct resolv_test_server *server)
|
||||
next local UDP address randomly. */
|
||||
if (errno == EADDRINUSE)
|
||||
{
|
||||
close (server->socket_udp);
|
||||
close (server->socket_tcp);
|
||||
xclose (server->socket_udp);
|
||||
xclose (server->socket_tcp);
|
||||
continue;
|
||||
}
|
||||
FAIL_EXIT1 ("TCP bind: %m");
|
||||
@ -1002,6 +1004,29 @@ make_server_sockets (struct resolv_test_server *server)
|
||||
}
|
||||
}
|
||||
|
||||
/* Like make_server_sockets, but the caller supplies the address to
|
||||
use. */
|
||||
static void
|
||||
make_server_sockets_for_address (struct resolv_test_server *server,
|
||||
const struct sockaddr *addr)
|
||||
{
|
||||
server->socket_udp = xsocket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
server->socket_tcp = xsocket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
|
||||
if (addr->sa_family == AF_INET)
|
||||
server->address = *(const struct sockaddr_in *) addr;
|
||||
else
|
||||
/* We cannot store the server address in the socket. This should
|
||||
not matter if disable_redirect is used. */
|
||||
server->address = (struct sockaddr_in) { .sin_family = 0, };
|
||||
|
||||
xbind (server->socket_udp,
|
||||
(struct sockaddr *)&server->address, sizeof (server->address));
|
||||
xbind (server->socket_tcp,
|
||||
(struct sockaddr *)&server->address, sizeof (server->address));
|
||||
xlisten (server->socket_tcp, 5);
|
||||
}
|
||||
|
||||
/* One-time initialization of NSS. */
|
||||
static void
|
||||
resolv_redirect_once (void)
|
||||
@ -1062,11 +1087,17 @@ resolv_test_start (struct resolv_redirect_config config)
|
||||
.lock = PTHREAD_MUTEX_INITIALIZER,
|
||||
};
|
||||
|
||||
resolv_test_init ();
|
||||
if (!config.disable_redirect)
|
||||
resolv_test_init ();
|
||||
|
||||
/* Create all the servers, to reserve the necessary ports. */
|
||||
for (int server_index = 0; server_index < config.nscount; ++server_index)
|
||||
make_server_sockets (obj->servers + server_index);
|
||||
if (config.disable_redirect && config.server_address_overrides != NULL)
|
||||
make_server_sockets_for_address
|
||||
(obj->servers + server_index,
|
||||
config.server_address_overrides[server_index]);
|
||||
else
|
||||
make_server_sockets (obj->servers + server_index);
|
||||
|
||||
/* Start server threads. Disable the server ports, as
|
||||
requested. */
|
||||
@ -1075,7 +1106,7 @@ resolv_test_start (struct resolv_redirect_config config)
|
||||
struct resolv_test_server *server = obj->servers + server_index;
|
||||
if (config.servers[server_index].disable_udp)
|
||||
{
|
||||
close (server->socket_udp);
|
||||
xclose (server->socket_udp);
|
||||
server->socket_udp = -1;
|
||||
}
|
||||
else if (!config.single_thread_udp)
|
||||
@ -1083,7 +1114,7 @@ resolv_test_start (struct resolv_redirect_config config)
|
||||
server_thread_udp);
|
||||
if (config.servers[server_index].disable_tcp)
|
||||
{
|
||||
close (server->socket_tcp);
|
||||
xclose (server->socket_tcp);
|
||||
server->socket_tcp = -1;
|
||||
}
|
||||
else
|
||||
@ -1093,6 +1124,9 @@ resolv_test_start (struct resolv_redirect_config config)
|
||||
if (config.single_thread_udp)
|
||||
start_server_thread_udp_single (obj);
|
||||
|
||||
if (config.disable_redirect)
|
||||
return obj;
|
||||
|
||||
int timeout = 1;
|
||||
|
||||
/* Initialize libresolv. */
|
||||
@ -1127,6 +1161,7 @@ resolv_test_start (struct resolv_redirect_config config)
|
||||
}
|
||||
for (int server_index = 0; server_index < config.nscount; ++server_index)
|
||||
{
|
||||
TEST_VERIFY_EXIT (obj->servers[server_index].address.sin_port != 0);
|
||||
_res.nsaddr_list[server_index] = obj->servers[server_index].address;
|
||||
if (test_verbose)
|
||||
{
|
||||
@ -1164,7 +1199,7 @@ resolv_test_end (struct resolv_test *obj)
|
||||
xsendto (sock, "", 1, 0,
|
||||
(struct sockaddr *) &obj->servers[server_index].address,
|
||||
sizeof (obj->servers[server_index].address));
|
||||
close (sock);
|
||||
xclose (sock);
|
||||
}
|
||||
if (!obj->config.servers[server_index].disable_tcp)
|
||||
{
|
||||
@ -1172,7 +1207,7 @@ resolv_test_end (struct resolv_test *obj)
|
||||
xconnect (sock,
|
||||
(struct sockaddr *) &obj->servers[server_index].address,
|
||||
sizeof (obj->servers[server_index].address));
|
||||
close (sock);
|
||||
xclose (sock);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1187,12 +1222,12 @@ resolv_test_end (struct resolv_test *obj)
|
||||
{
|
||||
if (!obj->config.single_thread_udp)
|
||||
xpthread_join (obj->servers[server_index].thread_udp);
|
||||
close (obj->servers[server_index].socket_udp);
|
||||
xclose (obj->servers[server_index].socket_udp);
|
||||
}
|
||||
if (!obj->config.servers[server_index].disable_tcp)
|
||||
{
|
||||
xpthread_join (obj->servers[server_index].thread_tcp);
|
||||
close (obj->servers[server_index].socket_tcp);
|
||||
xclose (obj->servers[server_index].socket_tcp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,16 @@ struct resolv_redirect_config
|
||||
may results in more predictable ordering of queries and
|
||||
responses. */
|
||||
bool single_thread_udp;
|
||||
|
||||
/* Do not rewrite the _res variable or change NSS defaults. Use
|
||||
server_address_overrides below to tell the testing framework on
|
||||
which addresses to create the servers. */
|
||||
bool disable_redirect;
|
||||
|
||||
/* Use these addresses for creating the DNS servers. The array must
|
||||
have ns_count (or resolv_max_test_servers) sockaddr * elements if
|
||||
not NULL. */
|
||||
const struct sockaddr *const *server_address_overrides;
|
||||
};
|
||||
|
||||
/* Configure NSS to use, nss_dns only for aplicable databases, and try
|
||||
|
30
support/support-xstat.c
Normal file
30
support/support-xstat.c
Normal 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);
|
||||
}
|
@ -44,6 +44,21 @@ void set_fortify_handler (void (*handler) (int sig));
|
||||
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. */
|
||||
|
||||
|
65
support/support_can_chroot.c
Normal file
65
support/support_can_chroot.c
Normal 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;
|
||||
}
|
108
support/support_capture_subprocess.c
Normal file
108
support/support_capture_subprocess.c
Normal 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);
|
||||
}
|
67
support/support_capture_subprocess_check.c
Normal file
67
support/support_capture_subprocess_check.c
Normal 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", proc->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");
|
||||
}
|
||||
}
|
71
support/support_chroot.c
Normal file
71
support/support_chroot.c
Normal file
@ -0,0 +1,71 @@
|
||||
/* Setup a chroot environment for use within tests.
|
||||
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 <stdlib.h>
|
||||
#include <support/check.h>
|
||||
#include <support/namespace.h>
|
||||
#include <support/support.h>
|
||||
#include <support/temp_file.h>
|
||||
#include <support/test-driver.h>
|
||||
#include <support/xunistd.h>
|
||||
|
||||
struct support_chroot *
|
||||
support_chroot_create (struct support_chroot_configuration conf)
|
||||
{
|
||||
struct support_chroot *chroot = xmalloc (sizeof (*chroot));
|
||||
|
||||
chroot->path_chroot = xasprintf ("%s/tst-resolv-res_init-XXXXXX", test_dir);
|
||||
if (mkdtemp (chroot->path_chroot) == NULL)
|
||||
FAIL_EXIT1 ("mkdtemp (\"%s\"): %m", chroot->path_chroot);
|
||||
add_temp_file (chroot->path_chroot);
|
||||
|
||||
/* Create the /etc directory in the chroot environment. */
|
||||
char *path_etc = xasprintf ("%s/etc", chroot->path_chroot);
|
||||
xmkdir (path_etc, 0777);
|
||||
add_temp_file (path_etc);
|
||||
|
||||
if (conf.resolv_conf != NULL)
|
||||
{
|
||||
/* Create an empty resolv.conf file. */
|
||||
chroot->path_resolv_conf = xasprintf ("%s/resolv.conf", path_etc);
|
||||
add_temp_file (chroot->path_resolv_conf);
|
||||
support_write_file_string (chroot->path_resolv_conf, conf.resolv_conf);
|
||||
}
|
||||
else
|
||||
chroot->path_resolv_conf = NULL;
|
||||
|
||||
free (path_etc);
|
||||
|
||||
/* valgrind needs a temporary directory in the chroot. */
|
||||
{
|
||||
char *path_tmp = xasprintf ("%s/tmp", chroot->path_chroot);
|
||||
xmkdir (path_tmp, 0777);
|
||||
add_temp_file (path_tmp);
|
||||
free (path_tmp);
|
||||
}
|
||||
|
||||
return chroot;
|
||||
}
|
||||
|
||||
void
|
||||
support_chroot_free (struct support_chroot *chroot)
|
||||
{
|
||||
free (chroot->path_chroot);
|
||||
free (chroot->path_resolv_conf);
|
||||
free (chroot);
|
||||
}
|
@ -23,9 +23,10 @@
|
||||
#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>
|
||||
#include <xsocket.h>
|
||||
|
||||
static bool in_uts_namespace;
|
||||
|
||||
@ -58,7 +59,7 @@ support_enter_network_namespace (void)
|
||||
req.ifr_flags |= IFF_UP | IFF_RUNNING;
|
||||
TEST_VERIFY_EXIT (ioctl (fd, SIOCSIFFLAGS, &req) == 0);
|
||||
}
|
||||
close (fd);
|
||||
xclose (fd);
|
||||
|
||||
return !already_up;
|
||||
}
|
||||
|
@ -39,8 +39,8 @@ socket_address_length (int family)
|
||||
}
|
||||
|
||||
static void
|
||||
format_ai_flags (FILE *out, struct addrinfo *ai, int flag, const char *name,
|
||||
int * flags_printed)
|
||||
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);
|
||||
@ -48,14 +48,16 @@ format_ai_flags (FILE *out, struct addrinfo *ai, int flag, const char *name,
|
||||
}
|
||||
|
||||
static void
|
||||
format_ai_one (FILE *out, struct addrinfo *ai, int *flags)
|
||||
format_ai_flags (FILE *out, struct addrinfo *ai)
|
||||
{
|
||||
/* ai_flags */
|
||||
if (ai->ai_flags != *flags)
|
||||
if (ai == NULL)
|
||||
return;
|
||||
|
||||
if (ai->ai_flags != 0)
|
||||
{
|
||||
fprintf (out, "flags:");
|
||||
int flags_printed = 0;
|
||||
#define FLAG(flag) format_ai_flags (out, ai, flag, #flag, &flags_printed)
|
||||
#define FLAG(flag) format_ai_flags_1 (out, ai, flag, #flag, &flags_printed)
|
||||
FLAG (AI_PASSIVE);
|
||||
FLAG (AI_CANONNAME);
|
||||
FLAG (AI_NUMERICHOST);
|
||||
@ -72,9 +74,47 @@ format_ai_one (FILE *out, struct addrinfo *ai, int *flags)
|
||||
if (remaining != 0)
|
||||
fprintf (out, " %08x", remaining);
|
||||
fprintf (out, "\n");
|
||||
*flags = ai->ai_flags;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
@ -156,20 +196,16 @@ format_ai_one (FILE *out, struct addrinfo *ai, int *flags)
|
||||
else
|
||||
fprintf (out, " %s %u\n", buf, ntohs (port));
|
||||
}
|
||||
|
||||
/* ai_canonname */
|
||||
if (ai->ai_canonname != NULL)
|
||||
fprintf (out, "canonname: %s\n", ai->ai_canonname);
|
||||
}
|
||||
|
||||
/* Format all the addresses in one address family. */
|
||||
static void
|
||||
format_ai_family (FILE *out, struct addrinfo *ai, int family, int *flags)
|
||||
format_ai_family (FILE *out, struct addrinfo *ai, int family)
|
||||
{
|
||||
while (ai)
|
||||
{
|
||||
if (ai->ai_family == family)
|
||||
format_ai_one (out, ai, flags);
|
||||
format_ai_one (out, ai);
|
||||
ai = ai->ai_next;
|
||||
}
|
||||
}
|
||||
@ -192,9 +228,10 @@ support_format_addrinfo (struct addrinfo *ai, int ret)
|
||||
}
|
||||
else
|
||||
{
|
||||
int flags = 0;
|
||||
format_ai_family (mem.out, ai, AF_INET, &flags);
|
||||
format_ai_family (mem.out, ai, AF_INET6, &flags);
|
||||
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);
|
||||
|
@ -174,7 +174,7 @@ support_format_dns_packet (const unsigned char *buffer, size_t length)
|
||||
goto out;
|
||||
}
|
||||
/* Skip non-matching record types. */
|
||||
if (rtype != qtype || rclass != qclass)
|
||||
if ((rtype != qtype && rtype != T_CNAME) || rclass != qclass)
|
||||
continue;
|
||||
switch (rtype)
|
||||
{
|
||||
@ -186,22 +186,29 @@ support_format_dns_packet (const unsigned char *buffer, size_t length)
|
||||
rdata.data[2],
|
||||
rdata.data[3]);
|
||||
else
|
||||
fprintf (mem.out, "error: A record of size %d: %s\n", rdlen, rname.name);
|
||||
fprintf (mem.out, "error: A record of size %d: %s\n",
|
||||
rdlen, rname.name);
|
||||
break;
|
||||
case T_AAAA:
|
||||
{
|
||||
char buf[100];
|
||||
if (inet_ntop (AF_INET6, rdata.data, buf, sizeof (buf)) == NULL)
|
||||
fprintf (mem.out, "error: AAAA record decoding failed: %m\n");
|
||||
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, "address: %s\n", buf);
|
||||
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, &in, &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");
|
||||
|
38
support/support_isolate_in_subprocess.c
Normal file
38
support/support_isolate_in_subprocess.c
Normal 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);
|
||||
}
|
@ -24,8 +24,8 @@
|
||||
#include <support/check.h>
|
||||
#include <support/support.h>
|
||||
#include <support/temp_file.h>
|
||||
#include <support/xunistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include <xunistd.h>
|
||||
|
||||
static char *
|
||||
write_to_temp_file (const char *prefix, const char *str)
|
||||
@ -36,7 +36,7 @@ write_to_temp_file (const char *prefix, const char *str)
|
||||
TEST_VERIFY_EXIT (fd >= 0);
|
||||
free (template);
|
||||
xwrite (fd, str, strlen (str));
|
||||
TEST_VERIFY_EXIT (close (fd) == 0);
|
||||
xclose (fd);
|
||||
return name;
|
||||
}
|
||||
|
||||
|
57
support/support_shared_allocate.c
Normal file
57
support/support_shared_allocate.c
Normal 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);
|
||||
}
|
@ -211,7 +211,8 @@ support_test_main (int argc, char **argv, const struct test_config *config)
|
||||
mallopt (M_PERTURB, 42);
|
||||
}
|
||||
|
||||
while ((opt = getopt_long (argc, argv, "+", options, NULL)) != -1)
|
||||
while ((opt = getopt_long (argc, argv, config->optstring, options, NULL))
|
||||
!= -1)
|
||||
switch (opt)
|
||||
{
|
||||
case '?':
|
||||
|
@ -22,12 +22,16 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
void
|
||||
support_test_verify_impl (int status, const char *file, int line,
|
||||
const char *expr)
|
||||
support_test_verify_impl (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);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
support_test_verify_exit_impl (int status, const char *file, int line,
|
||||
const char *expr)
|
||||
{
|
||||
support_test_verify_impl (file, line, expr);
|
||||
exit (status);
|
||||
}
|
||||
|
39
support/support_write_file_string.c
Normal file
39
support/support_write_file_string.c
Normal 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);
|
||||
}
|
@ -25,16 +25,17 @@
|
||||
#include <support/support.h>
|
||||
|
||||
#include <paths.h>
|
||||
#include <search.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* List of temporary files. */
|
||||
static struct temp_name_list
|
||||
{
|
||||
struct qelem q;
|
||||
struct temp_name_list *next;
|
||||
char *name;
|
||||
pid_t owner;
|
||||
} *temp_name_list;
|
||||
|
||||
/* Location of the temporary files. Set by the test skeleton via
|
||||
@ -50,10 +51,9 @@ add_temp_file (const char *name)
|
||||
if (newname != NULL)
|
||||
{
|
||||
newp->name = newname;
|
||||
if (temp_name_list == NULL)
|
||||
temp_name_list = (struct temp_name_list *) &newp->q;
|
||||
else
|
||||
insque (newp, temp_name_list);
|
||||
newp->next = temp_name_list;
|
||||
newp->owner = getpid ();
|
||||
temp_name_list = newp;
|
||||
}
|
||||
else
|
||||
free (newp);
|
||||
@ -97,13 +97,22 @@ support_set_test_dir (const char *path)
|
||||
void
|
||||
support_delete_temp_files (void)
|
||||
{
|
||||
pid_t pid = getpid ();
|
||||
while (temp_name_list != NULL)
|
||||
{
|
||||
remove (temp_name_list->name);
|
||||
/* 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
|
||||
= (struct temp_name_list *) temp_name_list->q.q_forw;
|
||||
struct temp_name_list *next = temp_name_list->next;
|
||||
free (temp_name_list);
|
||||
temp_name_list = next;
|
||||
}
|
||||
@ -116,9 +125,7 @@ support_print_temp_files (FILE *f)
|
||||
{
|
||||
struct temp_name_list *n;
|
||||
fprintf (f, "temp_files=(\n");
|
||||
for (n = temp_name_list;
|
||||
n != NULL;
|
||||
n = (struct temp_name_list *) n->q.q_forw)
|
||||
for (n = temp_name_list; n != NULL; n = n->next)
|
||||
fprintf (f, " '%s'\n", n->name);
|
||||
fprintf (f, ")\n");
|
||||
}
|
||||
|
@ -93,6 +93,10 @@
|
||||
has this type:
|
||||
|
||||
void CMDLINE_PROCESS (int);
|
||||
|
||||
If the program also to process custom default short command line
|
||||
argument (similar to getopt) it must define CMDLINE_OPTSTRING
|
||||
with the expected options (for instance "vb").
|
||||
*/
|
||||
|
||||
#include <support/test-driver.h>
|
||||
@ -151,6 +155,11 @@ main (int argc, char **argv)
|
||||
#ifdef CMDLINE_PROCESS
|
||||
test_config.cmdline_function = CMDLINE_PROCESS;
|
||||
#endif
|
||||
#ifdef CMDLINE_OPTSTRING
|
||||
test_config.optstring = "+" CMDLINE_OPTSTRING;
|
||||
#else
|
||||
test_config.optstring = "+";
|
||||
#endif
|
||||
|
||||
return support_test_main (argc, argv, &test_config);
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ struct test_config
|
||||
int expected_status; /* Expected exit status. */
|
||||
int expected_signal; /* If non-zero, expect termination by signal. */
|
||||
char no_mallopt; /* Boolean flag to disable mallopt. */
|
||||
const char *optstring; /* Short command line options. */
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -16,18 +16,98 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <support/check.h>
|
||||
#include <support/namespace.h>
|
||||
#include <support/xsocket.h>
|
||||
#include <support/xunistd.h>
|
||||
|
||||
/* Check that the loopback interface provides multiple addresses which
|
||||
can be used to run independent servers. */
|
||||
static void
|
||||
test_localhost_bind (void)
|
||||
{
|
||||
printf ("info: testing loopback interface with multiple addresses\n");
|
||||
|
||||
/* Create the two server addresses. */
|
||||
static const struct addrinfo hints =
|
||||
{
|
||||
.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_DGRAM,
|
||||
.ai_protocol = IPPROTO_UDP,
|
||||
};
|
||||
struct addrinfo *ai[3];
|
||||
TEST_VERIFY_EXIT (getaddrinfo ("127.0.0.1", "53", &hints, ai + 0) == 0);
|
||||
TEST_VERIFY_EXIT (getaddrinfo ("127.0.0.2", "53", &hints, ai + 1) == 0);
|
||||
TEST_VERIFY_EXIT (getaddrinfo ("127.0.0.3", "53", &hints, ai + 2) == 0);
|
||||
|
||||
/* Create the server scokets and bind them to these addresses. */
|
||||
int sockets[3];
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
sockets[i] = xsocket
|
||||
(ai[i]->ai_family, ai[i]->ai_socktype, ai[i]->ai_protocol);
|
||||
xbind (sockets[i], ai[i]->ai_addr, ai[i]->ai_addrlen);
|
||||
}
|
||||
|
||||
/* Send two packets to each server. */
|
||||
int client = xsocket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
TEST_VERIFY (sendto (client, &i, sizeof (i), 0,
|
||||
ai[i]->ai_addr, ai[i]->ai_addrlen) == sizeof (i));
|
||||
int j = i + 256;
|
||||
TEST_VERIFY (sendto (client, &j, sizeof (j), 0,
|
||||
ai[i]->ai_addr, ai[i]->ai_addrlen) == sizeof (j));
|
||||
}
|
||||
|
||||
/* Check that the packets can be received with the expected
|
||||
contents. Note that the receive calls interleave differently,
|
||||
which hopefully proves that the sockets are, indeed,
|
||||
independent. */
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
int buf;
|
||||
TEST_VERIFY (recv (sockets[i], &buf, sizeof (buf), 0) == sizeof (buf));
|
||||
TEST_VERIFY (buf == i);
|
||||
}
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
int buf;
|
||||
TEST_VERIFY (recv (sockets[i], &buf, sizeof (buf), 0) == sizeof (buf));
|
||||
TEST_VERIFY (buf == i + 256);
|
||||
/* Check that there is no more data to receive. */
|
||||
TEST_VERIFY (recv (sockets[i], &buf, sizeof (buf), MSG_DONTWAIT) == -1);
|
||||
TEST_VERIFY (errno == EWOULDBLOCK || errno == EAGAIN);
|
||||
}
|
||||
|
||||
/* Close all sockets and free the addresses. */
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
freeaddrinfo (ai[i]);
|
||||
xclose (sockets[i]);
|
||||
}
|
||||
xclose (client);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
if (support_become_root ())
|
||||
bool root = support_become_root ();
|
||||
if (root)
|
||||
printf ("info: acquired root-like privileges\n");
|
||||
if (support_enter_network_namespace ())
|
||||
bool netns = support_enter_network_namespace ();
|
||||
if (netns)
|
||||
printf ("info: entered network namespace\n");
|
||||
if (support_in_uts_namespace ())
|
||||
printf ("info: also entered UTS namespace\n");
|
||||
|
||||
if (root && netns)
|
||||
test_localhost_bind ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
188
support/tst-support_capture_subprocess.c
Normal file
188
support/tst-support_capture_subprocess.c
Normal 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>
|
101
support/tst-support_format_dns_packet.c
Normal file
101
support/tst-support_format_dns_packet.c
Normal 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>
|
@ -37,7 +37,7 @@ run_test () {
|
||||
set -e
|
||||
echo " exit status: $status"
|
||||
if test "$output" != "$expected_output" ; then
|
||||
echo "error: unexpected ouput: $output"
|
||||
echo "error: unexpected output: $output"
|
||||
exit 1
|
||||
fi
|
||||
if test "$status" -ne "$expected_status" ; then
|
||||
@ -52,9 +52,9 @@ different_status () {
|
||||
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:108: not true: false
|
||||
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:108: not true: false
|
||||
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
|
||||
}
|
||||
@ -62,8 +62,8 @@ error: 1 test failures" $direct --test-verify --verbose
|
||||
different_status
|
||||
different_status --direct
|
||||
|
||||
run_test 1 "error: tst-support_record_failure.c:115: not true: false
|
||||
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:115: not true: false" \
|
||||
run_test 1 "error: tst-support_record_failure.c:116: not true: false" \
|
||||
--direct --test-verify-exit
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static int exit_status_with_failure = -1;
|
||||
static bool test_verify;
|
||||
|
32
support/xaccept4.c
Normal file
32
support/xaccept4.c
Normal 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;
|
||||
}
|
28
support/xchroot.c
Normal file
28
support/xchroot.c
Normal 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
28
support/xclose.c
Normal 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);
|
||||
}
|
28
support/xdup2.c
Normal file
28
support/xdup2.c
Normal 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);
|
||||
}
|
28
support/xmkdir.c
Normal file
28
support/xmkdir.c
Normal 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);
|
||||
}
|
28
support/xmprotect.c
Normal file
28
support/xmprotect.c
Normal file
@ -0,0 +1,28 @@
|
||||
/* mprotect 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/mman.h>
|
||||
|
||||
void
|
||||
xmprotect (void *addr, size_t length, int prot)
|
||||
{
|
||||
if (mprotect (addr, length, prot) != 0)
|
||||
FAIL_EXIT1 ("mprotect (%p, %zu, 0x%x): %m", addr, length, prot);
|
||||
}
|
30
support/xopen.c
Normal file
30
support/xopen.c
Normal 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
28
support/xpipe.c
Normal 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");
|
||||
}
|
26
support/xpthread_attr_setguardsize.c
Normal file
26
support/xpthread_attr_setguardsize.c
Normal file
@ -0,0 +1,26 @@
|
||||
/* pthread_attr_setguardsize 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_setguardsize (pthread_attr_t *attr, size_t guardsize)
|
||||
{
|
||||
xpthread_check_return ("pthread_attr_setguardize",
|
||||
pthread_attr_setguardsize (attr, guardsize));
|
||||
}
|
27
support/xpthread_rwlock_init.c
Normal file
27
support/xpthread_rwlock_init.c
Normal file
@ -0,0 +1,27 @@
|
||||
/* pthread_rwlock_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_rwlock_init (pthread_rwlock_t *rwlock,
|
||||
const pthread_rwlockattr_t *attr)
|
||||
{
|
||||
xpthread_check_return ("pthread_rwlock_init",
|
||||
pthread_rwlock_init (rwlock, attr));
|
||||
}
|
26
support/xpthread_rwlock_rdlock.c
Normal file
26
support/xpthread_rwlock_rdlock.c
Normal file
@ -0,0 +1,26 @@
|
||||
/* pthread_rwlock_rdlock 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_rwlock_rdlock (pthread_rwlock_t *rwlock)
|
||||
{
|
||||
xpthread_check_return ("pthread_rwlock_rdlock",
|
||||
pthread_rwlock_rdlock (rwlock));
|
||||
}
|
26
support/xpthread_rwlock_unlock.c
Normal file
26
support/xpthread_rwlock_unlock.c
Normal file
@ -0,0 +1,26 @@
|
||||
/* pthread_rwlock_unlock 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_rwlock_unlock (pthread_rwlock_t *rwlock)
|
||||
{
|
||||
xpthread_check_return ("pthread_rwlock_unlock",
|
||||
pthread_rwlock_unlock (rwlock));
|
||||
}
|
26
support/xpthread_rwlock_wrlock.c
Normal file
26
support/xpthread_rwlock_wrlock.c
Normal file
@ -0,0 +1,26 @@
|
||||
/* pthread_rwlock_wrlock 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_rwlock_wrlock (pthread_rwlock_t *rwlock)
|
||||
{
|
||||
xpthread_check_return ("pthread_rwlock_wrlock",
|
||||
pthread_rwlock_wrlock (rwlock));
|
||||
}
|
26
support/xpthread_rwlockattr_init.c
Normal file
26
support/xpthread_rwlockattr_init.c
Normal file
@ -0,0 +1,26 @@
|
||||
/* pthread_rwlockattr_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_rwlockattr_init (pthread_rwlockattr_t *attr)
|
||||
{
|
||||
xpthread_check_return ("pthread_rwlockattr_init",
|
||||
pthread_rwlockattr_init (attr));
|
||||
}
|
27
support/xpthread_rwlockattr_setkind_np.c
Normal file
27
support/xpthread_rwlockattr_setkind_np.c
Normal file
@ -0,0 +1,27 @@
|
||||
/* pthread_rwlockattr_setkind_np 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_rwlockattr_setkind_np (pthread_rwlockattr_t *attr,
|
||||
int pref)
|
||||
{
|
||||
xpthread_check_return ("pthread_rwlockattr_setkind_np",
|
||||
pthread_rwlockattr_setkind_np (attr, pref));
|
||||
}
|
@ -30,6 +30,7 @@ void xconnect (int, const struct sockaddr *, socklen_t);
|
||||
void xbind (int, const struct sockaddr *, socklen_t);
|
||||
void xlisten (int, int);
|
||||
int xaccept (int, struct sockaddr *, socklen_t *);
|
||||
int xaccept4 (int, struct sockaddr *, socklen_t *, int);
|
||||
void xsendto (int, const void *, size_t, int,
|
||||
const struct sockaddr *, socklen_t);
|
||||
size_t xrecvfrom (int, void *, size_t, int, struct sockaddr *, socklen_t *);
|
||||
|
@ -67,11 +67,21 @@ void xpthread_attr_setdetachstate (pthread_attr_t *attr,
|
||||
int detachstate);
|
||||
void xpthread_attr_setstacksize (pthread_attr_t *attr,
|
||||
size_t stacksize);
|
||||
void xpthread_attr_setguardsize (pthread_attr_t *attr,
|
||||
size_t guardsize);
|
||||
|
||||
/* This function returns non-zero if pthread_barrier_wait returned
|
||||
PTHREAD_BARRIER_SERIAL_THREAD. */
|
||||
int xpthread_barrier_wait (pthread_barrier_t *barrier);
|
||||
|
||||
void xpthread_rwlock_init (pthread_rwlock_t *rwlock,
|
||||
const pthread_rwlockattr_t *attr);
|
||||
void xpthread_rwlockattr_init (pthread_rwlockattr_t *attr);
|
||||
void xpthread_rwlockattr_setkind_np (pthread_rwlockattr_t *attr, int pref);
|
||||
void xpthread_rwlock_wrlock (pthread_rwlock_t *rwlock);
|
||||
void xpthread_rwlock_rdlock (pthread_rwlock_t *rwlock);
|
||||
void xpthread_rwlock_unlock (pthread_rwlock_t *rwlock);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* SUPPORT_THREAD_H */
|
||||
|
@ -22,20 +22,33 @@
|
||||
#ifndef SUPPORT_XUNISTD_H
|
||||
#define SUPPORT_XUNISTD_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct stat64;
|
||||
|
||||
pid_t xfork (void);
|
||||
pid_t xwaitpid (pid_t, int *status, int flags);
|
||||
void xpipe (int[2]);
|
||||
void xdup2 (int, int);
|
||||
int xopen (const char *path, int flags, mode_t);
|
||||
void xstat (const char *path, struct stat64 *);
|
||||
void xmkdir (const char *path, mode_t);
|
||||
void xchroot (const char *path);
|
||||
|
||||
/* Close the file descriptor. Ignore EINTR errors, but terminate the
|
||||
process on other errors. */
|
||||
void xclose (int);
|
||||
|
||||
/* Write the buffer. Retry on short writes. */
|
||||
void xwrite (int, const void *, size_t);
|
||||
|
||||
/* Invoke mmap with a zero file offset. */
|
||||
void *xmmap (void *addr, size_t length, int prot, int flags, int fd);
|
||||
|
||||
void xmprotect (void *addr, size_t length, int prot);
|
||||
void xmunmap (void *addr, size_t length);
|
||||
|
||||
__END_DECLS
|
||||
|
Loading…
Reference in New Issue
Block a user