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 **) ®istExec); 431cc290419Sopenharmony_ci if (rc == 0) { 432cc290419Sopenharmony_ci registExec(reinterpret_cast<int *>(ExternalExecFunc)); 433cc290419Sopenharmony_ci } 434cc290419Sopenharmony_ci} 435cc290419Sopenharmony_ci} 436cc290419Sopenharmony_ci 437