1 /* Test of rename() function.
2 Copyright (C) 2009-2024 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 <https://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
343 || errno
== ENOENT
/* WSL */);
347 ASSERT (func (BASE
"dir2/.", BASE
"dir") == -1);
348 ASSERT (errno
== EINVAL
|| errno
== EBUSY
|| errno
== EEXIST
349 || errno
== ENOENT
/* WSL */);
351 ASSERT (rmdir (BASE
"dir") == 0);
352 /* Files present here:
358 ASSERT (func (BASE
"dir2", BASE
"dir/.//") == -1);
359 ASSERT (errno
== EINVAL
|| errno
== ENOENT
);
361 ASSERT (mkdir (BASE
"dir", 0700) == 0);
362 /* Files present here:
369 ASSERT (func (BASE
"dir2", BASE
"dir/.//") == -1);
370 ASSERT (errno
== EINVAL
|| errno
== EBUSY
|| errno
== EISDIR
371 || errno
== ENOTEMPTY
|| errno
== EEXIST
372 || errno
== ENOENT
/* WSL */);
376 ASSERT (func (BASE
"dir2/.//", BASE
"dir") == -1);
377 ASSERT (errno
== EINVAL
|| errno
== EBUSY
|| errno
== EEXIST
378 || errno
== ENOENT
/* WSL */);
380 ASSERT (rmdir (BASE
"dir2") == 0);
381 /* Files present here:
386 { /* Move into subdir. */
389 ASSERT (func (BASE
"dir", BASE
"dir/sub") == -1);
390 ASSERT (errno
== EINVAL
|| errno
== EACCES
);
394 ASSERT (stat (BASE
"dir/sub", &st
) == -1);
395 ASSERT (errno
== ENOENT
);
397 ASSERT (mkdir (BASE
"dir/sub", 0700) == 0);
398 /* Files present here:
405 ASSERT (func (BASE
"dir", BASE
"dir/sub") == -1);
406 ASSERT (errno
== EINVAL
);
407 ASSERT (stat (BASE
"dir/sub", &st
) == 0);
409 ASSERT (rmdir (BASE
"dir/sub") == 0);
412 /* Files present here:
417 /* Mixing file and directory. */
420 { /* File onto dir. */
423 ASSERT (func (BASE
"file", BASE
"dir") == -1);
424 ASSERT (errno
== EISDIR
|| errno
== ENOTDIR
);
428 ASSERT (func (BASE
"file", BASE
"dir/") == -1);
429 ASSERT (errno
== EISDIR
|| errno
== ENOTDIR
);
432 { /* Dir onto file. */
435 ASSERT (func (BASE
"dir", BASE
"file") == -1);
436 ASSERT (errno
== ENOTDIR
);
440 ASSERT (func (BASE
"dir/", BASE
"file") == -1);
441 ASSERT (errno
== ENOTDIR
);
448 { /* File onto self. */
449 ASSERT (func (BASE
"file", BASE
"file") == 0);
450 memset (&st
, 0, sizeof st
);
451 ASSERT (stat (BASE
"file", &st
) == 0);
452 ASSERT (st
.st_size
== 2);
454 /* Files present here:
458 { /* Empty dir onto self. */
459 ASSERT (func (BASE
"dir", BASE
"dir") == 0);
460 ASSERT (stat (BASE
"dir", &st
) == 0);
462 /* Files present here:
466 ASSERT (close (creat (BASE
"dir/file", 0600)) == 0);
467 /* Files present here:
472 { /* Full dir onto self. */
473 ASSERT (func (BASE
"dir", BASE
"dir") == 0);
475 ASSERT (unlink (BASE
"dir/file") == 0);
476 /* Files present here:
481 /* Not all file systems support link. Mingw doesn't have
482 reliable st_nlink on hard links, but our implementation does
483 fail with EPERM on poor file systems, and we can detect the
484 inferior stat() via st_ino. Cygwin 1.5.x copies rather than
485 links files on those file systems, but there, st_nlink and
486 st_ino are reliable. */
487 int ret
= link (BASE
"file", BASE
"file2");
490 memset (&st
, 0, sizeof st
);
491 ASSERT (stat (BASE
"file2", &st
) == 0);
492 if (st
.st_ino
&& st
.st_nlink
!= 2)
494 ASSERT (unlink (BASE
"file2") == 0);
501 /* If the device does not support hard links, errno is
503 EOPNOTSUPP on FreeBSD,
504 EACCES on Android within Termux. */
509 #if defined __ANDROID__
513 fputs ("skipping test: "
514 "hard links not supported on this file system\n",
516 ASSERT (unlink (BASE
"file") == 0);
517 ASSERT (rmdir (BASE
"dir") == 0);
526 /* Files present here:
528 {BASE}file2 (hard link to file)
531 { /* File onto hard link. */
532 ASSERT (func (BASE
"file", BASE
"file2") == 0);
533 memset (&st
, 0, sizeof st
);
534 if (stat (BASE
"file", &st
) != 0)
536 /* This can happen on NetBSD. */
537 ASSERT (errno
== ENOENT
);
538 ASSERT (link (BASE
"file2", BASE
"file") == 0);
539 ASSERT (stat (BASE
"file", &st
) == 0);
541 ASSERT (st
.st_size
== 2);
542 memset (&st
, 0, sizeof st
);
543 ASSERT (stat (BASE
"file2", &st
) == 0);
544 ASSERT (st
.st_size
== 2);
546 /* Files present here:
551 ASSERT (unlink (BASE
"file2") == 0);
552 /* Files present here:
559 if (symlink (BASE
"file", BASE
"link1"))
562 fputs ("skipping test: symlinks not supported on this file system\n",
564 ASSERT (unlink (BASE
"file") == 0);
565 ASSERT (rmdir (BASE
"dir") == 0);
568 /* Files present here:
570 {BASE}link1 -> {BASE}file
573 { /* Simple rename. */
574 ASSERT (func (BASE
"link1", BASE
"link2") == 0);
575 ASSERT (stat (BASE
"file", &st
) == 0);
577 ASSERT (lstat (BASE
"link1", &st
) == -1);
578 ASSERT (errno
== ENOENT
);
579 memset (&st
, 0, sizeof st
);
580 ASSERT (lstat (BASE
"link2", &st
) == 0);
581 ASSERT (S_ISLNK (st
.st_mode
));
583 /* Files present here:
585 {BASE}link2 -> {BASE}file
589 ASSERT (symlink (BASE
"nowhere", BASE
"link1") == 0);
590 /* Files present here:
592 {BASE}link1 -> {BASE}nowhere
593 {BASE}link2 -> {BASE}file
597 ASSERT (func (BASE
"link2", BASE
"link1") == 0);
598 memset (&st
, 0, sizeof st
);
599 ASSERT (stat (BASE
"link1", &st
) == 0);
600 ASSERT (st
.st_size
== 2);
602 ASSERT (lstat (BASE
"link2", &st
) == -1);
603 ASSERT (errno
== ENOENT
);
606 /* Files present here:
608 {BASE}link1 -> {BASE}file
611 { /* Symlink loop. */
612 ASSERT (symlink (BASE
"link2", BASE
"link2") == 0);
613 /* Files present here:
615 {BASE}link1 -> {BASE}file
616 {BASE}link2 -> {BASE}link2
620 ASSERT (func (BASE
"link2", BASE
"link2") == 0);
624 ASSERT (func (BASE
"link2/", BASE
"link2") == -1);
625 ASSERT (errno
== ELOOP
|| errno
== ENOTDIR
);
627 ASSERT (func (BASE
"link2", BASE
"link3") == 0);
628 /* Files present here:
630 {BASE}link1 -> {BASE}file
631 {BASE}link3 -> {BASE}link2
634 ASSERT (unlink (BASE
"link3") == 0);
636 /* Files present here:
638 {BASE}link1 -> {BASE}file
641 { /* Dangling link. */
642 ASSERT (symlink (BASE
"nowhere", BASE
"link2") == 0);
643 /* Files present here:
645 {BASE}link1 -> {BASE}file
646 {BASE}link2 -> {BASE}nowhere
650 ASSERT (func (BASE
"link2", BASE
"link3") == 0);
652 ASSERT (lstat (BASE
"link2", &st
) == -1);
653 ASSERT (errno
== ENOENT
);
654 memset (&st
, 0, sizeof st
);
655 ASSERT (lstat (BASE
"link3", &st
) == 0);
658 /* Files present here:
660 {BASE}link1 -> {BASE}file
661 {BASE}link3 -> {BASE}nowhere
664 { /* Trailing slash on dangling. */
667 ASSERT (func (BASE
"link3/", BASE
"link2") == -1);
668 ASSERT (errno
== ENOENT
|| errno
== ENOTDIR
);
672 ASSERT (func (BASE
"link3", BASE
"link2/") == -1);
673 ASSERT (errno
== ENOENT
|| errno
== ENOTDIR
);
677 ASSERT (lstat (BASE
"link2", &st
) == -1);
678 ASSERT (errno
== ENOENT
);
680 memset (&st
, 0, sizeof st
);
681 ASSERT (lstat (BASE
"link3", &st
) == 0);
683 /* Files present here:
685 {BASE}link1 -> {BASE}file
686 {BASE}link3 -> {BASE}nowhere
689 { /* Trailing slash on link to file. */
692 ASSERT (func (BASE
"link1/", BASE
"link2") == -1);
693 ASSERT (errno
== ENOTDIR
);
697 ASSERT (func (BASE
"link1", BASE
"link3/") == -1);
698 ASSERT (errno
== ENOENT
|| errno
== ENOTDIR
);
701 /* Files present here:
703 {BASE}link1 -> {BASE}file
704 {BASE}link3 -> {BASE}nowhere
708 /* Mixing symlink and file. */
710 { /* File onto link. */
711 ASSERT (close (creat (BASE
"file2", 0600)) == 0);
712 /* Files present here:
715 {BASE}link1 -> {BASE}file
716 {BASE}link3 -> {BASE}nowhere
720 ASSERT (func (BASE
"file2", BASE
"link3") == 0);
722 ASSERT (stat (BASE
"file2", &st
) == -1);
723 ASSERT (errno
== ENOENT
);
724 memset (&st
, 0, sizeof st
);
725 ASSERT (lstat (BASE
"link3", &st
) == 0);
726 ASSERT (S_ISREG (st
.st_mode
));
728 /* Files present here:
730 {BASE}link1 -> {BASE}file
734 ASSERT (unlink (BASE
"link3") == 0);
736 /* Files present here:
738 {BASE}link1 -> {BASE}file
741 { /* Link onto file. */
742 ASSERT (symlink (BASE
"nowhere", BASE
"link2") == 0);
743 /* Files present here:
745 {BASE}link1 -> {BASE}file
746 {BASE}link2 -> {BASE}nowhere
749 ASSERT (close (creat (BASE
"file2", 0600)) == 0);
750 /* Files present here:
753 {BASE}link1 -> {BASE}file
754 {BASE}link2 -> {BASE}nowhere
758 ASSERT (func (BASE
"link2", BASE
"file2") == 0);
760 ASSERT (lstat (BASE
"link2", &st
) == -1);
761 ASSERT (errno
== ENOENT
);
762 memset (&st
, 0, sizeof st
);
763 ASSERT (lstat (BASE
"file2", &st
) == 0);
764 ASSERT (S_ISLNK (st
.st_mode
));
766 /* Files present here:
768 {BASE}file2 -> {BASE}nowhere
769 {BASE}link1 -> {BASE}file
772 ASSERT (unlink (BASE
"file2") == 0);
774 /* Files present here:
776 {BASE}link1 -> {BASE}file
779 { /* Trailing slash. */
782 ASSERT (func (BASE
"file/", BASE
"link1") == -1);
783 ASSERT (errno
== ENOTDIR
);
787 ASSERT (func (BASE
"file", BASE
"link1/") == -1);
788 ASSERT (errno
== ENOTDIR
|| errno
== ENOENT
);
792 ASSERT (func (BASE
"link1/", BASE
"file") == -1);
793 ASSERT (errno
== ENOTDIR
);
797 ASSERT (func (BASE
"link1", BASE
"file/") == -1);
798 ASSERT (errno
== ENOTDIR
|| errno
== ENOENT
);
799 memset (&st
, 0, sizeof st
);
800 ASSERT (lstat (BASE
"file", &st
) == 0);
801 ASSERT (S_ISREG (st
.st_mode
));
802 memset (&st
, 0, sizeof st
);
803 ASSERT (lstat (BASE
"link1", &st
) == 0);
804 ASSERT (S_ISLNK (st
.st_mode
));
807 /* Files present here:
809 {BASE}link1 -> {BASE}file
813 /* Mixing symlink and directory. */
815 { /* Directory onto link. */
818 ASSERT (func (BASE
"dir", BASE
"link1") == -1);
819 ASSERT (errno
== ENOTDIR
);
823 ASSERT (func (BASE
"dir/", BASE
"link1") == -1);
824 ASSERT (errno
== ENOTDIR
);
828 ASSERT (func (BASE
"dir", BASE
"link1/") == -1);
829 ASSERT (errno
== ENOTDIR
);
832 { /* Link onto directory. */
835 ASSERT (func (BASE
"link1", BASE
"dir") == -1);
836 ASSERT (errno
== EISDIR
|| errno
== ENOTDIR
);
840 ASSERT (func (BASE
"link1", BASE
"dir/") == -1);
841 ASSERT (errno
== EISDIR
|| errno
== ENOTDIR
);
845 ASSERT (func (BASE
"link1/", BASE
"dir") == -1);
846 ASSERT (errno
== ENOTDIR
);
847 memset (&st
, 0, sizeof st
);
848 ASSERT (lstat (BASE
"link1", &st
) == 0);
849 ASSERT (S_ISLNK (st
.st_mode
));
850 memset (&st
, 0, sizeof st
);
851 ASSERT (lstat (BASE
"dir", &st
) == 0);
852 ASSERT (S_ISDIR (st
.st_mode
));
855 /* Files present here:
857 {BASE}link1 -> {BASE}file
861 /* POSIX requires rename("link-to-dir/","other") to rename "dir" and
862 leave "link-to-dir" dangling, but GNU rejects this. POSIX
863 requires rename("dir","dangling/") to create the directory so
864 that "dangling/" now resolves, but GNU rejects this. While we
865 prefer GNU behavior, we don't enforce it. However, we do test
866 that the system either follows POSIX in both cases, or follows
870 ASSERT (symlink (BASE
"dir2", BASE
"link2") == 0);
871 /* Files present here:
873 {BASE}link1 -> {BASE}file
874 {BASE}link2 -> {BASE}dir2
878 result
= func (BASE
"dir", BASE
"link2/");
883 ASSERT (lstat (BASE
"dir", &st
) == -1);
884 ASSERT (errno
== ENOENT
);
885 memset (&st
, 0, sizeof st
);
886 ASSERT (lstat (BASE
"dir2", &st
) == 0);
887 ASSERT (S_ISDIR (st
.st_mode
));
888 memset (&st
, 0, sizeof st
);
889 ASSERT (lstat (BASE
"link2", &st
) == 0);
890 ASSERT (S_ISLNK (st
.st_mode
));
891 /* Files present here:
893 {BASE}link1 -> {BASE}file
894 {BASE}link2 -> {BASE}dir2
898 ASSERT (func (BASE
"link2/", BASE
"dir") == 0);
899 memset (&st
, 0, sizeof st
);
900 ASSERT (lstat (BASE
"dir", &st
) == 0);
901 ASSERT (S_ISDIR (st
.st_mode
));
903 ASSERT (lstat (BASE
"dir2", &st
) == -1);
904 ASSERT (errno
== ENOENT
);
905 memset (&st
, 0, sizeof st
);
906 ASSERT (lstat (BASE
"link2", &st
) == 0);
907 ASSERT (S_ISLNK (st
.st_mode
));
913 ASSERT (result
== -1);
914 ASSERT (errno
== ENOTDIR
);
915 memset (&st
, 0, sizeof st
);
916 ASSERT (lstat (BASE
"dir", &st
) == 0);
917 ASSERT (S_ISDIR (st
.st_mode
));
919 ASSERT (lstat (BASE
"dir2", &st
) == -1);
920 ASSERT (errno
== ENOENT
);
921 memset (&st
, 0, sizeof st
);
922 ASSERT (lstat (BASE
"link2", &st
) == 0);
923 ASSERT (S_ISLNK (st
.st_mode
));
924 ASSERT (unlink (BASE
"link2") == 0);
925 ASSERT (symlink (BASE
"dir", BASE
"link2") == 0);
926 /* Files present here:
928 {BASE}link1 -> {BASE}file
929 {BASE}link2 -> {BASE}dir
932 errno
= 0; /* OpenBSD notices that link2/ and dir are the same. */
933 result
= func (BASE
"link2/", BASE
"dir");
934 if (result
) /* GNU/Linux rejects attempts to use link2/. */
936 ASSERT (result
== -1);
937 ASSERT (errno
== ENOTDIR
|| errno
== EISDIR
);
939 memset (&st
, 0, sizeof st
);
940 ASSERT (lstat (BASE
"dir", &st
) == 0);
941 ASSERT (S_ISDIR (st
.st_mode
));
943 ASSERT (lstat (BASE
"dir2", &st
) == -1);
944 ASSERT (errno
== ENOENT
);
945 memset (&st
, 0, sizeof st
);
946 ASSERT (lstat (BASE
"link2", &st
) == 0);
947 ASSERT (S_ISLNK (st
.st_mode
));
950 /* Files present here:
952 {BASE}link1 -> {BASE}file
953 {BASE}link2 -> {BASE}dir or {BASE}dir2
958 ASSERT (unlink (BASE
"file") == 0);
959 ASSERT (rmdir (BASE
"dir") == 0);
960 ASSERT (unlink (BASE
"link1") == 0);
961 ASSERT (unlink (BASE
"link2") == 0);