1 //===-- Unittest for fcntl ------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "hdr/fcntl_macros.h"
10 #include "hdr/types/struct_flock.h"
11 #include "src/errno/libc_errno.h"
12 #include "src/fcntl/fcntl.h"
13 #include "src/fcntl/open.h"
14 #include "src/unistd/close.h"
15 #include "test/UnitTest/ErrnoSetterMatcher.h"
16 #include "test/UnitTest/Test.h"
17
18 #include <stdio.h>
19 #include <sys/stat.h> // For S_IRWXU
20
TEST(LlvmLibcFcntlTest,FcntlDupfd)21 TEST(LlvmLibcFcntlTest, FcntlDupfd) {
22 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
23 constexpr const char *TEST_FILE_NAME = "testdata/fcntl_dup.test";
24 auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
25 int fd2, fd3;
26 int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC, S_IRWXU);
27 ASSERT_ERRNO_SUCCESS();
28 ASSERT_GT(fd, 0);
29
30 fd2 = LIBC_NAMESPACE::fcntl(fd, F_DUPFD, 0);
31 ASSERT_ERRNO_SUCCESS();
32 ASSERT_GT(fd2, 0);
33
34 fd3 = LIBC_NAMESPACE::fcntl(fd, F_DUPFD, 10);
35 ASSERT_ERRNO_SUCCESS();
36 ASSERT_GT(fd3, 0);
37
38 ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
39 ASSERT_THAT(LIBC_NAMESPACE::close(fd2), Succeeds(0));
40 ASSERT_THAT(LIBC_NAMESPACE::close(fd3), Succeeds(0));
41 }
42
TEST(LlvmLibcFcntlTest,FcntlGetFl)43 TEST(LlvmLibcFcntlTest, FcntlGetFl) {
44 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
45 constexpr const char *TEST_FILE_NAME = "testdata/fcntl_getfl.test";
46 auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
47 int retVal;
48 int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC, S_IRWXU);
49 ASSERT_ERRNO_SUCCESS();
50 ASSERT_GT(fd, 0);
51
52 retVal = LIBC_NAMESPACE::fcntl(fd, F_GETFL);
53 ASSERT_ERRNO_SUCCESS();
54 ASSERT_GT(retVal, -1);
55
56 ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
57 }
58
TEST(LlvmLibcFcntlTest,FcntlSetFl)59 TEST(LlvmLibcFcntlTest, FcntlSetFl) {
60 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
61 constexpr const char *TEST_FILE_NAME = "testdata/fcntl_setfl.test";
62 auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
63
64 int retVal;
65 int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
66 ASSERT_ERRNO_SUCCESS();
67 ASSERT_GT(fd, 0);
68
69 retVal = LIBC_NAMESPACE::fcntl(fd, F_GETFL);
70 ASSERT_ERRNO_SUCCESS();
71 ASSERT_GT(retVal, -1);
72
73 int oldFlags = LIBC_NAMESPACE::fcntl(fd, F_GETFL, 0);
74 ASSERT_ERRNO_SUCCESS();
75 ASSERT_GT(oldFlags, 0);
76
77 // Add the APPEND flag;
78 oldFlags |= O_APPEND;
79
80 retVal = LIBC_NAMESPACE::fcntl(fd, F_SETFL, oldFlags);
81 ASSERT_ERRNO_SUCCESS();
82 ASSERT_GT(retVal, -1);
83
84 // Remove the APPEND flag;
85 oldFlags = -oldFlags & O_APPEND;
86
87 retVal = LIBC_NAMESPACE::fcntl(fd, F_SETFL, oldFlags);
88 ASSERT_ERRNO_SUCCESS();
89 ASSERT_GT(retVal, -1);
90
91 ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
92 }
93
TEST(LlvmLibcFcntlTest,FcntlGetLkRead)94 TEST(LlvmLibcFcntlTest, FcntlGetLkRead) {
95 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
96 constexpr const char *TEST_FILE_NAME = "testdata/fcntl_getlkread.test";
97 auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
98
99 struct flock flk, svflk;
100 int retVal;
101 int fd =
102 LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC | O_RDONLY, S_IRWXU);
103 ASSERT_ERRNO_SUCCESS();
104 ASSERT_GT(fd, 0);
105
106 flk.l_type = F_RDLCK;
107 flk.l_start = 0;
108 flk.l_whence = SEEK_SET;
109 flk.l_len = 50;
110
111 // copy flk into svflk
112 svflk = flk;
113
114 retVal = LIBC_NAMESPACE::fcntl(fd, F_GETLK, &svflk);
115 ASSERT_ERRNO_SUCCESS();
116 ASSERT_GT(retVal, -1);
117 ASSERT_NE((int)flk.l_type, F_WRLCK); // File should not be write locked.
118
119 retVal = LIBC_NAMESPACE::fcntl(fd, F_SETLK, &svflk);
120 ASSERT_ERRNO_SUCCESS();
121 ASSERT_GT(retVal, -1);
122
123 ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
124 }
125
TEST(LlvmLibcFcntlTest,FcntlGetLkWrite)126 TEST(LlvmLibcFcntlTest, FcntlGetLkWrite) {
127 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
128 constexpr const char *TEST_FILE_NAME = "testdata/fcntl_getlkwrite.test";
129 auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
130
131 struct flock flk, svflk;
132 int retVal;
133 int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
134 ASSERT_ERRNO_SUCCESS();
135 ASSERT_GT(fd, 0);
136
137 flk.l_type = F_WRLCK;
138 flk.l_start = 0;
139 flk.l_whence = SEEK_SET;
140 flk.l_len = 0;
141
142 // copy flk into svflk
143 svflk = flk;
144
145 retVal = LIBC_NAMESPACE::fcntl(fd, F_GETLK, &svflk);
146 ASSERT_ERRNO_SUCCESS();
147 ASSERT_GT(retVal, -1);
148 ASSERT_NE((int)flk.l_type, F_RDLCK); // File should not be read locked.
149
150 retVal = LIBC_NAMESPACE::fcntl(fd, F_SETLK, &svflk);
151 ASSERT_ERRNO_SUCCESS();
152 ASSERT_GT(retVal, -1);
153
154 ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
155 }
156