1/*
2 * Copyright (c) 2022 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 <errno.h>
17#include <signal.h>
18
19#include "test.h"
20
21static int handler_count = 0;
22
23void handler(int sig)
24{
25    handler_count++;
26}
27
28/**
29 * @tc.name      : sigsuspend_0100
30 * @tc.desc      : wait for a signal
31 * @tc.level     : Level 0
32 */
33void sigsuspend_0100(void)
34{
35    sigset_t set;
36    sigemptyset(&set);
37
38    int sig = SIGALRM;
39    sigaddset(&set, sig);
40    sigprocmask(SIG_BLOCK, &set, NULL);
41
42    int flags = 0;
43    struct sigaction act = {.sa_flags = flags, .sa_handler = handler};
44    struct sigaction old_act = {0};
45    int result = sigaction(sig, &act, &old_act);
46    if (result != 0) {
47        t_error("%s failed: result = %d\n", __func__, result);
48    }
49
50    sigset_t pending_set;
51    sigemptyset(&pending_set);
52    sigpending(&pending_set);
53
54    for (int i = SIGHUP; i <= SIGSTKSZ; ++i) {
55        result = sigismember(&pending_set, i);
56        if (result != 0) {
57            t_error("%s failed: result = %d, i = %d\n", __func__, result, i);
58        }
59    }
60
61    raise(sig);
62    if (handler_count != 0) {
63        t_error("%s failed: handler_count = %d\n", __func__, handler_count);
64    }
65
66    sigemptyset(&pending_set);
67    sigpending(&pending_set);
68
69    for (int i = SIGHUP; i <= SIGSTKSZ; ++i) {
70        if ((i == sig) != (sigismember(&pending_set, i))) {
71            t_error("%s failed: i = %d, sig = %d\n", __func__, i, sig);
72        }
73    }
74
75    sigset_t set_without_sig;
76    sigfillset(&set_without_sig);
77    sigdelset(&set_without_sig, sig);
78
79    result = sigsuspend(&set_without_sig);
80    if (result != -1) {
81        t_error("%s failed: result = %d\n", __func__, result);
82    }
83
84    if (errno != EINTR) {
85        t_error("%s failed: errno = %d\n", __func__, errno);
86    }
87
88    if (handler_count != 1) {
89        t_error("%s failed: handler_count = %d\n", __func__, handler_count);
90    }
91}
92
93int main(int argc, char *argv[])
94{
95    sigsuspend_0100();
96
97    return t_status;
98}
99