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 <unistd.h>
20#include <gtest/gtest.h>
21#include <sys/mman.h>
22#include "securec.h"
23
24using namespace testing::ext;
25using namespace std;
26
27static const char *FILE_NAME = "shmem_file";
28static const char *NEW_FILE_NAME = "new_shmem_file";
29
30class Dup3ApiTest : public testing::Test {
31public:
32    static void SetUpTestCase();
33    static void TearDownTestCase();
34    void SetUp();
35    void TearDown();
36private:
37};
38void Dup3ApiTest::SetUp()
39{
40}
41void Dup3ApiTest::TearDown()
42{
43}
44void Dup3ApiTest::SetUpTestCase()
45{
46}
47void Dup3ApiTest::TearDownTestCase()
48{
49}
50
51/*
52 * @tc.number : SUB_KERNEL_SYSCALL_DUP3_0100
53 * @tc.name   : Dup3FileFdSuccess_0001
54 * @tc.desc   : dup3 file fd success.
55 * @tc.size   : MediumTest
56 * @tc.type   : Function
57 * @tc.level  : Level 1
58 */
59HWTEST_F(Dup3ApiTest, Dup3FileFdSuccess_0001, Function | MediumTest | Level1)
60{
61    int fd = -1;
62    int newFd = -1;
63    int oldFd = -1;
64    oldFd = memfd_create(FILE_NAME, 0);
65    newFd = memfd_create(NEW_FILE_NAME, 0);
66    EXPECT_NE(oldFd, -1);
67    EXPECT_NE(newFd, -1);
68
69    fd = dup3(oldFd, newFd, 0);
70    EXPECT_TRUE(fd >= 0);
71    EXPECT_EQ(fd, newFd);
72    EXPECT_NE(newFd, oldFd);
73    EXPECT_TRUE(oldFd >= 0);
74
75    close(fd);
76    close(oldFd);
77    close(newFd);
78}
79
80/*
81 * @tc.number : SUB_KERNEL_SYSCALL_DUP3_0200
82 * @tc.name   : Dup3SetFlagSuccess_0002
83 * @tc.desc   : dup3 force set the close-on-exec flag to the new fd success.
84 * @tc.size   : MediumTest
85 * @tc.type   : Function
86 * @tc.level  : Level 1
87 */
88HWTEST_F(Dup3ApiTest, Dup3SetFlagSuccess_0002, Function | MediumTest | Level1)
89{
90    int ret;
91    int fd = -1;
92    int newFd = -1;
93    int oldFd = -1;
94    oldFd = memfd_create(FILE_NAME, 0);
95    newFd = memfd_create(NEW_FILE_NAME, 0);
96    EXPECT_NE(oldFd, -1);
97    EXPECT_NE(newFd, -1);
98
99    fd = dup3(oldFd, newFd, O_CLOEXEC);
100    EXPECT_TRUE(fd >= 0);
101    EXPECT_EQ(fd, newFd);
102    EXPECT_NE(newFd, oldFd);
103
104    ret = fcntl(fd, F_GETFD);
105    EXPECT_EQ(ret & FD_CLOEXEC, FD_CLOEXEC);
106
107    close(fd);
108    close(oldFd);
109    close(newFd);
110}
111
112/*
113 * @tc.number : SUB_KERNEL_SYSCALL_DUP3_0300
114 * @tc.name   : Dup3FileInvalidFdFailed_0003
115 * @tc.desc   : dup3 file invalid fd failed.
116 * @tc.size   : MediumTest
117 * @tc.type   : Function
118 * @tc.level  : Level 2
119 */
120HWTEST_F(Dup3ApiTest, Dup3FileInvalidFdFailed_0003, Function | MediumTest | Level2)
121{
122    int fd = -1;
123    int oldFd = -1;
124    oldFd = memfd_create(FILE_NAME, 0);
125    EXPECT_NE(oldFd, -1);
126
127    fd = dup3(oldFd, 2, 0);
128    EXPECT_EQ(fd, 2);
129    errno = 0;
130    fd = dup3(oldFd, -3, 0);
131    EXPECT_EQ(fd, -1);
132    EXPECT_EQ(errno, EBADF);
133
134    close(fd);
135    close(oldFd);
136}
137
138/*
139 * @tc.number : SUB_KERNEL_SYSCALL_DUP3_0400
140 * @tc.name   : Dup3FileEqualFdFailed_0004
141 * @tc.desc   : dup3 file equal oldfd and newfd failed.
142 * @tc.size   : MediumTest
143 * @tc.type   : Function
144 * @tc.level  : Level 2
145 */
146HWTEST_F(Dup3ApiTest, Dup3FileEqualFdFailed_0004, Function | MediumTest | Level2)
147{
148    int fd = -1;
149
150    errno = 0;
151    fd = dup3(2, 2, 0);
152    EXPECT_EQ(fd, -1);
153    EXPECT_EQ(errno, EINVAL);
154
155    close(fd);
156}
157