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