@@ -94,78 +94,99 @@ TEST_F(LlvmLibcFcntlTest, FcntlSetFl) {
9494 ASSERT_THAT (LIBC_NAMESPACE::close (fd), Succeeds (0 ));
9595}
9696
97- TEST_F (LlvmLibcFcntlTest, FcntlGetLkRead) {
98- using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
99- constexpr const char *TEST_FILE_NAME = " testdata/fcntl_getlkread.test" ;
100- auto TEST_FILE = libc_make_test_file_path (TEST_FILE_NAME);
101-
102- struct flock flk, svflk;
103- int retVal;
104- int fd =
105- LIBC_NAMESPACE::open (TEST_FILE, O_CREAT | O_TRUNC | O_RDONLY, S_IRWXU);
106- ASSERT_ERRNO_SUCCESS ();
107- ASSERT_GT (fd, 0 );
108-
109- flk.l_type = F_RDLCK;
110- flk.l_start = 0 ;
111- flk.l_whence = SEEK_SET;
112- flk.l_len = 50 ;
113-
114- // copy flk into svflk
115- svflk = flk;
116-
117- retVal = LIBC_NAMESPACE::fcntl (fd, F_GETLK, &svflk);
118- ASSERT_ERRNO_SUCCESS ();
119- ASSERT_GT (retVal, -1 );
120- ASSERT_NE ((int )flk.l_type , F_WRLCK); // File should not be write locked.
121-
122- retVal = LIBC_NAMESPACE::fcntl (fd, F_SETLK, &svflk);
123- ASSERT_ERRNO_SUCCESS ();
124- ASSERT_GT (retVal, -1 );
125-
126- ASSERT_THAT (LIBC_NAMESPACE::close (fd), Succeeds (0 ));
127- }
128-
129- TEST_F (LlvmLibcFcntlTest, FcntlGetLkWrite) {
130- using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
131- constexpr const char *TEST_FILE_NAME = " testdata/fcntl_getlkwrite.test" ;
132- auto TEST_FILE = libc_make_test_file_path (TEST_FILE_NAME);
133-
134- struct flock flk, svflk;
135- int retVal;
136- int fd = LIBC_NAMESPACE::open (TEST_FILE, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
137- ASSERT_ERRNO_SUCCESS ();
138- ASSERT_GT (fd, 0 );
139-
140- flk.l_type = F_WRLCK;
141- flk.l_start = 0 ;
142- flk.l_whence = SEEK_SET;
143- flk.l_len = 0 ;
144-
145- // copy flk into svflk
146- svflk = flk;
147-
148- retVal = LIBC_NAMESPACE::fcntl (fd, F_GETLK, &svflk);
149- ASSERT_ERRNO_SUCCESS ();
150- ASSERT_GT (retVal, -1 );
151- ASSERT_NE ((int )flk.l_type , F_RDLCK); // File should not be read locked.
152-
153- retVal = LIBC_NAMESPACE::fcntl (fd, F_SETLK, &svflk);
154- ASSERT_ERRNO_SUCCESS ();
155- ASSERT_GT (retVal, -1 );
156-
157- ASSERT_THAT (LIBC_NAMESPACE::close (fd), Succeeds (0 ));
158- }
159-
160- TEST_F (LlvmLibcFcntlTest, UseAfterClose) {
161- using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
162- constexpr const char *TEST_FILE_NAME = " testdata/fcntl_use_after_close.test" ;
163- auto TEST_FILE = libc_make_test_file_path (TEST_FILE_NAME);
164- int fd = LIBC_NAMESPACE::open (TEST_FILE, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
165- ASSERT_THAT (LIBC_NAMESPACE::close (fd), Succeeds (0 ));
166- ASSERT_EQ (-1 , LIBC_NAMESPACE::fcntl (fd, F_GETFL));
167- ASSERT_ERRNO_EQ (EBADF);
168- }
97+ /* Tests that are common between OFD and traditional variants of fcntl locks. */
98+ template <int GETLK_CMD, int SETLK_CMD>
99+ class LibcFcntlCommonLockTests : public LlvmLibcFcntlTest {
100+ public:
101+ void GetLkRead () {
102+ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
103+ constexpr const char *TEST_FILE_NAME = " testdata/fcntl_getlkread.test" ;
104+ const auto TEST_FILE = libc_make_test_file_path (TEST_FILE_NAME);
105+
106+ struct flock flk = {};
107+ struct flock svflk = {};
108+ int retVal;
109+ int fd =
110+ LIBC_NAMESPACE::open (TEST_FILE, O_CREAT | O_TRUNC | O_RDONLY, S_IRWXU);
111+ ASSERT_ERRNO_SUCCESS ();
112+ ASSERT_GT (fd, 0 );
113+
114+ flk.l_type = F_RDLCK;
115+ flk.l_start = 0 ;
116+ flk.l_whence = SEEK_SET;
117+ flk.l_len = 50 ;
118+
119+ // copy flk into svflk
120+ svflk = flk;
121+
122+ retVal = LIBC_NAMESPACE::fcntl (fd, GETLK_CMD, &svflk);
123+ ASSERT_ERRNO_SUCCESS ();
124+ ASSERT_GT (retVal, -1 );
125+ ASSERT_NE ((int )svflk.l_type , F_WRLCK); // File should not be write locked.
126+
127+ retVal = LIBC_NAMESPACE::fcntl (fd, SETLK_CMD, &svflk);
128+ ASSERT_ERRNO_SUCCESS ();
129+ ASSERT_GT (retVal, -1 );
130+
131+ ASSERT_THAT (LIBC_NAMESPACE::close (fd), Succeeds (0 ));
132+ }
133+
134+ void GetLkWrite () {
135+ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
136+ constexpr const char *TEST_FILE_NAME = " testdata/fcntl_getlkwrite.test" ;
137+ const auto TEST_FILE = libc_make_test_file_path (TEST_FILE_NAME);
138+
139+ struct flock flk = {};
140+ struct flock svflk = {};
141+ int retVal;
142+ int fd =
143+ LIBC_NAMESPACE::open (TEST_FILE, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
144+ ASSERT_ERRNO_SUCCESS ();
145+ ASSERT_GT (fd, 0 );
146+
147+ flk.l_type = F_WRLCK;
148+ flk.l_start = 0 ;
149+ flk.l_whence = SEEK_SET;
150+ flk.l_len = 0 ;
151+
152+ // copy flk into svflk
153+ svflk = flk;
154+
155+ retVal = LIBC_NAMESPACE::fcntl (fd, GETLK_CMD, &svflk);
156+ ASSERT_ERRNO_SUCCESS ();
157+ ASSERT_GT (retVal, -1 );
158+ ASSERT_NE ((int )svflk.l_type , F_RDLCK); // File should not be read locked.
159+
160+ retVal = LIBC_NAMESPACE::fcntl (fd, SETLK_CMD, &svflk);
161+ ASSERT_ERRNO_SUCCESS ();
162+ ASSERT_GT (retVal, -1 );
163+
164+ ASSERT_THAT (LIBC_NAMESPACE::close (fd), Succeeds (0 ));
165+ }
166+
167+ void UseAfterClose () {
168+ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
169+ constexpr const char *TEST_FILE_NAME =
170+ " testdata/fcntl_use_after_close.test" ;
171+ const auto TEST_FILE = libc_make_test_file_path (TEST_FILE_NAME);
172+ int fd =
173+ LIBC_NAMESPACE::open (TEST_FILE, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
174+ ASSERT_THAT (LIBC_NAMESPACE::close (fd), Succeeds (0 ));
175+ ASSERT_EQ (-1 , LIBC_NAMESPACE::fcntl (fd, GETLK_CMD));
176+ ASSERT_ERRNO_EQ (EBADF);
177+ }
178+ };
179+
180+ #define COMMON_LOCK_TESTS (NAME, GETLK, SETLK ) \
181+ using NAME = LibcFcntlCommonLockTests<GETLK, SETLK>; \
182+ TEST_F (NAME, GetLkRead) { GetLkRead (); } \
183+ TEST_F (NAME, GetLkWrite) { GetLkWrite (); } \
184+ TEST_F (NAME, UseAfterClose) { UseAfterClose (); } \
185+ static_assert (true , " Require semicolon." )
186+
187+ COMMON_LOCK_TESTS(LlvmLibcFcntlProcessAssociatedLockTest, F_GETLK, F_SETLK);
188+ COMMON_LOCK_TESTS (LlvmLibcFcntlOpenFileDescriptionLockTest, F_OFD_GETLK,
189+ F_OFD_SETLK);
169190
170191TEST_F (LlvmLibcFcntlTest, SetGetOwnerTest) {
171192 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
0 commit comments