• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "js_process.h"
17 
18 #include <cstdlib>
19 #include <vector>
20 
21 #include <grp.h>
22 #include <pthread.h>
23 #include <pwd.h>
24 #include <sched.h>
25 #include <unistd.h>
26 #include <uv.h>
27 
28 #include <sys/resource.h>
29 #include <sys/syscall.h>
30 #include <sys/types.h>
31 
32 #include "securec.h"
33 #include "process_helper.h"
34 #include "utils/log.h"
35 namespace OHOS::JsSysModule::Process {
36 
37     using namespace Commonlibrary::Platform;
38     namespace {
39         constexpr int NUM_OF_DATA = 4;
40         constexpr int PER_USER_RANGE = 100000;
41         constexpr int32_t NAPI_RETURN_ZERO = 0;
42         constexpr int32_t NAPI_RETURN_ONE = 1;
43     }
44     thread_local std::multimap<std::string, napi_ref> eventMap;
45     thread_local std::map<napi_ref, napi_ref> pendingUnHandledRejections;
46     // support events
47     thread_local std::string events = "UnHandleRejection";
48     thread_local int g_processStartRealtime = 0;
49 
GetUid(napi_env env) const50     napi_value Process::GetUid(napi_env env) const
51     {
52         napi_value result = nullptr;
53         auto processGetuid = static_cast<uint32_t>(getuid());
54         NAPI_CALL(env, napi_create_uint32(env, processGetuid, &result));
55         return result;
56     }
57 
GetGid(napi_env env) const58     napi_value Process::GetGid(napi_env env) const
59     {
60         napi_value result = nullptr;
61         auto processGetgid = static_cast<uint32_t>(getgid());
62         NAPI_CALL(env, napi_create_uint32(env, processGetgid, &result));
63         return result;
64     }
65 
GetEUid(napi_env env) const66     napi_value Process::GetEUid(napi_env env) const
67     {
68         napi_value result = nullptr;
69         auto processGeteuid = static_cast<uint32_t>(geteuid());
70         NAPI_CALL(env, napi_create_uint32(env, processGeteuid, &result));
71         return result;
72     }
73 
GetEGid(napi_env env) const74     napi_value Process::GetEGid(napi_env env) const
75     {
76         napi_value result = nullptr;
77         auto processGetegid = static_cast<uint32_t>(getegid());
78         NAPI_CALL(env, napi_create_uint32(env, processGetegid, &result));
79         return result;
80     }
81 
GetGroups(napi_env env) const82     napi_value Process::GetGroups(napi_env env) const
83     {
84         napi_value result = nullptr;
85         int progroups = getgroups(0, nullptr);
86         if (progroups == -1) {
87             napi_throw_error(env, "-1", "getgroups initialize failed");
88             return nullptr;
89         }
90         std::vector<gid_t> pgrous(progroups);
91         progroups = getgroups(progroups, pgrous.data());
92         if (progroups == -1) {
93             napi_throw_error(env, "-1", "getgroups");
94             return nullptr;
95         }
96         pgrous.resize(static_cast<size_t>(progroups));
97         gid_t proegid = getegid();
98         if (std::find(pgrous.begin(), pgrous.end(), proegid) == pgrous.end()) {
99             pgrous.push_back(proegid);
100         }
101         std::vector<uint32_t> array;
102         for (auto iter = pgrous.begin(); iter != pgrous.end(); iter++) {
103             auto receive = static_cast<uint32_t>(*iter);
104             array.push_back(receive);
105         }
106         NAPI_CALL(env, napi_create_array(env, &result));
107         size_t len = array.size();
108         for (size_t i = 0; i < len; i++) {
109             napi_value numvalue = nullptr;
110             NAPI_CALL(env, napi_create_uint32(env, array[i], &numvalue));
111             NAPI_CALL(env, napi_set_element(env, result, i, numvalue));
112         }
113         return result;
114     }
115 
GetPid(napi_env env) const116     napi_value Process::GetPid(napi_env env) const
117     {
118         napi_value result = nullptr;
119         auto proPid = static_cast<int32_t>(getpid());
120         napi_create_int32(env, proPid, &result);
121         return result;
122     }
123 
GetPpid(napi_env env) const124     napi_value Process::GetPpid(napi_env env) const
125     {
126         napi_value result = nullptr;
127         auto proPpid = static_cast<int32_t>(getppid());
128         napi_create_int32(env, proPpid, &result);
129         return result;
130     }
131 
Chdir(napi_env env,napi_value args) const132     void Process::Chdir(napi_env env, napi_value args) const
133     {
134         size_t prolen = 0;
135         if (napi_get_value_string_utf8(env, args, nullptr, 0, &prolen) != napi_ok) {
136             HILOG_ERROR("can not get args size");
137             return;
138         }
139         std::string result = "";
140         result.reserve(prolen + 1);
141         result.resize(prolen);
142         if (napi_get_value_string_utf8(env, args, result.data(), prolen + 1, &prolen) != napi_ok) {
143             HILOG_ERROR("can not get args value");
144             return;
145         }
146         int proerr = 0;
147         proerr = uv_chdir(result.c_str());
148         if (proerr) {
149             napi_throw_error(env, "-1", "chdir");
150             return;
151         }
152     }
153 
Kill(napi_env env,napi_value signal,napi_value proid)154     napi_value Process::Kill(napi_env env, napi_value signal, napi_value proid)
155     {
156         int32_t pid = 0;
157         int32_t sig = 0;
158         napi_get_value_int32(env, proid, &pid);
159         napi_get_value_int32(env, signal, &sig);
160         uv_pid_t ownPid = uv_os_getpid();
161         // 64:The maximum valid signal value is 64.
162         if (sig > 64 && (!pid || pid == -1 || pid == ownPid || pid == -ownPid)) {
163             napi_throw_error(env, "0", "process exit");
164             return nullptr;
165         }
166         bool flag = false;
167         int err = uv_kill(pid, sig);
168         if (!err) {
169             flag = true;
170         }
171         napi_value result = nullptr;
172         NAPI_CALL(env, napi_get_boolean(env, flag, &result));
173         return result;
174     }
175 
Uptime(napi_env env) const176     napi_value Process::Uptime(napi_env env) const
177     {
178         napi_value result = nullptr;
179         double runsystime = 0.0;
180         auto systimer = GetSysTimer();
181         if (systimer > 0) {
182             runsystime = static_cast<double>(systimer);
183             NAPI_CALL(env, napi_create_double(env, runsystime, &result));
184         } else {
185             napi_throw_error(env, "-1", "Failed to get systimer");
186             return nullptr;
187         }
188         return result;
189     }
190 
Exit(napi_env env,napi_value number) const191     void Process::Exit(napi_env env, napi_value number) const
192     {
193         int32_t result = 0;
194         napi_get_value_int32(env, number, &result);
195         ProcessExit(result);
196     }
197 
Cwd(napi_env env) const198     napi_value Process::Cwd(napi_env env) const
199     {
200         napi_value result = nullptr;
201         char buf[260 * NUM_OF_DATA] = { 0 }; // 260:Only numbers path String size is 260.
202         size_t length = sizeof(buf);
203         int err = uv_cwd(buf, &length);
204         if (err) {
205             napi_throw_error(env, "1", "uv_cwd");
206             return nullptr;
207         }
208         napi_create_string_utf8(env, buf, length, &result);
209         return result;
210     }
211 
Abort() const212     void Process::Abort() const
213     {
214         std::abort();
215     }
216 
On(napi_env env,napi_value str,napi_value function)217     void Process::On(napi_env env, napi_value str, napi_value function)
218     {
219         std::string result = "";
220         size_t bufferSize = 0;
221         if (napi_get_value_string_utf8(env, str, nullptr, NAPI_RETURN_ZERO, &bufferSize) != napi_ok) {
222             HILOG_ERROR("can not get str size");
223             return;
224         }
225         result.reserve(bufferSize + NAPI_RETURN_ONE);
226         result.resize(bufferSize);
227         if (napi_get_value_string_utf8(env, str, result.data(), bufferSize + NAPI_RETURN_ONE,
228                                        &bufferSize) != napi_ok) {
229             HILOG_ERROR("can not get str value");
230             return;
231         }
232         if (function == nullptr) {
233             HILOG_ERROR("function is nullptr");
234             return;
235         }
236         napi_ref myCallRef = nullptr;
237         napi_status status = napi_create_reference(env, function, 1, &myCallRef);
238         if (status != napi_ok) {
239             HILOG_ERROR("napi_create_reference is failed");
240             return;
241         }
242         if (!result.empty()) {
243             size_t pos = events.find(result);
244             if (pos == std::string::npos) {
245                 HILOG_ERROR("illegal event");
246                 return;
247             }
248             eventMap.insert(std::make_pair(result, myCallRef));
249         }
250     }
251 
Off(napi_env env,napi_value str)252     napi_value Process::Off(napi_env env, napi_value str)
253     {
254         size_t bufferSize = 0;
255         bool flag = false;
256         if (napi_get_value_string_utf8(env, str, nullptr, 0, &bufferSize) != napi_ok) {
257             HILOG_ERROR("can not get str size");
258             return nullptr;
259         }
260         std::string result = "";
261         result.reserve(bufferSize + 1);
262         result.resize(bufferSize);
263         if (napi_get_value_string_utf8(env, str, result.data(), bufferSize + 1, &bufferSize) != napi_ok) {
264             HILOG_ERROR("can not get str value");
265             return nullptr;
266         }
267         std::string temp = "";
268         temp = result;
269         auto iter = eventMap.equal_range(temp);
270         while (iter.first != iter.second) {
271             NAPI_CALL(env, napi_delete_reference(env, iter.first->second));
272             iter.first = eventMap.erase(iter.first);
273             flag = true;
274         }
275         napi_value convertResult = nullptr;
276         NAPI_CALL(env, napi_get_boolean(env, flag, &convertResult));
277         return convertResult;
278     }
279 
GetTid(napi_env env) const280     napi_value Process::GetTid(napi_env env) const
281     {
282         napi_value result = nullptr;
283         auto proTid = static_cast<int32_t>(GetThreadId());
284         napi_create_int64(env, proTid, &result);
285         return result;
286     }
287 
IsIsolatedProcess(napi_env env) const288     napi_value Process::IsIsolatedProcess(napi_env env) const
289     {
290         napi_value result = nullptr;
291         bool flag = true;
292         auto prouid = static_cast<int32_t>(getuid());
293         auto uid = prouid % PER_USER_RANGE;
294         if ((uid >= 99000 && uid <= 99999) || // 99999:Only isolateuid numbers between 99000 and 99999.
295             (uid >= 9000 && uid <= 98999)) { // 98999:Only appuid numbers between 9000 and 98999.
296             NAPI_CALL(env, napi_get_boolean(env, flag, &result));
297             return result;
298         }
299         flag = false;
300         NAPI_CALL(env, napi_get_boolean(env, flag, &result));
301         return result;
302     }
303 
IsAppUid(napi_env env,napi_value uid) const304     napi_value Process::IsAppUid(napi_env env, napi_value uid) const
305     {
306         int32_t number = 0;
307         napi_value result = nullptr;
308         bool flag = true;
309         napi_get_value_int32(env, uid, &number);
310         if (number > 0) {
311             const auto appId = number % PER_USER_RANGE;
312             if (appId >= FIRST_APPLICATION_UID && appId <= LAST_APPLICATION_UID) {
313                 napi_get_boolean(env, flag, &result);
314                 return result;
315             }
316             flag = false;
317             NAPI_CALL(env, napi_get_boolean(env, flag, &result));
318             return result;
319         } else {
320             flag = false;
321             NAPI_CALL(env, napi_get_boolean(env, flag, &result));
322             return result;
323         }
324     }
325 
Is64Bit(napi_env env) const326     napi_value Process::Is64Bit(napi_env env) const
327     {
328         napi_value result = nullptr;
329         bool flag = true;
330         auto size = sizeof(char*);
331         flag = (size == NUM_OF_DATA) ? false : true;
332         NAPI_CALL(env, napi_get_boolean(env, flag, &result));
333         return result;
334     }
335 
GetEnvironmentVar(napi_env env,napi_value name) const336     napi_value Process::GetEnvironmentVar(napi_env env, napi_value name) const
337     {
338         napi_value convertResult = nullptr;
339         char buf[260 * NUM_OF_DATA] = { 0 }; // 260:Only numbers path String size is 260.
340         size_t length = sizeof(buf);
341         size_t bufferSize = 0;
342         if (napi_get_value_string_utf8(env, name, nullptr, 0, &bufferSize) != napi_ok) {
343             HILOG_ERROR("can not get name size");
344             return nullptr;
345         }
346         std::string result = "";
347         result.reserve(bufferSize + 1);
348         result.resize(bufferSize);
349         if (napi_get_value_string_utf8(env, name, result.data(), bufferSize + 1, &bufferSize) != napi_ok) {
350             HILOG_ERROR("can not get name value");
351             return nullptr;
352         }
353         std::string temp = "";
354         temp = result;
355         auto envNum = uv_os_getenv(temp.c_str(), buf, &length);
356         if (envNum == UV_ENOENT) {
357             NAPI_CALL(env, napi_get_undefined(env, &convertResult));
358             return convertResult;
359         }
360         napi_create_string_utf8(env, buf, strlen(buf), &convertResult);
361         return convertResult;
362     }
363 
GetUidForName(napi_env env,napi_value name) const364     napi_value Process::GetUidForName(napi_env env, napi_value name) const
365     {
366         napi_value convertResult = nullptr;
367         size_t bufferSize = 0;
368         if (napi_get_value_string_utf8(env, name, nullptr, 0, &bufferSize) != napi_ok) {
369             HILOG_ERROR("can not get name size");
370             return nullptr;
371         }
372         std::string result = "";
373         result.reserve(bufferSize + 1);
374         result.resize(bufferSize);
375         if (napi_get_value_string_utf8(env, name, result.data(), bufferSize + 1, &bufferSize) != napi_ok) {
376             HILOG_ERROR("can not get name value");
377             return nullptr;
378         }
379         struct passwd user;
380         int32_t uid = 0;
381         struct passwd *bufp = nullptr;
382         long bufLen = sysconf(_SC_GETPW_R_SIZE_MAX);
383         if (bufLen == -1) {
384             bufLen = 16384; // 16384:Should be more than enough
385         }
386 
387         std::string buf;
388         buf.reserve(bufLen + 1);
389         buf.resize(bufLen);
390         if (getpwnam_r(result.c_str(), &user, buf.data(), bufLen, &bufp) == 0 && bufp != nullptr) {
391             uid = static_cast<int32_t>(bufp->pw_uid);
392             napi_create_int32(env, uid, &convertResult);
393             return convertResult;
394         }
395         napi_create_int32(env, (-1), &convertResult);
396         return convertResult;
397     }
398 
GetThreadPriority(napi_env env,napi_value tid) const399     napi_value Process::GetThreadPriority(napi_env env, napi_value tid) const
400     {
401         errno = 0;
402         napi_value result = nullptr;
403         int32_t proTid = 0;
404         napi_get_value_int32(env, tid, &proTid);
405         int32_t pri = getpriority(PRIO_PROCESS, proTid);
406         if (errno) {
407             napi_throw_error(env, "-1", "Invalid tid");
408             return nullptr;
409         }
410         napi_create_int32(env, pri, &result);
411         return result;
412     }
413 
InitProcessStartRealtime(napi_env env)414     void Process::InitProcessStartRealtime(napi_env env)
415     {
416         struct timespec timespro = {0, 0};
417         struct timespec timessys = {0, 0};
418         auto res = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &timespro);
419         if (res) {
420             g_processStartRealtime = 0;
421             return;
422         }
423         auto res1 = clock_gettime(CLOCK_MONOTONIC, &timessys);
424         if (res1) {
425             g_processStartRealtime = 0;
426             return;
427         }
428         int whenpro = ConvertTime(timespro.tv_sec, timespro.tv_nsec);
429         int whensys = ConvertTime(timessys.tv_sec, timessys.tv_nsec);
430         g_processStartRealtime = (whensys - whenpro);
431     }
432 
GetStartRealtime(napi_env env) const433     napi_value Process::GetStartRealtime(napi_env env) const
434     {
435         napi_value result = nullptr;
436         napi_create_int32(env, g_processStartRealtime, &result);
437         return result;
438     }
439 
ConvertTime(time_t tvsec,int64_t tvnsec) const440     int Process::ConvertTime(time_t tvsec, int64_t tvnsec) const
441     {
442         return int(tvsec * 1000) + int(tvnsec / 1000000); // 98999:Only converttime numbers is 1000 and 1000000.
443     }
444 
GetPastCputime(napi_env env) const445     napi_value Process::GetPastCputime(napi_env env) const
446     {
447         struct timespec times = {0, 0};
448         napi_value result = nullptr;
449         auto res = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &times);
450         if (res) {
451             return 0;
452         }
453         int when =  ConvertTime(times.tv_sec, times.tv_nsec);
454         napi_create_int32(env, when, &result);
455         return result;
456     }
457 
GetSystemConfig(napi_env env,napi_value name) const458     napi_value Process::GetSystemConfig(napi_env env, napi_value name) const
459     {
460         int32_t number = 0;
461         napi_value result = nullptr;
462         napi_get_value_int32(env, name, &number);
463         auto configinfo = static_cast<int32_t>(sysconf(number));
464         napi_create_int32(env, configinfo, &result);
465         return result;
466     }
467 
UnHandle(napi_env env,napi_value promise,napi_value reason)468     napi_value UnHandle(napi_env env, napi_value promise, napi_value reason)
469     {
470         napi_ref promiseRef = nullptr;
471         NAPI_CALL(env, napi_create_reference(env, promise, 1, &promiseRef));
472         napi_ref reasonRef = nullptr;
473         NAPI_CALL(env, napi_create_reference(env, reason, 1, &reasonRef));
474         pendingUnHandledRejections.insert(std::make_pair(promiseRef, reasonRef));
475         napi_value res = nullptr;
476         NAPI_CALL(env, napi_get_undefined(env, &res));
477         return res;
478     }
479 
AddHandle(napi_env env,napi_value promise)480     napi_value AddHandle(napi_env env, napi_value promise)
481     {
482         auto iter = pendingUnHandledRejections.begin();
483         while (iter != pendingUnHandledRejections.end()) {
484             napi_value prom = nullptr;
485             NAPI_CALL(env, napi_get_reference_value(env, iter->first, &prom));
486             bool isEquals = false;
487             NAPI_CALL(env, napi_strict_equals(env, promise, prom, &isEquals));
488             if (isEquals) {
489                 NAPI_CALL(env, napi_delete_reference(env, iter->first));
490                 NAPI_CALL(env, napi_delete_reference(env, iter->second));
491                 iter = pendingUnHandledRejections.erase(iter);
492                 continue;
493             }
494             iter++;
495         }
496         napi_value res = nullptr;
497         NAPI_CALL(env, napi_get_undefined(env, &res));
498         return res;
499     }
500 
UnHandleRejection(napi_env env,napi_value promise,napi_value reason)501     napi_value UnHandleRejection(napi_env env, napi_value promise, napi_value reason)
502     {
503         auto it = eventMap.find("UnHandleRejection");
504         if (it != eventMap.end()) {
505             napi_value global = nullptr;
506             NAPI_CALL(env, napi_get_global(env, &global));
507             size_t argc = 2; // 2 parameter size
508             napi_value args[] = {reason, promise};
509             auto iter = eventMap.equal_range("UnHandleRejection");
510             while (iter.first != iter.second) {
511                 napi_value cb = nullptr;
512                 NAPI_CALL(env, napi_get_reference_value(env, iter.first->second, &cb));
513                 napi_value result = nullptr;
514                 NAPI_CALL(env, napi_call_function(env, global, cb, argc, args, &result));
515                 iter.first++;
516             }
517         }
518         napi_value res = nullptr;
519         NAPI_CALL(env, napi_get_undefined(env, &res));
520         return res;
521     }
522 
OnUnHandleRejection(napi_env env,napi_callback_info info)523     static napi_value OnUnHandleRejection(napi_env env, napi_callback_info info)
524     {
525         size_t argc = 3; // 3 parameter size
526         napi_value argv[3] = {0}; // 3 array length
527         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
528         int32_t event = 0;
529         NAPI_CALL(env, napi_get_value_int32(env, argv[0], &event));
530         if (event == static_cast<int32_t>(PromiseRejectionEvent::REJECT)) {
531             UnHandle(env, argv[1], argv[2]); // 2 array index
532         } else if (event == static_cast<int32_t>(PromiseRejectionEvent::HANDLE)) {
533             AddHandle(env, argv[1]);
534         }
535         napi_value res = nullptr;
536         NAPI_CALL(env, napi_get_undefined(env, &res));
537         return res;
538     }
539 
CheckUnhandleRejections(napi_env env,napi_callback_info info)540     static napi_value CheckUnhandleRejections(napi_env env, napi_callback_info info)
541     {
542         if (!pendingUnHandledRejections.empty()) {
543             auto iter = pendingUnHandledRejections.begin();
544             while (iter != pendingUnHandledRejections.end()) {
545                 napi_value promise = nullptr;
546                 NAPI_CALL(env, napi_get_reference_value(env, iter->first, &promise));
547                 napi_value reason = nullptr;
548                 NAPI_CALL(env, napi_get_reference_value(env, iter->second, &reason));
549 
550                 UnHandleRejection(env, promise, reason);
551 
552                 NAPI_CALL(env, napi_delete_reference(env, iter->first));
553                 NAPI_CALL(env, napi_delete_reference(env, iter->second));
554                 iter = pendingUnHandledRejections.erase(iter);
555             }
556         }
557         napi_value res = nullptr;
558         NAPI_CALL(env, napi_get_undefined(env, &res));
559         return res;
560     }
561 
SetRejectionCallback(napi_env env) const562     napi_value Process::SetRejectionCallback(napi_env env) const
563     {
564         napi_value cb = nullptr;
565         std::string callbackName = "onUnHandleRejection";
566         NAPI_CALL(env, napi_create_function(env, callbackName.c_str(), callbackName.size(), OnUnHandleRejection,
567                                              nullptr, &cb));
568         napi_ref unHandleRejectionCallbackRef = nullptr;
569         NAPI_CALL(env, napi_create_reference(env, cb, 1, &unHandleRejectionCallbackRef));
570 
571         napi_ref checkUnhandleRejectionsRef = nullptr;
572         napi_value checkcb = nullptr;
573         std::string cbName = "CheckUnhandleRejections";
574         NAPI_CALL(env, napi_create_function(env, cbName.c_str(), cbName.size(), CheckUnhandleRejections,
575                                              nullptr, &checkcb));
576         NAPI_CALL(env, napi_create_reference(env, checkcb, 1, &checkUnhandleRejectionsRef));
577         NAPI_CALL(env, napi_set_promise_rejection_callback(env,
578                   unHandleRejectionCallbackRef, checkUnhandleRejectionsRef));
579         napi_value res = nullptr;
580         NAPI_CALL(env, napi_get_undefined(env, &res));
581         return res;
582     }
583 
ClearReference(napi_env env)584     void Process::ClearReference(napi_env env)
585     {
586         auto iter = eventMap.begin();
587         while (iter != eventMap.end()) {
588             napi_status status = napi_delete_reference(env, iter->second);
589             if (status != napi_ok) {
590                 napi_throw_error(env, nullptr, "ClearReference failed");
591                 return;
592             }
593             iter++;
594         }
595         eventMap.clear();
596     }
597 
IsAppUid(napi_env env,napi_value uid) const598     napi_value ProcessManager::IsAppUid(napi_env env, napi_value uid) const
599     {
600         int32_t number = 0;
601         napi_value result = nullptr;
602         bool flag = true;
603         napi_get_value_int32(env, uid, &number);
604         if (number > 0) {
605             const auto appId = number % PER_USER_RANGE;
606             if (appId >= FIRST_APPLICATION_UID && appId <= LAST_APPLICATION_UID) {
607                 napi_get_boolean(env, flag, &result);
608                 return result;
609             }
610             flag = false;
611             NAPI_CALL(env, napi_get_boolean(env, flag, &result));
612             return result;
613         } else {
614             flag = false;
615             NAPI_CALL(env, napi_get_boolean(env, flag, &result));
616             return result;
617         }
618     }
619 
GetUidForName(napi_env env,napi_value name) const620     napi_value ProcessManager::GetUidForName(napi_env env, napi_value name) const
621     {
622         napi_value convertResult = nullptr;
623         size_t bufferSize = 0;
624         if (napi_get_value_string_utf8(env, name, nullptr, 0, &bufferSize) != napi_ok) {
625             HILOG_ERROR("can not get name size");
626             return nullptr;
627         }
628         std::string result = "";
629         result.reserve(bufferSize + 1);
630         result.resize(bufferSize);
631         if (napi_get_value_string_utf8(env, name, result.data(), bufferSize + 1, &bufferSize) != napi_ok) {
632             HILOG_ERROR("can not get name value");
633             return nullptr;
634         }
635         struct passwd user;
636         int32_t uid = 0;
637         struct passwd *bufp = nullptr;
638         long bufLen = sysconf(_SC_GETPW_R_SIZE_MAX);
639         if (bufLen == -1) {
640             bufLen = 16384; // 16384:Should be more than enough
641         }
642 
643         std::string buf;
644         buf.reserve(bufLen + 1);
645         buf.resize(bufLen);
646         if (getpwnam_r(result.c_str(), &user, buf.data(), bufLen, &bufp) == 0 && bufp != nullptr) {
647             uid = static_cast<int32_t>(bufp->pw_uid);
648             napi_create_int32(env, uid, &convertResult);
649             return convertResult;
650         }
651         napi_create_int32(env, (-1), &convertResult);
652         return convertResult;
653     }
654 
GetThreadPriority(napi_env env,napi_value tid) const655     napi_value ProcessManager::GetThreadPriority(napi_env env, napi_value tid) const
656     {
657         errno = 0;
658         napi_value result = nullptr;
659         int32_t proTid = 0;
660         napi_get_value_int32(env, tid, &proTid);
661         int32_t pri = GetThreadPRY(proTid);
662         if (errno) {
663             napi_throw_error(env, "-1", "Invalid tid");
664             return nullptr;
665         }
666         napi_create_int32(env, pri, &result);
667         return result;
668     }
669 
GetSystemConfig(napi_env env,napi_value name) const670     napi_value ProcessManager::GetSystemConfig(napi_env env, napi_value name) const
671     {
672         int32_t number = 0;
673         napi_value result = nullptr;
674         napi_get_value_int32(env, name, &number);
675         int32_t configinfo = GetSysConfig(number);
676         napi_create_int32(env, configinfo, &result);
677         return result;
678     }
679 
GetEnvironmentVar(napi_env env,napi_value name) const680     napi_value ProcessManager::GetEnvironmentVar(napi_env env, napi_value name) const
681     {
682         size_t bufferSize = 0;
683         if (napi_get_value_string_utf8(env, name, nullptr, 0, &bufferSize) != napi_ok) {
684             HILOG_ERROR("can not get name size");
685             return nullptr;
686         }
687         std::string result = "";
688         result.reserve(bufferSize + 1);
689         result.resize(bufferSize);
690         if (napi_get_value_string_utf8(env, name, result.data(), bufferSize + 1, &bufferSize) != napi_ok) {
691             HILOG_ERROR("can not get name value");
692             return nullptr;
693         }
694         std::string temp = "";
695         temp = result;
696         char buf[260 * NUM_OF_DATA] = { 0 }; // 260:Only numbers path String size is 260.
697         size_t length = sizeof(buf);
698         auto envNum = uv_os_getenv(temp.c_str(), buf, &length);
699         napi_value convertResult = nullptr;
700         if (envNum == UV_ENOENT) {
701             NAPI_CALL(env, napi_get_undefined(env, &convertResult));
702             return convertResult;
703         }
704         napi_create_string_utf8(env, buf, strlen(buf), &convertResult);
705         return convertResult;
706     }
707 
Exit(napi_env env,napi_value number) const708     void ProcessManager::Exit(napi_env env, napi_value number) const
709     {
710         int32_t result = 0;
711         napi_get_value_int32(env, number, &result);
712         ProcessExit(result);
713     }
714 
Kill(napi_env env,napi_value signal,napi_value proid)715     napi_value ProcessManager::Kill(napi_env env, napi_value signal, napi_value proid)
716     {
717         int32_t pid = 0;
718         int32_t sig = 0;
719         napi_get_value_int32(env, proid, &pid);
720         napi_get_value_int32(env, signal, &sig);
721         uv_pid_t ownPid = uv_os_getpid();
722         // 64:The maximum valid signal value is 64.
723         if (sig > 64 && (!pid || pid == -1 || pid == ownPid || pid == -ownPid)) {
724             napi_throw_error(env, "0", "process exit");
725             return nullptr;
726         }
727         bool flag = false;
728         int err = uv_kill(pid, sig);
729         if (!err) {
730             flag = true;
731         }
732         napi_value result = nullptr;
733         NAPI_CALL(env, napi_get_boolean(env, flag, &result));
734         return result;
735     }
736 } // namespace OHOS::JsSysModule::Process
737