1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
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 <malloc.h>
17 #include <sched.h>
18 #include <signal.h>
19 #include <unistd.h>
20 #include <pthread.h>
21 #include <stdlib.h>
22 #include <sys/wait.h>
23 #include "functionalext.h"
24 
25 /**
26  * @tc.name      : getprocpid_0100
27  * @tc.desc      : Get the pid by parsing the proc information
28  * @tc.level     : Level 0
29  */
getprocpid_0100(void)30 void getprocpid_0100(void)
31 {
32     pid_t pid1 = getprocpid();
33     EXPECT_EQ("getprocpid_0100", pid1 > 1, true);
34     pid_t pid2 = getprocpid();
35     EXPECT_EQ("getprocpid_0100", pid1, pid2);
36     EXPECT_EQ("getprocpid_0100", pid1, getpid());
37 }
38 
39 /**
40  * @tc.name      : getprocpid_0200
41  * @tc.desc      : Get the pid by parsing the proc information
42  * @tc.level     : Level 0
43  */
getprocpid_0200(void)44 void getprocpid_0200(void)
45 {
46     pid_t pid1 = getprocpid();
47     EXPECT_EQ("getprocpid_0200", pid1, getpid());
48 
49     pid_t child = fork();
50     if (child == 0) {
51         pid_t pid2 = getprocpid();
52         if (pid2 != getpid()) {
53             exit(1);
54         }
55         exit(0);
56     }
57     EXPECT_EQ("getprocpid_0200", child > 0, true);
58 
59     int status = 0;
60     int ret = waitpid(child, &status, 0);
61     EXPECT_EQ("getprocpid_0200", ret, child);
62     EXPECT_EQ("getprocpid_0200", WIFEXITED(status), true);
63 }
64 
child_func(void *arg)65 static int child_func(void *arg)
66 {
67     pid_t parent = *(pid_t *)arg;
68     if (getpid() != 1) {
69         return ESRCH;
70     }
71 
72     pid_t pid = getprocpid();
73     if (pid == parent) {
74         return ENOSYS;
75     }
76     return 0;
77 }
78 
79 /**
80  * @tc.name      : getprocpid_0300
81  * @tc.desc      : Get the pid by parsing the proc information
82  * @tc.level     : Level 0
83  */
getprocpid_0300(void)84 void getprocpid_0300(void)
85 {
86     pid_t pid1 = getprocpid();
87     EXPECT_EQ("getprocpid_0300", pid1, getpid());
88 
89     pid_t child = clone(child_func, NULL, CLONE_NEWPID | SIGCHLD, &pid1);
90     EXPECT_EQ("getprocpid_0300", child > 0, true);
91 
92     int status = 0;
93     int ret = waitpid(child, &status, 0);
94     EXPECT_EQ("getprocpid_0300", ret, child);
95     EXPECT_EQ("getprocpid_0300", WIFEXITED(status), true);
96 }
97 
pthread_func(void *arg)98 static void *pthread_func(void *arg)
99 {
100     pid_t parent = *(pid_t *)arg;
101     pid_t pid1 = getproctid();
102     if (parent == pid1) {
103         return (void *)ESRCH;
104     }
105     pid_t pid2 = gettid();
106     if (pid1 != pid2) {
107         return (void *)ENOSYS;
108     }
109     return NULL;
110 }
111 
112 /**
113  * @tc.name      : getproctid_0100
114  * @tc.desc      : Get the tid by parsing the proc information
115  * @tc.level     : Level 0
116  */
getproctid_0100(void)117 void getproctid_0100(void)
118 {
119     pid_t pid1 = getproctid();
120     EXPECT_EQ("getproctid_0100", pid1 > 1, true);
121     EXPECT_EQ("getproctid_0100", pid1, gettid());
122 
123     void *retVal = NULL;
124     pthread_t thread;
125     int ret = pthread_create(&thread, NULL, pthread_func, &pid1);
126     EXPECT_EQ("getproctid_0100", ret, 0);
127 
128     ret = pthread_join(thread, &retVal);
129     EXPECT_EQ("getproctid_0100", ret, 0);
130     EXPECT_EQ("getproctid_0100", retVal, NULL);
131 }
132 
133 /**
134  * @tc.name      : getproctid_0200
135  * @tc.desc      : Get the tid by parsing the proc information
136  * @tc.level     : Level 0
137  */
getproctid_0200(void)138 void getproctid_0200(void)
139 {
140     pid_t pid1 = getproctid();
141     EXPECT_EQ("getproctid_0200", pid1, gettid());
142 
143     pid_t child = fork();
144     if (child == 0) {
145         pid_t pid2 = getproctid();
146         if (pid2 != gettid()) {
147             exit(1);
148         }
149         exit(0);
150     }
151 
152     EXPECT_EQ("getproctid_0200", child > 0, true);
153 
154     int status = 0;
155     int ret = waitpid(child, &status, 0);
156     EXPECT_EQ("getproctid_0200", ret, child);
157     EXPECT_EQ("getproctid_0200", WIFEXITED(status), true);
158 }
159 
child_func_tid(void *arg)160 static int child_func_tid(void *arg)
161 {
162     pid_t parent = *(pid_t *)arg;
163     if (getpid() != 1) {
164         return ESRCH;
165     }
166 
167     pid_t pid = getproctid();
168     if (pid == parent) {
169         return ENOSYS;
170     }
171     return 0;
172 }
173 
174 /**
175  * @tc.name      : getproctid_0300
176  * @tc.desc      : Get the tid by parsing the proc information
177  * @tc.level     : Level 0
178  */
getproctid_0300(void)179 void getproctid_0300(void)
180 {
181     pid_t pid1 = getproctid();
182     EXPECT_EQ("getproctid_0300", pid1, gettid());
183 
184     pid_t child = clone(child_func_tid, NULL, CLONE_NEWPID | SIGCHLD, &pid1);
185     EXPECT_EQ("getproctid_0300", child > 0, true);
186 
187     int status = 0;
188     int ret = waitpid(child, &status, 0);
189     EXPECT_EQ("getproctid_0300", ret, child);
190     EXPECT_EQ("getproctid_0300", WIFEXITED(status), true);
191 }
192 
main(int argc, char *argv[])193 int main(int argc, char *argv[])
194 {
195     getprocpid_0100();
196     getprocpid_0200();
197     getprocpid_0300();
198     getproctid_0100();
199     getproctid_0200();
200     getproctid_0300();
201     return t_status;
202 }
203