diff mbox

extras: New test/build infrastructure

Message ID 9426ee75-3e45-6cde-b659-567398007a32@redhat.com
State New
Headers show

Commit Message

Florian Weimer Nov. 25, 2016, 3:59 p.m. UTC
I have split up test-skeleton.c into its components.  The new test 
skeleton should be compatible with compilation in C90 mode.  I expect to 
use some of these helper functions for future build support on the host 
(that is, these routines will have to be compiled twice, once against 
the built libc, and once against the host libc).

I converted a few tests to make sure that this works as expected.

I do not propose bulk migration at this point.  Some obscure use cases 
are not supported by the exported hooks.

If you think this goes in the right direction, I will port over my 
container-based nss_files testing, and the resolver test suite to this 
infrastructure.  It also eliminates the need for the hack in my fix for 
bug 16421 I posted earlier.

Tested on aarch64, ppc64le, s390x, x86_64.

Thanks,
Florian

Comments

Zack Weinberg Nov. 25, 2016, 4:14 p.m. UTC | #1
On 11/25/2016 10:59 AM, Florian Weimer wrote:
> I have split up test-skeleton.c into its components.  The new test
> skeleton should be compatible with compilation in C90 mode.  I expect to
> use some of these helper functions for future build support on the host
> (that is, these routines will have to be compiled twice, once against
> the built libc, and once against the host libc).

I support this general idea, especially the "not #including
test-skeleton.c anymore" part.

Can I ask why the new directory is called "extras"?  That makes it sound
like a home for extra features that we want to provide but not in the
core C library.  Something more obviously internal-use and
build/test-related would be better, I think.

(It looks like you've set it up so libextras is not installed, so that's
not a concern.)

> I do not propose bulk migration at this point.  Some obscure use cases
> are not supported by the exported hooks.

Could you give an example?

> +libextras-static-only-routines := $(libextras-routines)
> +# Only build one variant of the library.
> +libextras-inhibit-o := .os
> +ifeq ($(build-shared),yes)
> +libextras-inhibit-o += .o
> +endif

This doesn't look right if the goal is to build only the .a version of
the library.

> +#ifndef EXTRAS_CHECK_H
> +#define EXTRAS_CHECK_H
> +
> +#include <features.h>
> +
> +__BEGIN_DECLS
> +
> +/* Print failure message to standard output and return 1.  */
> +#define FAIL_RET(...) \
> +  return __extras_print_failure (__FILE__, __LINE__, __VA_ARGS__)

This library is _not_ part of the implementation and should not be using
__ names.  And I'm not sure it ought to be using features.h either.

(I haven't looked over extras/*.c in detail since I assume that these
are existing code copied out of test-skeleton.c.)

zw
Andreas Schwab Nov. 25, 2016, 5:11 p.m. UTC | #2
On Nov 25 2016, Zack Weinberg <zackw@panix.com> wrote:

> Can I ask why the new directory is called "extras"?  That makes it sound
> like a home for extra features that we want to provide but not in the
> core C library.  Something more obviously internal-use and
> build/test-related would be better, I think.

Like test-support or testsuite.

Andreas.
Joseph Myers Nov. 25, 2016, 5:29 p.m. UTC | #3
On Fri, 25 Nov 2016, Florian Weimer wrote:

> I do not propose bulk migration at this point.  Some obscure use cases are not
> supported by the exported hooks.

I agree with the other comments about naming this something like 
libtest-support.a (and naming headers, directories accordingly).

I think there would be clear advantages to setting things up so that all 
existing tests can use the new code with no changes at all.  That is, make 
test-skeleton.c look more or less like your extras/test-skeleton.c, with 
additional code to handle any missing pieces (e.g.

int
test_function (int argc, char **argv)
{
  return TEST_FUNCTION;
}

to handle existing TEST_FUNCTION definitions without needing changes to 
individual tests).  If a slightly different interface is preferred, then 
individual tests could be converted to that afterwards.
Florian Weimer Nov. 25, 2016, 5:45 p.m. UTC | #4
On 11/25/2016 05:14 PM, Zack Weinberg wrote:
> On 11/25/2016 10:59 AM, Florian Weimer wrote:
>> I have split up test-skeleton.c into its components.  The new test
>> skeleton should be compatible with compilation in C90 mode.  I expect to
>> use some of these helper functions for future build support on the host
>> (that is, these routines will have to be compiled twice, once against
>> the built libc, and once against the host libc).
>
> I support this general idea, especially the "not #including
> test-skeleton.c anymore" part.
>
> Can I ask why the new directory is called "extras"?  That makes it sound
> like a home for extra features that we want to provide but not in the
> core C library.  Something more obviously internal-use and
> build/test-related would be better, I think.

I plan to use bits of it for fixing localedef bugs and contributing 
Fedora changes upstream.  Those bits would then end up in installed 
binaries.

The immediate need is for testing only and generic test support code 
(container setup, a fake DNS server implementation, and so on).

> (It looks like you've set it up so libextras is not installed, so that's
> not a concern.)

Good point, I need to validate this.

To reiterate, there is no intent on my part to ship this for use in 
application code.

>> I do not propose bulk migration at this point.  Some obscure use cases
>> are not supported by the exported hooks.
>
> Could you give an example?

PREPARE with argc/argv arguments and command line parser extensions. 
The latter requires some gymnastics to support it's heavily based on 
preprocessor macros and assumes that <getopt.h> is always included.

>> +libextras-static-only-routines := $(libextras-routines)
>> +# Only build one variant of the library.
>> +libextras-inhibit-o := .os
>> +ifeq ($(build-shared),yes)
>> +libextras-inhibit-o += .o
>> +endif
>
> This doesn't look right if the goal is to build only the .a version of
> the library.

Could you clarify what worries you?  If there's just one variant, it has 
to be PIC, unless it's a static-only build.

>> +#ifndef EXTRAS_CHECK_H
>> +#define EXTRAS_CHECK_H
>> +
>> +#include <features.h>
>> +
>> +__BEGIN_DECLS
>> +
>> +/* Print failure message to standard output and return 1.  */
>> +#define FAIL_RET(...) \
>> +  return __extras_print_failure (__FILE__, __LINE__, __VA_ARGS__)
>
> This library is _not_ part of the implementation and should not be using
> __ names.  And I'm not sure it ought to be using features.h either.

<features.h> is needed for __BEGIN_DECLS.  Including <sys/cdefs.h> would 
be even more extreme, I think.

Florian
Florian Weimer Nov. 25, 2016, 5:46 p.m. UTC | #5
On 11/25/2016 06:11 PM, Andreas Schwab wrote:
> On Nov 25 2016, Zack Weinberg <zackw@panix.com> wrote:
>
>> Can I ask why the new directory is called "extras"?  That makes it sound
>> like a home for extra features that we want to provide but not in the
>> core C library.  Something more obviously internal-use and
>> build/test-related would be better, I think.
>
> Like test-support or testsuite.

It won't always be about testing.

For example, some time next year, I hope to contribute a tool which 
parses C test cases, extract warning/error markers, and use that to 
check fortify warnings.

Thanks,
Florian
Florian Weimer Nov. 25, 2016, 5:48 p.m. UTC | #6
On 11/25/2016 06:29 PM, Joseph Myers wrote:
> On Fri, 25 Nov 2016, Florian Weimer wrote:
>
>> I do not propose bulk migration at this point.  Some obscure use cases are not
>> supported by the exported hooks.
>
> I agree with the other comments about naming this something like
> libtest-support.a (and naming headers, directories accordingly).

See my other comments.  It's currently for testing only, but this will 
likely change.

> I think there would be clear advantages to setting things up so that all
> existing tests can use the new code with no changes at all.  That is, make
> test-skeleton.c look more or less like your extras/test-skeleton.c, with
> additional code to handle any missing pieces (e.g.

Can you clarify what the goal is?  If the

#include "../test-skeleton.c"

is at the end, it shall be possible to replace it with

#include <extras/test-skeleton.c>

?  Or do you want me to replace test-skeleton.c with a version which 
already includes <extras/test-skeleton.c>?  (All names subject to revision.)

Thanks,
Florian
Joseph Myers Nov. 25, 2016, 6:24 p.m. UTC | #7
On Fri, 25 Nov 2016, Florian Weimer wrote:

> > I think there would be clear advantages to setting things up so that all
> > existing tests can use the new code with no changes at all.  That is, make
> > test-skeleton.c look more or less like your extras/test-skeleton.c, with
> > additional code to handle any missing pieces (e.g.
> 
> Can you clarify what the goal is?  If the
> 
> #include "../test-skeleton.c"
> 
> is at the end, it shall be possible to replace it with
> 
> #include <extras/test-skeleton.c>
> 
> ?  Or do you want me to replace test-skeleton.c with a version which already
> includes <extras/test-skeleton.c>?  (All names subject to revision.)

I would like test-skeleton.c to either include extras/test-skeleton.c, or 
have essentially its contents in your patch, so that existing tests don't 
need changing at all to use the new facilities.  (This implies making your 
intrastructure support all the facilities test-skeleton.c does.)  This 
should work regardless of where in the test sources test-skeleton.c is 
included.

(If there are a few tests for which full compatibility is hard, the patch 
might fix those at the same time as making the changes to test-skeleton.c.  
But unchanged tests should use the new facilities and the number of tests 
that need changing to make that so should be as few as possible.)

(Changing all tests later to use a different name from 
"../test-skeleton.c" is fine, but I think such a global change to all 
tests' sources is best kept out of the initial patch.)
Zack Weinberg Nov. 25, 2016, 6:44 p.m. UTC | #8
On Fri, Nov 25, 2016 at 12:45 PM, Florian Weimer <fweimer@redhat.com> wrote:
> On 11/25/2016 05:14 PM, Zack Weinberg wrote:
>>
>> Can I ask why the new directory is called "extras"?  That makes it sound
>> like a home for extra features that we want to provide but not in the
>> core C library.  Something more obviously internal-use and
>> build/test-related would be better, I think.
>
> I plan to use bits of it for fixing localedef bugs and contributing Fedora
> changes upstream.  Those bits would then end up in installed binaries.
>
> The immediate need is for testing only and generic test support code
> (container setup, a fake DNS server implementation, and so on).

So maybe "support/" or "build-test-support/"?

>>> +libextras-static-only-routines := $(libextras-routines)
>>> +# Only build one variant of the library.
>>> +libextras-inhibit-o := .os
>>> +ifeq ($(build-shared),yes)
>>> +libextras-inhibit-o += .o
>>> +endif
>>
>> This doesn't look right if the goal is to build only the .a version of
>> the library.
>
> Could you clarify what worries you?  If there's just one variant, it has to
> be PIC, unless it's a static-only build.

I may well not understand what this combination of
-static-only-routines and -inhibit-o does, but what it *looks* like it
does is disable generation of .os (PIC) object files unconditionally,
and if shared libraries are enabled, it also disables .o (static)
object files. I would expect this to wind up either not working at
all, or producing only a *shared* library, or possibly only a
profiling library!

Also I don't know why this code would need to be PIC.

>> This library is _not_ part of the implementation and should not be using
>> __ names.  And I'm not sure it ought to be using features.h either.
>
> <features.h> is needed for __BEGIN_DECLS.  Including <sys/cdefs.h> would be
> even more extreme, I think.

Honestly I think sys/cdefs.h has a better claim to be a public
interface than features.h, since it exists on *BSD (and does in fact
define compatible __BEGIN_DECLS/__END_DECLS there too: see
https://github.com/freebsd/freebsd/blob/master/sys/sys/cdefs.h)

zw
Florian Weimer Nov. 25, 2016, 6:49 p.m. UTC | #9
On 11/25/2016 07:44 PM, Zack Weinberg wrote:
> On Fri, Nov 25, 2016 at 12:45 PM, Florian Weimer <fweimer@redhat.com> wrote:
>> On 11/25/2016 05:14 PM, Zack Weinberg wrote:
>>>
>>> Can I ask why the new directory is called "extras"?  That makes it sound
>>> like a home for extra features that we want to provide but not in the
>>> core C library.  Something more obviously internal-use and
>>> build/test-related would be better, I think.
>>
>> I plan to use bits of it for fixing localedef bugs and contributing Fedora
>> changes upstream.  Those bits would then end up in installed binaries.
>>
>> The immediate need is for testing only and generic test support code
>> (container setup, a fake DNS server implementation, and so on).
>
> So maybe "support/" or "build-test-support/"?

support/ works for me.  Any objects to that?

>>>> +libextras-static-only-routines := $(libextras-routines)
>>>> +# Only build one variant of the library.
>>>> +libextras-inhibit-o := .os
>>>> +ifeq ($(build-shared),yes)
>>>> +libextras-inhibit-o += .o
>>>> +endif
>>>
>>> This doesn't look right if the goal is to build only the .a version of
>>> the library.
>>
>> Could you clarify what worries you?  If there's just one variant, it has to
>> be PIC, unless it's a static-only build.
>
> I may well not understand what this combination of
> -static-only-routines and -inhibit-o does, but what it *looks* like it
> does is disable generation of .os (PIC) object files unconditionally,
> and if shared libraries are enabled, it also disables .o (static)
> object files. I would expect this to wind up either not working at
> all, or producing only a *shared* library, or possibly only a
> profiling library!

For shared builds, we still build .oS, that is lib_*nonshared.a.  Sure, 
it's rather strange, but it looks like this is the way it is expected to 
work.

> Also I don't know why this code would need to be PIC.

We already have one use of write_message from a test DSO, in 
dlfcn/bug-atexit3-lib.cc.  This was impossible with the existing test 
skeleton.

>>> This library is _not_ part of the implementation and should not be using
>>> __ names.  And I'm not sure it ought to be using features.h either.
>>
>> <features.h> is needed for __BEGIN_DECLS.  Including <sys/cdefs.h> would be
>> even more extreme, I think.
>
> Honestly I think sys/cdefs.h has a better claim to be a public
> interface than features.h, since it exists on *BSD (and does in fact
> define compatible __BEGIN_DECLS/__END_DECLS there too: see
> https://github.com/freebsd/freebsd/blob/master/sys/sys/cdefs.h)

Fine, <sys/cdefs.h> it is.

Thanks,
Florian
Florian Weimer Nov. 25, 2016, 7:26 p.m. UTC | #10
On 11/25/2016 07:24 PM, Joseph Myers wrote:
> On Fri, 25 Nov 2016, Florian Weimer wrote:
>
>>> I think there would be clear advantages to setting things up so that all
>>> existing tests can use the new code with no changes at all.  That is, make
>>> test-skeleton.c look more or less like your extras/test-skeleton.c, with
>>> additional code to handle any missing pieces (e.g.
>>
>> Can you clarify what the goal is?  If the
>>
>> #include "../test-skeleton.c"
>>
>> is at the end, it shall be possible to replace it with
>>
>> #include <extras/test-skeleton.c>
>>
>> ?  Or do you want me to replace test-skeleton.c with a version which already
>> includes <extras/test-skeleton.c>?  (All names subject to revision.)
>
> I would like test-skeleton.c to either include extras/test-skeleton.c, or
> have essentially its contents in your patch, so that existing tests don't
> need changing at all to use the new facilities.  (This implies making your
> intrastructure support all the facilities test-skeleton.c does.)  This
> should work regardless of where in the test sources test-skeleton.c is
> included.
>
> (If there are a few tests for which full compatibility is hard, the patch
> might fix those at the same time as making the changes to test-skeleton.c.
> But unchanged tests should use the new facilities and the number of tests
> that need changing to make that so should be as few as possible.)

Okay, what you suggest is reasonable.  I'll prepare a patch along these 
lines.

I'll also change the subdirectory name to “support”, as Zack suggested.

Thanks,
Florian
diff mbox

Patch

extras: Introduce new subdirectory for test infrastructure

2016-11-25  Florian Weimer  <fweimer@redhat.com>

	New subdirectory extras for build and test infrastructure.
	* Makeconfig (link-extra-libs-tests): Define.
	(+link-pie-tests, +link-static-tests, +link-tests): Use
	link-extra-libs-tests.
	(rpath-dirs, all-subdirs): Add extras.
	(built-modules): Add libextras.
	(libextras): Define.
	* extras: New directory.
	* extras/Makefile, extras/check.c, extras/chech.h,
	extras/extras.h, extras/ignore_stderr.c, extras/oom_error.c,
	extras/set_fortify_handler.c, extras/temp_file-internal.h,
	exteras/temp_file.c, extras_tempfile.h, extras/test-skeleton.c,
	extras_testmain.c, extras/test_main.h, extras/write_message.c,
	extras/xasprintf.c, extras/xcalloc.c, extras/xmalloc.c,
	extras/xrealloc.c: New files.
	* test-skeleton.c: Include <extras/extras.h>.
	(_FAIL, FAIL_RET, FAIL_EXIT, FAIL_EXIT1): Remove.  Now in
	extras/check.h.
	(oom_error, xmalloc, xcalloc, xrealloc, xasprintf, write_message)
	(ignore_stderr, set_fortify_handler): Remove.  Now in
	extras/extras.h.
	* dlfcn/Makefile (bug-atexit3-lib.so): Link with $(libextras).
	* dlfcn/bug-atexit3-lib.cc: Include <extras/extras.h>.
	(write_message): Remove.
	* io/test-open-tmpfile: Use new test skeleton.
	* io/tst-posix_fallocate-common.c: Likewise.
	* malloc/tst-malloc-backtrace.c: Likewise.
	* nptl/tst-cleanup0.c: Likewise.
	* posix/tst-posix_fadvise-common.c: Likewise.
	* sysdeps/unix/sysv/linux/tst-fallocate-common.c: Likewise.
	* sysdeps/unix/sysv/linux/tst-sync_file_range.c: Likewise.

diff --git a/Makeconfig b/Makeconfig
index a785860..c429917 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -394,6 +394,9 @@  ifndef after-link
 after-link =
 endif
 
+# Additional libraries to link into every test.
+link-extra-libs-tests = $(libextras)
+
 # Command for linking PIE programs with the C library.
 ifndef +link-pie
 +link-pie-before-libc = $(CC) -pie -Wl,-O1 -nostdlib -nostartfiles -o $@ \
@@ -412,8 +415,8 @@  $(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-libc) $(+link-pie-after-libc)
 $(call after-link,$@)
 endef
 define +link-pie-tests
-$(+link-pie-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \
-			 $(+link-pie-after-libc)
+$(+link-pie-before-libc) $(link-extra-libs-tests) \
+  $(rtld-tests-LDFLAGS) $(link-libc-tests) $(+link-pie-after-libc)
 $(call after-link,$@)
 endef
 endif
@@ -434,7 +437,8 @@  $(+link-static-before-libc) $(link-libc-static) $(+link-static-after-libc)
 $(call after-link,$@)
 endef
 define +link-static-tests
-$(+link-static-before-libc) $(link-libc-static-tests) $(+link-static-after-libc)
+$(+link-static-before-libc) $(link-extra-libs-tests) \
+  $(link-libc-static-tests) $(+link-static-after-libc)
 $(call after-link,$@)
 endef
 endif
@@ -462,8 +466,8 @@  $(+link-before-libc) $(rtld-LDFLAGS) $(link-libc) $(+link-after-libc)
 $(call after-link,$@)
 endef
 define +link-tests
-$(+link-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \
-		     $(+link-after-libc)
+$(+link-before-libc) $(link-extra-libs-tests) \
+  $(link-libc-tests) $(+link-after-libc)
 $(call after-link,$@)
 endef
 endif
@@ -503,7 +507,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 extras
 rpath-link = \
 $(common-objdir):$(subst $(empty) ,:,$(patsubst ../$(subdir),.,$(rpath-dirs:%=$(common-objpfx)%)))
 else
@@ -850,7 +854,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 libextras
 
 in-module = $(subst -,_,$(firstword $(libof-$(basename $(@F))) \
 				    $(libof-$(<F)) \
@@ -1091,6 +1095,12 @@  libm = $(common-objpfx)math/libm.a
 libmvec = $(common-objpfx)mathvec/libmvec.a
 endif
 
+ifeq ($(build-shared),yes)
+libextras = $(common-objpfx)extras/libextras_nonshared.a
+else
+libextras = $(common-objpfx)extras/libextras.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.
@@ -1098,7 +1108,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 extras	    \
 	      $(add-on-subdirs) dlfcn elf
 
 ifndef avoid-generated
diff --git a/dlfcn/Makefile b/dlfcn/Makefile
index deab96e..0e4d2b2 100644
--- a/dlfcn/Makefile
+++ b/dlfcn/Makefile
@@ -139,6 +139,7 @@  $(objpfx)bug-atexit2.out: $(objpfx)bug-atexit2-lib.so
 
 ifneq (,$(CXX))
 LDLIBS-bug-atexit3-lib.so = -lstdc++ -lgcc_eh
+$(objpfx)bug-atexit3-lib.so: $(libextras)
 $(objpfx)bug-atexit3: $(libdl)
 $(objpfx)bug-atexit3.out: $(objpfx)bug-atexit3-lib.so
 endif
diff --git a/dlfcn/bug-atexit3-lib.cc b/dlfcn/bug-atexit3-lib.cc
index aba7720..01fe84b 100644
--- a/dlfcn/bug-atexit3-lib.cc
+++ b/dlfcn/bug-atexit3-lib.cc
@@ -1,12 +1,7 @@ 
 #include <unistd.h>
 #include <string.h>
 
-static void
-write_message (const char *message)
-{
-  ssize_t unused __attribute__ ((unused));
-  unused = write (STDOUT_FILENO, message, strlen (message));
-}
+#include <extras/extras.h>
 
 struct statclass
 {
diff --git a/extras/Makefile b/extras/Makefile
new file mode 100644
index 0000000..504078c
--- /dev/null
+++ b/extras/Makefile
@@ -0,0 +1,46 @@ 
+# Makefile for extras library, used only at build and test time
+# Copyright (C) 2016 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 := elf
+
+include ../Makeconfig
+
+extra-libs := libextras
+extra-libs-others = $(extra-libs)
+
+libextras-routines = \
+  check \
+  ignore_stderr \
+  oom_error \
+  set_fortify_handler \
+  temp_file \
+  test_main \
+  write_message \
+  xasprintf \
+  xcalloc \
+  xmalloc \
+  xrealloc \
+
+libextras-static-only-routines := $(libextras-routines)
+# Only build one variant of the library.
+libextras-inhibit-o := .os
+ifeq ($(build-shared),yes)
+libextras-inhibit-o += .o
+endif
+
+include ../Rules
diff --git a/extras/check.c b/extras/check.c
new file mode 100644
index 0000000..b24c08c
--- /dev/null
+++ b/extras/check.c
@@ -0,0 +1,54 @@ 
+/* Support code for reporting test results.
+   Copyright (C) 2016 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 <extras/check.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.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
+__extras_print_failure (const char *file, int line,
+                        const char *format, ...)
+{
+  va_list ap;
+  va_start (ap, format);
+  print_failure (file, line, format, ap);
+  va_end (ap);
+  return 1;
+}
+
+void
+__extras_exit_failure (int status, const char *file, int line,
+                       const char *format, ...)
+{
+  va_list ap;
+  va_start (ap, format);
+  print_failure (file, line, format, ap);
+  va_end (ap);
+  exit (status);
+}
+
diff --git a/extras/check.h b/extras/check.h
new file mode 100644
index 0000000..f18062e
--- /dev/null
+++ b/extras/check.h
@@ -0,0 +1,49 @@ 
+/* Macros for reporting test results.
+   Copyright (C) 2016 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 EXTRAS_CHECK_H
+#define EXTRAS_CHECK_H
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Print failure message to standard output and return 1.  */
+#define FAIL_RET(...) \
+  return __extras_print_failure (__FILE__, __LINE__, __VA_ARGS__)
+
+/* Print failure message and terminate the process with STATUS.  */
+#define FAIL_EXIT(status, ...) \
+  __extras_exit_failure (status, __FILE__, __LINE__, __VA_ARGS__)
+
+/* Print failure message and terminate with exit status 1.  */
+#define FAIL_EXIT1(...) \
+  __extras_exit_failure (1, __FILE__, __LINE__, __VA_ARGS__)
+
+int __extras_print_failure (const char *file, int line,
+                             const char *format, ...)
+  __attribute__ ((nonnull (1), format (printf, 3, 4)));
+void __extras_exit_failure (int exit_status,
+                            const char *file, int line,
+                            const char *format, ...)
+  __attribute__ ((noreturn, nonnull (2), format (printf, 4, 5)));
+
+
+__END_DECLS
+
+#endif /* EXTRAS_CHECK_H */
diff --git a/extras/extras.h b/extras/extras.h
new file mode 100644
index 0000000..006996d
--- /dev/null
+++ b/extras/extras.h
@@ -0,0 +1,62 @@ 
+/* Common extra functions.
+   Copyright (C) 1998-2016 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 EXTRAS_H
+#define EXTRAS_H
+
+#include <features.h>
+#include <stddef.h>
+
+/* Test exit status which indicates that the feature is
+   unsupported.  */
+#define EXIT_UNSUPPORTED 77
+
+__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)));
+
+/* 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));
+
+__END_DECLS
+
+#endif
diff --git a/extras/ignore_stderr.c b/extras/ignore_stderr.c
new file mode 100644
index 0000000..d5b8ffc
--- /dev/null
+++ b/extras/ignore_stderr.c
@@ -0,0 +1,38 @@ 
+/* Avoid all the buffer overflow messages on stderr.
+   Copyright (C) 2015-2016 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 <extras/extras.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);
+}
diff --git a/extras/oom_error.c b/extras/oom_error.c
new file mode 100644
index 0000000..b881645
--- /dev/null
+++ b/extras/oom_error.c
@@ -0,0 +1,29 @@ 
+/* Reporting out-of-memory errors.
+   Copyright (C) 2016 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 <extras/extras.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);
+}
diff --git a/extras/set_fortify_handler.c b/extras/set_fortify_handler.c
new file mode 100644
index 0000000..3a9043f
--- /dev/null
+++ b/extras/set_fortify_handler.c
@@ -0,0 +1,35 @@ 
+/* Set signal handler for use in fortify tests.
+   Copyright (C) 2016 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 <extras/extras.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 ();
+}
+
diff --git a/extras/temp_file-internal.h b/extras/temp_file-internal.h
new file mode 100644
index 0000000..3c42b6a
--- /dev/null
+++ b/extras/temp_file-internal.h
@@ -0,0 +1,31 @@ 
+/* Internal weak declarations for temporary file handling.
+   Copyright (C) 2016 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 EXTRAS_TEMP_FILE_INTERNAL_H
+#define EXTRAS_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 __extras_set_test_dir (const char *name) __attribute__ ((weak));
+void __extras_delete_temp_files (void) __attribute__ ((weak));
+void __extras_print_temp_files (FILE *) __attribute__ ((weak));
+
+#endif /* EXTRAS_TEMP_FILE_INTERNAL_H */
diff --git a/extras/temp_file.c b/extras/temp_file.c
new file mode 100644
index 0000000..32b6560
--- /dev/null
+++ b/extras/temp_file.c
@@ -0,0 +1,121 @@ 
+/* Temporary file handling for tests.
+   Copyright (C) 1998-2016 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 <extras/temp_file.h>
+#include <extras/temp_file-internal.h>
+#include <extras/extras.h>
+
+#include <paths.h>
+#include <search.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* List of temporary files.  */
+static struct temp_name_list
+{
+  struct qelem q;
+  char *name;
+} *temp_name_list;
+
+/* Location of the temporary files.  Set by the test skeleton via
+   __extras_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;
+      if (temp_name_list == NULL)
+	temp_name_list = (struct temp_name_list *) &newp->q;
+      else
+	insque (newp, temp_name_list);
+    }
+  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
+__extras_set_test_dir (const char *path)
+{
+  test_dir = path;
+}
+
+void
+__extras_delete_temp_files (void)
+{
+  while (temp_name_list != NULL)
+    {
+      remove (temp_name_list->name);
+      free (temp_name_list->name);
+
+      struct temp_name_list *next
+	= (struct temp_name_list *) temp_name_list->q.q_forw;
+      free (temp_name_list);
+      temp_name_list = next;
+    }
+}
+
+void
+__extras_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 = (struct temp_name_list *) n->q.q_forw)
+        fprintf (f, "  '%s'\n", n->name);
+      fprintf (f, ")\n");
+    }
+}
diff --git a/extras/temp_file.h b/extras/temp_file.h
new file mode 100644
index 0000000..258169a
--- /dev/null
+++ b/extras/temp_file.h
@@ -0,0 +1,37 @@ 
+/* Declarations for temporary file handling.
+   Copyright (C) 2016 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 EXTRAS_TEMP_FILE_H
+#define EXTRAS_TEMP_FILE_H
+
+#include <features.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 /* EXTRAS_TEMP_FILE_H */
diff --git a/extras/test-skeleton.c b/extras/test-skeleton.c
new file mode 100644
index 0000000..0080c89
--- /dev/null
+++ b/extras/test-skeleton.c
@@ -0,0 +1,90 @@ 
+/* Skeleton for test programs.
+   Copyright (C) 2016 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 expression should always
+   return 0, 1, or 77.
+
+   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.
+
+   If PREPARE is defined, it must expand to the name of a function of
+   the type
+
+     void PREPARE (void);
+
+   This function will be called early, before running the test, in the
+   parent process which acts as the test supervisor.
+
+   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.  */
+
+#include <extras/test_main.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
+  test_config.test_function = do_test;
+#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
+  return test_main (argc, argv, &test_config);
+}
diff --git a/extras/test_main.c b/extras/test_main.c
new file mode 100644
index 0000000..8c188ca
--- /dev/null
+++ b/extras/test_main.c
@@ -0,0 +1,360 @@ 
+/* Main function of the test skeleton.
+   Copyright (C) 1998-2016 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 <extras/test_main.h>
+#include <extras/temp_file-internal.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <getopt.h>
+#include <malloc.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+enum
+  {
+    /* 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,
+  };
+
+static struct option options[] =
+{
+  { "direct", no_argument, NULL, OPT_DIRECT },
+  { "test-dir", required_argument, NULL, OPT_TESTDIR },
+  { NULL, 0, NULL, 0 }
+};
+
+/* Show people how to run the program.  */
+static void
+usage (void)
+{
+  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"
+          "\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 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;
+
+/* Timeout handler.  We kill the child and exit with an error.  */
+static void
+__attribute__ ((noreturn))
+signal_handler (int sig __attribute__ ((unused)))
+{
+  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 (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);
+}
+
+
+int
+test_main (int argc, char **argv, const struct test_config *config)
+{
+  int direct = 0;       /* Directly call the test function?  */
+  int status;
+  int opt;
+  unsigned int timeoutfactor = 1;
+  pid_t termpid;
+  const char *test_dir = NULL;
+
+  if (!config->no_mallopt)
+    /* Make uses of freed and uninitialized memory known.  */
+    mallopt (M_PERTURB, 42);
+
+  while ((opt = getopt_long (argc, argv, "+", options, NULL)) != -1)
+    switch (opt)
+      {
+      case '?':
+        usage ();
+        exit (1);
+      case OPT_DIRECT:
+        direct = 1;
+        break;
+      case OPT_TESTDIR:
+        test_dir = optarg;
+        break;
+      }
+
+  /* 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 (__extras_set_test_dir != NULL)
+    __extras_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 (__extras_delete_temp_files != NULL)
+      atexit (__extras_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 ();
+
+  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 (__extras_print_temp_files != NULL)
+        __extras_print_temp_files (f);
+
+      fclose (f);
+      direct = 1;
+    }
+
+  /* If we are not expected to fork run the function immediately.  */
+  if (direct)
+    return config->test_function ();
+
+  /* Set up the test environment:
+     - prevent core dumps
+     - set up the timer
+     - fork and execute the function.  */
+
+  pid_t test_pid = fork ();
+  if (test_pid == 0)
+    {
+      /* This is the child.  */
+#ifdef RLIMIT_CORE
+      /* Try to avoid dumping core.  */
+      struct rlimit core_limit;
+      core_limit.rlim_cur = 0;
+      core_limit.rlim_max = 0;
+      setrlimit (RLIMIT_CORE, &core_limit);
+#endif
+
+      /* 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 (config->test_function ());
+    }
+  else if (test_pid < 0)
+    {
+      printf ("Cannot fork test program: %m\n");
+      exit (1);
+    }
+
+  /* Set timeout.  */
+  signal (SIGALRM, signal_handler);
+  alarm (config->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)
+            /* Simply exit with the return value of the test.  */
+            return 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 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 0;
+    }
+}
diff --git a/extras/test_main.h b/extras/test_main.h
new file mode 100644
index 0000000..01627ea
--- /dev/null
+++ b/extras/test_main.h
@@ -0,0 +1,34 @@ 
+/* Interfaces for the test skeleton.
+   Copyright (C) 2016 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 EXTRAS_TEST_MAIN_H
+#define EXTRAS_TEST_MAIN_H
+
+struct test_config
+{
+  void (*prepare_function) (void);
+  int (*test_function) (void);
+  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.  */
+};
+
+int test_main (int argc, char **argv, const struct test_config *);
+
+#endif /* EXTRAS_TEST_MAIN_H */
diff --git a/extras/write_message.c b/extras/write_message.c
new file mode 100644
index 0000000..0fd8afc
--- /dev/null
+++ b/extras/write_message.c
@@ -0,0 +1,30 @@ 
+/* Write a message to standard output.
+   Copyright (C) 2016 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 <extras/extras.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));
+}
+
diff --git a/extras/xasprintf.c b/extras/xasprintf.c
new file mode 100644
index 0000000..045c2e8
--- /dev/null
+++ b/extras/xasprintf.c
@@ -0,0 +1,38 @@ 
+/* Error-checking wrapper for asprintf.
+   Copyright (C) 1998-2016 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 <extras/extras.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+char *
+xasprintf (const char *format, ...)
+{
+  va_list ap;
+  va_start (ap, format);
+  char *result;
+  if (vasprintf (&result, format, ap) < 0)
+    {
+      printf ("error: asprintf: %m\n");
+      exit (1);
+    }
+  va_end (ap);
+  return result;
+}
diff --git a/extras/xcalloc.c b/extras/xcalloc.c
new file mode 100644
index 0000000..4b6af5a
--- /dev/null
+++ b/extras/xcalloc.c
@@ -0,0 +1,34 @@ 
+/* Error-checking wrapper for calloc.
+   Copyright (C) 1998-2016 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 <extras/extras.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;
+}
diff --git a/extras/xmalloc.c b/extras/xmalloc.c
new file mode 100644
index 0000000..b53e2a0
--- /dev/null
+++ b/extras/xmalloc.c
@@ -0,0 +1,34 @@ 
+/* Error-checking wrapper for malloc.
+   Copyright (C) 1998-2016 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 <extras/extras.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;
+}
diff --git a/extras/xrealloc.c b/extras/xrealloc.c
new file mode 100644
index 0000000..9b0e7a6
--- /dev/null
+++ b/extras/xrealloc.c
@@ -0,0 +1,32 @@ 
+/* Error-checking wrapper for realloc.
+   Copyright (C) 1998-2016 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 <extras/extras.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void *
+xrealloc (void *p, size_t n)
+{
+  void *result = realloc (p, n);
+  if (result == NULL && (n > 0 || p == NULL))
+    oom_error ("realloc", n);
+  return result;
+}
diff --git a/io/tst-open-tmpfile.c b/io/tst-open-tmpfile.c
index 9242d62..d89aa79 100644
--- a/io/tst-open-tmpfile.c
+++ b/io/tst-open-tmpfile.c
@@ -28,10 +28,7 @@ 
 #include <sys/stat.h>
 #include <unistd.h>
 
-static int do_test (void);
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <extras/extras.h>
 
 #ifdef O_TMPFILE
 typedef int (*wrapper_func) (const char *, int, mode_t);
@@ -317,3 +314,5 @@  do_test (void)
 }
 
 #endif  /* O_TMPFILE */
+
+#include <extras/test-skeleton.c>
diff --git a/io/tst-posix_fallocate-common.c b/io/tst-posix_fallocate-common.c
index 2f15a5d..5157ec9 100644
--- a/io/tst-posix_fallocate-common.c
+++ b/io/tst-posix_fallocate-common.c
@@ -17,18 +17,15 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 #include <fcntl.h>
-#include <sys/types.h>
+#include <limits.h>
+#include <stdint.h>
 #include <sys/stat.h>
+#include <sys/types.h>
 #include <unistd.h>
 
-static void do_prepare (void);
-#define PREPARE(argc, argv)     do_prepare ()
-static int do_test (void);
-#define TEST_FUNCTION           do_test ()
-
-#define TIMEOUT 20 /* sec.  */
-
-#include <test-skeleton.c>
+#include <extras/extras.h>
+#include <extras/check.h>
+#include <extras/temp_file.h>
 
 static char *temp_filename;
 static int temp_fd;
@@ -41,9 +38,6 @@  do_prepare (void)
     FAIL_EXIT1 ("cannot create temporary file: %m\n");
 }
 
-#define FAIL(str) \
-  do { printf ("error: %s (line %d)\n", str, __LINE__); return 1; } while (0)
-
 static int
 do_test_with_offset (off_t offset)
 {
@@ -83,3 +77,10 @@  do_test_with_offset (off_t offset)
 
   return 0;
 }
+
+#define PREPARE do_prepare
+
+/* This function is defined by the individual tests.  */
+static int do_test (void);
+
+#include <extras/test-skeleton.c>
diff --git a/malloc/tst-malloc-backtrace.c b/malloc/tst-malloc-backtrace.c
index 3aee7fd..a6c34cf 100644
--- a/malloc/tst-malloc-backtrace.c
+++ b/malloc/tst-malloc-backtrace.c
@@ -16,9 +16,11 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-
+#include <signal.h>
 #include <stdlib.h>
 
+#include <extras/extras.h>
+
 #define SIZE 4096
 
 /* Wrap free with a function to prevent gcc from optimizing it out.  */
@@ -30,13 +32,6 @@  call_free (void *ptr)
   *(size_t *)(ptr - sizeof (size_t)) = 1;
 }
 
-int do_test (void);
-
-#define TEST_FUNCTION do_test ()
-#define EXPECTED_SIGNAL SIGABRT
-
-#include "../test-skeleton.c"
-
 int
 do_test (void)
 {
@@ -53,3 +48,6 @@  do_test (void)
      doesn't optimize out that malloc call.  */
   return (ptr1 == ptr2);
 }
+
+#define EXPECTED_SIGNAL SIGABRT
+#include <extras/test-skeleton.c>
diff --git a/nptl/tst-cleanup0.c b/nptl/tst-cleanup0.c
index 011e5a6..a3a868b 100644
--- a/nptl/tst-cleanup0.c
+++ b/nptl/tst-cleanup0.c
@@ -71,5 +71,4 @@  do_test (void)
 
 
 #define EXPECTED_STATUS 9
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <extras/test-skeleton.c>
diff --git a/posix/tst-posix_fadvise-common.c b/posix/tst-posix_fadvise-common.c
index bb04c61..2d37665 100644
--- a/posix/tst-posix_fadvise-common.c
+++ b/posix/tst-posix_fadvise-common.c
@@ -16,17 +16,17 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <errno.h>
 #include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
 
-static void do_prepare (void);
-#define PREPARE(argc, argv)     do_prepare ()
-static int do_test (void);
-#define TEST_FUNCTION           do_test ()
-
-#include <test-skeleton.c>
+#include <extras/extras.h>
+#include <extras/check.h>
+#include <extras/temp_file.h>
 
 static char *temp_filename;
 static int temp_fd;
@@ -101,3 +101,10 @@  do_test_common (void)
 
   return 0;
 }
+
+#define PREPARE do_prepare
+
+/* This function is defined by the individual tests.  */
+static int do_test (void);
+
+#include <extras/test-skeleton.c>
diff --git a/sysdeps/unix/sysv/linux/tst-fallocate-common.c b/sysdeps/unix/sysv/linux/tst-fallocate-common.c
index d98bf4a..b8f4333 100644
--- a/sysdeps/unix/sysv/linux/tst-fallocate-common.c
+++ b/sysdeps/unix/sysv/linux/tst-fallocate-common.c
@@ -16,23 +16,22 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <errno.h>
 #include <fcntl.h>
-#include <sys/types.h>
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
 #include <sys/stat.h>
+#include <sys/types.h>
 #include <unistd.h>
 
-static void do_prepare (void);
-#define PREPARE(argc, argv)     do_prepare ()
-static int do_test (void);
-#define TEST_FUNCTION           do_test ()
-
-#define TIMEOUT 20 /* sec.  */
+#include <extras/extras.h>
+#include <extras/check.h>
+#include <extras/temp_file.h>
 
 #define XSTR(s) STR(S)
 #define STR(s)  #s
 
-#include <test-skeleton.c>
-
 static char *temp_filename;
 static int temp_fd;
 
@@ -91,3 +90,10 @@  do_test_with_offset (off_t offset)
 
   return 0;
 }
+
+#define PREPARE do_prepare
+
+/* This function is defined by the individual tests.  */
+static int do_test (void);
+
+#include <extras/test-skeleton.c>
diff --git a/sysdeps/unix/sysv/linux/tst-sync_file_range.c b/sysdeps/unix/sysv/linux/tst-sync_file_range.c
index 499a234..a41e3ed 100644
--- a/sysdeps/unix/sysv/linux/tst-sync_file_range.c
+++ b/sysdeps/unix/sysv/linux/tst-sync_file_range.c
@@ -18,21 +18,18 @@ 
 
 /* sync_file_range is only define for LFS.  */
 #define _FILE_OFFSET_BITS 64
-#include <fcntl.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <sys/stat.h>
 
-static void do_prepare (void);
-#define PREPARE(argc, argv)     do_prepare ()
-static int do_test (void);
-#define TEST_FUNCTION           do_test ()
-
-#define TIMEOUT 20 /* sec.  */
+#include <extras/temp_file.h>
+#include <extras/check.h>
 
 #define XSTR(s) STR(S)
 #define STR(s)  #s
 
-#include <test-skeleton.c>
-
 static char *temp_filename;
 static int temp_fd;
 
@@ -129,3 +126,8 @@  do_test (void)
 
   return 0;
 }
+
+#define PREPARE do_prepare
+
+#include <extras/test-skeleton.c>
+
diff --git a/test-skeleton.c b/test-skeleton.c
index fa457be..e66e6f6 100644
--- a/test-skeleton.c
+++ b/test-skeleton.c
@@ -34,6 +34,8 @@ 
 #include <sys/param.h>
 #include <time.h>
 
+#include <extras/extras.h>
+
 /* The test function is normally called `do_test' and it is called
    with argc and argv as the arguments.  We nevertheless provide the
    possibility to overwrite this name.
@@ -85,94 +87,6 @@  static pid_t pid;
 /* Directory to place temporary files in.  */
 static const char *test_dir;
 
-#define _FAIL(...) \
-  printf ("error: %s:%d: ", __FILE__, __LINE__); \
-  printf (__VA_ARGS__); \
-  printf ("\n"); \
-
-#define FAIL_RET(...) \
-  ({ \
-     _FAIL (__VA_ARGS__); \
-     return 1; \
-  })
-
-#define FAIL_EXIT(value, ...) \
-  ({ \
-     _FAIL (__VA_ARGS__); \
-     exit (value); \
-  })
-
-#define FAIL_EXIT1(...) FAIL_EXIT(1, __VA_ARGS__)
-
-static void
-oom_error (const char *fn, size_t size)
-{
-  printf ("%s: unable to allocate %zu bytes: %m\n", fn, size);
-  exit (1);
-}
-
-/* Allocate N bytes of memory dynamically, with error checking.  */
-__attribute__ ((unused))
-static void *
-xmalloc (size_t n)
-{
-  void *p;
-
-  p = malloc (n);
-  if (p == NULL)
-    oom_error ("malloc", n);
-  return p;
-}
-
-/* Allocate memory for N elements of S bytes, with error checking.  */
-__attribute__ ((unused))
-static void *
-xcalloc (size_t n, size_t s)
-{
-  void *p;
-
-  p = calloc (n, s);
-  if (p == NULL)
-    oom_error ("calloc", n * s);
-  return p;
-}
-
-/* Change the size of an allocated block of memory P to N bytes,
-   with error checking.  */
-__attribute__ ((unused))
-static void *
-xrealloc (void *p, size_t n)
-{
-  void *result = realloc (p, n);
-  if (result == NULL && (n > 0 || p == NULL))
-    oom_error ("realloc", n);
-  return result;
-}
-
-/* Call asprintf with error checking.  */
-__attribute__ ((always_inline, format (printf, 1, 2)))
-static __inline__ char *
-xasprintf (const char *format, ...)
-{
-  char *result;
-  if (asprintf (&result, format, __builtin_va_arg_pack ()) < 0)
-    {
-      printf ("error: asprintf: %m\n");
-      exit (1);
-    }
-  return result;
-}
-
-/* Write a message to standard output.  Can be used in signal
-   handlers.  */
-static void
-__attribute__ ((unused))
-write_message (const char *message)
-{
-  ssize_t unused __attribute__ ((unused));
-  unused = write (STDOUT_FILENO, message, strlen (message));
-}
-
 /* List of temporary files.  */
 struct temp_name_list
 {
@@ -317,38 +231,6 @@  signal_handler (int sig __attribute__ ((unused)))
   exit (1);
 }
 
-/* Avoid all the buffer overflow messages on stderr.  */
-static void
-__attribute__ ((unused))
-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);
-}
-
-/* Set fortification error handler.  Used when tests want to verify that bad
-   code is caught by the library.  */
-static void
-__attribute__ ((unused))
-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 ();
-}
-
 /* Show people how to run the program.  */
 static void
 usage (void)