1cc290419Sopenharmony_ci/*
2cc290419Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd.
3cc290419Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4cc290419Sopenharmony_ci * you may not use this file except in compliance with the License.
5cc290419Sopenharmony_ci * You may obtain a copy of the License at
6cc290419Sopenharmony_ci *
7cc290419Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8cc290419Sopenharmony_ci *
9cc290419Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10cc290419Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11cc290419Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12cc290419Sopenharmony_ci * See the License for the specific language governing permissions and
13cc290419Sopenharmony_ci * limitations under the License.
14cc290419Sopenharmony_ci */
15cc290419Sopenharmony_ci#include "ext_client.h"
16cc290419Sopenharmony_ci#include "libgen.h"
17cc290419Sopenharmony_ci#include "common.h"
18cc290419Sopenharmony_ci
19cc290419Sopenharmony_cinamespace Hdc {
20cc290419Sopenharmony_ciExtClient::ExtClient()
21cc290419Sopenharmony_ci{
22cc290419Sopenharmony_ci    lib.handle = nullptr;
23cc290419Sopenharmony_ci}
24cc290419Sopenharmony_ci
25cc290419Sopenharmony_ciExtClient::~ExtClient()
26cc290419Sopenharmony_ci{
27cc290419Sopenharmony_ci    if (lib.handle != nullptr) {
28cc290419Sopenharmony_ci        uv_dlclose(&lib);
29cc290419Sopenharmony_ci    }
30cc290419Sopenharmony_ci}
31cc290419Sopenharmony_ci
32cc290419Sopenharmony_cistring ExtClient::GetPath()
33cc290419Sopenharmony_ci{
34cc290419Sopenharmony_ci#ifdef _WIN32
35cc290419Sopenharmony_ci    string path = "libexternal_hdc.dll";
36cc290419Sopenharmony_ci#elif defined(HOST_MAC)
37cc290419Sopenharmony_ci    string path = "libexternal_hdc.dylib";
38cc290419Sopenharmony_ci#else
39cc290419Sopenharmony_ci    string path = "libexternal_hdc.z.so";
40cc290419Sopenharmony_ci#endif
41cc290419Sopenharmony_ci    string hdcPath = Base::GetHdcAbsolutePath();
42cc290419Sopenharmony_ci    int index = hdcPath.find_last_of(Base::GetPathSep());
43cc290419Sopenharmony_ci    return (hdcPath.substr(0, index) + Base::GetPathSep() + path);
44cc290419Sopenharmony_ci}
45cc290419Sopenharmony_ci
46cc290419Sopenharmony_cibool ExtClient::Init()
47cc290419Sopenharmony_ci{
48cc290419Sopenharmony_ci    string path = GetPath();
49cc290419Sopenharmony_ci    int rc = uv_dlopen(path.c_str(), &lib);
50cc290419Sopenharmony_ci    if (rc != 0) {
51cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "uv_dlopen failed %s %s", path.c_str(), uv_dlerror(&lib));
52cc290419Sopenharmony_ci        return false;
53cc290419Sopenharmony_ci    }
54cc290419Sopenharmony_ci    RegistExecFunc(&lib);
55cc290419Sopenharmony_ci    return true;
56cc290419Sopenharmony_ci}
57cc290419Sopenharmony_ci
58cc290419Sopenharmony_cibool ExtClient::SharedLibraryExist()
59cc290419Sopenharmony_ci{
60cc290419Sopenharmony_ci    string path = GetPath();
61cc290419Sopenharmony_ci    return Base::CheckDirectoryOrPath(path.c_str(), true, true);
62cc290419Sopenharmony_ci}
63cc290419Sopenharmony_ci
64cc290419Sopenharmony_civoid ExtClient::ExecuteCommand(const string &command)
65cc290419Sopenharmony_ci{
66cc290419Sopenharmony_ci    if (!strncmp(command.c_str(), CMDSTR_SOFTWARE_VERSION.c_str(), CMDSTR_SOFTWARE_VERSION.size())) {
67cc290419Sopenharmony_ci        Version(command);
68cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), CMDSTR_SOFTWARE_HELP.c_str(), CMDSTR_SOFTWARE_HELP.size())) {
69cc290419Sopenharmony_ci        Help(command);
70cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), CMDSTR_TARGET_DISCOVER.c_str(), CMDSTR_TARGET_DISCOVER.size())) {
71cc290419Sopenharmony_ci        Discover(command);
72cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), CMDSTR_SERVICE_START.c_str(), CMDSTR_SERVICE_START.size())) {
73cc290419Sopenharmony_ci        Start(command);
74cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), CMDSTR_SERVICE_KILL.c_str(), CMDSTR_SERVICE_KILL.size())) {
75cc290419Sopenharmony_ci        Kill(command);
76cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), CMDSTR_CONNECT_TARGET.c_str(), CMDSTR_CONNECT_TARGET.size())) {
77cc290419Sopenharmony_ci        Connect(command);
78cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), CMDSTR_LIST_TARGETS.c_str(), CMDSTR_LIST_TARGETS.size())) {
79cc290419Sopenharmony_ci        ListTargets(command);
80cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), CMDSTR_SHELL.c_str(), CMDSTR_SHELL.size())) {
81cc290419Sopenharmony_ci        Shell(command);
82cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), CMDSTR_FILE_SEND.c_str(), CMDSTR_FILE_SEND.size()) ||
83cc290419Sopenharmony_ci               !strncmp(command.c_str(), CMDSTR_FILE_RECV.c_str(), CMDSTR_FILE_RECV.size())) {
84cc290419Sopenharmony_ci        File(command);
85cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), CMDSTR_APP_INSTALL.c_str(), CMDSTR_APP_INSTALL.size())) {
86cc290419Sopenharmony_ci        Install(command);
87cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), CMDSTR_APP_UNINSTALL.c_str(), CMDSTR_APP_UNINSTALL.size())) {
88cc290419Sopenharmony_ci        Uninstall(command);
89cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), CMDSTR_FORWARD_FPORT.c_str(), CMDSTR_FORWARD_FPORT.size())) {
90cc290419Sopenharmony_ci        Fport(command);
91cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), CMDSTR_FORWARD_RPORT.c_str(), CMDSTR_FORWARD_RPORT.size())) {
92cc290419Sopenharmony_ci        Rport(command);
93cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), CMDSTR_LIST_JDWP.c_str(), CMDSTR_LIST_JDWP.size())) {
94cc290419Sopenharmony_ci        Jpid(command);
95cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), CMDSTR_TRACK_JDWP.c_str(), CMDSTR_TRACK_JDWP.size())) {
96cc290419Sopenharmony_ci        TrackJpid(command);
97cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), (CMDSTR_SHELL + " ").c_str(), CMDSTR_SHELL.size() + 1) ||
98cc290419Sopenharmony_ci               !strncmp(command.c_str(), CMDSTR_TARGET_REBOOT.c_str(), CMDSTR_TARGET_REBOOT.size()) ||
99cc290419Sopenharmony_ci               !strncmp(command.c_str(), CMDSTR_TARGET_MOUNT.c_str(), CMDSTR_TARGET_MOUNT.size()) ||
100cc290419Sopenharmony_ci               !strncmp(command.c_str(), CMDSTR_STARTUP_MODE.c_str(), CMDSTR_STARTUP_MODE.size()) ||
101cc290419Sopenharmony_ci               !strncmp(command.c_str(), CMDSTR_TARGET_MODE.c_str(), CMDSTR_TARGET_MODE.size()) ||
102cc290419Sopenharmony_ci               !strncmp(command.c_str(), CMDSTR_HILOG.c_str(), CMDSTR_HILOG.size())) {
103cc290419Sopenharmony_ci        Utility(command);
104cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), CMDSTR_BUGREPORT.c_str(), CMDSTR_BUGREPORT.size())) {
105cc290419Sopenharmony_ci        Bugreport(command);
106cc290419Sopenharmony_ci    } else if (!strncmp(command.c_str(), CMDSTR_WAIT_FOR.c_str(), CMDSTR_WAIT_FOR.size())) {
107cc290419Sopenharmony_ci        WaitFor(command);
108cc290419Sopenharmony_ci    } else {
109cc290419Sopenharmony_ci        UnknowCommand(command);
110cc290419Sopenharmony_ci    }
111cc290419Sopenharmony_ci}
112cc290419Sopenharmony_ci
113cc290419Sopenharmony_civoid ExtClient::Version(const std::string &str)
114cc290419Sopenharmony_ci{
115cc290419Sopenharmony_ci    const char *name = "HdcExtVersion";
116cc290419Sopenharmony_ci    Handle(str, name);
117cc290419Sopenharmony_ci}
118cc290419Sopenharmony_ci
119cc290419Sopenharmony_civoid ExtClient::Help(const std::string &str)
120cc290419Sopenharmony_ci{
121cc290419Sopenharmony_ci    return;
122cc290419Sopenharmony_ci}
123cc290419Sopenharmony_ci
124cc290419Sopenharmony_civoid ExtClient::Discover(const std::string &str)
125cc290419Sopenharmony_ci{
126cc290419Sopenharmony_ci    const char *name = "HdcExtDiscover";
127cc290419Sopenharmony_ci    Handle(str, name);
128cc290419Sopenharmony_ci}
129cc290419Sopenharmony_ci
130cc290419Sopenharmony_civoid ExtClient::Start(const std::string &str)
131cc290419Sopenharmony_ci{
132cc290419Sopenharmony_ci    const char *name = "HdcExtStart";
133cc290419Sopenharmony_ci    Handle(str, name);
134cc290419Sopenharmony_ci}
135cc290419Sopenharmony_ci
136cc290419Sopenharmony_civoid ExtClient::Kill(const std::string &str)
137cc290419Sopenharmony_ci{
138cc290419Sopenharmony_ci    const char *name = "HdcExtKill";
139cc290419Sopenharmony_ci    Handle(str, name);
140cc290419Sopenharmony_ci}
141cc290419Sopenharmony_ci
142cc290419Sopenharmony_civoid ExtClient::Connect(const std::string &str)
143cc290419Sopenharmony_ci{
144cc290419Sopenharmony_ci    const char *name = "HdcExtConnect";
145cc290419Sopenharmony_ci    string res = Handle(str, name);
146cc290419Sopenharmony_ci    if (res.find("connected to") != std::string::npos) {
147cc290419Sopenharmony_ci        _exit(0);
148cc290419Sopenharmony_ci    }
149cc290419Sopenharmony_ci}
150cc290419Sopenharmony_ci
151cc290419Sopenharmony_civoid ExtClient::ListTargets(const std::string &str)
152cc290419Sopenharmony_ci{
153cc290419Sopenharmony_ci    typedef void (*HdcExtListTargets)(const char *, uint64_t, char *, uint64_t &);
154cc290419Sopenharmony_ci    const char *name = "HdcExtListTargets";
155cc290419Sopenharmony_ci    HdcExtListTargets listTargets;
156cc290419Sopenharmony_ci    int rc = uv_dlsym(&lib, name, (void **) &listTargets);
157cc290419Sopenharmony_ci    if (rc != 0) {
158cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "uv_dlsym %s failed %s", name, uv_dlerror(&lib));
159cc290419Sopenharmony_ci    } else {
160cc290419Sopenharmony_ci        uint64_t size = 4096;
161cc290419Sopenharmony_ci        char *buffer = new(std::nothrow) char[size]();
162cc290419Sopenharmony_ci        if (buffer == nullptr) {
163cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "new buffer failed with function %s", name);
164cc290419Sopenharmony_ci            return;
165cc290419Sopenharmony_ci        }
166cc290419Sopenharmony_ci        listTargets(str.c_str(), str.size(), buffer, size);
167cc290419Sopenharmony_ci        string extdevs(buffer);
168cc290419Sopenharmony_ci        UpdateList(extdevs);
169cc290419Sopenharmony_ci        delete[] buffer;
170cc290419Sopenharmony_ci        if (extdevs.empty()) {
171cc290419Sopenharmony_ci            return;
172cc290419Sopenharmony_ci        }
173cc290419Sopenharmony_ci        if (g_show) {
174cc290419Sopenharmony_ci            const string listv = "list targets -v";
175cc290419Sopenharmony_ci            if (!strncmp(str.c_str(), listv.c_str(), listv.size())) {
176cc290419Sopenharmony_ci                string all = extdevs;
177cc290419Sopenharmony_ci                all = Base::ReplaceAll(all, "\n", "\texternal\n");
178cc290419Sopenharmony_ci                Base::PrintMessage("%s", all.c_str());
179cc290419Sopenharmony_ci            } else {
180cc290419Sopenharmony_ci                Base::PrintMessage("%s", extdevs.c_str());
181cc290419Sopenharmony_ci            }
182cc290419Sopenharmony_ci        }
183cc290419Sopenharmony_ci    }
184cc290419Sopenharmony_ci}
185cc290419Sopenharmony_ci
186cc290419Sopenharmony_civoid ExtClient::UpdateList(const string &str)
187cc290419Sopenharmony_ci{
188cc290419Sopenharmony_ci    if (str.empty()) {
189cc290419Sopenharmony_ci        return;
190cc290419Sopenharmony_ci    }
191cc290419Sopenharmony_ci    vector<string> devs;
192cc290419Sopenharmony_ci    Base::SplitString(str, "\n", devs);
193cc290419Sopenharmony_ci    for (size_t i = 0; i < devs.size(); i++) {
194cc290419Sopenharmony_ci        string::size_type pos = devs[i].find("\t");
195cc290419Sopenharmony_ci        if (pos != string::npos || (pos = devs[i].find(" ")) != string::npos) {
196cc290419Sopenharmony_ci            string key = devs[i].substr(0, pos);
197cc290419Sopenharmony_ci            g_lists[key] = "external";
198cc290419Sopenharmony_ci        }
199cc290419Sopenharmony_ci    }
200cc290419Sopenharmony_ci}
201cc290419Sopenharmony_ci
202cc290419Sopenharmony_civoid ExtClient::Shell(const std::string &str)
203cc290419Sopenharmony_ci{
204cc290419Sopenharmony_ci    const char *name = "HdcExtShell";
205cc290419Sopenharmony_ci    string value = WithConnectKey(str);
206cc290419Sopenharmony_ci    Handle(value, name);
207cc290419Sopenharmony_ci}
208cc290419Sopenharmony_ci
209cc290419Sopenharmony_civoid ExtClient::File(const std::string &str)
210cc290419Sopenharmony_ci{
211cc290419Sopenharmony_ci    const char *name = "HdcExtFile";
212cc290419Sopenharmony_ci    std::string cmd = RemoveRemoteCwd(str);
213cc290419Sopenharmony_ci    string value = WithConnectKey(cmd);
214cc290419Sopenharmony_ci    Handle(value, name);
215cc290419Sopenharmony_ci}
216cc290419Sopenharmony_ci
217cc290419Sopenharmony_civoid ExtClient::Install(const std::string &str)
218cc290419Sopenharmony_ci{
219cc290419Sopenharmony_ci    const char *name = "HdcExtInstall";
220cc290419Sopenharmony_ci    std::string cmd = RemoveRemoteCwd(str);
221cc290419Sopenharmony_ci    string value = WithConnectKey(cmd);
222cc290419Sopenharmony_ci    Handle(value, name);
223cc290419Sopenharmony_ci}
224cc290419Sopenharmony_ci
225cc290419Sopenharmony_civoid ExtClient::Uninstall(const std::string &str)
226cc290419Sopenharmony_ci{
227cc290419Sopenharmony_ci    const char *name = "HdcExtUninstall";
228cc290419Sopenharmony_ci    string value = WithConnectKey(str);
229cc290419Sopenharmony_ci    Handle(value, name);
230cc290419Sopenharmony_ci}
231cc290419Sopenharmony_ci
232cc290419Sopenharmony_civoid ExtClient::Fport(const std::string &str)
233cc290419Sopenharmony_ci{
234cc290419Sopenharmony_ci    const char *name = "HdcExtFport";
235cc290419Sopenharmony_ci    string value = WithConnectKey(str);
236cc290419Sopenharmony_ci    Handle(value, name);
237cc290419Sopenharmony_ci}
238cc290419Sopenharmony_ci
239cc290419Sopenharmony_civoid ExtClient::Rport(const std::string &str)
240cc290419Sopenharmony_ci{
241cc290419Sopenharmony_ci    const char *name = "HdcExtRport";
242cc290419Sopenharmony_ci    string value = WithConnectKey(str);
243cc290419Sopenharmony_ci    Handle(value, name);
244cc290419Sopenharmony_ci}
245cc290419Sopenharmony_ci
246cc290419Sopenharmony_civoid ExtClient::Jpid(const std::string &str)
247cc290419Sopenharmony_ci{
248cc290419Sopenharmony_ci    const char *name = "HdcExtJpid";
249cc290419Sopenharmony_ci    string value = WithConnectKey(str);
250cc290419Sopenharmony_ci    Handle(value, name);
251cc290419Sopenharmony_ci}
252cc290419Sopenharmony_ci
253cc290419Sopenharmony_civoid ExtClient::TrackJpid(const std::string &str)
254cc290419Sopenharmony_ci{
255cc290419Sopenharmony_ci    const char *name = "HdcExtTrackJpid";
256cc290419Sopenharmony_ci    string value = WithConnectKey(str);
257cc290419Sopenharmony_ci    Handle(value, name);
258cc290419Sopenharmony_ci}
259cc290419Sopenharmony_ci
260cc290419Sopenharmony_civoid ExtClient::Utility(const std::string &str)
261cc290419Sopenharmony_ci{
262cc290419Sopenharmony_ci    const char *name = "HdcExtUtility";
263cc290419Sopenharmony_ci    string value = WithConnectKey(str);
264cc290419Sopenharmony_ci    Handle(value, name);
265cc290419Sopenharmony_ci}
266cc290419Sopenharmony_ci
267cc290419Sopenharmony_civoid ExtClient::Bugreport(const std::string &str)
268cc290419Sopenharmony_ci{
269cc290419Sopenharmony_ci    const char *name = "HdcExtBugreport";
270cc290419Sopenharmony_ci    string value = WithConnectKey(str);
271cc290419Sopenharmony_ci    Handle(value, name);
272cc290419Sopenharmony_ci}
273cc290419Sopenharmony_ci
274cc290419Sopenharmony_civoid ExtClient::WaitFor(const std::string &str)
275cc290419Sopenharmony_ci{
276cc290419Sopenharmony_ci    std::thread([str]() {
277cc290419Sopenharmony_ci        WaitForExtent(str);
278cc290419Sopenharmony_ci        _exit(0);
279cc290419Sopenharmony_ci    }).detach();
280cc290419Sopenharmony_ci}
281cc290419Sopenharmony_ci
282cc290419Sopenharmony_civoid ExtClient::UnknowCommand(const std::string &str)
283cc290419Sopenharmony_ci{
284cc290419Sopenharmony_ci    const char *name = "HdcExtUnknowCommand";
285cc290419Sopenharmony_ci    Handle(str, name);
286cc290419Sopenharmony_ci}
287cc290419Sopenharmony_ci
288cc290419Sopenharmony_cistd::string ExtClient::RemoveRemoteCwd(const std::string &str)
289cc290419Sopenharmony_ci{
290cc290419Sopenharmony_ci    int argc = 0;
291cc290419Sopenharmony_ci    std::string cmd = str;
292cc290419Sopenharmony_ci    char **argv = Base::SplitCommandToArgs(cmd.c_str(), &argc);
293cc290419Sopenharmony_ci    if (argv == nullptr) {
294cc290419Sopenharmony_ci        return cmd;
295cc290419Sopenharmony_ci    }
296cc290419Sopenharmony_ci    for (int i = 0; i < argc; i++) {
297cc290419Sopenharmony_ci        if (argv[i] == CMDSTR_REMOTE_PARAMETER) {
298cc290419Sopenharmony_ci            std::string remove = Base::StringFormat("%s %s \"%s\" ", argv[i], argv[i + 1], argv[i + 2]);
299cc290419Sopenharmony_ci            if (cmd.find(remove) != std::string::npos) {
300cc290419Sopenharmony_ci                cmd.replace(cmd.find(remove), remove.size(), "");
301cc290419Sopenharmony_ci            }
302cc290419Sopenharmony_ci            break;
303cc290419Sopenharmony_ci        }
304cc290419Sopenharmony_ci    }
305cc290419Sopenharmony_ci    delete[](reinterpret_cast<char *>(argv));
306cc290419Sopenharmony_ci    return cmd;
307cc290419Sopenharmony_ci}
308cc290419Sopenharmony_ci
309cc290419Sopenharmony_cistd::string ExtClient::HandleLib(const std::string &str, const char *name, uv_lib_t &lib)
310cc290419Sopenharmony_ci{
311cc290419Sopenharmony_ci    typedef void (*HdcExtCommand)(const char *, uint64_t, char *, uint64_t &);
312cc290419Sopenharmony_ci    HdcExtCommand command;
313cc290419Sopenharmony_ci    std::string strBuf;
314cc290419Sopenharmony_ci    int rc = uv_dlsym(&lib, name, (void **) &command);
315cc290419Sopenharmony_ci    if (rc != 0) {
316cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "uv_dlsym %s failed %s", name, uv_dlerror(&lib));
317cc290419Sopenharmony_ci    } else {
318cc290419Sopenharmony_ci        uint64_t size = 4096;
319cc290419Sopenharmony_ci        char *buffer = new(std::nothrow) char[size]();
320cc290419Sopenharmony_ci        if (buffer == nullptr) {
321cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "new buffer failed with function %s", name);
322cc290419Sopenharmony_ci            return "";
323cc290419Sopenharmony_ci        }
324cc290419Sopenharmony_ci        command(str.c_str(), str.size(), buffer, size);
325cc290419Sopenharmony_ci        strBuf = buffer;
326cc290419Sopenharmony_ci        if (!strBuf.empty()) {
327cc290419Sopenharmony_ci            Base::PrintMessage("%s", strBuf.c_str());
328cc290419Sopenharmony_ci        }
329cc290419Sopenharmony_ci        delete[] buffer;
330cc290419Sopenharmony_ci    }
331cc290419Sopenharmony_ci    return strBuf;
332cc290419Sopenharmony_ci}
333cc290419Sopenharmony_ci
334cc290419Sopenharmony_cistd::string ExtClient::Handle(const std::string &str, const char *name)
335cc290419Sopenharmony_ci{
336cc290419Sopenharmony_ci    return HandleLib(str, name, this->lib);
337cc290419Sopenharmony_ci}
338cc290419Sopenharmony_ci
339cc290419Sopenharmony_cistd::string ExtClient::WithConnectKey(const string &str)
340cc290419Sopenharmony_ci{
341cc290419Sopenharmony_ci    std::string value;
342cc290419Sopenharmony_ci    if (!connectKey.empty()) {
343cc290419Sopenharmony_ci        value = "-t " + connectKey + " ";
344cc290419Sopenharmony_ci    }
345cc290419Sopenharmony_ci    if (!containerInOut.empty()) {
346cc290419Sopenharmony_ci        value = value + containerInOut + " ";
347cc290419Sopenharmony_ci    }
348cc290419Sopenharmony_ci    value = value + str;
349cc290419Sopenharmony_ci    return value;
350cc290419Sopenharmony_ci}
351cc290419Sopenharmony_ci
352cc290419Sopenharmony_civoid ExtClient::WaitForExtent(const std::string &str)
353cc290419Sopenharmony_ci{
354cc290419Sopenharmony_ci    uv_lib_t uvLib;
355cc290419Sopenharmony_ci    string path = GetPath();
356cc290419Sopenharmony_ci    int rc = uv_dlopen(path.c_str(), &uvLib);
357cc290419Sopenharmony_ci    if (rc != 0) {
358cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "uv_dlopen failed %s %s", path.c_str(), uv_dlerror(&uvLib));
359cc290419Sopenharmony_ci        return;
360cc290419Sopenharmony_ci    }
361cc290419Sopenharmony_ci    RegistExecFunc(&uvLib);
362cc290419Sopenharmony_ci    const char *name = "HdcExtWaitFor";
363cc290419Sopenharmony_ci    HandleLib(str, name, uvLib);
364cc290419Sopenharmony_ci    uv_dlclose(&uvLib);
365cc290419Sopenharmony_ci}
366cc290419Sopenharmony_ci
367cc290419Sopenharmony_cistatic void OnExit(uv_process_t *req, int64_t exitStatus, int termSignal)
368cc290419Sopenharmony_ci{
369cc290419Sopenharmony_ci    uv_close((uv_handle_t*) req, nullptr);
370cc290419Sopenharmony_ci}
371cc290419Sopenharmony_ci
372cc290419Sopenharmony_cistatic int ExternalExecFunc(int argc, char *argv[])
373cc290419Sopenharmony_ci{
374cc290419Sopenharmony_ci#define EXTERNAL_KEEP_FDS 3
375cc290419Sopenharmony_ci    uv_loop_t loop;
376cc290419Sopenharmony_ci    uv_process_t childReq = { 0 };
377cc290419Sopenharmony_ci    uv_process_options_t options = { 0 };
378cc290419Sopenharmony_ci    uv_stdio_container_t childStdio[EXTERNAL_KEEP_FDS];
379cc290419Sopenharmony_ci
380cc290419Sopenharmony_ci    if (argc <= 0) {
381cc290419Sopenharmony_ci        return 1;
382cc290419Sopenharmony_ci    }
383cc290419Sopenharmony_ci
384cc290419Sopenharmony_ci    uv_loop_init(&loop);
385cc290419Sopenharmony_ci
386cc290419Sopenharmony_ci    for (int i = 0; i < EXTERNAL_KEEP_FDS; i++) {
387cc290419Sopenharmony_ci        childStdio[i].flags = UV_INHERIT_FD;
388cc290419Sopenharmony_ci        childStdio[i].data.fd = i;
389cc290419Sopenharmony_ci    }
390cc290419Sopenharmony_ci
391cc290419Sopenharmony_ci    size_t pathSize = BUF_SIZE_DEFAULT4;
392cc290419Sopenharmony_ci    char execPath[pathSize];
393cc290419Sopenharmony_ci    (void)memset_s(execPath, pathSize, 0, pathSize);
394cc290419Sopenharmony_ci    int ret = uv_exepath(execPath, &pathSize);
395cc290419Sopenharmony_ci    if (ret < 0) {
396cc290419Sopenharmony_ci        return 1;
397cc290419Sopenharmony_ci    }
398cc290419Sopenharmony_ci    string path = string(dirname(execPath)) + "/" + string(argv[0]);
399cc290419Sopenharmony_ci    options.file = path.c_str();
400cc290419Sopenharmony_ci    options.args = argv;
401cc290419Sopenharmony_ci    options.exit_cb = OnExit;
402cc290419Sopenharmony_ci    options.stdio_count = EXTERNAL_KEEP_FDS;
403cc290419Sopenharmony_ci    options.stdio = childStdio;
404cc290419Sopenharmony_ci
405cc290419Sopenharmony_ci    if (uv_spawn(&loop, &childReq, &options) != 0) {
406cc290419Sopenharmony_ci        return 1;
407cc290419Sopenharmony_ci    }
408cc290419Sopenharmony_ci    uv_run(&loop, UV_RUN_DEFAULT);
409cc290419Sopenharmony_ci
410cc290419Sopenharmony_ci#ifdef HOST_MINGW
411cc290419Sopenharmony_ci    DWORD status = 0;
412cc290419Sopenharmony_ci    if (GetExitCodeProcess(childReq.process_handle, &status)) {
413cc290419Sopenharmony_ci        return uv_translate_sys_error(GetLastError());
414cc290419Sopenharmony_ci    }
415cc290419Sopenharmony_ci#else
416cc290419Sopenharmony_ci    int status = 0;
417cc290419Sopenharmony_ci    if (!WIFEXITED(childReq.status)) {
418cc290419Sopenharmony_ci        return errno;
419cc290419Sopenharmony_ci    }
420cc290419Sopenharmony_ci    status = WEXITSTATUS(childReq.status);
421cc290419Sopenharmony_ci#endif
422cc290419Sopenharmony_ci    return static_cast<int>(status);
423cc290419Sopenharmony_ci}
424cc290419Sopenharmony_ci
425cc290419Sopenharmony_civoid ExtClient::RegistExecFunc(uv_lib_t *lib)
426cc290419Sopenharmony_ci{
427cc290419Sopenharmony_ci    typedef void (*HdcExtRegistExec)(int *);
428cc290419Sopenharmony_ci    HdcExtRegistExec registExec;
429cc290419Sopenharmony_ci    const char *name = "HdcExtRegistExecFunc";
430cc290419Sopenharmony_ci    int rc = uv_dlsym(lib, name, (void **) &registExec);
431cc290419Sopenharmony_ci    if (rc == 0) {
432cc290419Sopenharmony_ci        registExec(reinterpret_cast<int *>(ExternalExecFunc));
433cc290419Sopenharmony_ci    }
434cc290419Sopenharmony_ci}
435cc290419Sopenharmony_ci}
436cc290419Sopenharmony_ci
437