Share the unlink tests with unlinkat.
* tests/test-unlink.c (main): Factor guts...
* tests/test-unlink.h (test_rmdir_func): ...into new file.
* tests/test-rmdir.h (test_rmdir_func): Add parameter.
* tests/test-rmdir.c (main): Adjust caller.
* tests/test-unlinkat.c (main): Likewise. Add unlink tests.
(unlinker): New helper function.
(rmdirat): Enhance check.
* modules/rmdir-tests (Depends-on): Add stdbool.
* modules/unlink-tests (Depends-on): Likewise.
(Files): Add test-unlink.h.
* modules/openat-tests (Files): Likewise.
(Depends-on): Add unlinkdir.
Signed-off-by: Eric Blake <ebb9@byu.net>
2009-09-19 Eric Blake <ebb9@byu.net>
+ test-unlinkat: enhance test, to expose Solaris 9 bug
+ * tests/test-unlink.c (main): Factor guts...
+ * tests/test-unlink.h (test_rmdir_func): ...into new file.
+ * tests/test-rmdir.h (test_rmdir_func): Add parameter.
+ * tests/test-rmdir.c (main): Adjust caller.
+ * tests/test-unlinkat.c (main): Likewise. Add unlink tests.
+ (unlinker): New helper function.
+ (rmdirat): Enhance check.
+ * modules/rmdir-tests (Depends-on): Add stdbool.
+ * modules/unlink-tests (Depends-on): Likewise.
+ (Files): Add test-unlink.h.
+ * modules/openat-tests (Files): Likewise.
+ (Depends-on): Add unlinkdir.
+
test-fstatat: new test, to expose Solaris 9 bugs
* tests/test-stat.c (main): Factor guts...
* tests/test-stat.h (test_stat_func): ...into new file.
tests/test-lstat.h
tests/test-rmdir.h
tests/test-stat.h
+tests/test-unlink.h
tests/test-fstatat.c
tests/test-openat.c
tests/test-unlinkat.c
Depends-on:
pathmax
+unlinkdir
configure.ac:
AC_CHECK_FUNCS_ONCE([symlink])
tests/test-rmdir.c
Depends-on:
+stdbool
configure.ac:
AC_CHECK_FUNCS_ONCE([symlink])
Files:
+tests/test-unlink.h
tests/test-unlink.c
Depends-on:
+stdbool
unlinkdir
configure.ac:
#include <fcntl.h>
#include <errno.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
int
main ()
{
- return test_rmdir_func (rmdir);
+ return test_rmdir_func (rmdir, true);
}
/* This file is designed to test both rmdir(n) and
unlinkat(AT_FDCWD,n,AT_REMOVEDIR). FUNC is the function to test.
Assumes that BASE and ASSERT are already defined, and that
- appropriate headers are already included. */
+ appropriate headers are already included. If PRINT, then warn
+ before returning status 77 when symlinks are unsupported. */
static int
-test_rmdir_func (int (*func) (char const *name))
+test_rmdir_func (int (*func) (char const *name), bool print)
{
/* Remove any leftovers from a previous partial run. */
ASSERT (system ("rm -rf " BASE "*") == 0);
but not enough to penalize POSIX systems with an rpl_rmdir. */
if (symlink (BASE "dir", BASE "link") != 0)
{
- fputs ("skipping test: symlinks not supported on this filesystem\n",
- stderr);
+ if (print)
+ fputs ("skipping test: symlinks not supported on this filesystem\n",
+ stderr);
return 77;
}
ASSERT (mkdir (BASE "dir", 0700) == 0);
#include <fcntl.h>
#include <errno.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BASE "test-unlink.t"
+#include "test-unlink.h"
+
int
main ()
{
- /* Remove any leftovers from a previous partial run. */
- ASSERT (system ("rm -rf " BASE "*") == 0);
-
- /* Setup. */
- ASSERT (mkdir (BASE "dir", 0700) == 0);
- ASSERT (close (creat (BASE "dir/file", 0600)) == 0);
-
- /* Basic error conditions. */
- errno = 0;
- ASSERT (unlink ("") == -1);
- ASSERT (errno == ENOENT);
- errno = 0;
- ASSERT (unlink (BASE "nosuch") == -1);
- ASSERT (errno == ENOENT);
- errno = 0;
- ASSERT (unlink (BASE "nosuch/") == -1);
- ASSERT (errno == ENOENT);
- /* Resulting errno after directories is rather varied across
- implementations (EPERM, EINVAL, EACCES, EBUSY, EISDIR, ENOTSUP);
- however, we must be careful to not attempt unlink on a directory
- unless we know it must fail. */
- if (cannot_unlink_dir ())
- {
- ASSERT (unlink (".") == -1);
- ASSERT (unlink ("..") == -1);
- ASSERT (unlink ("/") == -1);
- ASSERT (unlink (BASE "dir") == -1);
- ASSERT (mkdir (BASE "dir1", 0700) == 0);
- ASSERT (unlink (BASE "dir1") == -1);
- ASSERT (rmdir (BASE "dir1") == 0);
- }
- errno = 0;
- ASSERT (unlink (BASE "dir/file/") == -1);
- ASSERT (errno == ENOTDIR);
-
- /* Test symlink behavior. Specifying trailing slash will attempt
- unlink of a directory, so only attempt it if we know it must
- fail. */
- if (symlink (BASE "dir", BASE "link") != 0)
- {
- ASSERT (unlink (BASE "dir/file") == 0);
- ASSERT (rmdir (BASE "dir") == 0);
- fputs ("skipping test: symlinks not supported on this filesystem\n",
- stderr);
- return 77;
- }
- if (cannot_unlink_dir ())
- ASSERT (unlink (BASE "link/") == -1);
- ASSERT (unlink (BASE "link") == 0);
- ASSERT (symlink (BASE "dir/file", BASE "link") == 0);
- /* Order here proves unlink of a symlink does not follow through to
- the file. */
- ASSERT (unlink (BASE "link") == 0);
- ASSERT (unlink (BASE "dir/file") == 0);
- ASSERT (rmdir (BASE "dir") == 0);
-
- return 0;
+ return test_unlink_func (unlink, true);
}
--- /dev/null
+/* Tests of unlink.
+ Copyright (C) 2009 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009. */
+
+/* This file is designed to test both unlink(n) and
+ unlinkat(AT_FDCWD,n,0). FUNC is the function to test. Assumes
+ that BASE and ASSERT are already defined, and that appropriate
+ headers are already included. If PRINT, then warn before returning
+ status 77 when symlinks are unsupported. */
+
+static int
+test_unlink_func (int (*func) (char const *name), bool print)
+{
+ /* Remove any leftovers from a previous partial run. */
+ ASSERT (system ("rm -rf " BASE "*") == 0);
+
+ /* Setup. */
+ ASSERT (mkdir (BASE "dir", 0700) == 0);
+ ASSERT (close (creat (BASE "dir/file", 0600)) == 0);
+
+ /* Basic error conditions. */
+ errno = 0;
+ ASSERT (func ("") == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func (BASE "nosuch") == -1);
+ ASSERT (errno == ENOENT);
+ errno = 0;
+ ASSERT (func (BASE "nosuch/") == -1);
+ ASSERT (errno == ENOENT);
+ /* Resulting errno after directories is rather varied across
+ implementations (EPERM, EINVAL, EACCES, EBUSY, EISDIR, ENOTSUP);
+ however, we must be careful to not attempt unlink on a directory
+ unless we know it must fail. */
+ if (cannot_unlink_dir ())
+ {
+ ASSERT (func (".") == -1);
+ ASSERT (func ("..") == -1);
+ ASSERT (func ("/") == -1);
+ ASSERT (func (BASE "dir") == -1);
+ ASSERT (mkdir (BASE "dir1", 0700) == 0);
+ ASSERT (func (BASE "dir1") == -1);
+ ASSERT (rmdir (BASE "dir1") == 0);
+ }
+ errno = 0;
+ ASSERT (func (BASE "dir/file/") == -1);
+ ASSERT (errno == ENOTDIR);
+
+ /* Test symlink behavior. Specifying trailing slash will attempt
+ unlink of a directory, so only attempt it if we know it must
+ fail. */
+ if (symlink (BASE "dir", BASE "link") != 0)
+ {
+ ASSERT (func (BASE "dir/file") == 0);
+ ASSERT (rmdir (BASE "dir") == 0);
+ if (print)
+ fputs ("skipping test: symlinks not supported on this filesystem\n",
+ stderr);
+ return 77;
+ }
+ if (cannot_unlink_dir ())
+ ASSERT (func (BASE "link/") == -1);
+ ASSERT (func (BASE "link") == 0);
+ ASSERT (symlink (BASE "dir/file", BASE "link") == 0);
+ /* Order here proves unlink of a symlink does not follow through to
+ the file. */
+ ASSERT (func (BASE "link") == 0);
+ ASSERT (func (BASE "dir/file") == 0);
+ ASSERT (rmdir (BASE "dir") == 0);
+
+ return 0;
+}
#include <fcntl.h>
#include <errno.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
+#include "unlinkdir.h"
+
#if !HAVE_SYMLINK
# define symlink(a,b) (-1)
#endif
#define BASE "test-unlinkat.t"
#include "test-rmdir.h"
+#include "test-unlink.h"
+
+static int dfd = AT_FDCWD;
/* Wrapper around unlinkat to test rmdir behavior. */
static int
rmdirat (char const *name)
{
- return unlinkat (AT_FDCWD, name, AT_REMOVEDIR);
+ return unlinkat (dfd, name, AT_REMOVEDIR);
+}
+
+/* Wrapper around unlinkat to test unlink behavior. */
+static int
+unlinker (char const *name)
+{
+ return unlinkat (dfd, name, 0);
}
int
main ()
{
- /* FIXME: Add tests of unlinkat(,0), and of fd instead of AT_FDCWD. */
- return test_rmdir_func (rmdirat);
+ /* FIXME: Add tests of fd other than ".". */
+ int result1;
+ int result2;
+ result1 = test_rmdir_func (rmdirat, false);
+ result2 = test_unlink_func (unlinker, false);
+ ASSERT (result1 == result2);
+ dfd = open (".", O_RDONLY);
+ ASSERT (0 <= dfd);
+ result2 = test_rmdir_func (rmdirat, false);
+ ASSERT (result1 == result2);
+ result2 = test_unlink_func (unlinker, false);
+ ASSERT (result1 == result2);
+ ASSERT (close (dfd) == 0);
+ if (result1 == 77)
+ fputs ("skipping test: symlinks not supported on this filesystem\n",
+ stderr);
+ return result1;
}