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 <cstdio>
17 #include <cstdlib>
18 #include <fcntl.h>
19 #include <string>
20 #include <unistd.h>
21 #include <vector>
22 #include <gtest/gtest.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 #include <sys/xattr.h>
26 #include "securec.h"
27 
28 using namespace testing::ext;
29 using namespace std;
30 
31 static const char *TEST_DIR = "/data/local/tmp";
32 static const char *OLD_FILE_NAME = "/data/local/tmp/old_file";
33 static const char *NEW_FILE_NAME = "/data/local/tmp/new_link";
34 static const char *INVALID_FILE_NAME = "/data/local/tmp/invalid";
35 
36 class LinkatApiTest : public testing::Test {
37 public:
38     static void SetUpTestCase();
39     static void TearDownTestCase();
40     void SetUp();
41     void TearDown();
42 private:
43 };
SetUp()44 void LinkatApiTest::SetUp()
45 {
46 }
TearDown()47 void LinkatApiTest::TearDown()
48 {
49 }
SetUpTestCase()50 void LinkatApiTest::SetUpTestCase()
51 {
52 }
TearDownTestCase()53 void LinkatApiTest::TearDownTestCase()
54 {
55 }
56 
57 /*
58  * @tc.number : SUB_KERNEL_SYSCALL_LINKAT_0100
59  * @tc.name   : LinkatCreateHardLinkSuccess_0001
60  * @tc.desc   : linkat create hard link success.
61  * @tc.size   : MediumTest
62  * @tc.type   : Function
63  * @tc.level  : Level 1
64  */
HWTEST_F(LinkatApiTest, LinkatCreateHardLinkSuccess_0001, Function | MediumTest | Level1)65 HWTEST_F(LinkatApiTest, LinkatCreateHardLinkSuccess_0001, Function | MediumTest | Level1)
66 {
67     int ret;
68     int dirFd;
69     dirFd = open(TEST_DIR, O_DIRECTORY);
70     EXPECT_GE(dirFd, 0);
71     int fd = open(OLD_FILE_NAME, O_CREAT | O_RDWR, 0644);
72     close(fd);
73 
74     ret = linkat(dirFd, OLD_FILE_NAME, dirFd, NEW_FILE_NAME, 0);
75     EXPECT_GE(ret, 0);
76 
77     close(dirFd);
78     unlink(NEW_FILE_NAME);
79     unlink(OLD_FILE_NAME);
80 }
81 
82 /*
83  * @tc.number : SUB_KERNEL_SYSCALL_LINKAT_0200
84  * @tc.name   : LinkatInvalidFlagFailed_0002
85  * @tc.desc   : linkat invalid flag failed errno EINVAL.
86  * @tc.size   : MediumTest
87  * @tc.type   : Function
88  * @tc.level  : Level 2
89  */
HWTEST_F(LinkatApiTest, LinkatInvalidFdFailed_0002, Function | MediumTest | Level2)90 HWTEST_F(LinkatApiTest, LinkatInvalidFdFailed_0002, Function | MediumTest | Level2)
91 {
92     int ret;
93     int fd = open(OLD_FILE_NAME, O_CREAT | O_RDWR, 0644);
94     close(fd);
95 
96     errno = 0;
97     ret = linkat(0, OLD_FILE_NAME, 0, NEW_FILE_NAME, -1);
98     EXPECT_EQ(ret, -1);
99     EXPECT_EQ(errno, EINVAL);
100 
101     unlink(NEW_FILE_NAME);
102     unlink(OLD_FILE_NAME);
103 }
104 
105 /*
106  * @tc.number : SUB_KERNEL_SYSCALL_LINKAT_0300
107  * @tc.name   : LinkatInvalidPathFailed_0003
108  * @tc.desc   : linkat invalid path failed errno ENOENT.
109  * @tc.size   : MediumTest
110  * @tc.type   : Function
111  * @tc.level  : Level 2
112  */
HWTEST_F(LinkatApiTest, LinkatInvalidPathFailed_0003, Function | MediumTest | Level2)113 HWTEST_F(LinkatApiTest, LinkatInvalidPathFailed_0003, Function | MediumTest | Level2)
114 {
115     int ret;
116     int dirFd;
117     dirFd = open(TEST_DIR, O_DIRECTORY);
118     EXPECT_GE(dirFd, 0);
119     int fd = open(OLD_FILE_NAME, O_CREAT | O_RDWR, 0644);
120     close(fd);
121 
122     ret = linkat(dirFd, INVALID_FILE_NAME, dirFd, NEW_FILE_NAME, 0);
123     EXPECT_EQ(ret, -1);
124     EXPECT_EQ(errno, ENOENT);
125 
126     close(dirFd);
127     unlink(NEW_FILE_NAME);
128     unlink(OLD_FILE_NAME);
129 }
130 
131 /*
132  * @tc.number : SUB_KERNEL_SYSCALL_LINKAT_0400
133  * @tc.name   : LinkatAT_SYMLINK_FOLLOWFlagSuccess_0004
134  * @tc.desc   : linkat AT_SYMLINK_FOLLOW flag test success.
135  * @tc.size   : MediumTest
136  * @tc.type   : Function
137  * @tc.level  : Level 1
138  */
HWTEST_F(LinkatApiTest, LinkatAT_SYMLINK_FOLLOWFlagSuccess_0004, Function | MediumTest | Level1)139 HWTEST_F(LinkatApiTest, LinkatAT_SYMLINK_FOLLOWFlagSuccess_0004, Function | MediumTest | Level1)
140 {
141     int ret;
142     int dirFd;
143     dirFd = open(TEST_DIR, O_DIRECTORY);
144     EXPECT_GE(dirFd, 0);
145     int fd = open(OLD_FILE_NAME, O_CREAT | O_RDWR, 0644);
146     close(fd);
147 
148     ret = linkat(dirFd, OLD_FILE_NAME, dirFd, NEW_FILE_NAME, AT_SYMLINK_FOLLOW);
149     EXPECT_GE(ret, 0);
150 
151     close(dirFd);
152     unlink(NEW_FILE_NAME);
153     unlink(OLD_FILE_NAME);
154 }