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