From 80a18298f02005310cf0edc6163ae5eff5fad09a Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 18 Mar 1998 12:22:11 +0000 Subject: [PATCH] Update. * dirent/list.c (test): Return error value. (main): Exit with error value. * sysdeps/unix/opendir.c (__opendir): Add missing initialization. * Makefile (distribute): Add test-skeleton.c. * test-skeleton.c: New file. * dirent/Makefile (tests): Add opendir-tst1. * dirent/opendir-tst1.c: New file. 1998-03-18 Ulrich Drepper Optimize memory handling. --- ChangeLog | 14 +++- Makefile | 2 +- dirent/Makefile | 6 +- dirent/list.c | 27 ++++--- dirent/opendir-tst1.c | 96 ++++++++++++++++++++++ sysdeps/unix/opendir.c | 1 + test-skeleton.c | 177 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 310 insertions(+), 13 deletions(-) create mode 100644 dirent/opendir-tst1.c create mode 100644 test-skeleton.c diff --git a/ChangeLog b/ChangeLog index 07fd47c9fd..91bda00f91 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,19 @@ +1998-03-18 Ulrich Drepper + + * dirent/list.c (test): Return error value. + (main): Exit with error value. + + * sysdeps/unix/opendir.c (__opendir): Add missing initialization. + + * Makefile (distribute): Add test-skeleton.c. + * test-skeleton.c: New file. + * dirent/Makefile (tests): Add opendir-tst1. + * dirent/opendir-tst1.c: New file. + 1998-03-18 Ulrich Drepper * sysdeps/unix/opendir.c (__opendir): Don't block on FIFOs etc. - Optimize memmory handling. + Optimize memory handling. * sysdeps/unix/closedir.c: Optmize memory handling. 1998-03-17 Ulrich Drepper diff --git a/Makefile b/Makefile index 6118685fe0..9c1e7dd81d 100644 --- a/Makefile +++ b/Makefile @@ -323,7 +323,7 @@ distribute := README README.libm INSTALL FAQ NOTES NEWS PROJECTS BUGS \ autolock.sh rellns-sh munch-tmpl.c munch.awk interp.c \ sysdep.h set-hooks.h libc-symbols.h version.h shlib-versions \ rpm/Makefile rpm/template rpm/rpmrc glibcbug.in abi-tags \ - stub-tag.h test-installation.pl + stub-tag.h test-installation.pl test-skeleton.c distribute := $(strip $(distribute)) generated := $(generated) stubs.h version-info.h diff --git a/dirent/Makefile b/dirent/Makefile index 7c36510ca1..e763dabeb7 100644 --- a/dirent/Makefile +++ b/dirent/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc. +# Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98 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 @@ -27,6 +27,8 @@ routines := opendir closedir readdir readdir_r rewinddir \ getdents dirfd readdir64 readdir64_r distribute := dirstream.h -tests := list tst-seekdir +tests := list tst-seekdir opendir-tst1 include ../Rules + +opendir-tst1.args = --test-dir=${objdir} diff --git a/dirent/list.c b/dirent/list.c index 38f770f0ed..6ce22c6ea1 100644 --- a/dirent/list.c +++ b/dirent/list.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1993, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1993, 1997, 1998 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 @@ -23,11 +23,12 @@ #include -void +int test (const char *name) { DIR *dirp; struct dirent *entp; + int retval = 0; puts (name); @@ -35,7 +36,7 @@ test (const char *name) if (dirp == NULL) { perror ("opendir"); - return; + return 1; } errno = 0; @@ -44,24 +45,32 @@ test (const char *name) entp->d_name, (unsigned long int) entp->d_fileno); if (errno) - perror ("readdir"); + { + perror ("readdir"); + retval = 1; + } if (closedir (dirp) < 0) - perror ("closedir"); + { + perror ("closedir"); + retval = 1; + } + + return retval; } int main (int argc, char **argv) { + int retval = 0; --argc; ++argv; if (argc == 0) - test ("."); + retval = test ("."); else while (argc-- > 0) - test (*argv++); + retval |= test (*argv++); - exit (0); - return 0; + return retval; } diff --git a/dirent/opendir-tst1.c b/dirent/opendir-tst1.c new file mode 100644 index 0000000000..dfab1d9b3d --- /dev/null +++ b/dirent/opendir-tst1.c @@ -0,0 +1,96 @@ +/* Copyright (C) 1998 Free Software Foundation, Inc. + Contributed by Ulrich Drepper , 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include +#include +#include +#include +#include +#include + +/* Name of the FIFO. */ +char tmpname[] = "fifoXXXXXX"; + + +/* Do the real work. */ +static int +real_test (void) +{ + DIR *dirp; + + /* This should not block for an FIFO. */ + dirp = opendir (tmpname); + + /* Successful. */ + if (dirp != NULL) + { + /* Oh, oh, how can this work? */ + fputs ("`opendir' succeeded on a FIFO???\n", stderr); + closedir (dirp); + return 1; + } + + if (errno != ENOTDIR) + { + fprintf (stderr, "`opendir' return error `%s' instead of `%s'\n", + strerror (errno), strerror (ENOTDIR)); + return 1; + } + + return 0; +} + + +static int +do_test (int argc, char *argv[]) +{ + int retval; + + if (mktemp (tmpname) == NULL) + { + perror ("mktemp"); + return 1; + } + + /* Try to generate a FIFO. */ + if (mknod (tmpname, 0600 | S_IFIFO, 0) < 0) + { + perror ("mknod"); + /* We cannot make this an error. */ + return 0; + } + + retval = real_test (); + + remove (tmpname); + + return retval; +} + + +void +do_cleanup (void) +{ + remove (tmpname); +} +#define CLEANUP_HANDLER do_cleanup () + + +/* Include the test skeleton. */ +#include diff --git a/sysdeps/unix/opendir.c b/sysdeps/unix/opendir.c index 2469917f45..ef7bc84866 100644 --- a/sysdeps/unix/opendir.c +++ b/sysdeps/unix/opendir.c @@ -83,6 +83,7 @@ __opendir (const char *name) return NULL; } dirp->data = (char *) (dirp + 1); + dirp->allocation = allocation; dirp->fd = fd; __libc_lock_init (dirp->lock); diff --git a/test-skeleton.c b/test-skeleton.c new file mode 100644 index 0000000000..418f69abdd --- /dev/null +++ b/test-skeleton.c @@ -0,0 +1,177 @@ +/* Skeleton for test programs. + Copyright (C) 1998 Free Software Foundation, Inc. + Contributed by Ulrich Drepper , 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include +#include +#include +#include +#include +#include + +/* 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. */ +#ifndef TEST_FUNCTION +# define TEST_FUNCTION do_test (argc, argv) +#endif + + +#define OPT_DIRECT 1000 +#define OPT_TESTDIR 1001 + +static struct option options[] = +{ +#ifdef CMDLINE_OPTIONS + CMDLINE_OPTIONS +#endif + { "direct", no_argument, NULL, OPT_DIRECT }, + { "test-dir", required_argument, NULL, OPT_TESTDIR }, + { NULL, 0, NULL, 0 } +}; + +/* PID of the test itself. */ +static int pid; + +/* Directory to place temporary files in. */ +static const char *test_dir; + +/* Timeout handler. We kill the child and exit with an error. */ +void +timeout_handler (int sig __attribute__ ((unused))) +{ + int killed; + + /* Send signal. */ + kill (pid, SIGKILL); + + /* Wait for it to terminate. */ + killed = waitpid (pid, NULL, WNOHANG); + if (killed != 0 && killed != pid) + { + perror ("Failed to killed test process"); + exit (1); + } + +#ifdef CLEANUP_HANDLER + CLEANUP_HANDLER; +#endif + + fputs ("Timed out: killed the child process\n", stderr); + + /* Exit with an error. */ + exit (1); +} + +/* We provide the entry point here. */ +int +main (int argc, char *argv[]) +{ + int direct = 0; /* Directly call the test function? */ + int status; + int opt; + + while ((opt = getopt_long (argc, argv, "", options, NULL)) != -1) + switch (opt) + { + case '?': + exit (1); + case OPT_DIRECT: + direct = 1; + break; + case OPT_TESTDIR: + test_dir = optarg; + break; +#ifdef CMDLINE_PROCESS + CMDLINE_PROCESS +#endif + } + + /* Set TMPDIR to specified test directory. */ + if (test_dir != NULL) + { + setenv ("TMPDIR", test_dir, 1); + + if (chdir (test_dir) < 0) + { + perror ("chdir"); + exit (1); + } + } + + /* If we are not expected to fork run the function immediately. */ + if (direct) + return TEST_FUNCTION; + + /* Set up the test environment: + - prevent core dumps + - set up the timer + - fork and execute the function. */ + + pid = fork (); + if (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 + + /* Execute the test function and exit with the return value. */ + exit (TEST_FUNCTION); + } + else if (pid < 0) + { + perror ("Cannot fork test program"); + exit (1); + } + + /* Set timeout. */ +#ifndef TIMEOUT + /* Default timeout is two seconds. */ +# define TIMEOUT 2 +#endif + alarm (TIMEOUT); + signal (SIGALRM, timeout_handler); + + /* Wait for the regular termination. */ + if (waitpid (pid, &status, 0) != pid) + { + perror ("Oops, wrong test program terminated"); + exit (1); + } + +#ifndef EXPECTED_SIGNAL + /* We don't expect any signal. */ +# define EXPECTED_SIGNAL 0 +#endif + if (WIFSIGNALED (status) != EXPECTED_SIGNAL) + { + fprintf (stderr, "Incorrect signal from child: got `%s', need `%s'\n", + strsignal (WIFSIGNALED (status)), + strsignal (EXPECTED_SIGNAL)); + exit (1); + } + + /* Simply exit with the return value of the test. */ + return WEXITSTATUS (status); +}