* tests/test-rmdir.c (main): Factor guts...
* tests/test-rmdir.h (test_rmdir_func): ...into new file.
* modules/rmdir-tests (Files): Ship new file.
* modules/openat-tests: New test.
* tests/test-unlinkat.c: Likewise.
Signed-off-by: Eric Blake <ebb9@byu.net>
2009-09-16 Eric Blake <ebb9@byu.net>
+ openat-tests: ensure unlinkat behaves like rmdir
+ * tests/test-rmdir.c (main): Factor guts...
+ * tests/test-rmdir.h (test_rmdir_func): ...into new file.
+ * modules/rmdir-tests (Files): Ship new file.
+ * modules/openat-tests: New test.
+ * tests/test-unlinkat.c: Likewise.
+
rmdir-errno: mark obsolete, it is unsafe for cross-compilation
* modules/rmdir-errno (Status, Notice): Now obsolete.
--- /dev/null
+Files:
+tests/test-rmdir.h
+tests/test-unlinkat.c
+
+Depends-on:
+
+configure.ac:
+AC_CHECK_FUNCS_ONCE([symlink])
+
+Makefile.am:
+TESTS += test-unlinkat
+check_PROGRAMS += test-unlinkat
+test_unlinkat_LDADD = $(LDADD) @LIBINTL@
Files:
+tests/test-rmdir.h
tests/test-rmdir.c
Depends-on:
#define BASE "test-rmdir.t"
+#include "test-rmdir.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 (rmdir ("") == -1);
- ASSERT (errno == ENOENT);
- errno = 0;
- ASSERT (rmdir (BASE "nosuch") == -1);
- ASSERT (errno == ENOENT);
- errno = 0;
- ASSERT (rmdir (BASE "nosuch/") == -1);
- ASSERT (errno == ENOENT);
- errno = 0;
- ASSERT (rmdir (".") == -1);
- ASSERT (errno == EINVAL || errno == EBUSY);
- /* Resulting errno after ".." or "/" is too varied to test; it is
- reasonable to see any of EINVAL, EBUSY, EEXIST, ENOTEMPTY,
- EACCES, EPERM. */
- ASSERT (rmdir ("..") == -1);
- ASSERT (rmdir ("/") == -1);
- ASSERT (rmdir ("///") == -1);
- errno = 0;
- ASSERT (rmdir (BASE "dir/file/") == -1);
- ASSERT (errno == ENOTDIR);
-
- /* Non-empty directory. */
- errno = 0;
- ASSERT (rmdir (BASE "dir") == -1);
- ASSERT (errno == EEXIST || errno == ENOTEMPTY);
-
- /* Non-directory. */
- errno = 0;
- ASSERT (rmdir (BASE "dir/file") == -1);
- ASSERT (errno == ENOTDIR);
-
- /* Empty directory. */
- ASSERT (unlink (BASE "dir/file") == 0);
- errno = 0;
- ASSERT (rmdir (BASE "dir/./") == -1);
- ASSERT (errno == EINVAL || errno == EBUSY);
- ASSERT (rmdir (BASE "dir") == 0);
-
- /* Test symlink behavior. Specifying trailing slash should remove
- referent directory (POSIX), or cause ENOTDIR failure (Linux), but
- not touch symlink. We prefer the Linux behavior for its
- intuitiveness (especially compared to rmdir("symlink-to-file/")),
- 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);
- return 77;
- }
- ASSERT (mkdir (BASE "dir", 0700) == 0);
- errno = 0;
- if (rmdir (BASE "link/") == 0)
- {
- struct stat st;
- errno = 0;
- ASSERT (stat (BASE "link", &st) == -1);
- ASSERT (errno == ENOENT);
- }
- else
- {
- ASSERT (errno == ENOTDIR);
- ASSERT (rmdir (BASE "dir") == 0);
- }
- ASSERT (unlink (BASE "link") == 0);
-
- return 0;
+ return test_rmdir_func (rmdir);
}
--- /dev/null
+/* Tests of rmdir.
+ 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 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. */
+
+static int
+test_rmdir_func (int (*func) (char const *name))
+{
+ /* 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);
+ errno = 0;
+ ASSERT (func (".") == -1);
+ ASSERT (errno == EINVAL || errno == EBUSY);
+ /* Resulting errno after ".." or "/" is too varied to test; it is
+ reasonable to see any of EINVAL, EBUSY, EEXIST, ENOTEMPTY,
+ EACCES, EPERM. */
+ ASSERT (func ("..") == -1);
+ ASSERT (func ("/") == -1);
+ ASSERT (func ("///") == -1);
+ errno = 0;
+ ASSERT (func (BASE "dir/file/") == -1);
+ ASSERT (errno == ENOTDIR);
+
+ /* Non-empty directory. */
+ errno = 0;
+ ASSERT (func (BASE "dir") == -1);
+ ASSERT (errno == EEXIST || errno == ENOTEMPTY);
+
+ /* Non-directory. */
+ errno = 0;
+ ASSERT (func (BASE "dir/file") == -1);
+ ASSERT (errno == ENOTDIR);
+
+ /* Empty directory. */
+ ASSERT (unlink (BASE "dir/file") == 0);
+ errno = 0;
+ ASSERT (func (BASE "dir/./") == -1);
+ ASSERT (errno == EINVAL || errno == EBUSY);
+ ASSERT (func (BASE "dir") == 0);
+
+ /* Test symlink behavior. Specifying trailing slash should remove
+ referent directory (POSIX), or cause ENOTDIR failure (Linux), but
+ not touch symlink. We prefer the Linux behavior for its
+ intuitiveness (especially compared to rmdir("symlink-to-file/")),
+ 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);
+ return 77;
+ }
+ ASSERT (mkdir (BASE "dir", 0700) == 0);
+ errno = 0;
+ if (func (BASE "link/") == 0)
+ {
+ struct stat st;
+ errno = 0;
+ ASSERT (stat (BASE "link", &st) == -1);
+ ASSERT (errno == ENOENT);
+ }
+ else
+ {
+ ASSERT (errno == ENOTDIR);
+ ASSERT (func (BASE "dir") == 0);
+ }
+ ASSERT (unlink (BASE "link") == 0);
+
+ return 0;
+}
--- /dev/null
+/* Tests of unlinkat.
+ 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. */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#if !HAVE_SYMLINK
+# define symlink(a,b) (-1)
+#endif
+
+#define ASSERT(expr) \
+ do \
+ { \
+ if (!(expr)) \
+ { \
+ fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
+ fflush (stderr); \
+ abort (); \
+ } \
+ } \
+ while (0)
+
+#define BASE "test-unlinkat.t"
+
+#include "test-rmdir.h"
+
+/* Wrapper around unlinkat to test rmdir behavior. */
+static int
+rmdirat (char const *name)
+{
+ return unlinkat (AT_FDCWD, name, AT_REMOVEDIR);
+}
+
+int
+main ()
+{
+ /* FIXME: Add tests of unlinkat(,0), and of fd instead of AT_FDCWD. */
+ return test_rmdir_func (rmdirat);
+}