1a69a01cdSopenharmony_ci/*
2a69a01cdSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3a69a01cdSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4a69a01cdSopenharmony_ci * you may not use this file except in compliance with the License.
5a69a01cdSopenharmony_ci * You may obtain a copy of the License at
6a69a01cdSopenharmony_ci *
7a69a01cdSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8a69a01cdSopenharmony_ci *
9a69a01cdSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10a69a01cdSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11a69a01cdSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a69a01cdSopenharmony_ci * See the License for the specific language governing permissions and
13a69a01cdSopenharmony_ci * limitations under the License.
14a69a01cdSopenharmony_ci */
15a69a01cdSopenharmony_ci
16a69a01cdSopenharmony_ci#include <cstdio>
17a69a01cdSopenharmony_ci#include <sys/stat.h>
18a69a01cdSopenharmony_ci
19a69a01cdSopenharmony_ci#include "app_manager.h"
20a69a01cdSopenharmony_ci#include "component_manager.h"
21a69a01cdSopenharmony_ci#include "exception_manager.h"
22a69a01cdSopenharmony_ci#include "multimode_manager.h"
23a69a01cdSopenharmony_ci#include "report.h"
24a69a01cdSopenharmony_ci#include "scene_delegate.h"
25a69a01cdSopenharmony_ci#include "string_ex.h"
26a69a01cdSopenharmony_ci#include "tree_manager.h"
27a69a01cdSopenharmony_ci#include "wukong_define.h"
28a69a01cdSopenharmony_ci#include "wukong_logger.h"
29a69a01cdSopenharmony_ci#include "wukong_shell_command.h"
30a69a01cdSopenharmony_ci#include "wukong_util.h"
31a69a01cdSopenharmony_ci#include "parameters.h"
32a69a01cdSopenharmony_ci
33a69a01cdSopenharmony_ciusing namespace OHOS::WuKong;
34a69a01cdSopenharmony_ci
35a69a01cdSopenharmony_cistatic const unsigned int NUMBER_TWO = 2;
36a69a01cdSopenharmony_ci
37a69a01cdSopenharmony_cistatic bool FreeSingtion()
38a69a01cdSopenharmony_ci{
39a69a01cdSopenharmony_ci    AppManager::DestroyInstance();
40a69a01cdSopenharmony_ci    ComponentManager::DestroyInstance();
41a69a01cdSopenharmony_ci    ExceptionManager::DestroyInstance();
42a69a01cdSopenharmony_ci    MultimodeManager::DestroyInstance();
43a69a01cdSopenharmony_ci    Report::DestroyInstance();
44a69a01cdSopenharmony_ci    SceneDelegate::DestroyInstance();
45a69a01cdSopenharmony_ci    TreeManager::DestroyInstance();
46a69a01cdSopenharmony_ci    WuKongUtil::DestroyInstance();
47a69a01cdSopenharmony_ci    return true;
48a69a01cdSopenharmony_ci}
49a69a01cdSopenharmony_ci
50a69a01cdSopenharmony_cistatic void WuKongMutexFile()
51a69a01cdSopenharmony_ci{
52a69a01cdSopenharmony_ci    int fileExist = access("/dev/shm", F_OK);
53a69a01cdSopenharmony_ci    if (fileExist == 0) {
54a69a01cdSopenharmony_ci        DEBUG_LOG("File exist. Now create wukong test mutex.");
55a69a01cdSopenharmony_ci    } else {
56a69a01cdSopenharmony_ci        const int wuKongGm = mkdir("/dev/shm", 0777);
57a69a01cdSopenharmony_ci        DEBUG_LOG("File create. Now create wukong test mutex.");
58a69a01cdSopenharmony_ci        if (wuKongGm == -1) {
59a69a01cdSopenharmony_ci            DEBUG_LOG("Error creating directory!");
60a69a01cdSopenharmony_ci        }
61a69a01cdSopenharmony_ci    }
62a69a01cdSopenharmony_ci}
63a69a01cdSopenharmony_ci
64a69a01cdSopenharmony_cistatic void InitSemaphore(NamedSemaphore& sem, const int count)
65a69a01cdSopenharmony_ci{
66a69a01cdSopenharmony_ci    bool res = sem.Open();
67a69a01cdSopenharmony_ci    if (!res) {
68a69a01cdSopenharmony_ci        WuKongMutexFile();
69a69a01cdSopenharmony_ci        res = sem.Create();
70a69a01cdSopenharmony_ci    }
71a69a01cdSopenharmony_ci    if (res) {
72a69a01cdSopenharmony_ci        DEBUG_LOG("Open Semaphore success");
73a69a01cdSopenharmony_ci        int value = sem.GetValue();
74a69a01cdSopenharmony_ci        if (value > count) {
75a69a01cdSopenharmony_ci            DEBUG_LOG_STR("the semaphore value is invalid (%d), and reopen Semaphore", value);
76a69a01cdSopenharmony_ci            res = sem.Create();
77a69a01cdSopenharmony_ci            if (!res) {
78a69a01cdSopenharmony_ci                ERROR_LOG("create sem failed");
79a69a01cdSopenharmony_ci                return;
80a69a01cdSopenharmony_ci            }
81a69a01cdSopenharmony_ci        } else {
82a69a01cdSopenharmony_ci            DEBUG_LOG_STR("Semaphore Value: (%d)", value);
83a69a01cdSopenharmony_ci        }
84a69a01cdSopenharmony_ci    }
85a69a01cdSopenharmony_ci    sem.Close();
86a69a01cdSopenharmony_ci}
87a69a01cdSopenharmony_ci
88a69a01cdSopenharmony_cistatic bool IsRunning(NamedSemaphore& sem)
89a69a01cdSopenharmony_ci{
90a69a01cdSopenharmony_ci    bool result = false;
91a69a01cdSopenharmony_ci    sem.Open();
92a69a01cdSopenharmony_ci    // the wukong pidof buffer size.
93a69a01cdSopenharmony_ci    const int bufferSize = 32;
94a69a01cdSopenharmony_ci    int value = sem.GetValue();
95a69a01cdSopenharmony_ci    TRACK_LOG_STR("Semaphore Is Open: (%d)", value);
96a69a01cdSopenharmony_ci    if (value <= 0) {
97a69a01cdSopenharmony_ci        FILE* fp = nullptr;
98a69a01cdSopenharmony_ci        fp = popen("pidof wukong", "r");
99a69a01cdSopenharmony_ci        TRACK_LOG("Run pidof wukong");
100a69a01cdSopenharmony_ci        if (fp == nullptr) {
101a69a01cdSopenharmony_ci            ERROR_LOG("popen function failed");
102a69a01cdSopenharmony_ci            return true;
103a69a01cdSopenharmony_ci        }
104a69a01cdSopenharmony_ci        char pid[bufferSize] = {0};
105a69a01cdSopenharmony_ci        if (fgets(pid, bufferSize - 1, fp) != nullptr) {
106a69a01cdSopenharmony_ci            std::string pidStr(pid);
107a69a01cdSopenharmony_ci            pidStr = OHOS::ReplaceStr(pidStr, "\n", " ");
108a69a01cdSopenharmony_ci            TRACK_LOG_STR("Wukong Pid: (%s)", pidStr.c_str());
109a69a01cdSopenharmony_ci            std::vector<std::string> strs;
110a69a01cdSopenharmony_ci            OHOS::SplitStr(pidStr, " ", strs);
111a69a01cdSopenharmony_ci            for (auto i : strs) {
112a69a01cdSopenharmony_ci                DEBUG_LOG_STR("Pid: (%s)", i.c_str());
113a69a01cdSopenharmony_ci            }
114a69a01cdSopenharmony_ci            if (strs.size() >= NUMBER_TWO) {
115a69a01cdSopenharmony_ci                result = true;
116a69a01cdSopenharmony_ci            } else {
117a69a01cdSopenharmony_ci                sem.Create();
118a69a01cdSopenharmony_ci                result = false;
119a69a01cdSopenharmony_ci            }
120a69a01cdSopenharmony_ci        } else {
121a69a01cdSopenharmony_ci            result = true;
122a69a01cdSopenharmony_ci        }
123a69a01cdSopenharmony_ci        pclose(fp);
124a69a01cdSopenharmony_ci    }
125a69a01cdSopenharmony_ci    return result;
126a69a01cdSopenharmony_ci}
127a69a01cdSopenharmony_ci
128a69a01cdSopenharmony_ciint main(int argc, char* argv[])
129a69a01cdSopenharmony_ci{
130a69a01cdSopenharmony_ci    if (!OHOS::system::GetBoolParameter("const.security.developermode.state", true)) {
131a69a01cdSopenharmony_ci        std::cout << "Not a development mode state, please check device mode." << std::endl;
132a69a01cdSopenharmony_ci        return 0;
133a69a01cdSopenharmony_ci    }
134a69a01cdSopenharmony_ci    std::shared_ptr<WuKongLogger> WuKonglogger = WuKongLogger::GetInstance();
135a69a01cdSopenharmony_ci    // first start logger
136a69a01cdSopenharmony_ci    WuKonglogger->SetLevel(LOG_LEVEL_INFO);
137a69a01cdSopenharmony_ci    bool isStop = false;
138a69a01cdSopenharmony_ci    for (int index = argc - 1; index >= 1; index--) {
139a69a01cdSopenharmony_ci        std::string arg = argv[index];
140a69a01cdSopenharmony_ci        if (arg == "--track") {
141a69a01cdSopenharmony_ci            argv[index][0] = '\0';
142a69a01cdSopenharmony_ci            WuKonglogger->SetLevel(LOG_LEVEL_TRACK);
143a69a01cdSopenharmony_ci        }
144a69a01cdSopenharmony_ci        if (arg == "--debug") {
145a69a01cdSopenharmony_ci            argv[index][0] = '\0';
146a69a01cdSopenharmony_ci            WuKonglogger->SetLevel(LOG_LEVEL_DEBUG);
147a69a01cdSopenharmony_ci        }
148a69a01cdSopenharmony_ci        if (arg == "stop") {
149a69a01cdSopenharmony_ci            isStop = true;
150a69a01cdSopenharmony_ci        }
151a69a01cdSopenharmony_ci    }
152a69a01cdSopenharmony_ci    if (!WuKonglogger->Start()) {
153a69a01cdSopenharmony_ci        return 1;
154a69a01cdSopenharmony_ci    }
155a69a01cdSopenharmony_ci    NamedSemaphore semRun(SEMPHORE_RUN_NAME, 1);
156a69a01cdSopenharmony_ci    InitSemaphore(semRun, 1);
157a69a01cdSopenharmony_ci    NamedSemaphore semStop(SEMPHORE_STOP_NAME, 1);
158a69a01cdSopenharmony_ci    InitSemaphore(semStop, 1);
159a69a01cdSopenharmony_ci    WuKongShellCommand cmd(argc, argv);
160a69a01cdSopenharmony_ci    if (isStop) {
161a69a01cdSopenharmony_ci        std::cout << cmd.ExecCommand();
162a69a01cdSopenharmony_ci    } else {
163a69a01cdSopenharmony_ci        if (IsRunning(semRun)) {
164a69a01cdSopenharmony_ci            ERROR_LOG("error: wukong has running, allow one program run.");
165a69a01cdSopenharmony_ci        } else {
166a69a01cdSopenharmony_ci            semRun.Open();
167a69a01cdSopenharmony_ci            semRun.Wait();
168a69a01cdSopenharmony_ci            std::cout << cmd.ExecCommand();
169a69a01cdSopenharmony_ci            semRun.Post();
170a69a01cdSopenharmony_ci            semRun.Close();
171a69a01cdSopenharmony_ci        }
172a69a01cdSopenharmony_ci    }
173a69a01cdSopenharmony_ci    FreeSingtion();
174a69a01cdSopenharmony_ci    WuKonglogger->Stop();
175a69a01cdSopenharmony_ci    std::cout << "exit main" << std::endl;
176a69a01cdSopenharmony_ci    return 0;
177a69a01cdSopenharmony_ci}
178