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