• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 HiHope Open Source Organization.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <cerrno>
17 #include <cstdlib>
18 #include <cstdio>
19 #include <string>
20 #include <fcntl.h>
21 #include <unistd.h>
22 #include <gtest/gtest.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 
26 using namespace testing::ext;
27 using namespace std;
28 
29 class OpenatApiTest : public testing::Test {
30 public:
31     static void SetUpTestCase();
32     static void TearDownTestCase();
33     void SetUp();
34     void TearDown();
35 
36 private:
37 };
38 
39 static const char *TEST_DIR = "/data/local/tmp/tmp";
40 static const char *TEST_FILE = "/data/local/tmp/tmp/test";
41 static const char *TEST_TARFILE = "/data/local/tmp/tmp/target";
42 
SetUpTestCase()43 void OpenatApiTest::SetUpTestCase()
44 {
45 }
46 
TearDownTestCase()47 void OpenatApiTest::TearDownTestCase()
48 {
49 }
50 
SetUp()51 void OpenatApiTest::SetUp()
52 {
53     mkdir(TEST_DIR, S_IRWXU | S_IRWXG | S_IRWXO);
54 }
55 
TearDown()56 void OpenatApiTest::TearDown()
57 {
58     unlink(TEST_FILE);
59     unlink(TEST_TARFILE);
60     rmdir(TEST_DIR);
61 }
62 
63 /*
64  * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0100
65  * @tc.name   : OpenatReadOnlySuccess_0001
66  * @tc.desc   : openat with O_RDONLY should open a file for reading only.
67  * @tc.size   : MediumTest
68  * @tc.type   : Function
69  * @tc.level  : Level 1
70  */
71 HWTEST_F(OpenatApiTest, OpenatReadOnlySuccess_0001, Function | MediumTest | Level1)
72 {
73     int dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY);
74 
75     int fd = openat(dirFd, TEST_FILE, O_WRONLY | O_CREAT, 0644);
76     EXPECT_TRUE(fd >= 0);
77     close(fd);
78 
79     fd = openat(dirFd, TEST_FILE, O_RDONLY);
80     EXPECT_TRUE(fd >= 0);
81 
82     errno = 0;
83     ssize_t bytesWritten = write(fd, "A", 1);
84     EXPECT_EQ(bytesWritten, -1);
85     EXPECT_EQ(errno, EBADF);
86     close(fd);
87     unlinkat(dirFd, TEST_FILE, 0);
88     close(dirFd);
89 }
90 
91 /*
92  * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0200
93  * @tc.name   : OpenatReadWriteSuccess_0002
94  * @tc.desc   : openat with O_RDWR should open a file for reading and writing.
95  * @tc.size   : MediumTest
96  * @tc.type   : Function
97  * @tc.level  : Level 1
98  */
99 HWTEST_F(OpenatApiTest, OpenatReadWriteSuccess_0002, Function | MediumTest | Level1)
100 {
101     const char *data = "Hello, World!";
102     char readBuf[128];
103     int dirFd = -1;
104     int fd = -1;
105     dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY);
106     EXPECT_TRUE(dirFd >= 0);
107 
108     fd = openat(dirFd, TEST_FILE, O_RDWR | O_CREAT, 0644);
109     EXPECT_TRUE(fd >= 0);
110     write(fd, data, strlen(data));
111     lseek(fd, 0, SEEK_SET);
112     read(fd, readBuf, sizeof(readBuf));
113     EXPECT_STREQ(readBuf, data);
114     close(fd);
115     unlinkat(dirFd, TEST_FILE, 0);
116     close(dirFd);
117 }
118 
119 /*
120  * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0300
121  * @tc.name   : OpenatAppendSuccess_0003
122  * @tc.desc   : openat with O_APPEND should append to the end of the file.
123  * @tc.size   : MediumTest
124  * @tc.type   : Function
125  * @tc.level  : Level 1
126  */
127 HWTEST_F(OpenatApiTest, OpenatAppendSuccess_0003, Function | MediumTest | Level1)
128 {
129     char readBuf[256] = {0};
130     const char *data = "Hello, World!";
131     const char *appendData = " More data";
132     int dirFd = -1;
133     int fd = -1;
134 
135     dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY);
136 
137     fd = openat(dirFd, TEST_FILE, O_WRONLY | O_CREAT, 0644);
138     EXPECT_TRUE(fd >= 0);
139     ssize_t bytesWritten = write(fd, data, strlen(data));
140     EXPECT_EQ(bytesWritten, strlen(data));
141 
142     close(fd);
143 
144     fd = openat(dirFd, TEST_FILE, O_WRONLY | O_APPEND);
145     EXPECT_TRUE(fd >= 0);
146     bytesWritten = write(fd, appendData, strlen(appendData));
147     EXPECT_EQ(bytesWritten, strlen(appendData));
148 
149     close(fd);
150 
151     fd = openat(dirFd, TEST_FILE, O_RDONLY);
152     EXPECT_TRUE(fd >= 0);
153     ssize_t bytesRead = read(fd, readBuf, sizeof(readBuf) - 1);
154     EXPECT_TRUE(bytesRead > 0);
155 
156     readBuf[bytesRead] = '\0';
157     std::string expectedContent(data);
158     expectedContent += appendData;
159     EXPECT_STREQ(readBuf, expectedContent.c_str());
160 
161     close(fd);
162     unlinkat(dirFd, TEST_FILE, 0);
163     close(dirFd);
164 }
165 
166 /*
167  * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0400
168  * @tc.name   : OpenatNoFollowFailed_0004
169  * @tc.desc   : openat with O_NOFOLLOW should fail if the path is a symbolic link.
170  * @tc.size   : MediumTest
171  * @tc.type   : Function
172  * @tc.level  : Level 2
173  */
174 HWTEST_F(OpenatApiTest, OpenatNoFollowFailed_0004, Function | MediumTest | Level2)
175 {
176     int dirFd = -1;
177     int fd = -1;
178     dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY);
179 
180     errno = 0;
181     symlink("target", TEST_FILE);
182     fd = openat(dirFd, TEST_FILE, O_WRONLY | O_CREAT | O_NOFOLLOW);
183     EXPECT_EQ(fd, -1);
184     EXPECT_EQ(errno, ELOOP);
185     close(dirFd);
186 }
187 
188 /*
189  * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0500
190  * @tc.name   : OpenatWriteOnlySuccess_0005
191  * @tc.desc   : openat with O_WRONLY should open a file for writing only.
192  * @tc.size   : MediumTest
193  * @tc.type   : Function
194  * @tc.level  : Level 1
195  */
196 HWTEST_F(OpenatApiTest, OpenatWriteOnlySuccess_0005, Function | MediumTest | Level1)
197 {
198     int dirFd;
199     int fd;
200     char buf;
201     ssize_t bytesRead;
202     ssize_t bytesWritten;
203     const char *data;
204 
205 
206     dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY);
207     fd = openat(dirFd, TEST_FILE, O_WRONLY | O_CREAT, 0644);
208     EXPECT_TRUE(fd >= 0);
209 
210     bytesRead = read(fd, &buf, 1);
211     EXPECT_EQ(bytesRead, -1);
212     EXPECT_EQ(errno, EBADF);
213 
214     data = "Test data";
215     bytesWritten = write(fd, data, strlen(data));
216     EXPECT_TRUE(bytesWritten == strlen(data));
217 
218     close(fd);
219     unlinkat(dirFd, TEST_FILE, 0);
220     close(dirFd);
221 }
222 
223 /*
224  * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0600
225  * @tc.name   : OpenatCreateTest_0006
226  * @tc.desc   : openat with O_CREAT.
227  * @tc.size   : MediumTest
228  * @tc.type   : Function
229  * @tc.level  : Level 2
230  */
231 HWTEST_F(OpenatApiTest, OpenatCreateTest_0006, Function | MediumTest | Level2)
232 {
233     int dirFd = -1;
234     int fd = -1;
235     struct stat buf;
236     dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY);
237 
238     fd = openat(dirFd, TEST_FILE, O_WRONLY, 0644);
239     EXPECT_TRUE(fd == -1);
240     stat(TEST_FILE, &buf);
241     EXPECT_EQ(errno, ENOENT);
242     fd = openat(dirFd, TEST_FILE, O_WRONLY | O_CREAT, 0644);
243     EXPECT_TRUE(fd >= 0);
244     EXPECT_TRUE(stat(TEST_FILE, &buf) == 0);
245 
246     close(fd);
247     unlinkat(dirFd, TEST_FILE, 0);
248     close(dirFd);
249 }
250 
251 /*
252  * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0700
253  * @tc.name   : OpenatDirectoryTest_0007
254  * @tc.desc   : openat with O_DIRECTORY.
255  * @tc.size   : MediumTest
256  * @tc.type   : Function
257  * @tc.level  : Level 2
258  */
259 HWTEST_F(OpenatApiTest, OpenatDirectoryTest_0007, Function | MediumTest | Level2)
260 {
261     int dirFd = -1;
262     int fd = -1;
263     struct stat buf;
264     dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY);
265 
266     fd = open(TEST_FILE, O_WRONLY | O_CREAT, 0644);
267     close(fd);
268     fd = openat(dirFd, TEST_FILE, O_WRONLY | O_DIRECTORY, 0644);
269     EXPECT_TRUE(fd == -1);
270     stat(TEST_FILE, &buf);
271     EXPECT_TRUE(S_ISREG(buf.st_mode));
272     unlinkat(dirFd, TEST_FILE, 0);
273 
274     mkdir(TEST_FILE, 0644);
275     fd = openat(dirFd, TEST_FILE, O_DIRECTORY, 0644);
276     EXPECT_TRUE(fd >= 0);
277     stat(TEST_FILE, &buf);
278     EXPECT_TRUE(S_ISDIR(buf.st_mode));
279 
280     close(fd);
281     rmdir(TEST_FILE);
282     close(dirFd);
283 }
284 
285 /*
286  * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0800
287  * @tc.name   : OpenatExclTest_0008
288  * @tc.desc   : openat with O_EXCL to prevent overwriting the content of existing files.
289  * @tc.size   : MediumTest
290  * @tc.type   : Function
291  * @tc.level  : Level 2
292  */
293 HWTEST_F(OpenatApiTest, OpenatExclTest_0008, Function | MediumTest | Level2)
294 {
295     int dirFd = -1;
296     int fd = -1;
297     dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY);
298 
299     EXPECT_TRUE(access(TEST_FILE, F_OK) == -1);
300     fd = openat(dirFd, TEST_FILE, O_WRONLY | O_CREAT | O_EXCL, 0644);
301     EXPECT_TRUE(fd >= 0);
302     close(fd);
303     EXPECT_TRUE(access(TEST_FILE, F_OK) == 0);
304 
305     fd = openat(dirFd, TEST_FILE, O_WRONLY | O_CREAT | O_EXCL, 0644);
306     EXPECT_TRUE(fd == -1);
307     EXPECT_TRUE(access(TEST_FILE, F_OK) == 0);
308 
309     unlinkat(dirFd, TEST_FILE, 0);
310     close(dirFd);
311 }
312 
313 /*
314  * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_0900
315  * @tc.name   : OpenatNoatimeSuccess_0009
316  * @tc.desc   : openat with O_NOATIME to prevent changing atime but still changing mtime.
317  * @tc.size   : MediumTest
318  * @tc.type   : Function
319  * @tc.level  : Level 1
320  */
321 HWTEST_F(OpenatApiTest, OpenatNoatimeSuccess_0009, Function | MediumTest | Level1)
322 {
323     int dirFd = -1;
324     int fd = -1;
325     struct stat bufFirst;
326     struct stat bufSecond;
327     dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY);
328 
329     fd = openat(dirFd, TEST_FILE, O_WRONLY | O_CREAT, 0644);
330     EXPECT_TRUE(fd >= 0);
331     close(fd);
332     stat(TEST_FILE, &bufFirst);
333 
334     usleep(100);
335     fd = openat(dirFd, TEST_FILE, O_WRONLY | O_NOATIME, 0644);
336     EXPECT_TRUE(fd >= 0);
337     close(fd);
338     stat(TEST_FILE, &bufSecond);
339     EXPECT_TRUE(bufFirst.st_atime == bufSecond.st_atime);
340 
341     unlinkat(dirFd, TEST_FILE, 0);
342     close(dirFd);
343 }
344 
345 /*
346  * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_1000
347  * @tc.name   : OpenatFlagsTestSuccess_0010
348  * @tc.desc   : openat with some flags.
349  * @tc.size   : MediumTest
350  * @tc.type   : Function
351  * @tc.level  : Level 1
352  */
353 HWTEST_F(OpenatApiTest, OpenatFlagsTestSuccess_0010, Function | MediumTest | Level1)
354 {
355     int dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY);
356 
357     // O_TRUNC test
358     int fd = openat(dirFd, TEST_FILE, O_RDWR | O_CREAT, 0644);
359     const char *data = "Test data";
360     write(fd, data, strlen(data));
361     close(fd);
362     fd = openat(dirFd, TEST_FILE, O_RDWR | O_TRUNC, 0644);
363     EXPECT_TRUE(fd >= 0);
364     close(fd);
365     unlinkat(dirFd, TEST_FILE, 0);
366 
367     // O_ASYNC test
368     fd = openat(dirFd, TEST_FILE, O_RDWR | O_CREAT | O_ASYNC, 0644);
369     EXPECT_TRUE(fd >= 0);
370     close(fd);
371     unlinkat(dirFd, TEST_FILE, 0);
372 
373     // O_DIRECT test
374     fd = openat(dirFd, TEST_FILE, O_RDWR | O_CREAT | O_DIRECT, 0644);
375     EXPECT_TRUE(fd >= 0);
376     close(fd);
377     unlinkat(dirFd, TEST_FILE, 0);
378 
379     // O_DSYNC test
380     fd = openat(dirFd, TEST_FILE, O_RDWR | O_CREAT | O_DSYNC, 0644);
381     EXPECT_TRUE(fd >= 0);
382     close(fd);
383     unlinkat(dirFd, TEST_FILE, 0);
384 
385     // O_SYNC test
386     fd = openat(dirFd, TEST_FILE, O_RDWR | O_CREAT | O_SYNC, 0644);
387     EXPECT_TRUE(fd >= 0);
388     close(fd);
389     unlinkat(dirFd, TEST_FILE, 0);
390 
391     close(dirFd);
392 }
393 
394 /*
395  * @tc.number : SUB_KERNEL_SYSCALL_OPENAT_1100
396  * @tc.name   : OpenatFlagsTestSuccess_0011
397  * @tc.desc   : openat O_CLOEXEC/O_LARGEFILE/O_NOCTTY/O_NONBLOCK flags test success.
398  * @tc.size   : MediumTest
399  * @tc.type   : Function
400  * @tc.level  : Level 1
401  */
402 HWTEST_F(OpenatApiTest, OpenatO_CLOEXECFlagSuccess_0011, Function | MediumTest | Level1)
403 {
404     int dirFd = open(TEST_DIR, O_RDONLY | O_DIRECTORY);
405 
406     int fd = openat(dirFd, TEST_FILE, O_RDWR | O_CLOEXEC | O_CREAT, 0755);
407     EXPECT_TRUE(fd >= 0);
408     close(fd);
409     unlinkat(dirFd, TEST_FILE, 0);
410 
411     fd = openat(dirFd, TEST_FILE, O_RDWR | O_LARGEFILE | O_CREAT, 0755);
412     EXPECT_TRUE(fd >= 0);
413     close(fd);
414     unlinkat(dirFd, TEST_FILE, 0);
415 
416     fd = openat(dirFd, TEST_FILE, O_RDWR | O_NOCTTY | O_CREAT, 0755);
417     EXPECT_TRUE(fd >= 0);
418     close(fd);
419     unlinkat(dirFd, TEST_FILE, 0);
420 
421     fd = openat(dirFd, TEST_FILE, O_RDWR | O_NONBLOCK | O_CREAT, 0755);
422     EXPECT_TRUE(fd >= 0);
423     close(fd);
424     unlinkat(dirFd, TEST_FILE, 0);
425 
426     close(dirFd);
427 }