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