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