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 "napi/native_api.h"
17 #include <cerrno>
18 #include <cstdio>
19 #include <cstring>
20 #include <fcntl.h>
21 #include <js_native_api_types.h>
22 #include <poll.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 
26 #define TEST_AT_FDCWD (-100)
27 #define TEST_ERROR_AT_FDCWD 100
28 
29 #define NO_ERR 0
30 #define SUCCESS 1
31 #define FAIL (-1)
32 #define TEN 10
33 #define TEST_FIFO_MODE 0666
34 #define TVSEC 1
35 #define TVNSEC 0
36 #define PARAM_0 0
37 #define PARAM_1 1
38 #define PARAM_2 2
39 #define PARAM_0777 0777
40 #define PARAM_UNNORMAL (-1)
41 #define ERRON_0 0
42 #define PARAM_100000000 100000000
43 #define PARAM_1000 1000
44 
Poll(napi_env env, napi_callback_info info)45 static napi_value Poll(napi_env env, napi_callback_info info)
46 {
47     int ret = PARAM_0;
48     errno = ERRON_0;
49     ret = poll(nullptr, PARAM_0, PARAM_1);
50     napi_value result = nullptr;
51     napi_create_int32(env, ret, &result);
52     return result;
53 }
Ppoll(napi_env env, napi_callback_info info)54 static napi_value Ppoll(napi_env env, napi_callback_info info)
55 {
56     int ret = PARAM_0;
57     int fd = open("ppoll_function_file", O_RDWR | O_CREAT, PARAM_0777);
58     struct pollfd pollfds[] = {{.fd = fd, .events = POLLIN, .revents = PARAM_0}};
59     struct timespec timeout = {PARAM_0};
60     timeout.tv_sec = TVSEC;
61     timeout.tv_nsec = TVNSEC;
62     ret = ppoll(pollfds, PARAM_1, &timeout, nullptr);
63     close(fd);
64     int res = access("ppoll_function_file", F_OK);
65     if (res != PARAM_UNNORMAL) {
66         remove("ppoll_function_file");
67     }
68     napi_value result = nullptr;
69     napi_create_int32(env, ret, &result);
70     return result;
71 }
PollChk(napi_env env, napi_callback_info info)72 static napi_value PollChk(napi_env env, napi_callback_info info)
73 {
74     int fd[2];
75     pipe(fd);
76 
77     int pollChk = PARAM_0;
78     int pid = fork();
79     if (pid == PARAM_UNNORMAL) {
80     } else if (pid == PARAM_0) {
81         close(fd[0]);
82         const char *message = "";
83         write(fd[1], message, strlen(message) + 1);
84         close(fd[1]);
85         _exit(PARAM_0);
86     } else {
87         close(fd[1]);
88         struct pollfd buf[2] = {{fd[0], POLLIN, PARAM_0}, {fd[0], POLLIN, PARAM_0}};
89         int ts = PARAM_1000;
90         pollChk = __poll_chk(buf, PARAM_1, ts, buf[0].fd);
91         char buff;
92         while (read(fd[0], &buff, PARAM_1) > PARAM_0)
93             ;
94         close(fd[0]);
95     }
96 
97     napi_value result = nullptr;
98     napi_create_int32(env, pollChk, &result);
99     return result;
100 }
101 
PpollChk(napi_env env, napi_callback_info info)102 static napi_value PpollChk(napi_env env, napi_callback_info info)
103 {
104     int fd[2];
105     pipe(fd);
106 
107     int pollChk = PARAM_0;
108     int pid = fork();
109     if (pid == PARAM_UNNORMAL) {
110     } else if (pid == PARAM_0) {
111         close(fd[0]);
112         const char *message = "";
113         write(fd[1], message, strlen(message) + 1);
114         close(fd[1]);
115         _exit(PARAM_0);
116     } else {
117         close(fd[1]);
118         struct pollfd buf[2] = {{fd[0], POLLIN, PARAM_0}, {fd[0], POLLIN, PARAM_0}};
119         struct timespec ts = {.tv_nsec = PARAM_100000000};
120         pollChk = __ppoll_chk(buf, PARAM_1, &ts, nullptr, buf[0].fd);
121         char buff;
122         while (read(fd[0], &buff, PARAM_1) > PARAM_0)
123             ;
124         close(fd[0]);
125     }
126 
127     napi_value result = nullptr;
128     napi_create_int32(env, pollChk, &result);
129     return result;
130 }
131 EXTERN_C_START
Init(napi_env env, napi_value exports)132 static napi_value Init(napi_env env, napi_value exports)
133 {
134     napi_property_descriptor desc[] = {
135         {"poll", nullptr, Poll, nullptr, nullptr, nullptr, napi_default, nullptr},
136         {"ppoll", nullptr, Ppoll, nullptr, nullptr, nullptr, napi_default, nullptr},
137         {"pollchk", nullptr, PollChk, nullptr, nullptr, nullptr, napi_default, nullptr},
138         {"ppollchk", nullptr, PpollChk, nullptr, nullptr, nullptr, napi_default, nullptr},
139     };
140     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
141     return exports;
142 }
143 EXTERN_C_END
144 
145 static napi_module demoModule = {
146     .nm_version = 1,
147     .nm_flags = 0,
148     .nm_filename = nullptr,
149     .nm_register_func = Init,
150     .nm_modname = "poll",
151     .nm_priv = ((void *)0),
152     .reserved = {0},
153 };
154 
RegisterModule(void)155 extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&demoModule); }
156