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, ×pro); 415 if (res) { 416 return 0; 417 } 418 auto res1 = clock_gettime(CLOCK_MONOTONIC, ×sys); 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, ×); 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