• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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