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, ×pro); 419 if (res) { 420 g_processStartRealtime = 0; 421 return; 422 } 423 auto res1 = clock_gettime(CLOCK_MONOTONIC, ×sys); 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, ×); 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