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 <csignal>
17 #include <cstdio>
18 #include <cstdlib>
19 #include <cstring>
20 #include <fcntl.h>
21 #include <js_native_api.h>
22 #include <node_api.h>
23 #include <pthread.h>
24 #include <sys/signalfd.h>
25 #include <unistd.h>
26 
27 #define PARAM_0 0
28 #define PARAM_1 1
29 #define PARAM_2 2
30 #define PARAM_6000 6000
31 #define PARAM_99999 99999
32 #define FAIL (-1)
33 #define NO_ERR 0
34 #define STRLENGTH 64
35 #define SUCCESS 1
36 #define ONE 1
37 #define SFD_CLOEXEC O_CLOEXEC
38 #define ONEVAL 1
39 #define MINUSONE (-1)
40 #define MINUSTWO (-2)
41 #define THRVAL 3
42 #define ERRON_0 0
43 
44 extern "C" int __sigtimedwait_time64(const sigset_t *__restrict, siginfo_t *__restrict,
45                                      const struct timespec *__restrict);
SigTimedWait_time641(napi_env env, napi_callback_info info)46 static napi_value SigTimedWait_time641(napi_env env, napi_callback_info info)
47 {
48     sigset_t set1;
49     sigemptyset(&set1);
50     sigaddset(&set1, SIGCHLD);
51     sigprocmask(SIG_BLOCK, &set1, nullptr);
52     pid_t pid = fork();
53     int ret = FAIL;
54     if (pid && pid != MINUSONE) {
55         sigset_t set2;
56         siginfo_t siginfo;
57         timespec timeout = {.tv_sec = PARAM_2, .tv_nsec = PARAM_0};
58         sigemptyset(&set2);
59         sigaddset(&set2, SIGCHLD);
60         ret = __sigtimedwait_time64(&set2, &siginfo, &timeout);
61     }
62     if (pid == PARAM_0) {
63         _exit(PARAM_0);
64     }
65     napi_value result = nullptr;
66     if (ret != FAIL) {
67         napi_create_int32(env, NO_ERR, &result);
68     } else {
69         napi_create_int32(env, FAIL, &result);
70     }
71     return result;
72 }
SigTimedWait_time642(napi_env env, napi_callback_info info)73 static napi_value SigTimedWait_time642(napi_env env, napi_callback_info info)
74 {
75     sigset_t set;
76     siginfo_t siginfo;
77     timespec timeout = {.tv_sec = PARAM_2, .tv_nsec = PARAM_0};
78     int ret = ret = __sigtimedwait_time64(&set, &siginfo, &timeout);
79 
80     napi_value result = nullptr;
81     if (ret != FAIL) {
82         napi_create_int32(env, NO_ERR, &result);
83     } else {
84         napi_create_int32(env, FAIL, &result);
85     }
86     return result;
87 }
88 
89 EXTERN_C_START
Init(napi_env env, napi_value exports)90 static napi_value Init(napi_env env, napi_value exports)
91 {
92     napi_property_descriptor desc[] = {
93         {"__sigtimedwait_time641", nullptr, SigTimedWait_time641, nullptr, nullptr, nullptr, napi_default, nullptr},
94         {"__sigtimedwait_time642", nullptr, SigTimedWait_time642, nullptr, nullptr, nullptr, napi_default, nullptr},
95     };
96     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
97     return exports;
98 }
99 EXTERN_C_END
100 
101 static napi_module demoModule = {
102     .nm_version = 1,
103     .nm_flags = 0,
104     .nm_filename = "signalndk1",
105     .nm_register_func = Init,
106     .nm_modname = "signalndk1",
107     .nm_priv = ((void *)0),
108     .reserved = {0},
109 };
110 
RegisterEntryModule(void)111 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
112