1 /*
2 * Copyright (c) 2021 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 "SignalTest.h"
17 #include <unistd.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <fcntl.h>
21 #include <sys/shm.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include "log.h"
25 #include "utils.h"
26 #include "KernelConstants.h"
27
28 using namespace testing::ext;
29
30 /**
31 * @tc.number SUB_KERNEL_IPC_SIG_ALL_0100
32 * @tc.name test the default action when receive a signal
33 default action: http://man7.org/linux/man-pages/man7/signal.7.html
34 * @tc.desc [C- SOFTWARE -0200]
35 */
HWTEST_P(IpcSignalTest, testAllSigDefaultAction, Function | MediumTest | Level1)36 HWTEST_P(IpcSignalTest, testAllSigDefaultAction, Function | MediumTest | Level1)
37 {
38 int index = GetParam();
39 SignalAction a = ALL_SIGNALS[index].action;
40 bool expectStop, coredump;
41 if (a == STOP) { // SIGSTOP should has no effect in liteos
42 expectStop = false;
43 coredump = false;
44 } else if (a == COREDUMP) {
45 expectStop = true;
46 coredump = true;
47 } else if (a == TERMINATE) {
48 expectStop = true;
49 coredump = false;
50 } else {
51 // CONTINUE's default action is ignore, if the process is not Stopped
52 expectStop = false;
53 coredump = false;
54 }
55 LOG("all supported signal DefaultActionTest test %d: %s, expectStop=%d",
56 index, ALL_SIGNALS[index].signame, expectStop);
57 DefaultActionTest(index, expectStop, coredump);
58 Msleep(100); // don't test too fast
59 }
60
61 /**
62 * @tc.number SUB_KERNEL_IPC_SIG_ALL_0200
63 * @tc.name test all supported signal's send and receive. SIGKILL, SIGSTOP SIGCONT is special, not tested here
64 * @tc.desc [C- SOFTWARE -0200]
65 */
HWTEST_P(IpcSignalTest, testAllSigSendAndRecv, Function | MediumTest | Level1)66 HWTEST_P(IpcSignalTest, testAllSigSendAndRecv, Function | MediumTest | Level1)
67 {
68 int index = GetParam();
69 // SIGKILL/SIGSTOP cannot be caught, blocked, or ignored, can not test here
70 if (index==SIGKILL || index==SIGSTOP || index==SIGCONT) {
71 return;
72 }
73 LOG("all supported signal SendAndRecv test %d: %s", index, ALL_SIGNALS[index].signame);
74 SendAndRecvTest(index);
75 Msleep(100); // don't test too fast
76 }
77
78 /**
79 * @tc.number SUB_KERNEL_IPC_SIG_ALL_0250
80 * @tc.name test all signal's description string
81 * @tc.desc [C- SOFTWARE -0200]
82 */
HWTEST_P(IpcSignalTest, testAllSigDescription, Function | MediumTest | Level3)83 HWTEST_P(IpcSignalTest, testAllSigDescription, Function | MediumTest | Level3)
84 {
85 int signo = GetParam();
86 const char* descipt = ALL_SIGNALS[signo].description;
87 LOG("all supported signal's description string test: %d(%s)", signo, ALL_SIGNALS[signo].signame);
88
89 // we use child to do the test here, cause 'restore of stderr' is not work by now.
90 pid_t pid = fork();
91 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
92 if (pid == 0) { // child
93 // redirect stderr to a file, so we can check the content.
94 char* outfile = WRITABLE_TEST_DIR "stderr.txt";
95 if (freopen(outfile, "w", stderr) == NULL) {
96 LOG("redirect stderr fail, freopen errno=%d\n", errno);
97 exit(1);
98 }
99 psignal(signo, nullptr);
100 int rt = CheckSigString(outfile, descipt);
101 exit(rt);
102 } else { // parent
103 WaitProcExitedOK(pid);
104 }
105 Msleep(100); // don't test too fast
106 }
107 INSTANTIATE_TEST_CASE_P(AllSignalTest, IpcSignalTest, testing::Range(1, MAX_SIGNAL));
108
109 /**
110 * @tc.number SUB_KERNEL_IPC_SIG_ALL_0300
111 * @tc.name test SIGKILL can't blocked. SIGSTOP can't be blocked too, but not supported by liteos
112 * @tc.desc [C- SOFTWARE -0200]
113 */
HWTEST_F(IpcSignalTest, testBlockSIGKILL, Function | MediumTest | Level2)114 HWTEST_F(IpcSignalTest, testBlockSIGKILL, Function | MediumTest | Level2)
115 {
116 pid_t pid = fork();
117 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
118 if (pid > 0) { // parent
119 LOG("parent in");
120 Msleep(50);
121 LOGD("parent: before kill");
122 kill(pid, SIGKILL);
123 Msleep(150); // wait to exit
124 WaitProcKilled(pid, SIGKILL);
125 } else { // child
126 LOG("child in");
127 sigset_t set;
128 sigemptyset(&set);
129 sigaddset(&set, SIGKILL);
130 int rt = sigprocmask(SIG_BLOCK, &set, nullptr);
131 LOG("sigprocmask rt = %d", rt);
132 KeepRun(100);
133 LOG("child exit 0");
134 exit(0);
135 }
136 }
137
138 /**
139 * @tc.number SUB_KERNEL_IPC_SIG_ALL_0400
140 * @tc.name test SIGKILL can't suspended.
141 * @tc.desc [C- SOFTWARE -0200]
142 */
HWTEST_F(IpcSignalTest, testSuspendSIGKILL, Function | MediumTest | Level3)143 HWTEST_F(IpcSignalTest, testSuspendSIGKILL, Function | MediumTest | Level3)
144 {
145 pid_t pid = fork();
146 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
147 if (pid > 0) { // parent
148 Msleep(20);
149 kill(pid, SIGKILL);
150 Msleep(150); // wait to exit
151 WaitProcKilled(pid, SIGKILL);
152 } else { // child
153 sigset_t set;
154 sigemptyset(&set);
155 sigaddset(&set, SIGKILL);
156 LOG("before sigsuspend");
157 int rt = sigsuspend(&set);
158 LOG("sigsuspend rt = %d", rt);
159 KeepRun(100);
160 exit(0);
161 }
162 }
163
164 /**
165 * @tc.number SUB_KERNEL_IPC_SIGNAL_0100
166 * @tc.name test SIGKILL and SIGSTOP's action can not changed by signal
167 * @tc.desc [C- SOFTWARE -0200]
168 */
HWTEST_F(IpcSignalTest, testSignalFailSig, Function | MediumTest | Level2)169 HWTEST_F(IpcSignalTest, testSignalFailSig, Function | MediumTest | Level2)
170 {
171 SignalFailTest(SIGKILL, SignalHandler);
172 SignalFailTest(SIGKILL, SIG_IGN);
173 SignalFailTest(SIGSTOP, SignalHandler);
174 SignalFailTest(SIGSTOP, SIG_IGN);
175 SignalFailTest(31, SignalHandler);
176 SignalFailTest(32, SignalHandler);
177 SignalFailTest(33, SignalHandler);
178 }
179
180 /**
181 * @tc.number SUB_KERNEL_IPC_SIGNAL_0200
182 * @tc.name test SIG_IGN and SIG_DFL
183 * @tc.desc [C- SOFTWARE -0200]
184 */
HWTEST_F(IpcSignalTest, testSignal_DFL_IGN, Function | MediumTest | Level2)185 HWTEST_F(IpcSignalTest, testSignal_DFL_IGN, Function | MediumTest | Level2)
186 {
187 pid_t pid = fork();
188 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
189 if (pid == 0) { // child
190 int exitCode = 0;
191 LOG("change handler to SIG_IGN");
192 signal(SIGURG, SIG_IGN);
193 Msleep(40);
194 if (mReceivedSignal != 0) {
195 LOG("Received signal check fail, expected 0, but get %d", mReceivedSignal);
196 exitCode = 1;
197 }
198
199 LOG("change handler to SignalHandler");
200 signal(SIGURG, SignalHandler);
201 mReceivedSignal = 0;
202 Msleep(50);
203 if (mReceivedSignal != SIGURG) {
204 LOG("Received signal check fail, expected %d, but get %d", SIGURG, mReceivedSignal);
205 exitCode = 1;
206 }
207
208 LOG("change handler to SIG_DFL");
209 signal(SIGURG, SIG_DFL);
210 mReceivedSignal = 0;
211 Msleep(50);
212 if (mReceivedSignal != 0) {
213 LOG("Received signal check fail, expected 0, but get %d", mReceivedSignal);
214 exitCode = 1;
215 }
216 exit(exitCode);
217 } else { // parent
218 Msleep(20);
219 LOG("------ Send SIGURG 1");
220 kill(pid, SIGURG);
221 Msleep(50);
222 LOG("------ Send SIGURG 2");
223 kill(pid, SIGURG);
224 Msleep(50);
225 LOG("------ Send SIGURG 3");
226 kill(pid, SIGURG);
227 Msleep(50);
228 WaitProcExitedOK(pid);
229 }
230 }
231
232 /**
233 * @tc.number SUB_KERNEL_IPC_SIG_RAISE_0100
234 * @tc.name raise basic function test
235 * @tc.desc [C- SOFTWARE -0200]
236 */
HWTEST_F(IpcSignalTest, testRaiseBasic, Function | MediumTest | Level1)237 HWTEST_F(IpcSignalTest, testRaiseBasic, Function | MediumTest | Level1)
238 {
239 pid_t pid = fork();
240 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
241 if (pid == 0) { // child
242 int exitCode = 0;
243 signal(SIGQUIT, SignalHandler);
244 raise(SIGQUIT);
245 if (mReceivedSignal != SIGQUIT) {
246 LOG("Received signal check fail, expected signal=%d", SIGQUIT);
247 exitCode = 1;
248 }
249 exit(exitCode);
250 } else { // parent
251 Msleep(30);
252 WaitProcExitedOK(pid);
253 }
254 }
255
256 /**
257 * @tc.number SUB_KERNEL_IPC_SIG_ABORT_0100
258 * @tc.name abort function test: SIGABRT handler
259 * @tc.desc [C- SOFTWARE -0200]
260 */
HWTEST_F(IpcSignalTest, testAbortHandler, Function | MediumTest | Level1)261 HWTEST_F(IpcSignalTest, testAbortHandler, Function | MediumTest | Level1)
262 {
263 const int memSize = 32;
264 mShmid = shmget(IPC_PRIVATE, memSize, 0666 | IPC_CREAT);
265 if (mShmid == -1){
266 LOG("shmget errno = %d\n", errno);
267 ADD_FAILURE();
268 }
269
270 pid_t pid = fork();
271 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
272 if (pid == 0) { // child
273 Msleep(30);
274 signal(SIGABRT, SigAbortHandler);
275 // try BLOCK SIGABRT
276 sigset_t set;
277 sigemptyset(&set);
278 sigaddset(&set, SIGABRT);
279 sigprocmask(SIG_BLOCK, &set, nullptr);
280
281 LOG("before abort");
282 abort();
283 // should never get here
284 LOG("after abort");
285 exit(1);
286 } else { // parent
287 Msleep(50);
288 WaitProcKilled(pid, SIGABRT);
289
290 int *shared = static_cast<int*>(shmat(mShmid, NULL, 0));
291 if (shared == reinterpret_cast<int*>(-1)) {
292 LOG("shmat fail, errno = %d", errno);
293 ADD_FAILURE();
294 } else if (*shared != SIGABRT) {
295 LOG("Received signal check fail, expected signal=%d", SIGABRT);
296 ADD_FAILURE();
297 }
298 shmdt(shared);
299 shmctl(mShmid, IPC_RMID, nullptr);
300 }
301 }
302
303 /**
304 * @tc.number SUB_KERNEL_IPC_SIGACTION_0100
305 * @tc.name sigaction function test: read siginfo
306 * @tc.desc [C- SOFTWARE -0200]
307 */
HWTEST_F(IpcSignalTest, testSigactionSiginfo, Function | MediumTest | Level1)308 HWTEST_F(IpcSignalTest, testSigactionSiginfo, Function | MediumTest | Level1)
309 {
310 pid_t pid = fork();
311 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
312 if (pid == 0) { // child
313 int exitCode = 0;
314 struct sigaction act = {0};
315 act.sa_sigaction = SigactionHandler;
316 sigemptyset(&act.sa_mask);
317 act.sa_flags = SA_SIGINFO;
318 int rt = sigaction(SIGALRM, &act, nullptr);
319 if (rt != 0) {
320 LOG("sigaction return fail, rt=%d", rt);
321 exit(1);
322 }
323 alarm(1);
324 Msleep(1100);
325
326 if (mReceivedSignal != SIGALRM) {
327 LOG("SigactionHandler check fail, expected signal:%d, actual:%d", SIGALRM, mReceivedSignal);
328 exit(1);
329 }
330 // other area of siginfo_t is not supported yet, test code deleted
331 LOG("child exited with code=%d", exitCode);
332 exit(exitCode);
333 } else { // parent
334 Msleep(1200);
335 WaitProcExitedOK(pid);
336 }
337 }
338
339 /**
340 * @tc.number SUB_KERNEL_IPC_SIGWAIT_0100
341 * @tc.name sigwait basic function test
342 * @tc.desc [C- SOFTWARE -0200]
343 */
HWTEST_F(IpcSignalTest, testSigwaitBasic, Function | MediumTest | Level1)344 HWTEST_F(IpcSignalTest, testSigwaitBasic, Function | MediumTest | Level1)
345 {
346 pid_t pid = fork();
347 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
348 if (pid == 0) { // child
349 int rt = 0;
350 int exitCode = 0;
351 sigset_t set;
352 int sig;
353 sigemptyset(&set);
354 sigaddset(&set, SIGALRM);
355 sigaddset(&set, SIGTERM);
356 signal(SIGTERM, SignalHandler);
357 signal(SIGALRM, SignalHandler);
358
359 rt = sigwait(&set, &sig);
360 LOG("sigwait1 returned: %d, signo=%d, mReceivedSignal1: %d", rt, sig, mReceivedSignal);
361 if (mReceivedSignal != SIGALRM || sig != SIGALRM) {
362 LOG("Received signal check fail, expected signal=%d", SIGALRM);
363 exitCode = 1;
364 }
365
366 rt = sigwait(&set, &sig);
367 LOG("sigwait2 returned: %d, signo=%d, mReceivedSignal1: %d", rt, sig, mReceivedSignal);
368 if (mReceivedSignal != SIGTERM || sig != SIGTERM) {
369 LOG("Received signal check fail, expected signal=%d", SIGALRM);
370 exitCode = 1;
371 }
372
373 rt = sigwait(&set, &sig);
374 LOG("sigwait3 returned: %d, signo=%d, mReceivedSignal3: %d", rt, sig, mReceivedSignal);
375 if (mReceivedSignal != SIGALRM || sig != SIGALRM) {
376 LOG("Received signal check fail, expected signal=%d", SIGALRM);
377 exitCode = 1;
378 }
379
380 LOG("child exited with code=%d", exitCode);
381 exit(exitCode);
382 } else { // parent
383 Msleep(30);
384 LOG("calling kill 1, signo=%d", SIGALRM);
385 kill(pid, SIGALRM);
386 Msleep(50);
387 LOG("calling kill 2, signo=%d", SIGTERM);
388 kill(pid, SIGTERM);
389 Msleep(50);
390 LOG("calling kill 3, signo=%d", SIGALRM);
391 kill(pid, SIGALRM);
392 Msleep(100);
393 AssertProcExitedOK(pid);
394 }
395 }
396 /**
397 * @tc.number SUB_KERNEL_IPC_SIGWAIT_0200
398 * @tc.name test that 'sigwait' should not return if a not-in-set signal is received
399 * @tc.desc [C- SOFTWARE -0200]
400 */
HWTEST_F(IpcSignalTest, testSigwaitNotInSet, Function | MediumTest | Level2)401 HWTEST_F(IpcSignalTest, testSigwaitNotInSet, Function | MediumTest | Level2)
402 {
403 pid_t pid = fork();
404 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
405 if (pid == 0) { // child
406 int rt = 0;
407 int exitCode = 0;
408 sigset_t set;
409 int sig;
410 sigemptyset(&set);
411 sigaddset(&set, SIGTERM);
412 signal(SIGTERM, SignalHandler);
413 signal(SIGALRM, SignalHandler);
414
415 rt = sigwait(&set, &sig);
416 LOG("sigwait1 returned: %d, signo=%d, mReceivedSignal1: %d", rt, sig, mReceivedSignal);
417 LOG("child exiting with code=%d", exitCode);
418 exit(exitCode);
419 } else { // parent
420 LOG("parent pid is %d, child pid is %d", getpid(), pid);
421 Msleep(30);
422 LOG("calling kill 1, signo=%d", SIGALRM);
423 kill(pid, SIGALRM);
424 Msleep(50);
425 AssertProcAlive(pid);
426
427 LOG("calling kill 2, signo=%d", SIGKILL);
428 kill(pid, SIGKILL);
429 Msleep(100);
430 AssertProcKilled(pid, SIGKILL);
431 }
432 }
433
434 /**
435 * @tc.number SUB_KERNEL_IPC_SIGTIMEDWAIT_0100
436 * @tc.name sigtimedwait still work even blocked by sigprocmask
437 * @tc.desc [C- SOFTWARE -0200]
438 */
HWTEST_F(IpcSignalTest, testSigtimedwaitBlock, Function | MediumTest | Level1)439 HWTEST_F(IpcSignalTest, testSigtimedwaitBlock, Function | MediumTest | Level1)
440 {
441 pid_t pid = fork();
442 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
443 if (pid == 0) { // child
444 int exitCode = 0;
445 signal(SIGSEGV, SignalHandler);
446 struct timespec time1 = {0, 100*1000000};
447 sigset_t sigmask, timeset;
448 sigemptyset(&sigmask);
449 sigaddset(&sigmask, SIGINT);
450 sigaddset(&sigmask, SIGSEGV);
451 sigemptyset(×et);
452 sigaddset(×et, SIGSEGV);
453
454 sigprocmask(SIG_BLOCK, &sigmask, nullptr);
455 Msleep(80);
456
457 int rt = sigtimedwait(×et, nullptr, &time1);
458 if (rt != SIGSEGV) {
459 LOG("sigtimedwait return fail, expected:%d, actual:%d", SIGSEGV, rt);
460 exitCode = 1;
461 }
462
463 // check the sigprocmask set not changed
464 sigemptyset(&sigmask);
465 sigprocmask(SIG_UNBLOCK, nullptr, &sigmask);
466 if (sigismember(&sigmask, SIGINT) != 1) {
467 LOG("SIGINT should still in block set!");
468 exitCode = 1;
469 }
470 if (sigismember(&sigmask, SIGSEGV) != 1) {
471 LOG("SIGSEGV should still in block set!");
472 exitCode = 1;
473 }
474 exit(exitCode);
475 } else { // parent
476 Msleep(40);
477 kill(pid, SIGSEGV);
478 Msleep(200);
479 WaitProcExitedOK(pid);
480 }
481 sigset_t pending;
482 sigemptyset(&pending);
483 sigpending(&pending);
484 if (sigisemptyset(&pending)) {
485 LOG("pending set empty");
486 return;
487 }
488 LOG("========pending set not empty=========");
489 if (sigismember(&pending, SIGCHLD)) {
490 LOG("pending set is SIGCHLD");
491 return;
492 } else {
493 LOG("pending set is not SIGCHLD!");
494 }
495 }
496
497 /**
498 * @tc.number SUB_KERNEL_IPC_SIGTIMEDWAIT_0200
499 * @tc.name sigtimedwait error test: timeout or interrupted.
500 * by now, liteos sigtimedwait cannot interrupted
501 * so the interrupted-check-code will run only when 'POSIX_TEST' is set
502 * @tc.desc [C- SOFTWARE -0200]
503 */
HWTEST_F(IpcSignalTest, testSigtimedwaitTimeout, Function | MediumTest | Level2)504 HWTEST_F(IpcSignalTest, testSigtimedwaitTimeout, Function | MediumTest | Level2)
505 {
506 pid_t pid = fork();
507 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
508 if (pid == 0) { // child
509 int rt;
510 int exitCode = 0;
511 sigset_t set;
512 siginfo_t si;
513 struct timespec ts = {0, 500*1000000};
514 sigemptyset(&set);
515 sigaddset(&set, SIGUSR1);
516
517 struct timespec time1 = {0, 0};
518 struct timespec time2 = {0, 0};
519 errno = 0;
520 clock_gettime(CLOCK_MONOTONIC, &time1);
521 rt = sigtimedwait(&set, &si, &ts);
522 clock_gettime(CLOCK_MONOTONIC, &time2);
523 LOG("sigtimedwait returned: %d", rt);
524 if (rt != -1 || errno != EAGAIN) {
525 LOG("sigtimedwait error check fail, expected errno=%d(EAGAIN), actual=%d", EAGAIN, errno);
526 exitCode = 1;
527 }
528 double duration = (time2.tv_sec - time1.tv_sec)*1000.0 + (time2.tv_nsec - time1.tv_nsec)/1000000.0;
529 LOG("clock_gettime1 : tv_sec=%ld, tv_nsec=%ld", time1.tv_sec, time1.tv_nsec);
530 LOG("clock_gettime2 : tv_sec=%ld, tv_nsec=%ld", time2.tv_sec, time2.tv_nsec);
531 LOG("duration : %f ms", duration);
532 if (CheckValueClose(1000, duration)) {
533 LOG("Timeout value accuracy check fail, expected=1000, actual=%f", duration);
534 exitCode = 1;
535 }
536
537 LOG("child exited with code=%d", exitCode);
538 exit(exitCode);
539 } else { // parent
540 sleep(1);
541 WaitProcExitedOK(pid);
542 }
543 }
544
545
546 /**
547 * @tc.number SUB_KERNEL_IPC_SIGTIMEDWAIT_0300
548 * @tc.name sigtimedwait siginfo_t test
549 * @tc.desc [C- SOFTWARE -0200]
550 */
HWTEST_F(IpcSignalTest, testSigtimedwaitSiginfo, Function | MediumTest | Level2)551 HWTEST_F(IpcSignalTest, testSigtimedwaitSiginfo, Function | MediumTest | Level2)
552 {
553 pid_t pid = fork();
554 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
555 if (pid == 0) { // child
556 int exitCode = 0;
557 signal(SIGINT, SignalHandler);
558 struct timespec time1 = {0, 100*1000000};
559 sigset_t set;
560 siginfo_t si;
561 sigemptyset(&set);
562 sigaddset(&set, SIGINT);
563 int rt = sigtimedwait(&set, &si, &time1);
564 if (rt != SIGINT) {
565 LOG("sigtimedwait should return the signal, expected:%d, actual:%d", SIGINT, rt);
566 exitCode = 1;
567 }
568 LOGD("si: %d,%d,%d,%p", si.si_signo, si.si_code, si.si_value.sival_int, si.si_value.sival_int);
569 if (si.si_signo != SIGINT) {
570 LOG("sigtimedwait set siginfo_t fail, si_signo=%d", si.si_signo);
571 exitCode = 1;
572 }
573 // other area of siginfo_t is not supported yet, test code deleted
574 LOG("child exited with code=%d", exitCode);
575 exit(exitCode);
576 } else { // parent
577 Msleep(20);
578 kill(pid, SIGINT);
579 Msleep(150);
580 AssertProcExitedOK(pid);
581 }
582 }
583
584 /**
585 * @tc.number SUB_KERNEL_IPC_SIGWAITINFO_0100
586 * @tc.name sigwaitinfo basic test: a pending signal should cause sigwaitinfo return immediately
587 * @tc.desc [C- SOFTWARE -0200]
588 */
HWTEST_F(IpcSignalTest, testSigwaitinfoBasic, Function | MediumTest | Level1)589 HWTEST_F(IpcSignalTest, testSigwaitinfoBasic, Function | MediumTest | Level1)
590 {
591 pid_t pid = fork();
592 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
593 if (pid == 0) { // child
594 int exitCode = 0;
595 sigset_t set, pending;
596 sigemptyset(&pending);
597 sigemptyset(&set);
598 sigaddset(&set, SIGALRM);
599 signal(SIGALRM, SignalHandler);
600 if (sigprocmask(SIG_BLOCK, &set, nullptr) == -1) {
601 LOG("sigprocmask failed");
602 exit(1);
603 }
604 LOG("raise SIGALRM");
605 raise(SIGALRM);
606
607 sigpending(&pending);
608 if (!sigismember(&pending, SIGALRM)) {
609 LOG("SIGALRM is not in pending set");
610 exit(1);
611 }
612
613 LOGD("before sigwaitinfo");
614 struct timespec time1 = {0, 0};
615 struct timespec time2 = {0, 0};
616 clock_gettime(CLOCK_MONOTONIC, &time1);
617 int rt = sigwaitinfo(&set, nullptr);
618 clock_gettime(CLOCK_MONOTONIC, &time2);
619
620 LOGD("after sigwaitinfo");
621 double duration = (time2.tv_sec - time1.tv_sec)*1000.0 + (time2.tv_nsec - time1.tv_nsec)/1000000.0;
622 LOG("duration: %f ms", duration);
623 if (CheckValueClose(0.1, duration)) {
624 LOG("sigwaitinfo should return immediately, but %f ms used", duration);
625 exitCode = 1;
626 }
627 if (rt != SIGALRM) {
628 LOG("sigwaitinfo should return the signal, expected:%d, actual:%d", SIGALRM, rt);
629 exitCode = 1;
630 }
631 LOG("child exited with code=%d", exitCode);
632 exit(exitCode);
633 } else { // parent
634 sleep(1);
635 AssertProcExitedOK(pid);
636 }
637 }
638
639 /**
640 * @tc.number SUB_KERNEL_IPC_SIG_PAUSE_0100
641 * @tc.name pause basic function test
642 * @tc.desc [C- SOFTWARE -0200]
643 */
HWTEST_F(IpcSignalTest, testPauseBasic, Function | MediumTest | Level1)644 HWTEST_F(IpcSignalTest, testPauseBasic, Function | MediumTest | Level1)
645 {
646 pid_t pid = fork();
647 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
648 if (pid == 0) { // child
649 struct timespec time1 = {0};
650 struct timespec time2 = {0};
651 int exitCode = 0;
652 signal(SIGQUIT, SignalHandler);
653 Msleep(100);
654
655 clock_gettime(CLOCK_MONOTONIC, &time1);
656 int rt = pause();
657 clock_gettime(CLOCK_MONOTONIC, &time2);
658 if (rt != -1) {
659 LOG("pause should return -1, but rt=%d", rt);
660 exitCode = 1;
661 }
662 if (errno != EINTR) {
663 LOG("pause should set errno to 4(EINTR),but get %d", errno);
664 exitCode = 1;
665 }
666
667 long duration = (time2.tv_sec - time1.tv_sec)*1000 + (time2.tv_nsec - time1.tv_nsec)/1000000;
668 LOG("paused time: %ld ms", duration);
669 if (! CheckValueClose(100, duration, 0.2)) {
670 LOG("paused time check error.");
671 exitCode = 1;
672 }
673 if (mReceivedSignal != SIGQUIT) {
674 LOG("Received signal check fail, expected signal=%d", SIGQUIT);
675 exitCode = 1;
676 }
677 exit(exitCode);
678 } else { // parent
679 Msleep(200);
680 kill(pid, SIGQUIT);
681 Msleep(200);
682 AssertProcExitedOK(pid);
683 }
684 }
685 /**
686 * @tc.number SUB_KERNEL_IPC_SIG_PAUSE_0200
687 * @tc.name pause and mask test
688 * @tc.desc [C- SOFTWARE -0200]
689 */
HWTEST_F(IpcSignalTest, testPauseAndMask, Function | MediumTest | Level1)690 HWTEST_F(IpcSignalTest, testPauseAndMask, Function | MediumTest | Level1)
691 {
692 pid_t pid = fork();
693 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
694 if (pid == 0) { // child
695 int exitCode = 0;
696 signal(SIGINT, SignalHandler);
697 signal(SIGTRAP, SignalHandler);
698
699 sigset_t sigmask;
700 sigemptyset(&sigmask);
701 sigaddset(&sigmask, SIGINT);
702 int rt = sigprocmask(SIG_BLOCK, &sigmask, nullptr);
703 if (rt != 0) {
704 LOG("sigprocmask fail, rt=%d, errno=%d", rt, errno);
705 exit(1);
706 }
707 LOG("before pause");
708 rt = pause();
709 if (rt != -1) {
710 LOG("pause should return -1, but rt=%d", rt);
711 exitCode = 1;
712 }
713 if (errno != EINTR) {
714 LOG("pause should set errno to 4(EINTR),but get %d", errno);
715 exitCode = 1;
716 }
717 LOG("after pause");
718 if (mReceivedSignal != SIGTRAP) {
719 LOG("Received signal check fail, expected %d,but get %d", SIGINT, mReceivedSignal);
720 exitCode = 1;
721 }
722 exit(exitCode);
723 } else { // parent
724 Msleep(20);
725 kill(pid, SIGINT);
726 Msleep(20);
727 AssertProcAlive(pid);
728 kill(pid, SIGTRAP);
729 Msleep(20);
730 WaitProcExitedOK(pid);
731 }
732 sigset_t pending;
733 sigemptyset(&pending);
734 sigpending(&pending);
735 if (sigisemptyset(&pending)) {
736 LOG("pending set empty");
737 } else {
738 LOG("========pending set not empty=========");
739 }
740 }
741
742 /**
743 * @tc.number SUB_KERNEL_IPC_SIGPENDING_0100
744 * @tc.name sigpending basic function test, also test pending-signal-set should not inherited after fork,
745 but signal mask set should inherited, and the change of child's pending set should not effect parent's.
746 * @tc.desc [C- SOFTWARE -0200]
747 */
HWTEST_F(IpcSignalTest, testSigpendingBasic, Function | MediumTest | Level1)748 HWTEST_F(IpcSignalTest, testSigpendingBasic, Function | MediumTest | Level1)
749 {
750 int rt;
751 sigset_t sigmask, oldmask;
752 sigset_t pending;
753 sigemptyset(&sigmask);
754 sigemptyset(&oldmask);
755 sigemptyset(&pending);
756 sigpending(&pending);
757 EXPECT_EQ(1, sigisemptyset(&pending)) << "initial pending set should empty";
758
759 signal(SIGALRM, SignalHandler);
760
761 sigaddset(&sigmask, SIGALRM);
762 sigaddset(&sigmask, SIGUSR1);
763 sigprocmask(SIG_BLOCK, &sigmask, &oldmask);
764 EXPECT_EQ(1, sigisemptyset(&oldmask)) << "initial sig mask set should empty";
765 rt = sigpending(&pending);
766 EXPECT_EQ(rt, 0);
767 EXPECT_EQ(1, sigisemptyset(&pending)) << "SIG_BLOCK set should not effect on pending set";
768
769 LOGD("raise SIGALRM");
770 raise(SIGALRM);
771 sigpending(&pending);
772 EXPECT_EQ(1, sigismember(&pending, SIGALRM));
773
774 pid_t pid = fork();
775 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
776 if (pid == 0) { // child
777 int exitCode = 0;
778 sigemptyset(&pending);
779 sigpending(&pending);
780 if (sigisemptyset(&pending) != 1) {
781 LOG("pending signal set should not reserved via fork");
782 exitCode = 1;
783 }
784
785 sigemptyset(&oldmask);
786 sigprocmask(SIG_BLOCK, nullptr, &oldmask); // read mask
787 if ((sigismember(&oldmask, SIGALRM) != 1) || (sigismember(&oldmask, SIGUSR1) != 1)) {
788 LOG("signal mask set should reserved via fork");
789 exitCode = 1;
790 }
791
792 LOG("unblock SIGALRM.");
793 rt = sigprocmask(SIG_UNBLOCK, &sigmask, nullptr);
794 sigemptyset(&pending);
795 sigpending(&pending);
796 if (sigisemptyset(&pending) != 1) {
797 LOG("pending signal set is not empty after unblock");
798 exitCode = 1;
799 }
800
801 LOG("child exit(%d).", exitCode);
802 exit(exitCode);
803 } else { // parent
804 Msleep(80);
805 WaitProcExitedOK(pid);
806 // check child's pending set should not effect parent's
807 sigemptyset(&pending);
808 sigpending(&pending);
809 EXPECT_EQ(1, sigismember(&pending, SIGALRM)) << "parent's pending set is changed!";
810 }
811 }
812
813 /**
814 * @tc.number SUB_KERNEL_IPC_SIGPROCMASK_0100
815 * @tc.name sigprocmask function test: use raise and kill to send signal
816 * @tc.desc [C- SOFTWARE -0200]
817 */
HWTEST_F(IpcSignalTest, testSigprocmaskBasic, Function | MediumTest | Level1)818 HWTEST_F(IpcSignalTest, testSigprocmaskBasic, Function | MediumTest | Level1)
819 {
820 int rt;
821 sigset_t sigmask, oldmask;
822 sigset_t pending;
823 sigemptyset(&sigmask);
824 sigemptyset(&oldmask);
825 sigemptyset(&pending);
826 sigaddset(&sigmask, SIGINT);
827 sigaddset(&sigmask, SIGUSR1);
828 rt = sigprocmask(SIG_BLOCK, &sigmask, &oldmask);
829 EXPECT_EQ(rt, 0);
830
831 signal(SIGINT, SignalHandler);
832 signal(SIGUSR1, SignalHandler);
833 ASSERT_EQ(mReceivedSignal, 0);
834
835 pid_t pid = fork();
836 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
837 if (pid == 0) { // child
838 int exitCode = 0;
839 raise(SIGINT);
840 if (mReceivedSignal != 0) {
841 LOG("SignalHandler check fail, expected=%d, actual=%d", 0, mReceivedSignal);
842 LOG("SIGINT(%d) should has blocked!", SIGINT);
843 exit(1);
844 }
845
846 LOG("unblock SIGINT");
847 sigemptyset(&sigmask);
848 sigaddset(&sigmask, SIGINT);
849 rt = sigprocmask(SIG_UNBLOCK, &sigmask, nullptr);
850 EXPECT_EQ(rt, 0);
851
852 // check the new block set
853 sigemptyset(&oldmask);
854 sigprocmask(SIG_UNBLOCK, nullptr, &oldmask);
855 if (sigismember(&oldmask, SIGINT) == 1) {
856 LOG("SIGINT should has deleted from block set!");
857 exitCode = 1;
858 }
859 if (sigismember(&oldmask, SIGUSR1) != 1) {
860 LOG("SIGUSR1 should still in block set!");
861 exitCode = 1;
862 }
863 if (mReceivedSignal != SIGINT) {
864 LOG("SignalHandler check fail, expected=%d, actual=%d", SIGINT, mReceivedSignal);
865 LOG("SIGALRM should deliver after unblock!");
866 exitCode = 1;
867 }
868
869 // test kill
870 mReceivedSignal = 0;
871 Msleep(80);
872 sigpending(&pending);
873 if (!sigismember(&pending, SIGUSR1)) {
874 LOG("SIGUSR1 is not in pending set!");
875 exitCode = 1;
876 } else {
877 LOG("SIGUSR1 is in pending set.");
878 }
879
880 if (mReceivedSignal != 0) {
881 LOG("SignalHandler check fail, expected=%d, actual=%d", 0, mReceivedSignal);
882 LOG("SIGUSR1(%d) should has blocked!", SIGUSR1);
883 exit(1);
884 }
885
886 LOG("unblock SIGUSR1");
887 sigemptyset(&sigmask);
888 sigaddset(&sigmask, SIGUSR1);
889 sigprocmask(SIG_UNBLOCK, &sigmask, nullptr);
890
891 if (mReceivedSignal != SIGUSR1) {
892 LOG("SignalHandler check fail, expected=%d, actual=%d", SIGUSR1, mReceivedSignal);
893 LOG("SIGUSR1 should deliver after unblock!");
894 exitCode = 1;
895 }
896
897 LOG("child exit(%d).", exitCode);
898 exit(exitCode);
899 } else { // parent
900 Msleep(50);
901 kill(pid, SIGUSR1);
902 Msleep(50);
903 WaitProcExitedOK(pid);
904 }
905 // restore default config
906 signal(SIGINT, SIG_DFL);
907 signal(SIGUSR1, SIG_DFL);
908 rt = sigprocmask(SIG_UNBLOCK, &sigmask, nullptr);
909 EXPECT_EQ(rt, 0);
910 }
911
912 /**
913 * @tc.number SUB_KERNEL_IPC_SIGPROCMASK_0200
914 * @tc.name sigprocmask function test: use alarm to send the signal
915 * @tc.desc [C- SOFTWARE -0200]
916 */
HWTEST_F(IpcSignalTest, testSigprocmaskAlarm, Function | MediumTest | Level2)917 HWTEST_F(IpcSignalTest, testSigprocmaskAlarm, Function | MediumTest | Level2)
918 {
919 int rt;
920 sigset_t sigmask, oldmask;
921 sigset_t pending;
922 sigemptyset(&sigmask);
923 sigemptyset(&oldmask);
924 sigemptyset(&pending);
925 sigaddset(&sigmask, SIGALRM);
926 rt = sigprocmask(SIG_BLOCK, &sigmask, &oldmask);
927 ASSERT_EQ(rt, 0);
928
929 signal(SIGALRM, SignalHandler);
930 ASSERT_EQ(mReceivedSignal, 0);
931 alarm(1);
932 Msleep(1100);
933
934 sigpending(&pending);
935 EXPECT_EQ(1, sigismember(&pending, SIGALRM));
936 EXPECT_EQ(mReceivedSignal, 0);
937
938 LOG("unblock SIGALRM.");
939 rt = sigprocmask(SIG_UNBLOCK, &sigmask, nullptr);
940 EXPECT_EQ(rt, 0);
941 ASSERT_EQ(mReceivedSignal, SIGALRM);
942
943 signal(SIGALRM, SIG_DFL);
944 }
945
946 /**
947 * @tc.number SUB_KERNEL_IPC_SIGPROCMASK_0300
948 * @tc.name sigprocmask function test: mask operation
949 * @tc.desc [C- SOFTWARE -0200]
950 */
HWTEST_F(IpcSignalTest, testSigprocmaskSetMask, Function | MediumTest | Level2)951 HWTEST_F(IpcSignalTest, testSigprocmaskSetMask, Function | MediumTest | Level2)
952 {
953 int rt;
954 sigset_t sigmask, oldmask, pending;
955 sigemptyset(&sigmask);
956 sigemptyset(&oldmask);
957 sigemptyset(&pending);
958 sigaddset(&sigmask, SIGALRM);
959 rt = sigprocmask(SIG_BLOCK, &sigmask, nullptr);
960 ASSERT_EQ(rt, 0);
961 sigemptyset(&sigmask);
962 sigaddset(&sigmask, SIGINT);
963 rt = sigprocmask(SIG_BLOCK, &sigmask, nullptr);
964 ASSERT_EQ(rt, 0);
965
966 LOG("add a new sig to block set");
967 rt = sigprocmask(SIG_BLOCK, nullptr, &oldmask); // check
968 ASSERT_EQ(rt, 0);
969 EXPECT_EQ(1, sigismember(&oldmask, SIGALRM));
970 EXPECT_EQ(1, sigismember(&oldmask, SIGINT));
971
972 LOG("unblock a not-in-set sig");
973 sigemptyset(&sigmask);
974 sigaddset(&sigmask, SIGTRAP);
975 rt = sigprocmask(SIG_UNBLOCK, &sigmask, nullptr);
976 ASSERT_EQ(rt, 0);
977 rt = sigprocmask(SIG_UNBLOCK, nullptr, &oldmask); // check
978 EXPECT_EQ(1, sigismember(&oldmask, SIGALRM));
979 EXPECT_EQ(1, sigismember(&oldmask, SIGINT));
980 EXPECT_EQ(0, sigismember(&oldmask, SIGTRAP));
981
982 LOG("set new block set, clear old one");
983 rt = sigprocmask(SIG_SETMASK, &sigmask, nullptr);
984 ASSERT_EQ(rt, 0);
985 rt = sigprocmask(10, nullptr, &oldmask); // check
986 ASSERT_EQ(rt, 0);
987 EXPECT_EQ(0, sigismember(&oldmask, SIGALRM));
988 EXPECT_EQ(0, sigismember(&oldmask, SIGINT));
989 EXPECT_EQ(1, sigismember(&oldmask, SIGTRAP));
990
991 LOG("unblock git, clear the block set");
992 rt = sigprocmask(SIG_UNBLOCK, &sigmask, nullptr);
993 ASSERT_EQ(rt, 0);
994 rt = sigprocmask(100, nullptr, &oldmask); // check
995 ASSERT_EQ(rt, 0);
996 EXPECT_EQ(1, sigisemptyset(&oldmask));
997 }
998 /**
999 * @tc.number SUB_KERNEL_IPC_SIGPROCMASK_0400
1000 * @tc.name sigprocmask function test: don't block signal that not in block-set with caught
1001 * @tc.desc [C- SOFTWARE -0200]
1002 */
HWTEST_F(IpcSignalTest, testSigprocmaskNotinSet, Function | MediumTest | Level2)1003 HWTEST_F(IpcSignalTest, testSigprocmaskNotinSet, Function | MediumTest | Level2)
1004 {
1005 LOG("Test: not-in-set signal could be caught.");
1006 pid_t pid = fork();
1007 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
1008 if (pid == 0) { // child
1009 sigset_t sigmask;
1010 sigemptyset(&sigmask);
1011 sigaddset(&sigmask, SIGTRAP);
1012 int rt = sigprocmask(SIG_BLOCK, &sigmask, nullptr);
1013 if (rt != 0) {
1014 LOG("sigprocmask fail, rt=%d, errno=%d", rt, errno);
1015 exit(1);
1016 }
1017 signal(SIGINT, SignalHandler);
1018 signal(SIGTRAP, SignalHandler);
1019
1020 Msleep(80);
1021 if (mReceivedSignal != SIGINT) {
1022 LOG("SignalHandler check fail, expected=SIGINT, actual=%d", mReceivedSignal);
1023 exit(1);
1024 }
1025 exit(0);
1026 } else { // parent
1027 Msleep(30);
1028 kill(pid, SIGINT);
1029 Msleep(50);
1030 WaitProcExitedOK(pid);
1031 }
1032 }
1033
1034 /**
1035 * @tc.number SUB_KERNEL_IPC_SIGPROCMASK_0800
1036 * @tc.name sigprocmask function test: don't block signal that not in block-set with terminate
1037 * @tc.desc [C- SOFTWARE -0200]
1038 */
HWTEST_F(IpcSignalTest, testSigprocmaskNotinSet0800, Function | MediumTest | Level2)1039 HWTEST_F(IpcSignalTest, testSigprocmaskNotinSet0800, Function | MediumTest | Level2)
1040 {
1041 LOG("Test: not-in-set signal could terminate the process.");
1042 pid_t pid = fork();
1043 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
1044 if (pid == 0) { // child
1045 sigset_t sigmask;
1046 sigemptyset(&sigmask);
1047 sigaddset(&sigmask, SIGTRAP);
1048 int rt = sigprocmask(SIG_BLOCK, &sigmask, nullptr);
1049 if (rt != 0) {
1050 LOG("sigprocmask fail, rt=%d, errno=%d", rt, errno);
1051 exit(1);
1052 }
1053 Msleep(60);
1054 exit(0);
1055 } else { // parent
1056 Msleep(30);
1057 kill(pid, SIGINT);
1058 Msleep(30);
1059 WaitProcKilled(pid, SIGINT);
1060 }
1061 }
1062
1063 /**
1064 * @tc.number SUB_KERNEL_IPC_SIGSUSPEND_0100
1065 * @tc.name sigsuspend basic function test1: the sigsuspend-signal terminates the process
1066 * @tc.desc [C- SOFTWARE -0200]
1067 */
HWTEST_F(IpcSignalTest, testSigsuspendTerminate, Function | MediumTest | Level1)1068 HWTEST_F(IpcSignalTest, testSigsuspendTerminate, Function | MediumTest | Level1)
1069 {
1070 pid_t pid = fork();
1071 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
1072 if (pid == 0) { // child
1073 signal(SIGTRAP, SignalHandler);
1074 sigset_t set;
1075 sigemptyset(&set);
1076 sigaddset(&set, SIGHUP);
1077 int rt = sigsuspend(&set);
1078 // should not get here:
1079 LOG("sigsuspend rt = %d, errno=%d", rt, errno);
1080 exit(1);
1081 } else { // parent
1082 Msleep(20);
1083
1084 kill(pid, SIGHUP); // this should blocked by sigsuspend
1085 Msleep(20);
1086 AssertProcAlive(pid);
1087
1088 kill(pid, SIGTRAP); // this should interrupt sigsuspend
1089 Msleep(100);
1090 WaitProcKilled(pid, SIGHUP);
1091 }
1092 }
1093 /**
1094 * @tc.number SUB_KERNEL_IPC_SIGSUSPEND_0200
1095 * @tc.name sigsuspend basic function test2: the sigsuspend-signal caught, and process continue run
1096 * @tc.desc [C- SOFTWARE -0200]
1097 */
HWTEST_F(IpcSignalTest, testSigsuspendContinue, Function | MediumTest | Level2)1098 HWTEST_F(IpcSignalTest, testSigsuspendContinue, Function | MediumTest | Level2)
1099 {
1100 pid_t pid = fork();
1101 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
1102 if (pid == 0) { // child
1103 int exitCode = 0;
1104 signal(SIGTRAP, SignalHandler);
1105 signal(SIGHUP, SignalHandler);
1106 sigset_t set;
1107 sigemptyset(&set);
1108 sigaddset(&set, SIGHUP);
1109 int rt = sigsuspend(&set);
1110 if (rt != -1) {
1111 LOG("sigsuspend should return -1, but rt=%d", rt);
1112 exitCode = 1;
1113 }
1114 if (errno != EINTR) {
1115 LOG("sigsuspend should set errno to 4(EINTR),but get %d", errno);
1116 exitCode = 1;
1117 }
1118 if (mReceivedSignal != SIGHUP) {
1119 LOG("Received signal check fail, expected signal=%d", SIGHUP);
1120 exitCode = 1;
1121 }
1122 exit(exitCode);
1123 } else { // parent
1124 Msleep(20);
1125
1126 kill(pid, SIGHUP);
1127 Msleep(20);
1128 AssertProcAlive(pid);
1129
1130 kill(pid, SIGTRAP);
1131 Msleep(100);
1132 AssertProcExitedOK(pid);
1133 }
1134 }
1135
1136 /**
1137 * @tc.number SUB_KERNEL_IPC_SIGSUSPEND_0300
1138 * @tc.name sigsuspend test with sigprocmask
1139 * @tc.desc [C- SOFTWARE -0200]
1140 */
HWTEST_F(IpcSignalTest, testSigsuspendAndMask, Function | MediumTest | Level1)1141 HWTEST_F(IpcSignalTest, testSigsuspendAndMask, Function | MediumTest | Level1)
1142 {
1143 pid_t pid = fork();
1144 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
1145 if (pid == 0) { // child
1146 int exitCode = 0;
1147 sigset_t procMask, suspendMask;
1148 sigemptyset(&suspendMask);
1149 sigemptyset(&procMask);
1150 sigaddset(&suspendMask, SIGQUIT);
1151 sigaddset(&procMask, SIGINT);
1152
1153 signal(SIGINT, SignalHandler);
1154 signal(SIGQUIT, SignalHandler);
1155
1156 LOG("Block SIGINT...");
1157 int rt = sigprocmask(SIG_SETMASK, &procMask, nullptr);
1158 if (rt != 0) {
1159 LOG("sigprocmask fail, rt=%d, errno=%d", rt, errno);
1160 exit(1);
1161 }
1162 LOG("Suspend SIGQUIT...");
1163 rt = sigsuspend(&suspendMask);
1164 if (rt != -1) {
1165 LOG("sigsuspend should return -1, but rt=%d", rt);
1166 exitCode = 1;
1167 }
1168 // signal in procmask should received 1st
1169 // need change to check SIGQUIT only if multi-signal issue fixed
1170 if ((mReceivedSignal != SIGQUIT) && (mReceivedSignal != SIGINT)) {
1171 LOG("Received signal check fail, get %d", mReceivedSignal);
1172 exitCode = 1;
1173 }
1174
1175 LOG("Check current mask...");
1176 sigemptyset(&procMask);
1177 sigprocmask(10, nullptr, &procMask);
1178 if (!sigismember(&procMask, SIGINT)) {
1179 LOG("SIGINT should in block set!");
1180 exitCode = 1;
1181 }
1182 if (sigismember(&procMask, SIGQUIT)) {
1183 LOG("SIGQUIT should not in block set!");
1184 exitCode = 1;
1185 }
1186 exit(exitCode);
1187 } else { // parent
1188 Msleep(20);
1189 kill(pid, SIGQUIT);
1190 Msleep(20);
1191 AssertProcAlive(pid);
1192
1193 kill(pid, SIGINT); // this should interrupt sigsuspend
1194 Msleep(100);
1195 AssertProcExitedOK(pid);
1196 }
1197 }
1198
1199 /**
1200 * @tc.number SUB_KERNEL_IPC_SIG_PTDKILL_0100
1201 * @tc.name pthread_kill function test: basic
1202 * @tc.desc [C- SOFTWARE -0200]
1203 */
HWTEST_F(IpcSignalTest, testPthreadkill, Function | MediumTest | Level1)1204 HWTEST_F(IpcSignalTest, testPthreadkill, Function | MediumTest | Level1)
1205 {
1206 pthread_t tid;
1207 int sigNo = SIGXCPU;
1208 int ret = pthread_create(&tid, NULL, ThreadFunc1, (void*)sigNo);
1209 ASSERT_EQ(ret, 0) << "pthread_create failed, errno=" << ret;
1210 Msleep(30);
1211 ret = pthread_kill(tid, sigNo);
1212 EXPECT_EQ(ret, 0) << "pthread_kill failed, errno=" << ret;
1213 ret = pthread_join(tid, NULL);
1214 EXPECT_EQ(ret, 0) << "pthread_join failed, errno=" << ret;
1215 EXPECT_EQ(mReceivedSignal, sigNo) << "Thread received signal check fail";
1216 // restore handler
1217 handler_type rt = signal(sigNo, SIG_DFL);
1218 ASSERT_NE(rt, SIG_ERR) << "restore signal failed, errno=" << errno;
1219 }
1220
1221 /**
1222 * @tc.number SUB_KERNEL_IPC_SIG_PTDKILL_0200
1223 * @tc.name pthread_kill function test: try kill main thread
1224 * @tc.desc [C- SOFTWARE -0200]
1225 */
HWTEST_F(IpcSignalTest, testPthreadkillMain, Function | MediumTest | Level2)1226 HWTEST_F(IpcSignalTest, testPthreadkillMain, Function | MediumTest | Level2)
1227 {
1228 pid_t pid = fork();
1229 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
1230 if (pid == 0) { // child
1231 pthread_t mainThread = pthread_self();
1232 signal(SIGINT, SignalHandler);
1233 pthread_t tid;
1234 int ret = pthread_create(&tid, NULL, ThreadFunc2, &mainThread);
1235 if (ret != 0) {
1236 LOG("pthread_create failed, errno=%d", ret);
1237 exit(1);
1238 }
1239
1240 void* threadExitCode = nullptr;
1241 ret = pthread_join(tid, &threadExitCode);
1242 if (ret != 0) {
1243 LOG("pthread_join failed, errno=%d", ret);
1244 exit(1);
1245 }
1246 int c = (int)((uintptr_t)threadExitCode);
1247 if (c != 0) {
1248 LOG("sub thread exited failed, code=%d", c);
1249 exit(1);
1250 }
1251
1252 if (mReceivedSignal != SIGINT) {
1253 LOG("SignalHandler check fail, expected signal:%d, actual:%d", SIGINT, mReceivedSignal);
1254 exit(1);
1255 }
1256 exit(0);
1257 } else { // parent
1258 Msleep(100);
1259 AssertProcExitedOK(pid);
1260 }
1261 }
1262
1263 /**
1264 * @tc.number SUB_KERNEL_IPC_SIG_PTDSIGMASK_0100
1265 * @tc.name pthread_sigmask function test: basic
1266 * @tc.desc [C- SOFTWARE -0200]
1267 */
HWTEST_F(IpcSignalTest, testPthreadSigmask, Function | MediumTest | Level1)1268 HWTEST_F(IpcSignalTest, testPthreadSigmask, Function | MediumTest | Level1)
1269 {
1270 pthread_t tid;
1271 int ret = pthread_create(&tid, NULL, ThreadFuncForSigmask1, (void*)1);
1272 ASSERT_EQ(ret, 0) << "pthread_create failed, errno=" << ret;
1273 ret = pthread_join(tid, NULL);
1274 EXPECT_EQ(ret, 0) << "pthread_join failed, errno=" << ret;
1275 }
1276
1277 /**
1278 * @tc.number SUB_KERNEL_IPC_SIG_PTDSIGMASK_0200
1279 * @tc.name pthread_sigmask function test: handler
1280 * @tc.desc [C- SOFTWARE -0200]
1281 */
HWTEST_F(IpcSignalTest, testPthreadSigmaskHandler, Function | MediumTest | Level1)1282 HWTEST_F(IpcSignalTest, testPthreadSigmaskHandler, Function | MediumTest | Level1)
1283 {
1284 signal(SIGINT, SignalHandler);
1285 pthread_t tid;
1286 int ret = pthread_create(&tid, NULL, ThreadFuncForSigmask1, (void*)2);
1287 EXPECT_EQ(ret, 0) << "pthread_create failed, errno=" << ret;
1288
1289 ret = pthread_join(tid, NULL);
1290 EXPECT_EQ(ret, 0) << "pthread_join failed, errno=" << ret;
1291
1292 signal(SIGINT, SIG_DFL);
1293 }
1294
1295 /**
1296 * @tc.number SUB_KERNEL_IPC_SIG_PTDSIGMASK_0300
1297 * @tc.name test that the signal-mask should inherited from the creator
1298 * @tc.desc [C- SOFTWARE -0200]
1299 */
HWTEST_F(IpcSignalTest, testPthreadSigmaskInherit, Function | MediumTest | Level3)1300 HWTEST_F(IpcSignalTest, testPthreadSigmaskInherit, Function | MediumTest | Level3)
1301 {
1302 sigset_t sigmask, oldmask;
1303 sigemptyset(&sigmask);
1304 sigemptyset(&oldmask);
1305
1306 LOG("add SIGUSR1 to block set");
1307 sigaddset(&sigmask, SIGUSR1);
1308 int rt = sigprocmask(SIG_BLOCK, &sigmask, &oldmask);
1309 EXPECT_EQ(rt, 0);
1310
1311 pthread_t tid;
1312 int ret = pthread_create(&tid, NULL, ThreadFuncForSigmask2, NULL);
1313 EXPECT_EQ(ret, 0) << "pthread_create failed, errno=" << ret;
1314
1315 void* threadExitCode = nullptr;
1316 ret = pthread_join(tid, &threadExitCode);
1317 EXPECT_EQ(ret, 0) << "pthread_join failed, errno=" << ret;
1318 int code = (int)((uintptr_t)threadExitCode);
1319 EXPECT_EQ(code, 0);
1320
1321 LOG("check the block set is not effected");
1322 sigprocmask(SIG_UNBLOCK, nullptr, &oldmask);
1323
1324 EXPECT_EQ(sigismember(&oldmask, SIGINT), 0) << "SIGINT should not in block set!";
1325 EXPECT_EQ(sigismember(&oldmask, SIGUSR1), 1) << "SIGUSR1 should still in block set!";
1326
1327 LOG("restore default config");
1328 rt = sigprocmask(SIG_UNBLOCK, &sigmask, nullptr);
1329 EXPECT_EQ(rt, 0);
1330 }
1331
1332 /**
1333 * @tc.number SUB_KERNEL_IPC_SIG_SETOP_0100
1334 * @tc.name test sig set operator APIs:sigemptyset,sigaddset,sigisemptyset,sigismember
1335 * @tc.desc [C- SOFTWARE -0200]
1336 */
HWTEST_F(IpcSignalTest, testSigsetBasic, Function | MediumTest | Level2)1337 HWTEST_F(IpcSignalTest, testSigsetBasic, Function | MediumTest | Level2)
1338 {
1339 sigset_t set;
1340 int rt = sigemptyset(&set);
1341 EXPECT_EQ(rt, 0) << "sigandset failed";
1342 EXPECT_EQ(sigisemptyset(&set), 1) << "set should empty";
1343
1344 rt = sigaddset(&set, SIGINT);
1345 EXPECT_EQ(rt, 0) << "sigaddset failed, errno=" << errno;
1346 EXPECT_EQ(sigismember(&set, SIGINT), 1) << "SIGINT should in set";
1347 EXPECT_EQ(sigismember(&set, SIGQUIT), 0) << "SIGQUIT should not in set";
1348
1349 rt = sigaddset(&set, SIGQUIT);
1350 EXPECT_EQ(rt, 0) << "sigaddset failed, errno=" << errno;
1351 EXPECT_EQ(sigismember(&set, SIGQUIT), 1) << "SIGQUIT should in set";
1352
1353 rt = sigaddset(&set, -1);
1354 EXPECT_EQ(rt, -1);
1355 EXPECT_EQ(errno, EINVAL);
1356
1357 rt = sigaddset(&set, MAX_SIGNAL_NUMBER + 1);
1358 EXPECT_EQ(rt, -1);
1359 EXPECT_EQ(errno, EINVAL);
1360
1361 LOG("check that set not changed after failed-sigadd");
1362 EXPECT_EQ(sigismember(&set, SIGINT), 1) << "SIGINT should in set";
1363 EXPECT_EQ(sigismember(&set, SIGQUIT), 1) << "SIGQUIT should in set";
1364
1365 sigemptyset(&set);
1366 EXPECT_EQ(sigisemptyset(&set), 1) << "set should empty";
1367 }
1368
1369 /**
1370 * @tc.number SUB_KERNEL_IPC_SIG_SETOP_0200
1371 * @tc.name test sig set operator API: sigandset
1372 * @tc.desc [C- SOFTWARE -0200]
1373 */
HWTEST_F(IpcSignalTest, testSigsetAnd, Function | MediumTest | Level2)1374 HWTEST_F(IpcSignalTest, testSigsetAnd, Function | MediumTest | Level2)
1375 {
1376 sigset_t set1, set2, setAnd;
1377 sigemptyset(&set1);
1378 sigemptyset(&set2);
1379 sigemptyset(&setAnd);
1380 int rt;
1381
1382 LOG("test and-set with empty set:");
1383 sigaddset(&set1, SIGINT);
1384 rt = sigandset(&setAnd, &set1, &set2);
1385 EXPECT_EQ(rt, 0) << "sigandset failed, errno=" << errno;
1386 EXPECT_EQ(sigisemptyset(&setAnd), 1) << "setAnd should empty";
1387 }
1388
1389 /**
1390 * @tc.number SUB_KERNEL_IPC_SIG_SETOP_0300
1391 * @tc.name test sig set operator API: sigorset
1392 * @tc.desc [C- SOFTWARE -0200]
1393 */
HWTEST_F(IpcSignalTest, testSigsetOr, Function | MediumTest | Level2)1394 HWTEST_F(IpcSignalTest, testSigsetOr, Function | MediumTest | Level2)
1395 {
1396 sigset_t set1, set2, setOr;
1397 sigemptyset(&set1);
1398 sigemptyset(&set2);
1399 sigemptyset(&setOr);
1400 int rt;
1401
1402 LOG("test or-set with empty set:");
1403 sigaddset(&set1, SIGINT);
1404 rt = sigorset(&setOr, &set1, &set2);
1405 EXPECT_EQ(rt, 0) << "sigorset failed, errno=" << errno;
1406 EXPECT_EQ(sigismember(&setOr, SIGINT), 1) << "SIGINT should in setOr";
1407 }
1408
1409 /**
1410 * @tc.number SUB_KERNEL_IPC_SIG_SETOP_0400
1411 * @tc.name test sig set operator APIs: sigdelset
1412 * @tc.desc [C- SOFTWARE -0200]
1413 */
HWTEST_F(IpcSignalTest, testSigsetDelete, Function | MediumTest | Level2)1414 HWTEST_F(IpcSignalTest, testSigsetDelete, Function | MediumTest | Level2)
1415 {
1416 sigset_t set;
1417 sigemptyset(&set);
1418 sigaddset(&set, SIGINT);
1419
1420 LOG("delete in-set sig:");
1421 int rt = sigdelset(&set, SIGINT);
1422 EXPECT_EQ(rt, 0) << "sigdelset failed, errno=" << errno;
1423 EXPECT_EQ(sigisemptyset(&set), 1);
1424
1425 sigaddset(&set, SIGINT);
1426 sigaddset(&set, SIGQUIT);
1427 rt = sigdelset(&set, SIGINT);
1428 EXPECT_EQ(rt, 0) << "sigdelset failed, errno=" << errno;
1429 EXPECT_EQ(sigismember(&set, SIGQUIT), 1) << "SIGQUIT should in set";
1430 EXPECT_EQ(sigismember(&set, SIGINT), 0) << "SIGINT should not in set";
1431 }
1432
1433 /**
1434 * @tc.number SUB_KERNEL_IPC_SIG_SETOP_0500
1435 * @tc.name test sig set operator APIs: sigfillset
1436 * @tc.desc [C- SOFTWARE -0200]
1437 */
HWTEST_F(IpcSignalTest, testSigsetFill, Function | MediumTest | Level2)1438 HWTEST_F(IpcSignalTest, testSigsetFill, Function | MediumTest | Level2)
1439 {
1440 sigset_t set;
1441 sigemptyset(&set);
1442 sigaddset(&set, SIGINT);
1443
1444 int rt = sigfillset(&set);
1445 EXPECT_EQ(rt, 0) << "sigfillset failed, errno=" << errno;
1446 for (int i = 1; i <= MAX_SIGNAL; i++) {
1447 EXPECT_EQ(sigismember(&set, i), 1) << i << " not in set!";
1448 }
1449
1450 sigdelset(&set, SIGINT);
1451 for (int i = 1; i <= MAX_SIGNAL; i++) {
1452 if (i == SIGINT) {
1453 EXPECT_EQ(sigismember(&set, i), 0) << "SIGINT should not in set!";
1454 } else {
1455 EXPECT_EQ(sigismember(&set, i), 1) << i << " not in set!";
1456 }
1457 }
1458 }
1459
1460 /**
1461 * @tc.number SUB_KERNEL_IPC_SIG_SETOP_0600
1462 * @tc.name test sigdelset operator APIs: sigdelset
1463 * @tc.desc [C- SOFTWARE -0200]
1464 */
HWTEST_F(IpcSignalTest, testSigsetDelete0600, Function | MediumTest | Level2)1465 HWTEST_F(IpcSignalTest, testSigsetDelete0600, Function | MediumTest | Level2)
1466 {
1467 int rt;
1468 sigset_t set;
1469 sigemptyset(&set);
1470 sigaddset(&set, SIGINT);
1471
1472 LOG("delete not-in-set sig:");
1473 sigemptyset(&set);
1474 sigaddset(&set, SIGQUIT);
1475 rt = sigdelset(&set, SIGINT);
1476 EXPECT_EQ(rt, 0) << "sigdelset failed, errno=" << errno;
1477 EXPECT_EQ(sigismember(&set, SIGQUIT), 1) << "SIGQUIT should in set";
1478 EXPECT_EQ(sigismember(&set, SIGINT), 0) << "SIGINT should not in set";
1479 }
1480
1481 /**
1482 * @tc.number SUB_KERNEL_IPC_SIG_SETOP_0700
1483 * @tc.name test sig set operator APIs: sigdelset with invalid
1484 * @tc.desc [C- SOFTWARE -0200]
1485 */
HWTEST_F(IpcSignalTest, testSigsetDelete0700, Function | MediumTest | Level2)1486 HWTEST_F(IpcSignalTest, testSigsetDelete0700, Function | MediumTest | Level2)
1487 {
1488 int rt;
1489 sigset_t set;
1490 sigemptyset(&set);
1491 sigaddset(&set, SIGINT);
1492
1493 LOG("delete invalid sig:");
1494 rt = sigdelset(&set, -1);
1495 EXPECT_EQ(rt, -1);
1496 EXPECT_EQ(errno, EINVAL);
1497
1498 rt = sigdelset(&set, MAX_SIGNAL_NUMBER + 1);
1499 EXPECT_EQ(rt, -1);
1500 EXPECT_EQ(errno, EINVAL);
1501
1502 LOG("check that set not changed after failed-delete");
1503 EXPECT_EQ(sigismember(&set, SIGQUIT), 0) << "SIGQUIT should in set";
1504 EXPECT_EQ(sigismember(&set, SIGINT), 1) << "SIGINT should not in set";
1505 }
1506
1507 /**
1508 * @tc.number SUB_KERNEL_IPC_SIG_SETOP_1000
1509 * @tc.name test sig set operator API: sigorset with non-overlap
1510 * @tc.desc [C- SOFTWARE -0200]
1511 */
HWTEST_F(IpcSignalTest, testSigsetOr1000, Function | MediumTest | Level2)1512 HWTEST_F(IpcSignalTest, testSigsetOr1000, Function | MediumTest | Level2)
1513 {
1514 sigset_t set1, set2, setOr;
1515 sigemptyset(&set1);
1516 sigemptyset(&set2);
1517 sigemptyset(&setOr);
1518 int rt;
1519
1520 LOG("test or-set with non-overlap sets:");
1521 sigaddset(&set1, SIGINT);
1522 sigaddset(&set2, SIGABRT);
1523 rt = sigorset(&setOr, &set1, &set2);
1524 EXPECT_EQ(rt, 0) << "sigorset failed, errno=" << errno;
1525 EXPECT_EQ(sigismember(&setOr, SIGINT), 1) << "SIGINT should in setOr";
1526 EXPECT_EQ(sigismember(&setOr, SIGABRT), 1) << "SIGABRT should in setOr";
1527 }
1528
1529 /**
1530 * @tc.number SUB_KERNEL_IPC_SIG_SETOP_1100
1531 * @tc.name test sig set operator API: sigorset with overlapping
1532 * @tc.desc [C- SOFTWARE -0200]
1533 */
HWTEST_F(IpcSignalTest, testSigsetOr1100, Function | MediumTest | Level2)1534 HWTEST_F(IpcSignalTest, testSigsetOr1100, Function | MediumTest | Level2)
1535 {
1536 sigset_t set1, set2, setOr;
1537 sigemptyset(&set1);
1538 sigemptyset(&set2);
1539 sigemptyset(&setOr);
1540 int rt;
1541
1542 LOG("test or-set with overlapping sets:");
1543 sigaddset(&setOr, SIGHUP); // original siganl in setOr
1544 sigaddset(&set1, SIGINT);
1545 sigaddset(&set2, SIGABRT);
1546 sigaddset(&set1, SIGQUIT);
1547 sigaddset(&set2, SIGQUIT);
1548 rt = sigorset(&setOr, &set1, &set2);
1549 EXPECT_EQ(rt, 0) << "sigorset failed, errno=" << errno;
1550 EXPECT_EQ(sigismember(&setOr, SIGINT), 1) << "SIGINT should in setOr";
1551 EXPECT_EQ(sigismember(&setOr, SIGABRT), 1) << "SIGABRT should in setOr";
1552 EXPECT_EQ(sigismember(&setOr, SIGQUIT), 1) << "SIGQUIT should in setOr";
1553 EXPECT_EQ(sigismember(&setOr, SIGHUP), 0) << "original siganl in setOr should deleted";
1554 }
1555
1556
1557 /**
1558 * @tc.number SUB_KERNEL_IPC_SIG_SETOP_1200
1559 * @tc.name test sig set operator API: sigandset with non-overlap
1560 * @tc.desc [C- SOFTWARE -0200]
1561 */
HWTEST_F(IpcSignalTest, testSigsetAnd1200, Function | MediumTest | Level2)1562 HWTEST_F(IpcSignalTest, testSigsetAnd1200, Function | MediumTest | Level2)
1563 {
1564 sigset_t set1, set2, setAnd;
1565 sigemptyset(&set1);
1566 sigemptyset(&set2);
1567 sigemptyset(&setAnd);
1568 int rt;
1569
1570 LOG("test and-set with non-overlap sets:");
1571 sigaddset(&set1, SIGINT);
1572 sigaddset(&set2, SIGABRT);
1573 rt = sigandset(&setAnd, &set1, &set2);
1574 EXPECT_EQ(rt, 0) << "sigandset failed, errno=" << errno;
1575 EXPECT_EQ(sigisemptyset(&setAnd), 1) << "setAnd should empty";
1576 }
1577
1578 /**
1579 * @tc.number SUB_KERNEL_IPC_SIG_SETOP_1300
1580 * @tc.name test sig set operator API: sigandset with overlapping
1581 * @tc.desc [C- SOFTWARE -0200]
1582 */
HWTEST_F(IpcSignalTest, testSigsetAnd1300, Function | MediumTest | Level2)1583 HWTEST_F(IpcSignalTest, testSigsetAnd1300, Function | MediumTest | Level2)
1584 {
1585 sigset_t set1, set2, setAnd;
1586 sigemptyset(&set1);
1587 sigemptyset(&set2);
1588 sigemptyset(&setAnd);
1589 int rt;
1590
1591 LOG("test and-set with overlapping sets:");
1592 sigaddset(&set1, SIGINT);
1593 sigaddset(&set2, SIGABRT);
1594 sigaddset(&set1, SIGQUIT);
1595 sigaddset(&set2, SIGQUIT);
1596 sigaddset(&setAnd, SIGHUP); // original siganl in setAnd
1597 rt = sigandset(&setAnd, &set1, &set2);
1598 EXPECT_EQ(rt, 0) << "sigandset failed, errno=" << errno;
1599 EXPECT_EQ(sigismember(&setAnd, SIGQUIT), 1) << "SIGQUIT should in setAnd";
1600 EXPECT_EQ(sigismember(&setAnd, SIGINT), 0) << "SIGINT should not in setAnd";
1601 EXPECT_EQ(sigismember(&setAnd, SIGABRT), 0) << "SIGABRT should not in setAnd";
1602 EXPECT_EQ(sigismember(&setAnd, SIGHUP), 0) << "original siganl in setAnd should deleted";
1603 }
1604
1605 /**
1606 * @tc.number SUB_KERNEL_IPC_SIG_SETOP_1400
1607 * @tc.name test sig set operator API: sigandset with multi-overlapping
1608 * @tc.desc [C- SOFTWARE -0200]
1609 */
HWTEST_F(IpcSignalTest, testSigsetAnd1400, Function | MediumTest | Level2)1610 HWTEST_F(IpcSignalTest, testSigsetAnd1400, Function | MediumTest | Level2)
1611 {
1612 sigset_t set1, set2, setAnd;
1613 sigemptyset(&set1);
1614 sigemptyset(&set2);
1615 sigemptyset(&setAnd);
1616 int rt;
1617 LOG("test and-set with multi-overlapping sets:");
1618 sigaddset(&set1, SIGINT);
1619 sigaddset(&set2, SIGABRT);
1620 sigaddset(&set1, SIGQUIT);
1621 sigaddset(&set2, SIGQUIT);
1622 sigaddset(&setAnd, SIGHUP); // original siganl in setAnd
1623 sigaddset(&set1, SIGUSR1);
1624 sigaddset(&set2, SIGUSR1);
1625 rt = sigandset(&setAnd, &set1, &set2);
1626 EXPECT_EQ(rt, 0) << "sigandset failed, errno=" << errno;
1627 EXPECT_EQ(sigismember(&setAnd, SIGQUIT), 1) << "SIGQUIT should in setAnd";
1628 EXPECT_EQ(sigismember(&setAnd, SIGUSR1), 1) << "SIGUSR1 should in setAnd";
1629 EXPECT_EQ(sigismember(&setAnd, SIGINT), 0) << "SIGINT should not in setAnd";
1630 EXPECT_EQ(sigismember(&setAnd, SIGABRT), 0) << "SIGABRT should not in setAnd";
1631 }
1632
1633 /**
1634 * @tc.number SUB_KERNEL_IPC_SIG_SIGHOLD_0100
1635 * @tc.name sighold function test
1636 * @tc.desc [C- SOFTWARE -0200]
1637 */
HWTEST_F(IpcSignalTest, testSigHold, Function | MediumTest | Level2)1638 HWTEST_F(IpcSignalTest, testSigHold, Function | MediumTest | Level2)
1639 {
1640 int sigNo = SIGINT;
1641 int rt = sighold(sigNo);
1642 ASSERT_EQ(rt, 0) << "sighold failed, errno=" << errno;
1643
1644 LOG("check that the signal is added to the mask");
1645 sigset_t oldmask;
1646 sigemptyset(&oldmask);
1647 rt = sigprocmask(SIG_BLOCK, nullptr, &oldmask);
1648 EXPECT_EQ(rt, 0);
1649 EXPECT_EQ(sigismember(&oldmask, sigNo), 1);
1650
1651 // restore default config
1652 rt = sigprocmask(SIG_UNBLOCK, &oldmask, nullptr);
1653 EXPECT_EQ(rt, 0);
1654 }
1655
1656 /**
1657 * @tc.number SUB_KERNEL_IPC_SIG_SIGHOLD_0200
1658 * @tc.name sighold function error test
1659 * @tc.desc [C- SOFTWARE -0200]
1660 */
HWTEST_F(IpcSignalTest, testSigHoldError, Function | MediumTest | Level2)1661 HWTEST_F(IpcSignalTest, testSigHoldError, Function | MediumTest | Level2)
1662 {
1663 int rt = sighold(-1);
1664 EXPECT_EQ(rt, -1);
1665 EXPECT_EQ(errno, EINVAL);
1666
1667 rt = sighold(MAX_SIGNAL_NUMBER + 1);
1668 EXPECT_EQ(rt, -1);
1669 EXPECT_EQ(errno, EINVAL);
1670 }
1671
1672 /**
1673 * @tc.number SUB_KERNEL_IPC_SIG_SIGRELSE_0100
1674 * @tc.name sigrelse function test
1675 * @tc.desc [C- SOFTWARE -0200]
1676 */
HWTEST_F(IpcSignalTest, testSigRelse, Function | MediumTest | Level2)1677 HWTEST_F(IpcSignalTest, testSigRelse, Function | MediumTest | Level2)
1678 {
1679 LOG("add sig to mask");
1680 sigset_t mask;
1681 sigemptyset(&mask);
1682 sigaddset(&mask, SIGINT);
1683 int rt = sigprocmask(SIG_BLOCK, &mask, nullptr);
1684 ASSERT_EQ(rt, 0);
1685
1686 LOG("delete signal from the mask");
1687 rt = sigrelse(SIGINT);
1688 EXPECT_EQ(rt, 0);
1689
1690 LOG("check that the signal is deleted");
1691 sigemptyset(&mask);
1692 rt = sigprocmask(SIG_BLOCK, nullptr, &mask);
1693 EXPECT_EQ(rt, 0);
1694 EXPECT_EQ(sigisemptyset(&mask), 1);
1695 }
1696
1697 /**
1698 * @tc.number SUB_KERNEL_IPC_SIG_SIGRELSE_0200
1699 * @tc.name sigrelse function error test
1700 * @tc.desc [C- SOFTWARE -0200]
1701 */
HWTEST_F(IpcSignalTest, testSigRelseError, Function | MediumTest | Level2)1702 HWTEST_F(IpcSignalTest, testSigRelseError, Function | MediumTest | Level2)
1703 {
1704 int rt = sigrelse(-1);
1705 EXPECT_EQ(rt, -1);
1706 EXPECT_EQ(errno, EINVAL);
1707
1708 rt = sigrelse(MAX_SIGNAL_NUMBER + 1);
1709 EXPECT_EQ(rt, -1);
1710 EXPECT_EQ(errno, EINVAL);
1711 }
1712
1713 /**
1714 * @tc.number SUB_KERNEL_IPC_SIG_PSIGNAL_0100
1715 * @tc.name psignal function test
1716 * @tc.desc [C- SOFTWARE -0200]
1717 */
HWTEST_F(IpcSignalTest, testPsignal, Function | MediumTest | Level2)1718 HWTEST_F(IpcSignalTest, testPsignal, Function | MediumTest | Level2)
1719 {
1720 // we use child to do the test here, cause 'restore of stderr' is not work by now.
1721 pid_t pid = fork();
1722 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
1723 if (pid == 0) { // child
1724 // redirect stderr to a file, so we can check the content.
1725 char* outfile = WRITABLE_TEST_DIR "stderr.txt";
1726 if (freopen(outfile, "w", stderr) == NULL) {
1727 LOG("redirect stderr fail, freopen errno=%d\n", errno);
1728 exit(1);
1729 }
1730 psignal(SIGFPE, "SIGFPE");
1731 int rt = CheckSigString(outfile, "SIGFPE: Arithmetic exception");
1732 exit(rt);
1733 } else { // parent
1734 WaitProcExitedOK(pid);
1735 }
1736 }
1737
1738 /**
1739 * @tc.number SUB_KERNEL_IPC_SIG_PSIGNAL_0200
1740 * @tc.name psignal function error test1
1741 * @tc.desc [C- SOFTWARE -0200]
1742 */
HWTEST_F(IpcSignalTest, testPsignalError1, Function | MediumTest | Level3)1743 HWTEST_F(IpcSignalTest, testPsignalError1, Function | MediumTest | Level3)
1744 {
1745 pid_t pid = fork();
1746 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
1747 if (pid == 0) { // child
1748 char* outfile = WRITABLE_TEST_DIR "stderr.txt";
1749 if (freopen(outfile, "w", stderr) == NULL) {
1750 LOG("redirect stderr fail, freopen errno=%d\n", errno);
1751 exit(1);
1752 }
1753 psignal(-1, "===");
1754 int rt = CheckSigString(outfile, "===: Unknown signal");
1755 exit(rt);
1756 } else { // parent
1757 WaitProcExitedOK(pid);
1758 }
1759 }
1760
1761 /**
1762 * @tc.number SUB_KERNEL_IPC_SIG_PSIGNAL_0300
1763 * @tc.name psignal function error test2
1764 * @tc.desc [C- SOFTWARE -0200]
1765 */
HWTEST_F(IpcSignalTest, testPsignalError2, Function | MediumTest | Level3)1766 HWTEST_F(IpcSignalTest, testPsignalError2, Function | MediumTest | Level3)
1767 {
1768 pid_t pid = fork();
1769 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
1770 if (pid == 0) { // child
1771 char* outfile = WRITABLE_TEST_DIR "stderr.txt";
1772 if (freopen(outfile, "w", stderr) == NULL) {
1773 LOG("redirect stderr fail, freopen errno=%d\n", errno);
1774 exit(1);
1775 }
1776 psignal(MAX_SIGNAL_NUMBER + 1, "***");
1777 int rt = CheckSigString(outfile, "***: Unknown signal");
1778 exit(rt);
1779 } else { // parent
1780 WaitProcExitedOK(pid);
1781 }
1782 }
1783