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