xref: /xnu-12377.81.4/tests/rename_excl.c (revision 043036a2b3718f7f0be807e2870f8f47d3fa0796) !
1*043036a2SApple OSS Distributions #include <darwintest.h>
2*043036a2SApple OSS Distributions #include <darwintest_utils.h>
3*043036a2SApple OSS Distributions #include <dirent.h>
4*043036a2SApple OSS Distributions #include <errno.h>
5*043036a2SApple OSS Distributions #include <fcntl.h>
6*043036a2SApple OSS Distributions #include <stdio.h>
7*043036a2SApple OSS Distributions #include <stdlib.h>
8*043036a2SApple OSS Distributions #include <unistd.h>
9*043036a2SApple OSS Distributions #include <sys/stat.h>
10*043036a2SApple OSS Distributions 
11*043036a2SApple OSS Distributions 
12*043036a2SApple OSS Distributions T_GLOBAL_META(
13*043036a2SApple OSS Distributions 	T_META_NAMESPACE("xnu.vfs"),
14*043036a2SApple OSS Distributions 	T_META_CHECK_LEAKS(false),
15*043036a2SApple OSS Distributions 	T_META_TAG_VM_PREFERRED);
16*043036a2SApple OSS Distributions 
17*043036a2SApple OSS Distributions #define TEST_DIR         "rename_dir"
18*043036a2SApple OSS Distributions #define TEST_FILE1       TEST_DIR "/file1"
19*043036a2SApple OSS Distributions #define TEST_FILE1_UC    TEST_DIR "/FILE1"
20*043036a2SApple OSS Distributions #define TEST_FILE2       TEST_DIR "/file2"
21*043036a2SApple OSS Distributions #define TEST_FILE3_HL    TEST_DIR "/file3"
22*043036a2SApple OSS Distributions 
23*043036a2SApple OSS Distributions static void
cleanup(void)24*043036a2SApple OSS Distributions cleanup(void)
25*043036a2SApple OSS Distributions {
26*043036a2SApple OSS Distributions 	(void) remove(TEST_FILE1);
27*043036a2SApple OSS Distributions 	(void) remove(TEST_FILE1_UC);
28*043036a2SApple OSS Distributions 	(void) remove(TEST_FILE2);
29*043036a2SApple OSS Distributions 	(void) remove(TEST_FILE3_HL);
30*043036a2SApple OSS Distributions 	(void) rmdir(TEST_DIR);
31*043036a2SApple OSS Distributions }
32*043036a2SApple OSS Distributions 
33*043036a2SApple OSS Distributions /*
34*043036a2SApple OSS Distributions  * This unit-test validates the behavior of renamex_np() with RENAME_EXCL flag.
35*043036a2SApple OSS Distributions  * On either a case-insensitve/case-sensitive volume:
36*043036a2SApple OSS Distributions  * 1. rename from source to existing target should succeed when the change is
37*043036a2SApple OSS Distributions  *    only case-variant (for e.g rename_dir/file1 -> rename_dir/FILE1)
38*043036a2SApple OSS Distributions  * 2. rename from source to existing target should fail with EEXIST
39*043036a2SApple OSS Distributions  * 3. rename from source to existing target which is a hardlink of the source
40*043036a2SApple OSS Distributions  *    should fail with EEXIST
41*043036a2SApple OSS Distributions  *
42*043036a2SApple OSS Distributions  * On case-insensitive volume:
43*043036a2SApple OSS Distributions  * 1. rename from source to itself should succeed
44*043036a2SApple OSS Distributions  *    (rename_dir/file1 -> rename_dir/file1)
45*043036a2SApple OSS Distributions  *
46*043036a2SApple OSS Distributions  * On case-sensitive volume:
47*043036a2SApple OSS Distributions  * 1. rename from source to itself should fail with EEXIST
48*043036a2SApple OSS Distributions  *    (rename_dir/file1 -> rename_dir/file1)
49*043036a2SApple OSS Distributions  */
50*043036a2SApple OSS Distributions 
51*043036a2SApple OSS Distributions T_DECL(rename_excl_with_case_variant,
52*043036a2SApple OSS Distributions     "test renamex_np() with RENAME_EXCL flag for files with case variants")
53*043036a2SApple OSS Distributions {
54*043036a2SApple OSS Distributions 	const char *tmpdir = dt_tmpdir();
55*043036a2SApple OSS Distributions 	long case_sensitive_vol;
56*043036a2SApple OSS Distributions 	int err, saved_errno;
57*043036a2SApple OSS Distributions 	int fd;
58*043036a2SApple OSS Distributions 
59*043036a2SApple OSS Distributions 	T_SETUPBEGIN;
60*043036a2SApple OSS Distributions 
61*043036a2SApple OSS Distributions 	atexit(cleanup);
62*043036a2SApple OSS Distributions 
63*043036a2SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(chdir(tmpdir),
64*043036a2SApple OSS Distributions 	    "Setup: changing to tmpdir: %s", tmpdir);
65*043036a2SApple OSS Distributions 
66*043036a2SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(mkdir(TEST_DIR, 0777),
67*043036a2SApple OSS Distributions 	    "Setup: creating test dir: %s", TEST_DIR);
68*043036a2SApple OSS Distributions 
69*043036a2SApple OSS Distributions 	T_WITH_ERRNO;
70*043036a2SApple OSS Distributions 	fd = open(TEST_FILE1, O_CREAT | O_RDWR, 0666);
71*043036a2SApple OSS Distributions 	T_ASSERT_TRUE(fd != -1, "Creating test file1: %s", TEST_FILE1);
72*043036a2SApple OSS Distributions 
73*043036a2SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(fd), "Closing test file1: %s",
74*043036a2SApple OSS Distributions 	    TEST_FILE1);
75*043036a2SApple OSS Distributions 
76*043036a2SApple OSS Distributions 	T_WITH_ERRNO;
77*043036a2SApple OSS Distributions 	fd = open(TEST_FILE2, O_CREAT | O_RDWR, 0666);
78*043036a2SApple OSS Distributions 	T_ASSERT_TRUE(fd != -1, "Creating test file2: %s", TEST_FILE2);
79*043036a2SApple OSS Distributions 
80*043036a2SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(fd), "Closing test file2: %s",
81*043036a2SApple OSS Distributions 	    TEST_FILE2);
82*043036a2SApple OSS Distributions 
83*043036a2SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(link(TEST_FILE1, TEST_FILE3_HL),
84*043036a2SApple OSS Distributions 	    "Creating hardlink for %s from source: %s",
85*043036a2SApple OSS Distributions 	    TEST_FILE3_HL, TEST_FILE1);
86*043036a2SApple OSS Distributions 
87*043036a2SApple OSS Distributions 	case_sensitive_vol = pathconf(TEST_DIR, _PC_CASE_SENSITIVE);
88*043036a2SApple OSS Distributions 	T_ASSERT_TRUE(case_sensitive_vol != -1,
89*043036a2SApple OSS Distributions 	    "Checking if target volume is case-sensitive, is_case_sensitive: %ld",
90*043036a2SApple OSS Distributions 	    case_sensitive_vol);
91*043036a2SApple OSS Distributions 
92*043036a2SApple OSS Distributions 	T_SETUPEND;
93*043036a2SApple OSS Distributions 
94*043036a2SApple OSS Distributions 	err = renamex_np(TEST_FILE1, TEST_FILE2, RENAME_EXCL);
95*043036a2SApple OSS Distributions 	saved_errno = errno;
96*043036a2SApple OSS Distributions 	T_ASSERT_TRUE((err == -1 && saved_errno == EEXIST),
97*043036a2SApple OSS Distributions 	    "Renaming with RENAME_EXCL from source: %s to target: %s",
98*043036a2SApple OSS Distributions 	    TEST_FILE1, TEST_FILE2);
99*043036a2SApple OSS Distributions 
100*043036a2SApple OSS Distributions 	err = renamex_np(TEST_FILE1, TEST_FILE3_HL, RENAME_EXCL);
101*043036a2SApple OSS Distributions 	saved_errno = errno;
102*043036a2SApple OSS Distributions 	T_ASSERT_TRUE((err == -1 && saved_errno == EEXIST),
103*043036a2SApple OSS Distributions 	    "Renaming with RENAME_EXCL from source: %s to hardlink target: %s",
104*043036a2SApple OSS Distributions 	    TEST_FILE1, TEST_FILE3_HL);
105*043036a2SApple OSS Distributions 
106*043036a2SApple OSS Distributions 	if (case_sensitive_vol) {
107*043036a2SApple OSS Distributions 		err = renamex_np(TEST_FILE1, TEST_FILE1, RENAME_EXCL);
108*043036a2SApple OSS Distributions 		saved_errno = errno;
109*043036a2SApple OSS Distributions 		T_ASSERT_TRUE((err == -1 && saved_errno == EEXIST),
110*043036a2SApple OSS Distributions 		    "Renaming with RENAME_EXCL from source: %s to target: %s",
111*043036a2SApple OSS Distributions 		    TEST_FILE1, TEST_FILE1);
112*043036a2SApple OSS Distributions 	} else {
113*043036a2SApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(renamex_np(TEST_FILE1, TEST_FILE1, RENAME_EXCL),
114*043036a2SApple OSS Distributions 		    "Renaming with RENAME_EXCL from source: %s to target: %s",
115*043036a2SApple OSS Distributions 		    TEST_FILE1, TEST_FILE1);
116*043036a2SApple OSS Distributions 	}
117*043036a2SApple OSS Distributions 
118*043036a2SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(renamex_np(TEST_FILE1, TEST_FILE1_UC, RENAME_EXCL),
119*043036a2SApple OSS Distributions 	    "Renaming with RENAME_EXCL from source: %s to target: %s",
120*043036a2SApple OSS Distributions 	    TEST_FILE1, TEST_FILE1_UC);
121*043036a2SApple OSS Distributions }
122