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 <cstdlib>
19 #include <cstring>
20 #include <fcntl.h>
21 #include <termios.h>
22 #include <unistd.h>
23 
24 #define FAIL (-1)
25 #define PARAM_0 0
26 #define PARAM_1 1
27 #define SUCCESS 1
28 #define ERRON_0 0
29 #define PARAM_0xff 0xff
30 
31 #define PATH "/data/storage/el2/base/files"
32 
Tcdrain(napi_env env, napi_callback_info info)33 static napi_value Tcdrain(napi_env env, napi_callback_info info)
34 {
35     size_t argc = PARAM_1;
36     napi_value args[1] = {nullptr};
37     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
38     int valueFirst;
39     napi_get_value_int32(env, args[0], &valueFirst);
40     int result = PARAM_0;
41 
42     if (valueFirst == PARAM_0) {
43         result = tcdrain(PARAM_0);
44     } else {
45         char path[] = PATH;
46         int fileDescribe;
47         fileDescribe = open(path, O_RDWR | O_NONBLOCK);
48         result = tcdrain(fileDescribe);
49         close(fileDescribe);
50     }
51     napi_value results = nullptr;
52     napi_create_int32(env, result, &results);
53     return results;
54 }
Tcflow(napi_env env, napi_callback_info info)55 static napi_value Tcflow(napi_env env, napi_callback_info info)
56 {
57     size_t argc = PARAM_1;
58     napi_value args[1] = {nullptr};
59     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
60     int valueFirst;
61     napi_get_value_int32(env, args[0], &valueFirst);
62     int result = PARAM_0;
63     const char *text = "Hello";
64 
65     if (valueFirst == PARAM_0) {
66         result = tcflow(FAIL, TCOON);
67     } else {
68         int fd = open(PATH, O_CREAT | O_NOCTTY);
69         grantpt(fd);
70         unlockpt(fd);
71         char *returnValue = ptsname(fd);
72         int fileDescribe = open(returnValue, O_CREAT | O_NOCTTY);
73         write(fileDescribe, text, strlen(text));
74         result = tcflow(fileDescribe, TCOON);
75         close(fd);
76         close(fileDescribe);
77     }
78     napi_value results = nullptr;
79     napi_create_int32(env, result, &results);
80     return results;
81 }
82 
Tcflush(napi_env env, napi_callback_info info)83 static napi_value Tcflush(napi_env env, napi_callback_info info)
84 {
85     size_t argc = PARAM_1;
86     napi_value args[1] = {nullptr};
87     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
88     int valueFirst;
89     napi_get_value_int32(env, args[0], &valueFirst);
90     int result = PARAM_0;
91     if (valueFirst == PARAM_0) {
92         result = tcflush(FAIL, FAIL);
93     } else {
94         int fd = open(PATH, O_RDWR | O_NOCTTY);
95         grantpt(fd);
96         unlockpt(fd);
97         char *returnValue = ptsname(fd);
98         int fileDescribe = open(returnValue, O_RDWR | O_NOCTTY);
99         result = tcflush(fileDescribe, TCOON);
100         close(fd);
101         close(fileDescribe);
102     }
103     napi_value results = nullptr;
104     napi_create_int32(env, result, &results);
105     return results;
106 }
Tcgetattr(napi_env env, napi_callback_info info)107 static napi_value Tcgetattr(napi_env env, napi_callback_info info)
108 {
109     size_t argc = PARAM_1;
110     napi_value args[1] = {nullptr};
111     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
112     int valueFirst;
113     napi_get_value_int32(env, args[0], &valueFirst);
114     int result = PARAM_0;
115 
116     if (valueFirst == PARAM_0) {
117         result = tcgetattr(FAIL, nullptr);
118     } else {
119         struct termios tio = {};
120         result = tcgetattr(STDIN_FILENO, &tio);
121     }
122     napi_value results = nullptr;
123     napi_create_int32(env, result, &results);
124     return results;
125 }
126 
Tcgetsid(napi_env env, napi_callback_info info)127 static napi_value Tcgetsid(napi_env env, napi_callback_info info)
128 {
129     size_t argc = PARAM_1;
130     napi_value args[1] = {nullptr};
131     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
132     int valueFirst;
133     napi_get_value_int32(env, args[0], &valueFirst);
134     int result = PARAM_0;
135 
136     if (valueFirst == PARAM_0) {
137         pid_t sid;
138         sid = tcgetsid(FAIL);
139         result = sid;
140     } else {
141         errno = ERRON_0;
142         pid_t sid;
143         sid = tcgetsid(STDIN_FILENO);
144         result = sid;
145     }
146 
147     napi_value results = nullptr;
148     napi_create_int32(env, result, &results);
149     return results;
150 }
151 
Tcsendbreak(napi_env env, napi_callback_info info)152 static napi_value Tcsendbreak(napi_env env, napi_callback_info info)
153 {
154     size_t argc = PARAM_1;
155     napi_value args[1] = {nullptr};
156     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
157     int valueFirst;
158     napi_get_value_int32(env, args[0], &valueFirst);
159     int result = PARAM_0;
160 
161     if (valueFirst == PARAM_0) {
162         result = tcsendbreak(FAIL, PARAM_0);
163     } else {
164         result = tcsendbreak(STDIN_FILENO, PARAM_0);
165     }
166     napi_value results = nullptr;
167     napi_create_int32(env, result, &results);
168     return results;
169 }
Tcsetattr(napi_env env, napi_callback_info info)170 static napi_value Tcsetattr(napi_env env, napi_callback_info info)
171 {
172     size_t argc = PARAM_1;
173     napi_value args[1] = {nullptr};
174     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
175     int valueFirst;
176     napi_get_value_int32(env, args[0], &valueFirst);
177     int result = PARAM_0;
178     const cc_t veof = (cc_t)0x07;
179 
180     if (valueFirst == PARAM_0) {
181         result = tcsetattr(FAIL, FAIL, nullptr);
182     } else {
183         struct termios tio = {};
184         tio.c_cc[VEOF] = veof;
185         result = tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio);
186         tcgetattr(STDIN_FILENO, &tio);
187     }
188     napi_value results = nullptr;
189     napi_create_int32(env, result, &results);
190     return results;
191 }
192 
Cfsetispeed(napi_env env, napi_callback_info info)193 static napi_value Cfsetispeed(napi_env env, napi_callback_info info)
194 {
195     struct termios term;
196     speed_t returnValue = cfsetispeed(&term, 1);
197     napi_value result;
198     napi_create_int32(env, returnValue, &result);
199     return result;
200 }
201 
Cfsetospeed(napi_env env, napi_callback_info info)202 static napi_value Cfsetospeed(napi_env env, napi_callback_info info)
203 {
204     struct termios term;
205     speed_t value = cfsetospeed(&term, 1);
206     napi_value result;
207     napi_create_int32(env, value, &result);
208     return result;
209 }
210 
Cfmakeraw(napi_env env, napi_callback_info info)211 static napi_value Cfmakeraw(napi_env env, napi_callback_info info)
212 {
213     struct termios t;
214     errno = ERRON_0;
215     memset(&t, PARAM_0xff, sizeof(t));
216     int ret = FAIL;
217     cfmakeraw(&t);
218     if (errno == PARAM_0) {
219         ret = SUCCESS;
220     }
221     napi_value result;
222     napi_create_int32(env, ret, &result);
223     return result;
224 }
225 
Cfgetispeed(napi_env env, napi_callback_info info)226 static napi_value Cfgetispeed(napi_env env, napi_callback_info info)
227 {
228     struct termios t = {};
229     int value = FAIL;
230     cfsetispeed(&t, B1200);
231     speed_t ret = cfgetispeed(&t);
232     if (ret >= PARAM_0) {
233         value = SUCCESS;
234     }
235     napi_value result;
236     napi_create_int32(env, value, &result);
237     return result;
238 }
239 
Cfgetospeed(napi_env env, napi_callback_info info)240 static napi_value Cfgetospeed(napi_env env, napi_callback_info info)
241 {
242     struct termios t = {};
243     int value = FAIL;
244     cfsetospeed(&t, B1200);
245     speed_t ret = cfgetospeed(&t);
246     if (ret >= PARAM_0) {
247         value = SUCCESS;
248     }
249     napi_value result;
250     napi_create_int32(env, value, &result);
251     return result;
252 }
253 
Cfsetspeed(napi_env env, napi_callback_info info)254 static napi_value Cfsetspeed(napi_env env, napi_callback_info info)
255 {
256     struct termios t = {};
257     int value = cfsetspeed(&t, B1200);
258     napi_value result;
259     napi_create_int32(env, value, &result);
260     return result;
261 }
262 
263 EXTERN_C_START
Init(napi_env env, napi_value exports)264 static napi_value Init(napi_env env, napi_value exports)
265 {
266     napi_property_descriptor desc[] = {
267         {"tcdrain", nullptr, Tcdrain, nullptr, nullptr, nullptr, napi_default, nullptr},
268         {"tcflow", nullptr, Tcflow, nullptr, nullptr, nullptr, napi_default, nullptr},
269         {"tcflush", nullptr, Tcflush, nullptr, nullptr, nullptr, napi_default, nullptr},
270         {"tcgetattr", nullptr, Tcgetattr, nullptr, nullptr, nullptr, napi_default, nullptr},
271         {"tcgetsid", nullptr, Tcgetsid, nullptr, nullptr, nullptr, napi_default, nullptr},
272         {"tcsendbreak", nullptr, Tcsendbreak, nullptr, nullptr, nullptr, napi_default, nullptr},
273         {"tcsetattr", nullptr, Tcsetattr, nullptr, nullptr, nullptr, napi_default, nullptr},
274         {"cfsetispeed", nullptr, Cfsetispeed, nullptr, nullptr, nullptr, napi_default, nullptr},
275         {"cfsetospeed", nullptr, Cfsetospeed, nullptr, nullptr, nullptr, napi_default, nullptr},
276         {"cfmakeraw", nullptr, Cfmakeraw, nullptr, nullptr, nullptr, napi_default, nullptr},
277         {"cfgetispeed", nullptr, Cfgetispeed, nullptr, nullptr, nullptr, napi_default, nullptr},
278         {"cfgetospeed", nullptr, Cfgetospeed, nullptr, nullptr, nullptr, napi_default, nullptr},
279         {"cfsetspeed", nullptr, Cfsetspeed, nullptr, nullptr, nullptr, napi_default, nullptr}};
280     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
281     return exports;
282 }
283 EXTERN_C_END
284 
285 static napi_module demoModule = {
286     .nm_version = 1,
287     .nm_flags = 0,
288     .nm_filename = nullptr,
289     .nm_register_func = Init,
290     .nm_modname = "termios",
291     .nm_priv = ((void *)0),
292     .reserved = {0},
293 };
294 
RegisterModule(void)295 extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&demoModule); }
296