14d6c458bSopenharmony_ci/*
24d6c458bSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
34d6c458bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44d6c458bSopenharmony_ci * you may not use this file except in compliance with the License.
54d6c458bSopenharmony_ci * You may obtain a copy of the License at
64d6c458bSopenharmony_ci *
74d6c458bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84d6c458bSopenharmony_ci *
94d6c458bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104d6c458bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114d6c458bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124d6c458bSopenharmony_ci * See the License for the specific language governing permissions and
134d6c458bSopenharmony_ci * limitations under the License.
144d6c458bSopenharmony_ci */
154d6c458bSopenharmony_ci
164d6c458bSopenharmony_ci#include "js_process.h"
174d6c458bSopenharmony_ci
184d6c458bSopenharmony_ci#include <cstdlib>
194d6c458bSopenharmony_ci#include <vector>
204d6c458bSopenharmony_ci
214d6c458bSopenharmony_ci#include <grp.h>
224d6c458bSopenharmony_ci#include <mutex>
234d6c458bSopenharmony_ci#include <pthread.h>
244d6c458bSopenharmony_ci#include <pwd.h>
254d6c458bSopenharmony_ci#include <sched.h>
264d6c458bSopenharmony_ci#include <unistd.h>
274d6c458bSopenharmony_ci#include <uv.h>
284d6c458bSopenharmony_ci
294d6c458bSopenharmony_ci#include <sys/resource.h>
304d6c458bSopenharmony_ci#include <sys/syscall.h>
314d6c458bSopenharmony_ci#include <sys/types.h>
324d6c458bSopenharmony_ci
334d6c458bSopenharmony_ci#include "securec.h"
344d6c458bSopenharmony_ci#include "process_helper.h"
354d6c458bSopenharmony_ci#include "tools/log.h"
364d6c458bSopenharmony_cinamespace OHOS::JsSysModule::Process {
374d6c458bSopenharmony_ci
384d6c458bSopenharmony_ci    using namespace Commonlibrary::Platform;
394d6c458bSopenharmony_ci    namespace {
404d6c458bSopenharmony_ci        constexpr int NUM_OF_DATA = 4;
414d6c458bSopenharmony_ci        constexpr int PER_USER_RANGE = 100000;
424d6c458bSopenharmony_ci        constexpr int32_t NAPI_RETURN_ZERO = 0;
434d6c458bSopenharmony_ci        constexpr int32_t NAPI_RETURN_ONE = 1;
444d6c458bSopenharmony_ci    }
454d6c458bSopenharmony_ci    constexpr int FIRST_APPLICATION_UID = 10000; // 10000 : bundleId lower limit
464d6c458bSopenharmony_ci    constexpr int LAST_APPLICATION_UID = 65535; // 65535 : bundleId upper limit
474d6c458bSopenharmony_ci    thread_local std::multimap<std::string, napi_ref> eventMap;
484d6c458bSopenharmony_ci    static std::mutex g_sharedTimedMutex;
494d6c458bSopenharmony_ci    thread_local std::map<napi_ref, napi_ref> pendingUnHandledRejections;
504d6c458bSopenharmony_ci    // support g_events
514d6c458bSopenharmony_ci    thread_local std::string g_events = "UnHandleRejection";
524d6c458bSopenharmony_ci
534d6c458bSopenharmony_ci    napi_value Process::GetUid(napi_env env) const
544d6c458bSopenharmony_ci    {
554d6c458bSopenharmony_ci        napi_value result = nullptr;
564d6c458bSopenharmony_ci        auto processGetuid = static_cast<uint32_t>(getuid());
574d6c458bSopenharmony_ci        NAPI_CALL(env, napi_create_uint32(env, processGetuid, &result));
584d6c458bSopenharmony_ci        return result;
594d6c458bSopenharmony_ci    }
604d6c458bSopenharmony_ci
614d6c458bSopenharmony_ci    napi_value Process::GetGid(napi_env env) const
624d6c458bSopenharmony_ci    {
634d6c458bSopenharmony_ci        napi_value result = nullptr;
644d6c458bSopenharmony_ci        auto processGetgid = static_cast<uint32_t>(getgid());
654d6c458bSopenharmony_ci        NAPI_CALL(env, napi_create_uint32(env, processGetgid, &result));
664d6c458bSopenharmony_ci        return result;
674d6c458bSopenharmony_ci    }
684d6c458bSopenharmony_ci
694d6c458bSopenharmony_ci    napi_value Process::GetEUid(napi_env env) const
704d6c458bSopenharmony_ci    {
714d6c458bSopenharmony_ci        napi_value result = nullptr;
724d6c458bSopenharmony_ci        auto processGeteuid = static_cast<uint32_t>(geteuid());
734d6c458bSopenharmony_ci        NAPI_CALL(env, napi_create_uint32(env, processGeteuid, &result));
744d6c458bSopenharmony_ci        return result;
754d6c458bSopenharmony_ci    }
764d6c458bSopenharmony_ci
774d6c458bSopenharmony_ci    napi_value Process::GetEGid(napi_env env) const
784d6c458bSopenharmony_ci    {
794d6c458bSopenharmony_ci        napi_value result = nullptr;
804d6c458bSopenharmony_ci        auto processGetegid = static_cast<uint32_t>(getegid());
814d6c458bSopenharmony_ci        NAPI_CALL(env, napi_create_uint32(env, processGetegid, &result));
824d6c458bSopenharmony_ci        return result;
834d6c458bSopenharmony_ci    }
844d6c458bSopenharmony_ci
854d6c458bSopenharmony_ci    napi_value Process::GetGroups(napi_env env) const
864d6c458bSopenharmony_ci    {
874d6c458bSopenharmony_ci        napi_value result = nullptr;
884d6c458bSopenharmony_ci        int progroups = getgroups(0, nullptr);
894d6c458bSopenharmony_ci        if (progroups == -1) {
904d6c458bSopenharmony_ci            napi_throw_error(env, "-1", "getgroups initialize failed");
914d6c458bSopenharmony_ci            return nullptr;
924d6c458bSopenharmony_ci        }
934d6c458bSopenharmony_ci        std::vector<gid_t> pgrous(progroups);
944d6c458bSopenharmony_ci        progroups = getgroups(progroups, pgrous.data());
954d6c458bSopenharmony_ci        if (progroups == -1) {
964d6c458bSopenharmony_ci            napi_throw_error(env, "-1", "getgroups");
974d6c458bSopenharmony_ci            return nullptr;
984d6c458bSopenharmony_ci        }
994d6c458bSopenharmony_ci        pgrous.resize(static_cast<size_t>(progroups));
1004d6c458bSopenharmony_ci        gid_t proegid = getegid();
1014d6c458bSopenharmony_ci        if (std::find(pgrous.begin(), pgrous.end(), proegid) == pgrous.end()) {
1024d6c458bSopenharmony_ci            pgrous.push_back(proegid);
1034d6c458bSopenharmony_ci        }
1044d6c458bSopenharmony_ci        std::vector<uint32_t> array;
1054d6c458bSopenharmony_ci        for (auto iter = pgrous.begin(); iter != pgrous.end(); iter++) {
1064d6c458bSopenharmony_ci            auto receive = static_cast<uint32_t>(*iter);
1074d6c458bSopenharmony_ci            array.push_back(receive);
1084d6c458bSopenharmony_ci        }
1094d6c458bSopenharmony_ci        NAPI_CALL(env, napi_create_array(env, &result));
1104d6c458bSopenharmony_ci        size_t len = array.size();
1114d6c458bSopenharmony_ci        for (size_t i = 0; i < len; i++) {
1124d6c458bSopenharmony_ci            napi_value numvalue = nullptr;
1134d6c458bSopenharmony_ci            NAPI_CALL(env, napi_create_uint32(env, array[i], &numvalue));
1144d6c458bSopenharmony_ci            NAPI_CALL(env, napi_set_element(env, result, i, numvalue));
1154d6c458bSopenharmony_ci        }
1164d6c458bSopenharmony_ci        return result;
1174d6c458bSopenharmony_ci    }
1184d6c458bSopenharmony_ci
1194d6c458bSopenharmony_ci    napi_value Process::GetPid(napi_env env) const
1204d6c458bSopenharmony_ci    {
1214d6c458bSopenharmony_ci        napi_value result = nullptr;
1224d6c458bSopenharmony_ci        auto proPid = static_cast<int32_t>(getpid());
1234d6c458bSopenharmony_ci        napi_create_int32(env, proPid, &result);
1244d6c458bSopenharmony_ci        return result;
1254d6c458bSopenharmony_ci    }
1264d6c458bSopenharmony_ci
1274d6c458bSopenharmony_ci    napi_value Process::GetPpid(napi_env env) const
1284d6c458bSopenharmony_ci    {
1294d6c458bSopenharmony_ci        napi_value result = nullptr;
1304d6c458bSopenharmony_ci        auto proPpid = static_cast<int32_t>(getppid());
1314d6c458bSopenharmony_ci        napi_create_int32(env, proPpid, &result);
1324d6c458bSopenharmony_ci        return result;
1334d6c458bSopenharmony_ci    }
1344d6c458bSopenharmony_ci
1354d6c458bSopenharmony_ci    void Process::Chdir(napi_env env, napi_value args) const
1364d6c458bSopenharmony_ci    {
1374d6c458bSopenharmony_ci        size_t prolen = 0;
1384d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, args, nullptr, 0, &prolen) != napi_ok) {
1394d6c458bSopenharmony_ci            HILOG_ERROR("can not get args size");
1404d6c458bSopenharmony_ci            return;
1414d6c458bSopenharmony_ci        }
1424d6c458bSopenharmony_ci        std::string result = "";
1434d6c458bSopenharmony_ci        result.reserve(prolen + 1);
1444d6c458bSopenharmony_ci        result.resize(prolen);
1454d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, args, result.data(), prolen + 1, &prolen) != napi_ok) {
1464d6c458bSopenharmony_ci            HILOG_ERROR("can not get args value");
1474d6c458bSopenharmony_ci            return;
1484d6c458bSopenharmony_ci        }
1494d6c458bSopenharmony_ci        int proerr = 0;
1504d6c458bSopenharmony_ci        proerr = uv_chdir(result.c_str());
1514d6c458bSopenharmony_ci        if (proerr) {
1524d6c458bSopenharmony_ci            napi_throw_error(env, "-1", "chdir");
1534d6c458bSopenharmony_ci            return;
1544d6c458bSopenharmony_ci        }
1554d6c458bSopenharmony_ci    }
1564d6c458bSopenharmony_ci
1574d6c458bSopenharmony_ci    napi_value Process::Kill(napi_env env, napi_value signal, napi_value proid)
1584d6c458bSopenharmony_ci    {
1594d6c458bSopenharmony_ci        int32_t pid = 0;
1604d6c458bSopenharmony_ci        int32_t sig = 0;
1614d6c458bSopenharmony_ci        napi_get_value_int32(env, proid, &pid);
1624d6c458bSopenharmony_ci        napi_get_value_int32(env, signal, &sig);
1634d6c458bSopenharmony_ci        uv_pid_t ownPid = uv_os_getpid();
1644d6c458bSopenharmony_ci        // 64:The maximum valid signal value is 64.
1654d6c458bSopenharmony_ci        if (sig > 64 && (!pid || pid == -1 || pid == ownPid || pid == -ownPid)) {
1664d6c458bSopenharmony_ci            napi_throw_error(env, "0", "process exit");
1674d6c458bSopenharmony_ci            return nullptr;
1684d6c458bSopenharmony_ci        }
1694d6c458bSopenharmony_ci        bool flag = false;
1704d6c458bSopenharmony_ci        int err = uv_kill(pid, sig);
1714d6c458bSopenharmony_ci        if (!err) {
1724d6c458bSopenharmony_ci            flag = true;
1734d6c458bSopenharmony_ci        }
1744d6c458bSopenharmony_ci        napi_value result = nullptr;
1754d6c458bSopenharmony_ci        NAPI_CALL(env, napi_get_boolean(env, flag, &result));
1764d6c458bSopenharmony_ci        return result;
1774d6c458bSopenharmony_ci    }
1784d6c458bSopenharmony_ci
1794d6c458bSopenharmony_ci    napi_value Process::Uptime(napi_env env) const
1804d6c458bSopenharmony_ci    {
1814d6c458bSopenharmony_ci        napi_value result = nullptr;
1824d6c458bSopenharmony_ci        double runsystime = 0.0;
1834d6c458bSopenharmony_ci        auto systimer = GetSysTimer();
1844d6c458bSopenharmony_ci        if (systimer > 0) {
1854d6c458bSopenharmony_ci            runsystime = static_cast<double>(systimer);
1864d6c458bSopenharmony_ci            NAPI_CALL(env, napi_create_double(env, runsystime, &result));
1874d6c458bSopenharmony_ci        } else {
1884d6c458bSopenharmony_ci            napi_throw_error(env, "-1", "Failed to get systimer");
1894d6c458bSopenharmony_ci            return nullptr;
1904d6c458bSopenharmony_ci        }
1914d6c458bSopenharmony_ci        return result;
1924d6c458bSopenharmony_ci    }
1934d6c458bSopenharmony_ci
1944d6c458bSopenharmony_ci    void Process::Exit(napi_env env, napi_value number) const
1954d6c458bSopenharmony_ci    {
1964d6c458bSopenharmony_ci        int32_t result = 0;
1974d6c458bSopenharmony_ci        napi_get_value_int32(env, number, &result);
1984d6c458bSopenharmony_ci        ProcessExit(result);
1994d6c458bSopenharmony_ci    }
2004d6c458bSopenharmony_ci
2014d6c458bSopenharmony_ci    napi_value Process::Cwd(napi_env env) const
2024d6c458bSopenharmony_ci    {
2034d6c458bSopenharmony_ci        napi_value result = nullptr;
2044d6c458bSopenharmony_ci        char buf[260 * NUM_OF_DATA] = { 0 }; // 260:Only numbers path String size is 260.
2054d6c458bSopenharmony_ci        size_t length = sizeof(buf);
2064d6c458bSopenharmony_ci        int err = uv_cwd(buf, &length);
2074d6c458bSopenharmony_ci        if (err) {
2084d6c458bSopenharmony_ci            napi_throw_error(env, "1", "uv_cwd");
2094d6c458bSopenharmony_ci            return nullptr;
2104d6c458bSopenharmony_ci        }
2114d6c458bSopenharmony_ci        napi_create_string_utf8(env, buf, length, &result);
2124d6c458bSopenharmony_ci        return result;
2134d6c458bSopenharmony_ci    }
2144d6c458bSopenharmony_ci
2154d6c458bSopenharmony_ci    void Process::Abort() const
2164d6c458bSopenharmony_ci    {
2174d6c458bSopenharmony_ci        std::abort();
2184d6c458bSopenharmony_ci    }
2194d6c458bSopenharmony_ci
2204d6c458bSopenharmony_ci    void Process::On(napi_env env, napi_value str, napi_value function)
2214d6c458bSopenharmony_ci    {
2224d6c458bSopenharmony_ci        std::string result = "";
2234d6c458bSopenharmony_ci        size_t bufferSize = 0;
2244d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, str, nullptr, NAPI_RETURN_ZERO, &bufferSize) != napi_ok) {
2254d6c458bSopenharmony_ci            HILOG_ERROR("can not get str size");
2264d6c458bSopenharmony_ci            return;
2274d6c458bSopenharmony_ci        }
2284d6c458bSopenharmony_ci        result.reserve(bufferSize + NAPI_RETURN_ONE);
2294d6c458bSopenharmony_ci        result.resize(bufferSize);
2304d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, str, result.data(), bufferSize + NAPI_RETURN_ONE,
2314d6c458bSopenharmony_ci                                       &bufferSize) != napi_ok) {
2324d6c458bSopenharmony_ci            HILOG_ERROR("can not get str value");
2334d6c458bSopenharmony_ci            return;
2344d6c458bSopenharmony_ci        }
2354d6c458bSopenharmony_ci        if (function == nullptr) {
2364d6c458bSopenharmony_ci            HILOG_ERROR("function is nullptr");
2374d6c458bSopenharmony_ci            return;
2384d6c458bSopenharmony_ci        }
2394d6c458bSopenharmony_ci        napi_ref myCallRef = nullptr;
2404d6c458bSopenharmony_ci        napi_status status = napi_create_reference(env, function, 1, &myCallRef);
2414d6c458bSopenharmony_ci        if (status != napi_ok) {
2424d6c458bSopenharmony_ci            HILOG_ERROR("napi_create_reference is failed");
2434d6c458bSopenharmony_ci            return;
2444d6c458bSopenharmony_ci        }
2454d6c458bSopenharmony_ci        if (!result.empty()) {
2464d6c458bSopenharmony_ci            size_t pos = g_events.find(result);
2474d6c458bSopenharmony_ci            if (pos == std::string::npos) {
2484d6c458bSopenharmony_ci                HILOG_ERROR("illegal event");
2494d6c458bSopenharmony_ci                return;
2504d6c458bSopenharmony_ci            }
2514d6c458bSopenharmony_ci            std::unique_lock<std::mutex> lock(g_sharedTimedMutex);
2524d6c458bSopenharmony_ci            eventMap.insert(std::make_pair(result, myCallRef));
2534d6c458bSopenharmony_ci        }
2544d6c458bSopenharmony_ci    }
2554d6c458bSopenharmony_ci
2564d6c458bSopenharmony_ci    napi_value Process::Off(napi_env env, napi_value str)
2574d6c458bSopenharmony_ci    {
2584d6c458bSopenharmony_ci        size_t bufferSize = 0;
2594d6c458bSopenharmony_ci        bool flag = false;
2604d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, str, nullptr, 0, &bufferSize) != napi_ok) {
2614d6c458bSopenharmony_ci            HILOG_ERROR("can not get str size");
2624d6c458bSopenharmony_ci            return nullptr;
2634d6c458bSopenharmony_ci        }
2644d6c458bSopenharmony_ci        std::string result = "";
2654d6c458bSopenharmony_ci        result.reserve(bufferSize + 1);
2664d6c458bSopenharmony_ci        result.resize(bufferSize);
2674d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, str, result.data(), bufferSize + 1, &bufferSize) != napi_ok) {
2684d6c458bSopenharmony_ci            HILOG_ERROR("can not get str value");
2694d6c458bSopenharmony_ci            return nullptr;
2704d6c458bSopenharmony_ci        }
2714d6c458bSopenharmony_ci        std::string temp = "";
2724d6c458bSopenharmony_ci        temp = result;
2734d6c458bSopenharmony_ci        auto iter = eventMap.equal_range(temp);
2744d6c458bSopenharmony_ci        while (iter.first != iter.second) {
2754d6c458bSopenharmony_ci            NAPI_CALL(env, napi_delete_reference(env, iter.first->second));
2764d6c458bSopenharmony_ci            std::unique_lock<std::mutex> lock(g_sharedTimedMutex);
2774d6c458bSopenharmony_ci            iter.first = eventMap.erase(iter.first);
2784d6c458bSopenharmony_ci            flag = true;
2794d6c458bSopenharmony_ci        }
2804d6c458bSopenharmony_ci        napi_value convertResult = nullptr;
2814d6c458bSopenharmony_ci        NAPI_CALL(env, napi_get_boolean(env, flag, &convertResult));
2824d6c458bSopenharmony_ci        return convertResult;
2834d6c458bSopenharmony_ci    }
2844d6c458bSopenharmony_ci
2854d6c458bSopenharmony_ci    napi_value Process::GetTid(napi_env env) const
2864d6c458bSopenharmony_ci    {
2874d6c458bSopenharmony_ci        napi_value result = nullptr;
2884d6c458bSopenharmony_ci        auto proTid = static_cast<int32_t>(GetThreadId());
2894d6c458bSopenharmony_ci        napi_create_int64(env, proTid, &result);
2904d6c458bSopenharmony_ci        return result;
2914d6c458bSopenharmony_ci    }
2924d6c458bSopenharmony_ci
2934d6c458bSopenharmony_ci    napi_value Process::IsIsolatedProcess(napi_env env) const
2944d6c458bSopenharmony_ci    {
2954d6c458bSopenharmony_ci        napi_value result = nullptr;
2964d6c458bSopenharmony_ci        bool flag = true;
2974d6c458bSopenharmony_ci        auto prouid = static_cast<int32_t>(getuid());
2984d6c458bSopenharmony_ci        auto uid = prouid % PER_USER_RANGE;
2994d6c458bSopenharmony_ci        if ((uid >= 99000 && uid <= 99999) || // 99999:Only isolateuid numbers between 99000 and 99999.
3004d6c458bSopenharmony_ci            (uid >= 9000 && uid <= 98999)) { // 98999:Only appuid numbers between 9000 and 98999.
3014d6c458bSopenharmony_ci            NAPI_CALL(env, napi_get_boolean(env, flag, &result));
3024d6c458bSopenharmony_ci            return result;
3034d6c458bSopenharmony_ci        }
3044d6c458bSopenharmony_ci        flag = false;
3054d6c458bSopenharmony_ci        NAPI_CALL(env, napi_get_boolean(env, flag, &result));
3064d6c458bSopenharmony_ci        return result;
3074d6c458bSopenharmony_ci    }
3084d6c458bSopenharmony_ci
3094d6c458bSopenharmony_ci    napi_value Process::IsAppUid(napi_env env, napi_value uid) const
3104d6c458bSopenharmony_ci    {
3114d6c458bSopenharmony_ci        int32_t number = 0;
3124d6c458bSopenharmony_ci        napi_value result = nullptr;
3134d6c458bSopenharmony_ci        bool flag = true;
3144d6c458bSopenharmony_ci        napi_get_value_int32(env, uid, &number);
3154d6c458bSopenharmony_ci        if (number > 0) {
3164d6c458bSopenharmony_ci            const auto appId = number % PER_USER_RANGE;
3174d6c458bSopenharmony_ci            if (appId >= FIRST_APPLICATION_UID && appId <= LAST_APPLICATION_UID) {
3184d6c458bSopenharmony_ci                napi_get_boolean(env, flag, &result);
3194d6c458bSopenharmony_ci                return result;
3204d6c458bSopenharmony_ci            }
3214d6c458bSopenharmony_ci        }
3224d6c458bSopenharmony_ci        flag = false;
3234d6c458bSopenharmony_ci        NAPI_CALL(env, napi_get_boolean(env, flag, &result));
3244d6c458bSopenharmony_ci        return result;
3254d6c458bSopenharmony_ci    }
3264d6c458bSopenharmony_ci
3274d6c458bSopenharmony_ci    napi_value Process::Is64Bit(napi_env env) const
3284d6c458bSopenharmony_ci    {
3294d6c458bSopenharmony_ci        napi_value result = nullptr;
3304d6c458bSopenharmony_ci        bool flag = true;
3314d6c458bSopenharmony_ci        auto size = sizeof(char*);
3324d6c458bSopenharmony_ci        flag = (size == NUM_OF_DATA) ? false : true;
3334d6c458bSopenharmony_ci        NAPI_CALL(env, napi_get_boolean(env, flag, &result));
3344d6c458bSopenharmony_ci        return result;
3354d6c458bSopenharmony_ci    }
3364d6c458bSopenharmony_ci
3374d6c458bSopenharmony_ci    napi_value Process::GetEnvironmentVar(napi_env env, napi_value name) const
3384d6c458bSopenharmony_ci    {
3394d6c458bSopenharmony_ci        napi_value convertResult = nullptr;
3404d6c458bSopenharmony_ci        char buf[260 * NUM_OF_DATA] = { 0 }; // 260:Only numbers path String size is 260.
3414d6c458bSopenharmony_ci        size_t length = sizeof(buf);
3424d6c458bSopenharmony_ci        size_t bufferSize = 0;
3434d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, name, nullptr, 0, &bufferSize) != napi_ok) {
3444d6c458bSopenharmony_ci            HILOG_ERROR("can not get name size");
3454d6c458bSopenharmony_ci            return nullptr;
3464d6c458bSopenharmony_ci        }
3474d6c458bSopenharmony_ci        std::string result = "";
3484d6c458bSopenharmony_ci        result.reserve(bufferSize + 1);
3494d6c458bSopenharmony_ci        result.resize(bufferSize);
3504d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, name, result.data(), bufferSize + 1, &bufferSize) != napi_ok) {
3514d6c458bSopenharmony_ci            HILOG_ERROR("can not get name value");
3524d6c458bSopenharmony_ci            return nullptr;
3534d6c458bSopenharmony_ci        }
3544d6c458bSopenharmony_ci        std::string temp = "";
3554d6c458bSopenharmony_ci        temp = result;
3564d6c458bSopenharmony_ci        auto envNum = uv_os_getenv(temp.c_str(), buf, &length);
3574d6c458bSopenharmony_ci        if (envNum == UV_ENOENT) {
3584d6c458bSopenharmony_ci            NAPI_CALL(env, napi_get_undefined(env, &convertResult));
3594d6c458bSopenharmony_ci            return convertResult;
3604d6c458bSopenharmony_ci        }
3614d6c458bSopenharmony_ci        napi_create_string_utf8(env, buf, strlen(buf), &convertResult);
3624d6c458bSopenharmony_ci        return convertResult;
3634d6c458bSopenharmony_ci    }
3644d6c458bSopenharmony_ci
3654d6c458bSopenharmony_ci    napi_value Process::GetUidForName(napi_env env, napi_value name) const
3664d6c458bSopenharmony_ci    {
3674d6c458bSopenharmony_ci        napi_value convertResult = nullptr;
3684d6c458bSopenharmony_ci        size_t bufferSize = 0;
3694d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, name, nullptr, 0, &bufferSize) != napi_ok) {
3704d6c458bSopenharmony_ci            HILOG_ERROR("can not get name size");
3714d6c458bSopenharmony_ci            return nullptr;
3724d6c458bSopenharmony_ci        }
3734d6c458bSopenharmony_ci        std::string result = "";
3744d6c458bSopenharmony_ci        result.reserve(bufferSize + 1);
3754d6c458bSopenharmony_ci        result.resize(bufferSize);
3764d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, name, result.data(), bufferSize + 1, &bufferSize) != napi_ok) {
3774d6c458bSopenharmony_ci            HILOG_ERROR("can not get name value");
3784d6c458bSopenharmony_ci            return nullptr;
3794d6c458bSopenharmony_ci        }
3804d6c458bSopenharmony_ci        struct passwd user;
3814d6c458bSopenharmony_ci        int32_t uid = 0;
3824d6c458bSopenharmony_ci        struct passwd *bufp = nullptr;
3834d6c458bSopenharmony_ci        long bufLen = sysconf(_SC_GETPW_R_SIZE_MAX);
3844d6c458bSopenharmony_ci        if (bufLen == -1) {
3854d6c458bSopenharmony_ci            bufLen = 16384; // 16384:Should be more than enough
3864d6c458bSopenharmony_ci        }
3874d6c458bSopenharmony_ci
3884d6c458bSopenharmony_ci        std::string buf;
3894d6c458bSopenharmony_ci        buf.reserve(bufLen + 1);
3904d6c458bSopenharmony_ci        buf.resize(bufLen);
3914d6c458bSopenharmony_ci        if (getpwnam_r(result.c_str(), &user, buf.data(), bufLen, &bufp) == 0 && bufp != nullptr) {
3924d6c458bSopenharmony_ci            uid = static_cast<int32_t>(bufp->pw_uid);
3934d6c458bSopenharmony_ci            napi_create_int32(env, uid, &convertResult);
3944d6c458bSopenharmony_ci            return convertResult;
3954d6c458bSopenharmony_ci        }
3964d6c458bSopenharmony_ci        napi_create_int32(env, (-1), &convertResult);
3974d6c458bSopenharmony_ci        return convertResult;
3984d6c458bSopenharmony_ci    }
3994d6c458bSopenharmony_ci
4004d6c458bSopenharmony_ci    napi_value Process::GetThreadPriority(napi_env env, napi_value tid) const
4014d6c458bSopenharmony_ci    {
4024d6c458bSopenharmony_ci        errno = 0;
4034d6c458bSopenharmony_ci        napi_value result = nullptr;
4044d6c458bSopenharmony_ci        int32_t proTid = 0;
4054d6c458bSopenharmony_ci        napi_get_value_int32(env, tid, &proTid);
4064d6c458bSopenharmony_ci        int32_t pri = getpriority(PRIO_PROCESS, proTid);
4074d6c458bSopenharmony_ci        if (errno) {
4084d6c458bSopenharmony_ci            napi_throw_error(env, "-1", "Invalid tid");
4094d6c458bSopenharmony_ci            return nullptr;
4104d6c458bSopenharmony_ci        }
4114d6c458bSopenharmony_ci        napi_create_int32(env, pri, &result);
4124d6c458bSopenharmony_ci        return result;
4134d6c458bSopenharmony_ci    }
4144d6c458bSopenharmony_ci
4154d6c458bSopenharmony_ci    napi_value Process::GetStartRealtime(napi_env env) const
4164d6c458bSopenharmony_ci    {
4174d6c458bSopenharmony_ci        napi_value result = nullptr;
4184d6c458bSopenharmony_ci        double startRealtime = GetProcessStartRealtime();
4194d6c458bSopenharmony_ci        napi_create_double(env, startRealtime, &result);
4204d6c458bSopenharmony_ci        return result;
4214d6c458bSopenharmony_ci    }
4224d6c458bSopenharmony_ci
4234d6c458bSopenharmony_ci    int Process::ConvertTime(time_t tvsec, int64_t tvnsec) const
4244d6c458bSopenharmony_ci    {
4254d6c458bSopenharmony_ci        return int(tvsec * 1000) + int(tvnsec / 1000000); // 98999:Only converttime numbers is 1000 and 1000000.
4264d6c458bSopenharmony_ci    }
4274d6c458bSopenharmony_ci
4284d6c458bSopenharmony_ci    napi_value Process::GetPastCputime(napi_env env) const
4294d6c458bSopenharmony_ci    {
4304d6c458bSopenharmony_ci        struct timespec times = {0, 0};
4314d6c458bSopenharmony_ci        napi_value result = nullptr;
4324d6c458bSopenharmony_ci        auto res = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &times);
4334d6c458bSopenharmony_ci        if (res) {
4344d6c458bSopenharmony_ci            return 0;
4354d6c458bSopenharmony_ci        }
4364d6c458bSopenharmony_ci        int when =  ConvertTime(times.tv_sec, times.tv_nsec);
4374d6c458bSopenharmony_ci        napi_create_int32(env, when, &result);
4384d6c458bSopenharmony_ci        return result;
4394d6c458bSopenharmony_ci    }
4404d6c458bSopenharmony_ci
4414d6c458bSopenharmony_ci    napi_value Process::GetSystemConfig(napi_env env, napi_value name) const
4424d6c458bSopenharmony_ci    {
4434d6c458bSopenharmony_ci        int32_t number = 0;
4444d6c458bSopenharmony_ci        napi_value result = nullptr;
4454d6c458bSopenharmony_ci        napi_get_value_int32(env, name, &number);
4464d6c458bSopenharmony_ci        auto configinfo = static_cast<int32_t>(sysconf(number));
4474d6c458bSopenharmony_ci        napi_create_int32(env, configinfo, &result);
4484d6c458bSopenharmony_ci        return result;
4494d6c458bSopenharmony_ci    }
4504d6c458bSopenharmony_ci
4514d6c458bSopenharmony_ci    void Process::ClearReference(napi_env env)
4524d6c458bSopenharmony_ci    {
4534d6c458bSopenharmony_ci        auto iter = eventMap.begin();
4544d6c458bSopenharmony_ci        while (iter != eventMap.end()) {
4554d6c458bSopenharmony_ci            napi_status status = napi_delete_reference(env, iter->second);
4564d6c458bSopenharmony_ci            if (status != napi_ok) {
4574d6c458bSopenharmony_ci                napi_throw_error(env, nullptr, "ClearReference failed");
4584d6c458bSopenharmony_ci                return;
4594d6c458bSopenharmony_ci            }
4604d6c458bSopenharmony_ci            iter++;
4614d6c458bSopenharmony_ci        }
4624d6c458bSopenharmony_ci        eventMap.clear();
4634d6c458bSopenharmony_ci    }
4644d6c458bSopenharmony_ci
4654d6c458bSopenharmony_ci    napi_value ProcessManager::IsAppUid(napi_env env, napi_value uid) const
4664d6c458bSopenharmony_ci    {
4674d6c458bSopenharmony_ci        int32_t number = 0;
4684d6c458bSopenharmony_ci        napi_value result = nullptr;
4694d6c458bSopenharmony_ci        bool flag = true;
4704d6c458bSopenharmony_ci        napi_get_value_int32(env, uid, &number);
4714d6c458bSopenharmony_ci        if (number > 0) {
4724d6c458bSopenharmony_ci            const auto appId = number % PER_USER_RANGE;
4734d6c458bSopenharmony_ci            if (appId >= FIRST_APPLICATION_UID && appId <= LAST_APPLICATION_UID) {
4744d6c458bSopenharmony_ci                napi_get_boolean(env, flag, &result);
4754d6c458bSopenharmony_ci                return result;
4764d6c458bSopenharmony_ci            }
4774d6c458bSopenharmony_ci        }
4784d6c458bSopenharmony_ci        flag = false;
4794d6c458bSopenharmony_ci        NAPI_CALL(env, napi_get_boolean(env, flag, &result));
4804d6c458bSopenharmony_ci        return result;
4814d6c458bSopenharmony_ci    }
4824d6c458bSopenharmony_ci
4834d6c458bSopenharmony_ci    napi_value ProcessManager::GetUidForName(napi_env env, napi_value name) const
4844d6c458bSopenharmony_ci    {
4854d6c458bSopenharmony_ci        napi_value convertResult = nullptr;
4864d6c458bSopenharmony_ci        size_t bufferSize = 0;
4874d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, name, nullptr, 0, &bufferSize) != napi_ok) {
4884d6c458bSopenharmony_ci            HILOG_ERROR("can not get name size");
4894d6c458bSopenharmony_ci            return nullptr;
4904d6c458bSopenharmony_ci        }
4914d6c458bSopenharmony_ci        std::string result = "";
4924d6c458bSopenharmony_ci        result.reserve(bufferSize + 1);
4934d6c458bSopenharmony_ci        result.resize(bufferSize);
4944d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, name, result.data(), bufferSize + 1, &bufferSize) != napi_ok) {
4954d6c458bSopenharmony_ci            HILOG_ERROR("can not get name value");
4964d6c458bSopenharmony_ci            return nullptr;
4974d6c458bSopenharmony_ci        }
4984d6c458bSopenharmony_ci        struct passwd user;
4994d6c458bSopenharmony_ci        int32_t uid = 0;
5004d6c458bSopenharmony_ci        struct passwd *bufp = nullptr;
5014d6c458bSopenharmony_ci        long bufLen = sysconf(_SC_GETPW_R_SIZE_MAX);
5024d6c458bSopenharmony_ci        if (bufLen == -1) {
5034d6c458bSopenharmony_ci            bufLen = 16384; // 16384:Should be more than enough
5044d6c458bSopenharmony_ci        }
5054d6c458bSopenharmony_ci
5064d6c458bSopenharmony_ci        std::string buf;
5074d6c458bSopenharmony_ci        buf.reserve(bufLen + 1);
5084d6c458bSopenharmony_ci        buf.resize(bufLen);
5094d6c458bSopenharmony_ci        if (getpwnam_r(result.c_str(), &user, buf.data(), bufLen, &bufp) == 0 && bufp != nullptr) {
5104d6c458bSopenharmony_ci            uid = static_cast<int32_t>(bufp->pw_uid);
5114d6c458bSopenharmony_ci            napi_create_int32(env, uid, &convertResult);
5124d6c458bSopenharmony_ci            return convertResult;
5134d6c458bSopenharmony_ci        }
5144d6c458bSopenharmony_ci        napi_create_int32(env, (-1), &convertResult);
5154d6c458bSopenharmony_ci        return convertResult;
5164d6c458bSopenharmony_ci    }
5174d6c458bSopenharmony_ci
5184d6c458bSopenharmony_ci    napi_value ProcessManager::GetThreadPriority(napi_env env, napi_value tid) const
5194d6c458bSopenharmony_ci    {
5204d6c458bSopenharmony_ci        errno = 0;
5214d6c458bSopenharmony_ci        napi_value result = nullptr;
5224d6c458bSopenharmony_ci        int32_t proTid = 0;
5234d6c458bSopenharmony_ci        napi_get_value_int32(env, tid, &proTid);
5244d6c458bSopenharmony_ci        int32_t pri = GetThreadPRY(proTid);
5254d6c458bSopenharmony_ci        if (errno) {
5264d6c458bSopenharmony_ci            napi_throw_error(env, "401", "Parameter error. The type of Parameter must be number and a valid tid.");
5274d6c458bSopenharmony_ci            return nullptr;
5284d6c458bSopenharmony_ci        }
5294d6c458bSopenharmony_ci        napi_create_int32(env, pri, &result);
5304d6c458bSopenharmony_ci        return result;
5314d6c458bSopenharmony_ci    }
5324d6c458bSopenharmony_ci
5334d6c458bSopenharmony_ci    napi_value ProcessManager::GetSystemConfig(napi_env env, napi_value name) const
5344d6c458bSopenharmony_ci    {
5354d6c458bSopenharmony_ci        int32_t number = 0;
5364d6c458bSopenharmony_ci        napi_value result = nullptr;
5374d6c458bSopenharmony_ci        napi_get_value_int32(env, name, &number);
5384d6c458bSopenharmony_ci        int32_t configinfo = GetSysConfig(number);
5394d6c458bSopenharmony_ci        napi_create_int32(env, configinfo, &result);
5404d6c458bSopenharmony_ci        return result;
5414d6c458bSopenharmony_ci    }
5424d6c458bSopenharmony_ci
5434d6c458bSopenharmony_ci    napi_value ProcessManager::GetEnvironmentVar(napi_env env, napi_value name) const
5444d6c458bSopenharmony_ci    {
5454d6c458bSopenharmony_ci        size_t bufferSize = 0;
5464d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, name, nullptr, 0, &bufferSize) != napi_ok) {
5474d6c458bSopenharmony_ci            HILOG_ERROR("can not get name size");
5484d6c458bSopenharmony_ci            return nullptr;
5494d6c458bSopenharmony_ci        }
5504d6c458bSopenharmony_ci        std::string result = "";
5514d6c458bSopenharmony_ci        result.reserve(bufferSize + 1);
5524d6c458bSopenharmony_ci        result.resize(bufferSize);
5534d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, name, result.data(), bufferSize + 1, &bufferSize) != napi_ok) {
5544d6c458bSopenharmony_ci            HILOG_ERROR("can not get name value");
5554d6c458bSopenharmony_ci            return nullptr;
5564d6c458bSopenharmony_ci        }
5574d6c458bSopenharmony_ci        std::string temp = "";
5584d6c458bSopenharmony_ci        temp = result;
5594d6c458bSopenharmony_ci        char buf[260 * NUM_OF_DATA] = { 0 }; // 260:Only numbers path String size is 260.
5604d6c458bSopenharmony_ci        size_t length = sizeof(buf);
5614d6c458bSopenharmony_ci        auto envNum = uv_os_getenv(temp.c_str(), buf, &length);
5624d6c458bSopenharmony_ci        napi_value convertResult = nullptr;
5634d6c458bSopenharmony_ci        if (envNum == UV_ENOENT) {
5644d6c458bSopenharmony_ci            NAPI_CALL(env, napi_get_undefined(env, &convertResult));
5654d6c458bSopenharmony_ci            return convertResult;
5664d6c458bSopenharmony_ci        }
5674d6c458bSopenharmony_ci        napi_create_string_utf8(env, buf, strlen(buf), &convertResult);
5684d6c458bSopenharmony_ci        return convertResult;
5694d6c458bSopenharmony_ci    }
5704d6c458bSopenharmony_ci
5714d6c458bSopenharmony_ci    void ProcessManager::Exit(napi_env env, napi_value number) const
5724d6c458bSopenharmony_ci    {
5734d6c458bSopenharmony_ci        int32_t result = 0;
5744d6c458bSopenharmony_ci        napi_get_value_int32(env, number, &result);
5754d6c458bSopenharmony_ci        ProcessExit(result);
5764d6c458bSopenharmony_ci    }
5774d6c458bSopenharmony_ci
5784d6c458bSopenharmony_ci    napi_value ProcessManager::Kill(napi_env env, napi_value signal, napi_value proid)
5794d6c458bSopenharmony_ci    {
5804d6c458bSopenharmony_ci        int32_t pid = 0;
5814d6c458bSopenharmony_ci        int32_t sig = 0;
5824d6c458bSopenharmony_ci        napi_get_value_int32(env, proid, &pid);
5834d6c458bSopenharmony_ci        napi_get_value_int32(env, signal, &sig);
5844d6c458bSopenharmony_ci        uv_pid_t ownPid = uv_os_getpid();
5854d6c458bSopenharmony_ci        // 64:The maximum valid signal value is 64.
5864d6c458bSopenharmony_ci        if (sig > 64 && (!pid || pid == -1 || pid == ownPid || pid == -ownPid)) {
5874d6c458bSopenharmony_ci            napi_throw_error(env, "401", "Parameter error. The type of signal must be number,and from 1 to 64.");
5884d6c458bSopenharmony_ci            return nullptr;
5894d6c458bSopenharmony_ci        }
5904d6c458bSopenharmony_ci        bool flag = false;
5914d6c458bSopenharmony_ci        int err = uv_kill(pid, sig);
5924d6c458bSopenharmony_ci        if (!err) {
5934d6c458bSopenharmony_ci            flag = true;
5944d6c458bSopenharmony_ci        }
5954d6c458bSopenharmony_ci        napi_value result = nullptr;
5964d6c458bSopenharmony_ci        NAPI_CALL(env, napi_get_boolean(env, flag, &result));
5974d6c458bSopenharmony_ci        return result;
5984d6c458bSopenharmony_ci    }
5994d6c458bSopenharmony_ci} // namespace OHOS::JsSysModule::Process
600