support: Add xstrndup, xunlink, xreadlink, support_create_temp_directory

This commit is contained in:
Florian Weimer 2017-11-12 09:53:06 +01:00
parent 456b40a97f
commit 1ffe1ccb6e
11 changed files with 219 additions and 5 deletions

View File

@ -1,3 +1,15 @@
2017-11-12 Florian Weimer <fweimer@redhat.com>
* support/support.h (xstrndup): Declare.
* support/xunistd.h (xunlink, xreadlink): Declare.
* support/temp_file.h (support_create_temp_directory): Declare.
* support/temp_file.c (support_create_temp_directory): New function.
* support/support_chroot.c (support_chroot_create): Use it.
* support/xreadlink.c: New file.
* support/xstrndup.c: Likewise.
* support/xunlink.c: Likewise.
* support/tst-xreadlink.c: Likewise.
2017-11-11 John David Anglin <danglin@gcc.gnu.org>
* sysdeps/hppa/fpu/libm-test-ulps: Update clog10_downward ulps.

View File

@ -109,19 +109,22 @@ libsupport-routines = \
xpthread_once \
xpthread_rwlock_init \
xpthread_rwlock_rdlock \
xpthread_rwlock_wrlock \
xpthread_rwlock_unlock \
xpthread_rwlock_wrlock \
xpthread_rwlockattr_init \
xpthread_rwlockattr_setkind_np \
xpthread_sigmask \
xpthread_spin_lock \
xpthread_spin_unlock \
xreadlink \
xrealloc \
xrecvfrom \
xsendto \
xsetsockopt \
xsocket \
xstrdup \
xstrndup \
xunlink \
xwaitpid \
xwrite \
@ -138,6 +141,7 @@ tests = \
tst-support_capture_subprocess \
tst-support_format_dns_packet \
tst-support_record_failure \
tst-xreadlink \
ifeq ($(run-built-tests),yes)
tests-special = \

View File

@ -68,6 +68,7 @@ void *xrealloc (void *p, size_t n);
char *xasprintf (const char *format, ...)
__attribute__ ((format (printf, 1, 2), malloc));
char *xstrdup (const char *);
char *xstrndup (const char *, size_t);
__END_DECLS

View File

@ -46,10 +46,11 @@ 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);
{
char *template = xasprintf ("%s/tst-resolv-res_init-XXXXXX", test_dir);
chroot->path_chroot = support_create_temp_directory (template);
free (template);
}
/* Create the /etc directory in the chroot environment. */
char *path_etc = xasprintf ("%s/etc", chroot->path_chroot);

View File

@ -86,6 +86,19 @@ create_temp_file (const char *base, char **filename)
return fd;
}
char *
support_create_temp_directory (const char *base)
{
char *base_copy = xstrdup (base);
if (mkdtemp (base_copy) == NULL)
{
printf ("error: mkdtemp (\"%s\"): %m", base);
exit (1);
}
add_temp_file (base_copy);
return base_copy;
}
/* Helper functions called by the test skeleton follow. */
void

View File

@ -32,6 +32,11 @@ void add_temp_file (const char *name);
*FILENAME. */
int create_temp_file (const char *base, char **filename);
/* Create a temporary directory and schedule it for deletion. BASE
must end with the six characters "XXXXXX". Return the name of the
temporary directory. The caller should free the string. */
char *support_create_temp_directory (const char *base);
__END_DECLS
#endif /* SUPPORT_TEMP_FILE_H */

72
support/tst-xreadlink.c Normal file
View File

@ -0,0 +1,72 @@
/* Test the xreadlink function.
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 <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <support/check.h>
#include <support/support.h>
#include <support/temp_file.h>
#include <support/xunistd.h>
static int
do_test (void)
{
char *dir = support_create_temp_directory ("/tmp/tst-xreadlink-XXXXXX");
char *symlink_name = xasprintf ("%s/symlink", dir);
add_temp_file (symlink_name);
/* The limit 10000 is arbitrary and simply there to prevent an
attempt to exhaust all available disk space. */
for (int size = 1; size < 10000; ++size)
{
char *contents = xmalloc (size + 1);
for (int i = 0; i < size; ++i)
contents[i] = 'a' + (rand () % 26);
contents[size] = '\0';
if (symlink (contents, symlink_name) != 0)
{
if (errno == ENAMETOOLONG)
{
printf ("info: ENAMETOOLONG failure at %d bytes\n", size);
free (contents);
break;
}
FAIL_EXIT1 ("symlink (%d bytes): %m", size);
}
char *readlink_result = xreadlink (symlink_name);
TEST_VERIFY (strcmp (readlink_result, contents) == 0);
free (readlink_result);
xunlink (symlink_name);
free (contents);
}
/* Create an empty file to suppress the temporary file deletion
warning. */
xclose (xopen (symlink_name, O_WRONLY | O_CREAT, 0));
free (symlink_name);
free (dir);
return 0;
}
#include <support/test-driver.c>

44
support/xreadlink.c Normal file
View File

@ -0,0 +1,44 @@
/* Error-checking, allocating wrapper for readlink.
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 <scratch_buffer.h>
#include <support/check.h>
#include <support/support.h>
#include <xunistd.h>
char *
xreadlink (const char *path)
{
struct scratch_buffer buf;
scratch_buffer_init (&buf);
while (true)
{
ssize_t count = readlink (path, buf.data, buf.length);
if (count < 0)
FAIL_EXIT1 ("readlink (\"%s\"): %m", path);
if (count < buf.length)
{
char *result = xstrndup (buf.data, count);
scratch_buffer_free (&buf);
return result;
}
if (!scratch_buffer_grow (&buf))
FAIL_EXIT1 ("scratch_buffer_grow in xreadlink");
}
}

30
support/xstrndup.c Normal file
View File

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

View File

@ -38,6 +38,11 @@ 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);
void xunlink (const char *path);
/* Read the link at PATH. The caller should free the returned string
with free. */
char *xreadlink (const char *path);
/* Close the file descriptor. Ignore EINTR errors, but terminate the
process on other errors. */

27
support/xunlink.c Normal file
View File

@ -0,0 +1,27 @@
/* Error-checking wrapper for unlink.
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
xunlink (const char *path)
{
if (unlink (path) != 0)
FAIL_EXIT1 ("unlink (\"%s\"): %m", path);
}