1 /* Test of rename() function.
2 Copyright (C) 2009, 2010 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. */
24 test_rename (int (*func) (char const *, char const *), bool print)
28 int fd = creat (BASE "file", 0600);
30 ASSERT (write (fd, "hi", 2) == 2);
31 ASSERT (close (fd) == 0);
32 ASSERT (mkdir (BASE "dir", 0700) == 0);
34 /* Files present here:
41 { /* Missing source. */
44 ASSERT (func (BASE "missing", BASE "missing") == -1);
45 ASSERT (errno == ENOENT);
49 ASSERT (func (BASE "missing/", BASE "missing") == -1);
50 ASSERT (errno == ENOENT);
54 ASSERT (func (BASE "missing", BASE "missing/") == -1);
55 ASSERT (errno == ENOENT);
58 { /* Empty operand. */
61 ASSERT (func ("", BASE "missing") == -1);
62 ASSERT (errno == ENOENT);
66 ASSERT (func (BASE "file", "") == -1);
67 ASSERT (errno == ENOENT);
71 ASSERT (func (BASE "", "") == -1);
72 ASSERT (errno == ENOENT);
78 { /* Trailing slash. */
81 ASSERT (func (BASE "file", BASE "file2/") == -1);
82 ASSERT (errno == ENOENT || errno == ENOTDIR);
86 ASSERT (func (BASE "file/", BASE "file2") == -1);
87 ASSERT (errno == ENOTDIR);
91 ASSERT (stat (BASE "file2", &st) == -1);
92 ASSERT (errno == ENOENT);
95 { /* Simple rename. */
96 ASSERT (func (BASE "file", BASE "file2") == 0);
98 ASSERT (stat (BASE "file", &st) == -1);
99 ASSERT (errno == ENOENT);
100 memset (&st, 0, sizeof st);
101 ASSERT (stat (BASE "file2", &st) == 0);
102 ASSERT (st.st_size == 2);
104 /* Files present here:
109 ASSERT (close (creat (BASE "file", 0600)) == 0);
111 ASSERT (func (BASE "file2", BASE "file/") == -1);
112 ASSERT (errno == ENOTDIR);
113 ASSERT (func (BASE "file2", BASE "file") == 0);
114 memset (&st, 0, sizeof st);
115 ASSERT (stat (BASE "file", &st) == 0);
116 ASSERT (st.st_size == 2);
118 ASSERT (stat (BASE "file2", &st) == -1);
119 ASSERT (errno == ENOENT);
121 /* Files present here:
128 { /* Simple rename. */
130 ASSERT (func (BASE "dir", BASE "dir2/") == 0);
132 ASSERT (stat (BASE "dir", &st) == -1);
133 ASSERT (errno == ENOENT);
134 ASSERT (stat (BASE "dir2", &st) == 0);
136 /* Files present here:
141 ASSERT (func (BASE "dir2/", BASE "dir") == 0);
142 ASSERT (stat (BASE "dir", &st) == 0);
144 ASSERT (stat (BASE "dir2", &st) == -1);
145 ASSERT (errno == ENOENT);
147 /* Files present here:
152 ASSERT (func (BASE "dir", BASE "dir2") == 0);
154 ASSERT (stat (BASE "dir", &st) == -1);
155 ASSERT (errno == ENOENT);
156 ASSERT (stat (BASE "dir2", &st) == 0);
158 /* Files present here:
162 { /* Empty onto empty. */
163 ASSERT (mkdir (BASE "dir", 0700) == 0);
164 /* Files present here:
169 ASSERT (func (BASE "dir2", BASE "dir") == 0);
170 /* Files present here:
174 ASSERT (mkdir (BASE "dir2", 0700) == 0);
175 /* Files present here:
180 ASSERT (func (BASE "dir2", BASE "dir/") == 0);
181 /* Files present here:
185 ASSERT (mkdir (BASE "dir2", 0700) == 0);
186 /* Files present here:
191 ASSERT (func (BASE "dir2/", BASE "dir") == 0);
192 /* Files present here:
196 ASSERT (mkdir (BASE "dir2", 0700) == 0);
198 /* Files present here:
203 { /* Empty onto full. */
204 ASSERT (close (creat (BASE "dir/file", 0600)) == 0);
205 /* Files present here:
213 ASSERT (func (BASE "dir2", BASE "dir") == -1);
214 ASSERT (errno == EEXIST || errno == ENOTEMPTY);
218 ASSERT (func (BASE "dir2/", BASE "dir") == -1);
219 ASSERT (errno == EEXIST || errno == ENOTEMPTY);
223 ASSERT (func (BASE "dir2", BASE "dir/") == -1);
224 ASSERT (errno == EEXIST || errno == ENOTEMPTY);
227 { /* Full onto empty. */
228 ASSERT (func (BASE "dir", BASE "dir2") == 0);
230 ASSERT (stat (BASE "dir", &st) == -1);
231 ASSERT (errno == ENOENT);
232 ASSERT (stat (BASE "dir2/file", &st) == 0);
233 /* Files present here:
238 ASSERT (mkdir (BASE "dir", 0700) == 0);
239 /* Files present here:
246 ASSERT (func (BASE "dir2/", BASE "dir") == 0);
247 ASSERT (stat (BASE "dir/file", &st) == 0);
249 ASSERT (stat (BASE "dir2", &st) == -1);
250 ASSERT (errno == ENOENT);
252 /* Files present here:
257 ASSERT (mkdir (BASE "dir2", 0700) == 0);
258 /* Files present here:
265 ASSERT (func (BASE "dir", BASE "dir2/") == 0);
267 ASSERT (stat (BASE "dir", &st) == -1);
268 ASSERT (errno == ENOENT);
269 ASSERT (stat (BASE "dir2/file", &st) == 0);
271 /* Files present here:
276 ASSERT (unlink (BASE "dir2/file") == 0);
278 /* Files present here:
282 { /* Reject trailing dot. */
285 ASSERT (func (BASE "dir2", BASE "dir/.") == -1);
286 ASSERT (errno == EINVAL || errno == ENOENT);
288 ASSERT (mkdir (BASE "dir", 0700) == 0);
289 /* Files present here:
296 ASSERT (func (BASE "dir2", BASE "dir/.") == -1);
297 ASSERT (errno == EINVAL || errno == EBUSY || errno == EISDIR
298 || errno == ENOTEMPTY);
302 ASSERT (func (BASE "dir2/.", BASE "dir") == -1);
303 ASSERT (errno == EINVAL || errno == EBUSY);
305 ASSERT (rmdir (BASE "dir") == 0);
306 /* Files present here:
312 ASSERT (func (BASE "dir2", BASE "dir/.//") == -1);
313 ASSERT (errno == EINVAL || errno == ENOENT);
315 ASSERT (mkdir (BASE "dir", 0700) == 0);
316 /* Files present here:
323 ASSERT (func (BASE "dir2", BASE "dir/.//") == -1);
324 ASSERT (errno == EINVAL || errno == EBUSY || errno == EISDIR
325 || errno == ENOTEMPTY);
329 ASSERT (func (BASE "dir2/.//", BASE "dir") == -1);
330 ASSERT (errno == EINVAL || errno == EBUSY);
332 ASSERT (rmdir (BASE "dir2") == 0);
333 /* Files present here:
338 { /* Move into subdir. */
341 ASSERT (func (BASE "dir", BASE "dir/sub") == -1);
342 ASSERT (errno == EINVAL || errno == EACCES);
346 ASSERT (stat (BASE "dir/sub", &st) == -1);
347 ASSERT (errno == ENOENT);
349 ASSERT (mkdir (BASE "dir/sub", 0700) == 0);
350 /* Files present here:
357 ASSERT (func (BASE "dir", BASE "dir/sub") == -1);
358 ASSERT (errno == EINVAL);
359 ASSERT (stat (BASE "dir/sub", &st) == 0);
361 ASSERT (rmdir (BASE "dir/sub") == 0);
364 /* Files present here:
369 /* Mixing file and directory. */
372 { /* File onto dir. */
375 ASSERT (func (BASE "file", BASE "dir") == -1);
376 ASSERT (errno == EISDIR || errno == ENOTDIR);
380 ASSERT (func (BASE "file", BASE "dir/") == -1);
381 ASSERT (errno == EISDIR || errno == ENOTDIR);
384 { /* Dir onto file. */
387 ASSERT (func (BASE "dir", BASE "file") == -1);
388 ASSERT (errno == ENOTDIR);
392 ASSERT (func (BASE "dir/", BASE "file") == -1);
393 ASSERT (errno == ENOTDIR);
400 { /* File onto self. */
401 ASSERT (func (BASE "file", BASE "file") == 0);
402 memset (&st, 0, sizeof st);
403 ASSERT (stat (BASE "file", &st) == 0);
404 ASSERT (st.st_size == 2);
406 /* Files present here:
410 { /* Empty dir onto self. */
411 ASSERT (func (BASE "dir", BASE "dir") == 0);
412 ASSERT (stat (BASE "dir", &st) == 0);
414 /* Files present here:
418 ASSERT (close (creat (BASE "dir/file", 0600)) == 0);
419 /* Files present here:
424 { /* Full dir onto self. */
425 ASSERT (func (BASE "dir", BASE "dir") == 0);
427 ASSERT (unlink (BASE "dir/file") == 0);
428 /* Files present here:
433 /* Not all file systems support link. Mingw doesn't have
434 reliable st_nlink on hard links, but our implementation does
435 fail with EPERM on poor file systems, and we can detect the
436 inferior stat() via st_ino. Cygwin 1.5.x copies rather than
437 links files on those file systems, but there, st_nlink and
438 st_ino are reliable. */
439 int ret = link (BASE "file", BASE "file2");
442 memset (&st, 0, sizeof st);
443 ASSERT (stat (BASE "file2", &st) == 0);
444 if (st.st_ino && st.st_nlink != 2)
446 ASSERT (unlink (BASE "file2") == 0);
453 /* If the device does not support hard links, errno is
454 EPERM on Linux, EOPNOTSUPP on FreeBSD. */
460 fputs ("skipping test: "
461 "hard links not supported on this file system\n",
463 ASSERT (unlink (BASE "file") == 0);
464 ASSERT (rmdir (BASE "dir") == 0);
473 /* Files present here:
475 {BASE}file2 (hard link to file)
478 { /* File onto hard link. */
479 ASSERT (func (BASE "file", BASE "file2") == 0);
480 memset (&st, 0, sizeof st);
481 ASSERT (stat (BASE "file", &st) == 0);
482 ASSERT (st.st_size == 2);
483 memset (&st, 0, sizeof st);
484 ASSERT (stat (BASE "file2", &st) == 0);
485 ASSERT (st.st_size == 2);
487 /* Files present here:
492 ASSERT (unlink (BASE "file2") == 0);
493 /* Files present here:
500 if (symlink (BASE "file", BASE "link1"))
503 fputs ("skipping test: symlinks not supported on this file system\n",
505 ASSERT (unlink (BASE "file") == 0);
506 ASSERT (rmdir (BASE "dir") == 0);
509 /* Files present here:
511 {BASE}link1 -> {BASE}file
514 { /* Simple rename. */
515 ASSERT (func (BASE "link1", BASE "link2") == 0);
516 ASSERT (stat (BASE "file", &st) == 0);
518 ASSERT (lstat (BASE "link1", &st) == -1);
519 ASSERT (errno == ENOENT);
520 memset (&st, 0, sizeof st);
521 ASSERT (lstat (BASE "link2", &st) == 0);
522 ASSERT (S_ISLNK (st.st_mode));
524 /* Files present here:
526 {BASE}link2 -> {BASE}file
530 ASSERT (symlink (BASE "nowhere", BASE "link1") == 0);
531 /* Files present here:
533 {BASE}link1 -> {BASE}nowhere
534 {BASE}link2 -> {BASE}file
538 ASSERT (func (BASE "link2", BASE "link1") == 0);
539 memset (&st, 0, sizeof st);
540 ASSERT (stat (BASE "link1", &st) == 0);
541 ASSERT (st.st_size == 2);
543 ASSERT (lstat (BASE "link2", &st) == -1);
544 ASSERT (errno == ENOENT);
547 /* Files present here:
549 {BASE}link1 -> {BASE}file
552 { /* Symlink loop. */
553 ASSERT (symlink (BASE "link2", BASE "link2") == 0);
554 /* Files present here:
556 {BASE}link1 -> {BASE}file
557 {BASE}link2 -> {BASE}link2
561 ASSERT (func (BASE "link2", BASE "link2") == 0);
565 ASSERT (func (BASE "link2/", BASE "link2") == -1);
566 ASSERT (errno == ELOOP || errno == ENOTDIR);
568 ASSERT (func (BASE "link2", BASE "link3") == 0);
569 /* Files present here:
571 {BASE}link1 -> {BASE}file
572 {BASE}link3 -> {BASE}link2
575 ASSERT (unlink (BASE "link3") == 0);
577 /* Files present here:
579 {BASE}link1 -> {BASE}file
582 { /* Dangling link. */
583 ASSERT (symlink (BASE "nowhere", BASE "link2") == 0);
584 /* Files present here:
586 {BASE}link1 -> {BASE}file
587 {BASE}link2 -> {BASE}nowhere
591 ASSERT (func (BASE "link2", BASE "link3") == 0);
593 ASSERT (lstat (BASE "link2", &st) == -1);
594 ASSERT (errno == ENOENT);
595 memset (&st, 0, sizeof st);
596 ASSERT (lstat (BASE "link3", &st) == 0);
599 /* Files present here:
601 {BASE}link1 -> {BASE}file
602 {BASE}link3 -> {BASE}nowhere
605 { /* Trailing slash on dangling. */
608 ASSERT (func (BASE "link3/", BASE "link2") == -1);
609 ASSERT (errno == ENOENT || errno == ENOTDIR);
613 ASSERT (func (BASE "link3", BASE "link2/") == -1);
614 ASSERT (errno == ENOENT || errno == ENOTDIR);
618 ASSERT (lstat (BASE "link2", &st) == -1);
619 ASSERT (errno == ENOENT);
621 memset (&st, 0, sizeof st);
622 ASSERT (lstat (BASE "link3", &st) == 0);
624 /* Files present here:
626 {BASE}link1 -> {BASE}file
627 {BASE}link3 -> {BASE}nowhere
630 { /* Trailing slash on link to file. */
633 ASSERT (func (BASE "link1/", BASE "link2") == -1);
634 ASSERT (errno == ENOTDIR);
638 ASSERT (func (BASE "link1", BASE "link3/") == -1);
639 ASSERT (errno == ENOENT || errno == ENOTDIR);
642 /* Files present here:
644 {BASE}link1 -> {BASE}file
645 {BASE}link3 -> {BASE}nowhere
649 /* Mixing symlink and file. */
651 { /* File onto link. */
652 ASSERT (close (creat (BASE "file2", 0600)) == 0);
653 /* Files present here:
656 {BASE}link1 -> {BASE}file
657 {BASE}link3 -> {BASE}nowhere
661 ASSERT (func (BASE "file2", BASE "link3") == 0);
663 ASSERT (stat (BASE "file2", &st) == -1);
664 ASSERT (errno == ENOENT);
665 memset (&st, 0, sizeof st);
666 ASSERT (lstat (BASE "link3", &st) == 0);
667 ASSERT (S_ISREG (st.st_mode));
669 /* Files present here:
671 {BASE}link1 -> {BASE}file
675 ASSERT (unlink (BASE "link3") == 0);
677 /* Files present here:
679 {BASE}link1 -> {BASE}file
682 { /* Link onto file. */
683 ASSERT (symlink (BASE "nowhere", BASE "link2") == 0);
684 /* Files present here:
686 {BASE}link1 -> {BASE}file
687 {BASE}link2 -> {BASE}nowhere
690 ASSERT (close (creat (BASE "file2", 0600)) == 0);
691 /* Files present here:
694 {BASE}link1 -> {BASE}file
695 {BASE}link2 -> {BASE}nowhere
699 ASSERT (func (BASE "link2", BASE "file2") == 0);
701 ASSERT (lstat (BASE "link2", &st) == -1);
702 ASSERT (errno == ENOENT);
703 memset (&st, 0, sizeof st);
704 ASSERT (lstat (BASE "file2", &st) == 0);
705 ASSERT (S_ISLNK (st.st_mode));
707 /* Files present here:
709 {BASE}file2 -> {BASE}nowhere
710 {BASE}link1 -> {BASE}file
713 ASSERT (unlink (BASE "file2") == 0);
715 /* Files present here:
717 {BASE}link1 -> {BASE}file
720 { /* Trailing slash. */
723 ASSERT (func (BASE "file/", BASE "link1") == -1);
724 ASSERT (errno == ENOTDIR);
728 ASSERT (func (BASE "file", BASE "link1/") == -1);
729 ASSERT (errno == ENOTDIR || errno == ENOENT);
733 ASSERT (func (BASE "link1/", BASE "file") == -1);
734 ASSERT (errno == ENOTDIR);
738 ASSERT (func (BASE "link1", BASE "file/") == -1);
739 ASSERT (errno == ENOTDIR || errno == ENOENT);
740 memset (&st, 0, sizeof st);
741 ASSERT (lstat (BASE "file", &st) == 0);
742 ASSERT (S_ISREG (st.st_mode));
743 memset (&st, 0, sizeof st);
744 ASSERT (lstat (BASE "link1", &st) == 0);
745 ASSERT (S_ISLNK (st.st_mode));
747 /* Files present here:
749 {BASE}link1 -> {BASE}file
753 /* Mixing symlink and directory. */
755 { /* Directory onto link. */
758 ASSERT (func (BASE "dir", BASE "link1") == -1);
759 ASSERT (errno == ENOTDIR);
763 ASSERT (func (BASE "dir/", BASE "link1") == -1);
764 ASSERT (errno == ENOTDIR);
768 ASSERT (func (BASE "dir", BASE "link1/") == -1);
769 ASSERT (errno == ENOTDIR);
772 { /* Link onto directory. */
775 ASSERT (func (BASE "link1", BASE "dir") == -1);
776 ASSERT (errno == EISDIR || errno == ENOTDIR);
780 ASSERT (func (BASE "link1", BASE "dir/") == -1);
781 ASSERT (errno == EISDIR || errno == ENOTDIR);
785 ASSERT (func (BASE "link1/", BASE "dir") == -1);
786 ASSERT (errno == ENOTDIR);
787 memset (&st, 0, sizeof st);
788 ASSERT (lstat (BASE "link1", &st) == 0);
789 ASSERT (S_ISLNK (st.st_mode));
790 memset (&st, 0, sizeof st);
791 ASSERT (lstat (BASE "dir", &st) == 0);
792 ASSERT (S_ISDIR (st.st_mode));
795 /* Files present here:
797 {BASE}link1 -> {BASE}file
801 /* POSIX requires rename("link-to-dir/","other") to rename "dir" and
802 leave "link-to-dir" dangling, but GNU rejects this. POSIX
803 requires rename("dir","dangling/") to create the directory so
804 that "dangling/" now resolves, but GNU rejects this. While we
805 prefer GNU behavior, we don't enforce it. However, we do test
806 that the system either follows POSIX in both cases, or follows
810 ASSERT (symlink (BASE "dir2", BASE "link2") == 0);
811 /* Files present here:
813 {BASE}link1 -> {BASE}file
814 {BASE}link2 -> {BASE}dir2
818 result = func (BASE "dir", BASE "link2/");
823 ASSERT (lstat (BASE "dir", &st) == -1);
824 ASSERT (errno == ENOENT);
825 memset (&st, 0, sizeof st);
826 ASSERT (lstat (BASE "dir2", &st) == 0);
827 ASSERT (S_ISDIR (st.st_mode));
828 memset (&st, 0, sizeof st);
829 ASSERT (lstat (BASE "link2", &st) == 0);
830 ASSERT (S_ISLNK (st.st_mode));
831 /* Files present here:
833 {BASE}link1 -> {BASE}file
834 {BASE}link2 -> {BASE}dir2
838 ASSERT (func (BASE "link2/", BASE "dir") == 0);
839 memset (&st, 0, sizeof st);
840 ASSERT (lstat (BASE "dir", &st) == 0);
841 ASSERT (S_ISDIR (st.st_mode));
843 ASSERT (lstat (BASE "dir2", &st) == -1);
844 ASSERT (errno == ENOENT);
845 memset (&st, 0, sizeof st);
846 ASSERT (lstat (BASE "link2", &st) == 0);
847 ASSERT (S_ISLNK (st.st_mode));
853 ASSERT (result == -1);
854 ASSERT (errno == ENOTDIR);
855 memset (&st, 0, sizeof st);
856 ASSERT (lstat (BASE "dir", &st) == 0);
857 ASSERT (S_ISDIR (st.st_mode));
859 ASSERT (lstat (BASE "dir2", &st) == -1);
860 ASSERT (errno == ENOENT);
861 memset (&st, 0, sizeof st);
862 ASSERT (lstat (BASE "link2", &st) == 0);
863 ASSERT (S_ISLNK (st.st_mode));
864 ASSERT (unlink (BASE "link2") == 0);
865 ASSERT (symlink (BASE "dir", BASE "link2") == 0);
866 /* Files present here:
868 {BASE}link1 -> {BASE}file
869 {BASE}link2 -> {BASE}dir
872 errno = 0; /* OpenBSD notices that link2/ and dir are the same. */
873 result = func (BASE "link2/", BASE "dir");
874 if (result) /* GNU/Linux rejects attempts to use link2/. */
876 ASSERT (result == -1);
877 ASSERT (errno == ENOTDIR);
879 memset (&st, 0, sizeof st);
880 ASSERT (lstat (BASE "dir", &st) == 0);
881 ASSERT (S_ISDIR (st.st_mode));
883 ASSERT (lstat (BASE "dir2", &st) == -1);
884 ASSERT (errno == ENOENT);
885 memset (&st, 0, sizeof st);
886 ASSERT (lstat (BASE "link2", &st) == 0);
887 ASSERT (S_ISLNK (st.st_mode));
890 /* Files present here:
892 {BASE}link1 -> {BASE}file
893 {BASE}link2 -> {BASE}dir or {BASE}dir2
898 ASSERT (unlink (BASE "file") == 0);
899 ASSERT (rmdir (BASE "dir") == 0);
900 ASSERT (unlink (BASE "link1") == 0);
901 ASSERT (unlink (BASE "link2") == 0);