1 /* Test of rename() function.
2 Copyright (C) 2009-2013 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* This file is designed to test both rename(a,b) and
18 renameat(AT_FDCWD,a,AT_FDCWD,b). FUNC is the function to test.
19 Assumes that BASE and ASSERT are already defined, and that
20 appropriate headers are already included. If PRINT, warn before
21 skipping symlink tests with status 77. */
23 /* Tests whether a file, given by a file name without slashes, exists in
24 the current directory, by scanning the directory entries. */
26 dentry_exists (const char *filename)
29 DIR *dir = opendir (".");
34 struct dirent *d = readdir (dir);
37 if (strcmp (d->d_name, filename) == 0)
43 ASSERT (closedir (dir) == 0);
47 /* Asserts that a specific file, given by a file name without slashes, does
48 not exist in the current directory. */
50 assert_nonexistent (const char *filename)
54 /* The usual way to test the presence of a file is via stat() or lstat(). */
56 if (stat (filename, &st) == -1)
57 ASSERT (errno == ENOENT);
60 /* But after renaming a directory over an empty directory on an NFS-
61 mounted file system, on Linux 2.6.18, for a period of 30 seconds the
62 old directory name is "present" according to stat() but "nonexistent"
63 according to dentry_exists(). */
64 ASSERT (!dentry_exists (filename));
65 /* Remove the old directory name, so that subsequent mkdir calls
67 (void) rmdir (filename);
72 test_rename (int (*func) (char const *, char const *), bool print)
76 int fd = creat (BASE "file", 0600);
78 ASSERT (write (fd, "hi", 2) == 2);
79 ASSERT (close (fd) == 0);
80 ASSERT (mkdir (BASE "dir", 0700) == 0);
82 /* Files present here:
89 { /* Missing source. */
92 ASSERT (func (BASE "missing", BASE "missing") == -1);
93 ASSERT (errno == ENOENT);
97 ASSERT (func (BASE "missing/", BASE "missing") == -1);
98 ASSERT (errno == ENOENT);
102 ASSERT (func (BASE "missing", BASE "missing/") == -1);
103 ASSERT (errno == ENOENT);
106 { /* Empty operand. */
109 ASSERT (func ("", BASE "missing") == -1);
110 ASSERT (errno == ENOENT);
114 ASSERT (func (BASE "file", "") == -1);
115 ASSERT (errno == ENOENT);
119 ASSERT (func (BASE "", "") == -1);
120 ASSERT (errno == ENOENT);
126 { /* Trailing slash. */
129 ASSERT (func (BASE "file", BASE "file2/") == -1);
130 ASSERT (errno == ENOENT || errno == ENOTDIR);
134 ASSERT (func (BASE "file/", BASE "file2") == -1);
135 ASSERT (errno == ENOTDIR);
139 ASSERT (stat (BASE "file2", &st) == -1);
140 ASSERT (errno == ENOENT);
143 { /* Simple rename. */
144 ASSERT (func (BASE "file", BASE "file2") == 0);
146 ASSERT (stat (BASE "file", &st) == -1);
147 ASSERT (errno == ENOENT);
148 memset (&st, 0, sizeof st);
149 ASSERT (stat (BASE "file2", &st) == 0);
150 ASSERT (st.st_size == 2);
152 /* Files present here:
157 ASSERT (close (creat (BASE "file", 0600)) == 0);
159 ASSERT (func (BASE "file2", BASE "file/") == -1);
160 ASSERT (errno == ENOTDIR);
161 ASSERT (func (BASE "file2", BASE "file") == 0);
162 memset (&st, 0, sizeof st);
163 ASSERT (stat (BASE "file", &st) == 0);
164 ASSERT (st.st_size == 2);
166 ASSERT (stat (BASE "file2", &st) == -1);
167 ASSERT (errno == ENOENT);
169 /* Files present here:
176 { /* Simple rename. */
178 ASSERT (func (BASE "dir", BASE "dir2/") == 0);
180 ASSERT (stat (BASE "dir", &st) == -1);
181 ASSERT (errno == ENOENT);
182 ASSERT (stat (BASE "dir2", &st) == 0);
184 /* Files present here:
189 ASSERT (func (BASE "dir2/", BASE "dir") == 0);
190 ASSERT (stat (BASE "dir", &st) == 0);
192 ASSERT (stat (BASE "dir2", &st) == -1);
193 ASSERT (errno == ENOENT);
195 /* Files present here:
200 ASSERT (func (BASE "dir", BASE "dir2") == 0);
202 ASSERT (stat (BASE "dir", &st) == -1);
203 ASSERT (errno == ENOENT);
204 ASSERT (stat (BASE "dir2", &st) == 0);
206 /* Files present here:
210 { /* Empty onto empty. */
211 ASSERT (mkdir (BASE "dir", 0700) == 0);
212 /* Files present here:
217 ASSERT (func (BASE "dir2", BASE "dir") == 0);
218 /* Files present here:
222 ASSERT (mkdir (BASE "dir2", 0700) == 0);
223 /* Files present here:
228 ASSERT (func (BASE "dir2", BASE "dir/") == 0);
229 /* Files present here:
233 ASSERT (mkdir (BASE "dir2", 0700) == 0);
234 /* Files present here:
239 ASSERT (func (BASE "dir2/", BASE "dir") == 0);
240 /* Files present here:
244 ASSERT (mkdir (BASE "dir2", 0700) == 0);
246 /* Files present here:
251 { /* Empty onto full. */
252 ASSERT (close (creat (BASE "dir/file", 0600)) == 0);
253 /* Files present here:
261 ASSERT (func (BASE "dir2", BASE "dir") == -1);
262 ASSERT (errno == EEXIST || errno == ENOTEMPTY);
266 ASSERT (func (BASE "dir2/", BASE "dir") == -1);
267 ASSERT (errno == EEXIST || errno == ENOTEMPTY);
271 ASSERT (func (BASE "dir2", BASE "dir/") == -1);
272 ASSERT (errno == EEXIST || errno == ENOTEMPTY);
275 { /* Full onto empty. */
276 ASSERT (func (BASE "dir", BASE "dir2") == 0);
277 assert_nonexistent (BASE "dir");
278 ASSERT (stat (BASE "dir2/file", &st) == 0);
279 /* Files present here:
284 ASSERT (mkdir (BASE "dir", 0700) == 0);
285 /* Files present here:
292 ASSERT (func (BASE "dir2/", BASE "dir") == 0);
293 ASSERT (stat (BASE "dir/file", &st) == 0);
295 ASSERT (stat (BASE "dir2", &st) == -1);
296 ASSERT (errno == ENOENT);
298 /* Files present here:
303 ASSERT (mkdir (BASE "dir2", 0700) == 0);
304 /* Files present here:
311 ASSERT (func (BASE "dir", BASE "dir2/") == 0);
312 assert_nonexistent (BASE "dir");
313 ASSERT (stat (BASE "dir2/file", &st) == 0);
315 /* Files present here:
320 ASSERT (unlink (BASE "dir2/file") == 0);
322 /* Files present here:
326 { /* Reject trailing dot. */
329 ASSERT (func (BASE "dir2", BASE "dir/.") == -1);
330 ASSERT (errno == EINVAL || errno == ENOENT);
332 ASSERT (mkdir (BASE "dir", 0700) == 0);
333 /* Files present here:
340 ASSERT (func (BASE "dir2", BASE "dir/.") == -1);
341 ASSERT (errno == EINVAL || errno == EBUSY || errno == EISDIR
342 || errno == ENOTEMPTY || errno == EEXIST);
346 ASSERT (func (BASE "dir2/.", BASE "dir") == -1);
347 ASSERT (errno == EINVAL || errno == EBUSY || errno == EEXIST);
349 ASSERT (rmdir (BASE "dir") == 0);
350 /* Files present here:
356 ASSERT (func (BASE "dir2", BASE "dir/.//") == -1);
357 ASSERT (errno == EINVAL || errno == ENOENT);
359 ASSERT (mkdir (BASE "dir", 0700) == 0);
360 /* Files present here:
367 ASSERT (func (BASE "dir2", BASE "dir/.//") == -1);
368 ASSERT (errno == EINVAL || errno == EBUSY || errno == EISDIR
369 || errno == ENOTEMPTY || errno == EEXIST);
373 ASSERT (func (BASE "dir2/.//", BASE "dir") == -1);
374 ASSERT (errno == EINVAL || errno == EBUSY || errno == EEXIST);
376 ASSERT (rmdir (BASE "dir2") == 0);
377 /* Files present here:
382 { /* Move into subdir. */
385 ASSERT (func (BASE "dir", BASE "dir/sub") == -1);
386 ASSERT (errno == EINVAL || errno == EACCES);
390 ASSERT (stat (BASE "dir/sub", &st) == -1);
391 ASSERT (errno == ENOENT);
393 ASSERT (mkdir (BASE "dir/sub", 0700) == 0);
394 /* Files present here:
401 ASSERT (func (BASE "dir", BASE "dir/sub") == -1);
402 ASSERT (errno == EINVAL);
403 ASSERT (stat (BASE "dir/sub", &st) == 0);
405 ASSERT (rmdir (BASE "dir/sub") == 0);
408 /* Files present here:
413 /* Mixing file and directory. */
416 { /* File onto dir. */
419 ASSERT (func (BASE "file", BASE "dir") == -1);
420 ASSERT (errno == EISDIR || errno == ENOTDIR);
424 ASSERT (func (BASE "file", BASE "dir/") == -1);
425 ASSERT (errno == EISDIR || errno == ENOTDIR);
428 { /* Dir onto file. */
431 ASSERT (func (BASE "dir", BASE "file") == -1);
432 ASSERT (errno == ENOTDIR);
436 ASSERT (func (BASE "dir/", BASE "file") == -1);
437 ASSERT (errno == ENOTDIR);
444 { /* File onto self. */
445 ASSERT (func (BASE "file", BASE "file") == 0);
446 memset (&st, 0, sizeof st);
447 ASSERT (stat (BASE "file", &st) == 0);
448 ASSERT (st.st_size == 2);
450 /* Files present here:
454 { /* Empty dir onto self. */
455 ASSERT (func (BASE "dir", BASE "dir") == 0);
456 ASSERT (stat (BASE "dir", &st) == 0);
458 /* Files present here:
462 ASSERT (close (creat (BASE "dir/file", 0600)) == 0);
463 /* Files present here:
468 { /* Full dir onto self. */
469 ASSERT (func (BASE "dir", BASE "dir") == 0);
471 ASSERT (unlink (BASE "dir/file") == 0);
472 /* Files present here:
477 /* Not all file systems support link. Mingw doesn't have
478 reliable st_nlink on hard links, but our implementation does
479 fail with EPERM on poor file systems, and we can detect the
480 inferior stat() via st_ino. Cygwin 1.5.x copies rather than
481 links files on those file systems, but there, st_nlink and
482 st_ino are reliable. */
483 int ret = link (BASE "file", BASE "file2");
486 memset (&st, 0, sizeof st);
487 ASSERT (stat (BASE "file2", &st) == 0);
488 if (st.st_ino && st.st_nlink != 2)
490 ASSERT (unlink (BASE "file2") == 0);
497 /* If the device does not support hard links, errno is
498 EPERM on Linux, EOPNOTSUPP on FreeBSD. */
504 fputs ("skipping test: "
505 "hard links not supported on this file system\n",
507 ASSERT (unlink (BASE "file") == 0);
508 ASSERT (rmdir (BASE "dir") == 0);
517 /* Files present here:
519 {BASE}file2 (hard link to file)
522 { /* File onto hard link. */
523 ASSERT (func (BASE "file", BASE "file2") == 0);
524 memset (&st, 0, sizeof st);
525 ASSERT (stat (BASE "file", &st) == 0);
526 ASSERT (st.st_size == 2);
527 memset (&st, 0, sizeof st);
528 ASSERT (stat (BASE "file2", &st) == 0);
529 ASSERT (st.st_size == 2);
531 /* Files present here:
536 ASSERT (unlink (BASE "file2") == 0);
537 /* Files present here:
544 if (symlink (BASE "file", BASE "link1"))
547 fputs ("skipping test: symlinks not supported on this file system\n",
549 ASSERT (unlink (BASE "file") == 0);
550 ASSERT (rmdir (BASE "dir") == 0);
553 /* Files present here:
555 {BASE}link1 -> {BASE}file
558 { /* Simple rename. */
559 ASSERT (func (BASE "link1", BASE "link2") == 0);
560 ASSERT (stat (BASE "file", &st) == 0);
562 ASSERT (lstat (BASE "link1", &st) == -1);
563 ASSERT (errno == ENOENT);
564 memset (&st, 0, sizeof st);
565 ASSERT (lstat (BASE "link2", &st) == 0);
566 ASSERT (S_ISLNK (st.st_mode));
568 /* Files present here:
570 {BASE}link2 -> {BASE}file
574 ASSERT (symlink (BASE "nowhere", BASE "link1") == 0);
575 /* Files present here:
577 {BASE}link1 -> {BASE}nowhere
578 {BASE}link2 -> {BASE}file
582 ASSERT (func (BASE "link2", BASE "link1") == 0);
583 memset (&st, 0, sizeof st);
584 ASSERT (stat (BASE "link1", &st) == 0);
585 ASSERT (st.st_size == 2);
587 ASSERT (lstat (BASE "link2", &st) == -1);
588 ASSERT (errno == ENOENT);
591 /* Files present here:
593 {BASE}link1 -> {BASE}file
596 { /* Symlink loop. */
597 ASSERT (symlink (BASE "link2", BASE "link2") == 0);
598 /* Files present here:
600 {BASE}link1 -> {BASE}file
601 {BASE}link2 -> {BASE}link2
605 ASSERT (func (BASE "link2", BASE "link2") == 0);
609 ASSERT (func (BASE "link2/", BASE "link2") == -1);
610 ASSERT (errno == ELOOP || errno == ENOTDIR);
612 ASSERT (func (BASE "link2", BASE "link3") == 0);
613 /* Files present here:
615 {BASE}link1 -> {BASE}file
616 {BASE}link3 -> {BASE}link2
619 ASSERT (unlink (BASE "link3") == 0);
621 /* Files present here:
623 {BASE}link1 -> {BASE}file
626 { /* Dangling link. */
627 ASSERT (symlink (BASE "nowhere", BASE "link2") == 0);
628 /* Files present here:
630 {BASE}link1 -> {BASE}file
631 {BASE}link2 -> {BASE}nowhere
635 ASSERT (func (BASE "link2", BASE "link3") == 0);
637 ASSERT (lstat (BASE "link2", &st) == -1);
638 ASSERT (errno == ENOENT);
639 memset (&st, 0, sizeof st);
640 ASSERT (lstat (BASE "link3", &st) == 0);
643 /* Files present here:
645 {BASE}link1 -> {BASE}file
646 {BASE}link3 -> {BASE}nowhere
649 { /* Trailing slash on dangling. */
652 ASSERT (func (BASE "link3/", BASE "link2") == -1);
653 ASSERT (errno == ENOENT || errno == ENOTDIR);
657 ASSERT (func (BASE "link3", BASE "link2/") == -1);
658 ASSERT (errno == ENOENT || errno == ENOTDIR);
662 ASSERT (lstat (BASE "link2", &st) == -1);
663 ASSERT (errno == ENOENT);
665 memset (&st, 0, sizeof st);
666 ASSERT (lstat (BASE "link3", &st) == 0);
668 /* Files present here:
670 {BASE}link1 -> {BASE}file
671 {BASE}link3 -> {BASE}nowhere
674 { /* Trailing slash on link to file. */
677 ASSERT (func (BASE "link1/", BASE "link2") == -1);
678 ASSERT (errno == ENOTDIR);
682 ASSERT (func (BASE "link1", BASE "link3/") == -1);
683 ASSERT (errno == ENOENT || errno == ENOTDIR);
686 /* Files present here:
688 {BASE}link1 -> {BASE}file
689 {BASE}link3 -> {BASE}nowhere
693 /* Mixing symlink and file. */
695 { /* File onto link. */
696 ASSERT (close (creat (BASE "file2", 0600)) == 0);
697 /* Files present here:
700 {BASE}link1 -> {BASE}file
701 {BASE}link3 -> {BASE}nowhere
705 ASSERT (func (BASE "file2", BASE "link3") == 0);
707 ASSERT (stat (BASE "file2", &st) == -1);
708 ASSERT (errno == ENOENT);
709 memset (&st, 0, sizeof st);
710 ASSERT (lstat (BASE "link3", &st) == 0);
711 ASSERT (S_ISREG (st.st_mode));
713 /* Files present here:
715 {BASE}link1 -> {BASE}file
719 ASSERT (unlink (BASE "link3") == 0);
721 /* Files present here:
723 {BASE}link1 -> {BASE}file
726 { /* Link onto file. */
727 ASSERT (symlink (BASE "nowhere", BASE "link2") == 0);
728 /* Files present here:
730 {BASE}link1 -> {BASE}file
731 {BASE}link2 -> {BASE}nowhere
734 ASSERT (close (creat (BASE "file2", 0600)) == 0);
735 /* Files present here:
738 {BASE}link1 -> {BASE}file
739 {BASE}link2 -> {BASE}nowhere
743 ASSERT (func (BASE "link2", BASE "file2") == 0);
745 ASSERT (lstat (BASE "link2", &st) == -1);
746 ASSERT (errno == ENOENT);
747 memset (&st, 0, sizeof st);
748 ASSERT (lstat (BASE "file2", &st) == 0);
749 ASSERT (S_ISLNK (st.st_mode));
751 /* Files present here:
753 {BASE}file2 -> {BASE}nowhere
754 {BASE}link1 -> {BASE}file
757 ASSERT (unlink (BASE "file2") == 0);
759 /* Files present here:
761 {BASE}link1 -> {BASE}file
764 { /* Trailing slash. */
767 ASSERT (func (BASE "file/", BASE "link1") == -1);
768 ASSERT (errno == ENOTDIR);
772 ASSERT (func (BASE "file", BASE "link1/") == -1);
773 ASSERT (errno == ENOTDIR || errno == ENOENT);
777 ASSERT (func (BASE "link1/", BASE "file") == -1);
778 ASSERT (errno == ENOTDIR);
782 ASSERT (func (BASE "link1", BASE "file/") == -1);
783 ASSERT (errno == ENOTDIR || errno == ENOENT);
784 memset (&st, 0, sizeof st);
785 ASSERT (lstat (BASE "file", &st) == 0);
786 ASSERT (S_ISREG (st.st_mode));
787 memset (&st, 0, sizeof st);
788 ASSERT (lstat (BASE "link1", &st) == 0);
789 ASSERT (S_ISLNK (st.st_mode));
792 /* Files present here:
794 {BASE}link1 -> {BASE}file
798 /* Mixing symlink and directory. */
800 { /* Directory onto link. */
803 ASSERT (func (BASE "dir", BASE "link1") == -1);
804 ASSERT (errno == ENOTDIR);
808 ASSERT (func (BASE "dir/", BASE "link1") == -1);
809 ASSERT (errno == ENOTDIR);
813 ASSERT (func (BASE "dir", BASE "link1/") == -1);
814 ASSERT (errno == ENOTDIR);
817 { /* Link onto directory. */
820 ASSERT (func (BASE "link1", BASE "dir") == -1);
821 ASSERT (errno == EISDIR || errno == ENOTDIR);
825 ASSERT (func (BASE "link1", BASE "dir/") == -1);
826 ASSERT (errno == EISDIR || errno == ENOTDIR);
830 ASSERT (func (BASE "link1/", BASE "dir") == -1);
831 ASSERT (errno == ENOTDIR);
832 memset (&st, 0, sizeof st);
833 ASSERT (lstat (BASE "link1", &st) == 0);
834 ASSERT (S_ISLNK (st.st_mode));
835 memset (&st, 0, sizeof st);
836 ASSERT (lstat (BASE "dir", &st) == 0);
837 ASSERT (S_ISDIR (st.st_mode));
840 /* Files present here:
842 {BASE}link1 -> {BASE}file
846 /* POSIX requires rename("link-to-dir/","other") to rename "dir" and
847 leave "link-to-dir" dangling, but GNU rejects this. POSIX
848 requires rename("dir","dangling/") to create the directory so
849 that "dangling/" now resolves, but GNU rejects this. While we
850 prefer GNU behavior, we don't enforce it. However, we do test
851 that the system either follows POSIX in both cases, or follows
855 ASSERT (symlink (BASE "dir2", BASE "link2") == 0);
856 /* Files present here:
858 {BASE}link1 -> {BASE}file
859 {BASE}link2 -> {BASE}dir2
863 result = func (BASE "dir", BASE "link2/");
868 ASSERT (lstat (BASE "dir", &st) == -1);
869 ASSERT (errno == ENOENT);
870 memset (&st, 0, sizeof st);
871 ASSERT (lstat (BASE "dir2", &st) == 0);
872 ASSERT (S_ISDIR (st.st_mode));
873 memset (&st, 0, sizeof st);
874 ASSERT (lstat (BASE "link2", &st) == 0);
875 ASSERT (S_ISLNK (st.st_mode));
876 /* Files present here:
878 {BASE}link1 -> {BASE}file
879 {BASE}link2 -> {BASE}dir2
883 ASSERT (func (BASE "link2/", BASE "dir") == 0);
884 memset (&st, 0, sizeof st);
885 ASSERT (lstat (BASE "dir", &st) == 0);
886 ASSERT (S_ISDIR (st.st_mode));
888 ASSERT (lstat (BASE "dir2", &st) == -1);
889 ASSERT (errno == ENOENT);
890 memset (&st, 0, sizeof st);
891 ASSERT (lstat (BASE "link2", &st) == 0);
892 ASSERT (S_ISLNK (st.st_mode));
898 ASSERT (result == -1);
899 ASSERT (errno == ENOTDIR);
900 memset (&st, 0, sizeof st);
901 ASSERT (lstat (BASE "dir", &st) == 0);
902 ASSERT (S_ISDIR (st.st_mode));
904 ASSERT (lstat (BASE "dir2", &st) == -1);
905 ASSERT (errno == ENOENT);
906 memset (&st, 0, sizeof st);
907 ASSERT (lstat (BASE "link2", &st) == 0);
908 ASSERT (S_ISLNK (st.st_mode));
909 ASSERT (unlink (BASE "link2") == 0);
910 ASSERT (symlink (BASE "dir", BASE "link2") == 0);
911 /* Files present here:
913 {BASE}link1 -> {BASE}file
914 {BASE}link2 -> {BASE}dir
917 errno = 0; /* OpenBSD notices that link2/ and dir are the same. */
918 result = func (BASE "link2/", BASE "dir");
919 if (result) /* GNU/Linux rejects attempts to use link2/. */
921 ASSERT (result == -1);
922 ASSERT (errno == ENOTDIR || errno == EISDIR);
924 memset (&st, 0, sizeof st);
925 ASSERT (lstat (BASE "dir", &st) == 0);
926 ASSERT (S_ISDIR (st.st_mode));
928 ASSERT (lstat (BASE "dir2", &st) == -1);
929 ASSERT (errno == ENOENT);
930 memset (&st, 0, sizeof st);
931 ASSERT (lstat (BASE "link2", &st) == 0);
932 ASSERT (S_ISLNK (st.st_mode));
935 /* Files present here:
937 {BASE}link1 -> {BASE}file
938 {BASE}link2 -> {BASE}dir or {BASE}dir2
943 ASSERT (unlink (BASE "file") == 0);
944 ASSERT (rmdir (BASE "dir") == 0);
945 ASSERT (unlink (BASE "link1") == 0);
946 ASSERT (unlink (BASE "link2") == 0);