]> git.saurik.com Git - apple/xnu.git/blame - tests/rename_excl.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / tests / rename_excl.c
CommitLineData
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
12T_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
23static void
24cleanup(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
51T_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}