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