1cc290419Sopenharmony_ci/* 2cc290419Sopenharmony_ci * Copyright (C) 2021 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 16cc290419Sopenharmony_ci#include <grp.h> 17cc290419Sopenharmony_ci#include <pwd.h> 18cc290419Sopenharmony_ci#include <unistd.h> 19cc290419Sopenharmony_ci#include <sys/types.h> 20cc290419Sopenharmony_ci#include "daemon_common.h" 21cc290419Sopenharmony_ci#if defined(SURPPORT_SELINUX) 22cc290419Sopenharmony_ci#include "selinux/selinux.h" 23cc290419Sopenharmony_ci#endif 24cc290419Sopenharmony_ciusing namespace Hdc; 25cc290419Sopenharmony_ci 26cc290419Sopenharmony_cistatic bool g_enableUsb = false; 27cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART 28cc290419Sopenharmony_cistatic bool g_enableUart = false; 29cc290419Sopenharmony_ci#endif 30cc290419Sopenharmony_cistatic bool g_enableTcp = false; 31cc290419Sopenharmony_ci#ifdef HDC_EMULATOR 32cc290419Sopenharmony_cistatic bool g_enableBridge = false; 33cc290419Sopenharmony_ci#endif 34cc290419Sopenharmony_cistatic bool g_backgroundRun = false; 35cc290419Sopenharmony_cinamespace Hdc { 36cc290419Sopenharmony_cibool RestartDaemon(bool forkchild) 37cc290419Sopenharmony_ci{ 38cc290419Sopenharmony_ci char path[256] = ""; 39cc290419Sopenharmony_ci size_t nPathSize = 256; 40cc290419Sopenharmony_ci uv_exepath(path, &nPathSize); 41cc290419Sopenharmony_ci execl(path, "hdcd", forkchild ? "-forkchild" : nullptr, nullptr); 42cc290419Sopenharmony_ci return true; 43cc290419Sopenharmony_ci} 44cc290419Sopenharmony_ci 45cc290419Sopenharmony_civoid GetTCPChannelMode(void) 46cc290419Sopenharmony_ci{ 47cc290419Sopenharmony_ci string modeValue; 48cc290419Sopenharmony_ci if (SystemDepend::GetDevItem("persist.hdc.mode.tcp", modeValue)) { 49cc290419Sopenharmony_ci g_enableTcp = (modeValue == "enable"); 50cc290419Sopenharmony_ci WRITE_LOG(LOG_INFO, "Property %s TCP", modeValue.c_str()); 51cc290419Sopenharmony_ci } 52cc290419Sopenharmony_ci modeValue.clear(); 53cc290419Sopenharmony_ci if (SystemDepend::GetDevItem("persist.hdc.mode.usb", modeValue)) { 54cc290419Sopenharmony_ci g_enableUsb = (modeValue == "enable"); 55cc290419Sopenharmony_ci WRITE_LOG(LOG_INFO, "Property %s USB", modeValue.c_str()); 56cc290419Sopenharmony_ci } 57cc290419Sopenharmony_ci return; 58cc290419Sopenharmony_ci} 59cc290419Sopenharmony_ci 60cc290419Sopenharmony_cibool ForkChildCheck(int argc, const char *argv[]) 61cc290419Sopenharmony_ci{ 62cc290419Sopenharmony_ci // hdcd #service start foreground 63cc290419Sopenharmony_ci // hdcd -b #service start backgroundRun 64cc290419Sopenharmony_ci // hdcd -fork #fork 65cc290419Sopenharmony_ci Base::PrintMessage("Background mode, persist.hdc.mode"); 66cc290419Sopenharmony_ci string workMode; 67cc290419Sopenharmony_ci SystemDepend::GetDevItem("persist.hdc.mode", workMode); 68cc290419Sopenharmony_ci workMode = Base::Trim(workMode); 69cc290419Sopenharmony_ci if (workMode == "all") { 70cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "Property enable USB and TCP"); 71cc290419Sopenharmony_ci g_enableUsb = true; 72cc290419Sopenharmony_ci g_enableTcp = true; 73cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART 74cc290419Sopenharmony_ci g_enableUart = true; 75cc290419Sopenharmony_ci#endif 76cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART 77cc290419Sopenharmony_ci } else if (workMode == CMDSTR_TMODE_UART) { 78cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "Property enable UART"); 79cc290419Sopenharmony_ci g_enableUart = true; 80cc290419Sopenharmony_ci#endif 81cc290419Sopenharmony_ci#ifdef HDC_EMULATOR 82cc290419Sopenharmony_ci } else if (workMode == CMDSTR_TMODE_BRIDGE || workMode.empty()) { 83cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "Property enable Bridge"); 84cc290419Sopenharmony_ci g_enableBridge = true; 85cc290419Sopenharmony_ci#endif 86cc290419Sopenharmony_ci } else if (workMode == CMDSTR_TMODE_USB || workMode == CMDSTR_TMODE_TCP) { 87cc290419Sopenharmony_ci // for tcp and usb, we use persist.hdc.mode.tcp and persist.hdc.mode.usb to control 88cc290419Sopenharmony_ci GetTCPChannelMode(); 89cc290419Sopenharmony_ci } else { 90cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "Default USB mode"); 91cc290419Sopenharmony_ci g_enableUsb = true; 92cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART 93cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "Default UART mode"); 94cc290419Sopenharmony_ci g_enableUart = true; 95cc290419Sopenharmony_ci#endif 96cc290419Sopenharmony_ci } 97cc290419Sopenharmony_ci if (argc == CMD_ARG1_COUNT) { 98cc290419Sopenharmony_ci if (!strcmp(argv[1], "-forkchild")) { 99cc290419Sopenharmony_ci g_backgroundRun = false; // forkchild,Forced foreground 100cc290419Sopenharmony_ci } else if (!strcmp(argv[1], "-b")) { 101cc290419Sopenharmony_ci g_backgroundRun = true; 102cc290419Sopenharmony_ci } 103cc290419Sopenharmony_ci } 104cc290419Sopenharmony_ci return true; 105cc290419Sopenharmony_ci} 106cc290419Sopenharmony_ci 107cc290419Sopenharmony_cistatic size_t CheckUvThreadConfig() 108cc290419Sopenharmony_ci{ 109cc290419Sopenharmony_ci return SystemDepend::GetDevUint("persist.hdc.uv.threads", SIZE_THREAD_POOL); 110cc290419Sopenharmony_ci} 111cc290419Sopenharmony_ci 112cc290419Sopenharmony_ciint BackgroundRun() 113cc290419Sopenharmony_ci{ 114cc290419Sopenharmony_ci pid_t pc = fork(); // create process as daemon process 115cc290419Sopenharmony_ci if (pc < 0) { 116cc290419Sopenharmony_ci return -1; 117cc290419Sopenharmony_ci } else if (!pc) { 118cc290419Sopenharmony_ci int i; 119cc290419Sopenharmony_ci const int MAX_NUM = 64; 120cc290419Sopenharmony_ci for (i = 0; i < MAX_NUM; ++i) { 121cc290419Sopenharmony_ci int fd = i; 122cc290419Sopenharmony_ci Base::CloseFd(fd); 123cc290419Sopenharmony_ci } 124cc290419Sopenharmony_ci RestartDaemon(true); 125cc290419Sopenharmony_ci } else { // >0 orig process 126cc290419Sopenharmony_ci } 127cc290419Sopenharmony_ci return 0; 128cc290419Sopenharmony_ci} 129cc290419Sopenharmony_ci 130cc290419Sopenharmony_cistring DaemonUsage() 131cc290419Sopenharmony_ci{ 132cc290419Sopenharmony_ci string ret = ""; 133cc290419Sopenharmony_ci ret = "\n Harmony device connector daemon(HDCD) Usage: hdcd [options]...\n\n" 134cc290419Sopenharmony_ci "\n" 135cc290419Sopenharmony_ci "general options:\n" 136cc290419Sopenharmony_ci " -h - Print help\n" 137cc290419Sopenharmony_ci " -l 0-5 - Print runtime log\n" 138cc290419Sopenharmony_ci "\n" 139cc290419Sopenharmony_ci "daemon mode options:\n" 140cc290419Sopenharmony_ci " -b - Daemon run in background/fork mode\n" 141cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART 142cc290419Sopenharmony_ci " -i - Enable UART mode\n" 143cc290419Sopenharmony_ci#endif 144cc290419Sopenharmony_ci " -u - Enable USB mode\n" 145cc290419Sopenharmony_ci " -t - Enable TCP mode\n"; 146cc290419Sopenharmony_ci return ret; 147cc290419Sopenharmony_ci} 148cc290419Sopenharmony_ci 149cc290419Sopenharmony_cibool GetDaemonCommandlineOptions(int argc, const char *argv[]) 150cc290419Sopenharmony_ci{ 151cc290419Sopenharmony_ci int ch; 152cc290419Sopenharmony_ci // hdcd -l4 ... 153cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "Foreground cli-mode"); 154cc290419Sopenharmony_ci // Both settings are running with parameters 155cc290419Sopenharmony_ci while ((ch = getopt(argc, const_cast<char *const *>(argv), "utl:")) != -1) { 156cc290419Sopenharmony_ci switch (ch) { 157cc290419Sopenharmony_ci case 'l': { 158cc290419Sopenharmony_ci int logLevel = atoi(optarg); 159cc290419Sopenharmony_ci if (logLevel < 0 || logLevel > LOG_LAST) { 160cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "Loglevel error!\n"); 161cc290419Sopenharmony_ci return -1; 162cc290419Sopenharmony_ci } 163cc290419Sopenharmony_ci Base::SetLogLevel(logLevel); 164cc290419Sopenharmony_ci break; 165cc290419Sopenharmony_ci } 166cc290419Sopenharmony_ci case 'u': { 167cc290419Sopenharmony_ci Base::PrintMessage("Option USB enabled"); 168cc290419Sopenharmony_ci g_enableUsb = true; 169cc290419Sopenharmony_ci break; 170cc290419Sopenharmony_ci } 171cc290419Sopenharmony_ci case 't': { 172cc290419Sopenharmony_ci Base::PrintMessage("Option TCP enabled"); 173cc290419Sopenharmony_ci g_enableTcp = true; 174cc290419Sopenharmony_ci break; 175cc290419Sopenharmony_ci } 176cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART 177cc290419Sopenharmony_ci case 'i': { // enable uart 178cc290419Sopenharmony_ci Base::PrintMessage("Parament Enable UART"); 179cc290419Sopenharmony_ci g_enableUart = true; 180cc290419Sopenharmony_ci break; 181cc290419Sopenharmony_ci } 182cc290419Sopenharmony_ci#endif 183cc290419Sopenharmony_ci default: 184cc290419Sopenharmony_ci Base::PrintMessage("Option:%c non-supported!", ch); 185cc290419Sopenharmony_ci exit(0); 186cc290419Sopenharmony_ci break; 187cc290419Sopenharmony_ci } 188cc290419Sopenharmony_ci } 189cc290419Sopenharmony_ci return true; 190cc290419Sopenharmony_ci} 191cc290419Sopenharmony_ci 192cc290419Sopenharmony_cibool DropRootPrivileges() 193cc290419Sopenharmony_ci{ 194cc290419Sopenharmony_ci int ret; 195cc290419Sopenharmony_ci const char *userName = "shell"; 196cc290419Sopenharmony_ci vector<const char *> groupsNames = { "shell", "log", "readproc", "file_manager" }; 197cc290419Sopenharmony_ci struct passwd *user; 198cc290419Sopenharmony_ci gid_t *gids = nullptr; 199cc290419Sopenharmony_ci 200cc290419Sopenharmony_ci user = getpwnam(userName); 201cc290419Sopenharmony_ci if (user == nullptr) { 202cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "getpwuid %s fail, %s", userName, strerror(errno)); 203cc290419Sopenharmony_ci return false; 204cc290419Sopenharmony_ci } 205cc290419Sopenharmony_ci 206cc290419Sopenharmony_ci gids = static_cast<gid_t *>(calloc(groupsNames.size(), sizeof(gid_t))); 207cc290419Sopenharmony_ci if (gids == nullptr) { 208cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "calloc fail"); 209cc290419Sopenharmony_ci return false; 210cc290419Sopenharmony_ci } 211cc290419Sopenharmony_ci 212cc290419Sopenharmony_ci for (size_t i = 0; i < groupsNames.size(); i++) { 213cc290419Sopenharmony_ci struct group *group = getgrnam(groupsNames[i]); 214cc290419Sopenharmony_ci if (group == nullptr) { 215cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "calloc fail"); 216cc290419Sopenharmony_ci continue; 217cc290419Sopenharmony_ci } 218cc290419Sopenharmony_ci gids[i] = group->gr_gid; 219cc290419Sopenharmony_ci } 220cc290419Sopenharmony_ci 221cc290419Sopenharmony_ci ret = setuid(user->pw_uid); 222cc290419Sopenharmony_ci if (ret) { 223cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "setuid %s fail, %s", userName, strerror(errno)); 224cc290419Sopenharmony_ci free(gids); 225cc290419Sopenharmony_ci return false; 226cc290419Sopenharmony_ci } 227cc290419Sopenharmony_ci 228cc290419Sopenharmony_ci ret = setgid(user->pw_gid); 229cc290419Sopenharmony_ci if (ret) { 230cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "setgid %s fail, %s", userName, strerror(errno)); 231cc290419Sopenharmony_ci free(gids); 232cc290419Sopenharmony_ci return false; 233cc290419Sopenharmony_ci } 234cc290419Sopenharmony_ci 235cc290419Sopenharmony_ci ret = setgroups(groupsNames.size(), gids); 236cc290419Sopenharmony_ci if (ret) { 237cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "setgroups %s fail, %s", userName, strerror(errno)); 238cc290419Sopenharmony_ci free(gids); 239cc290419Sopenharmony_ci return false; 240cc290419Sopenharmony_ci } 241cc290419Sopenharmony_ci 242cc290419Sopenharmony_ci free(gids); 243cc290419Sopenharmony_ci#if defined(SURPPORT_SELINUX) 244cc290419Sopenharmony_ci if (setcon("u:r:hdcd:s0") != 0) { 245cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "setcon fail, errno %s", userName, strerror(errno)); 246cc290419Sopenharmony_ci } 247cc290419Sopenharmony_ci#endif 248cc290419Sopenharmony_ci return true; 249cc290419Sopenharmony_ci} 250cc290419Sopenharmony_ci 251cc290419Sopenharmony_cibool NeedDropRootPrivileges() 252cc290419Sopenharmony_ci{ 253cc290419Sopenharmony_ci string rootMode; 254cc290419Sopenharmony_ci string debugMode; 255cc290419Sopenharmony_ci SystemDepend::GetDevItem("const.debuggable", debugMode); 256cc290419Sopenharmony_ci SystemDepend::GetDevItem("persist.hdc.root", rootMode); 257cc290419Sopenharmony_ci if (debugMode == "1") { 258cc290419Sopenharmony_ci if (rootMode == "1") { 259cc290419Sopenharmony_ci int rc = setuid(0); 260cc290419Sopenharmony_ci if (rc != 0) { 261cc290419Sopenharmony_ci char buffer[BUF_SIZE_DEFAULT] = { 0 }; 262cc290419Sopenharmony_ci strerror_r(errno, buffer, BUF_SIZE_DEFAULT); 263cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "setuid(0) fail %s", buffer); 264cc290419Sopenharmony_ci } 265cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "Root run rc:%d", rc); 266cc290419Sopenharmony_ci } else if (rootMode == "0") { 267cc290419Sopenharmony_ci if (getuid() == 0) { 268cc290419Sopenharmony_ci return DropRootPrivileges(); 269cc290419Sopenharmony_ci } 270cc290419Sopenharmony_ci } 271cc290419Sopenharmony_ci // default keep root 272cc290419Sopenharmony_ci } else { 273cc290419Sopenharmony_ci return DropRootPrivileges(); 274cc290419Sopenharmony_ci } 275cc290419Sopenharmony_ci return true; 276cc290419Sopenharmony_ci} 277cc290419Sopenharmony_ci} // namespace Hdc 278cc290419Sopenharmony_ci 279cc290419Sopenharmony_ci#ifndef UNIT_TEST 280cc290419Sopenharmony_ci// daemon running with default behavior. options also can be given to custom its behavior including b/t/u/l etc. 281cc290419Sopenharmony_ciint main(int argc, const char *argv[]) 282cc290419Sopenharmony_ci{ 283cc290419Sopenharmony_ci#ifdef CONFIG_USE_JEMALLOC_DFX_INIF 284cc290419Sopenharmony_ci mallopt(M_DELAYED_FREE, M_DELAYED_FREE_DISABLE); 285cc290419Sopenharmony_ci mallopt(M_SET_THREAD_CACHE, M_THREAD_CACHE_DISABLE); 286cc290419Sopenharmony_ci#endif 287cc290419Sopenharmony_ci#ifndef UPDATER_MODE 288cc290419Sopenharmony_ci string developerMode; 289cc290419Sopenharmony_ci SystemDepend::GetDevItem("const.security.developermode.state", developerMode); 290cc290419Sopenharmony_ci if (developerMode != "true") { 291cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "non developer mode, hdcd does not start"); 292cc290419Sopenharmony_ci return -1; 293cc290419Sopenharmony_ci } 294cc290419Sopenharmony_ci#endif 295cc290419Sopenharmony_ci // check property 296cc290419Sopenharmony_ci if (argc == CMD_ARG1_COUNT && !strcmp(argv[1], "-h")) { 297cc290419Sopenharmony_ci string usage = DaemonUsage(); 298cc290419Sopenharmony_ci fprintf(stderr, "%s", usage.c_str()); 299cc290419Sopenharmony_ci return 0; 300cc290419Sopenharmony_ci } 301cc290419Sopenharmony_ci if (argc == CMD_ARG1_COUNT && !strcmp(argv[1], "-v")) { 302cc290419Sopenharmony_ci string ver = Hdc::Base::GetVersion(); 303cc290419Sopenharmony_ci fprintf(stderr, "%s\n", ver.c_str()); 304cc290419Sopenharmony_ci return 0; 305cc290419Sopenharmony_ci } 306cc290419Sopenharmony_ci if (argc == 1 || (argc == CMD_ARG1_COUNT && (!strcmp(argv[1], "-forkchild") || !strcmp(argv[1], "-b")))) { 307cc290419Sopenharmony_ci ForkChildCheck(argc, argv); 308cc290419Sopenharmony_ci } else { 309cc290419Sopenharmony_ci GetDaemonCommandlineOptions(argc, argv); 310cc290419Sopenharmony_ci } 311cc290419Sopenharmony_ci if (!g_enableTcp && !g_enableUsb) { 312cc290419Sopenharmony_ci#ifdef HDC_EMULATOR 313cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART 314cc290419Sopenharmony_ci if (!g_enableBridge && !g_enableUart) { 315cc290419Sopenharmony_ci Base::PrintMessage("TCP, USB, Bridge and Uart are disable, cannot run continue\n"); 316cc290419Sopenharmony_ci return -1; 317cc290419Sopenharmony_ci } 318cc290419Sopenharmony_ci#else 319cc290419Sopenharmony_ci if (!g_enableBridge) { 320cc290419Sopenharmony_ci Base::PrintMessage("Both TCP, Bridge and USB are disable, cannot run continue\n"); 321cc290419Sopenharmony_ci return -1; 322cc290419Sopenharmony_ci } 323cc290419Sopenharmony_ci#endif 324cc290419Sopenharmony_ci#else 325cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART 326cc290419Sopenharmony_ci if (!g_enableUart) { 327cc290419Sopenharmony_ci Base::PrintMessage("TCP, USB and Uart are disable, cannot run continue\n"); 328cc290419Sopenharmony_ci return -1; 329cc290419Sopenharmony_ci } 330cc290419Sopenharmony_ci#else 331cc290419Sopenharmony_ci Base::PrintMessage("Both TCP and USB are disable, cannot run continue\n"); 332cc290419Sopenharmony_ci return -1; 333cc290419Sopenharmony_ci#endif 334cc290419Sopenharmony_ci#endif 335cc290419Sopenharmony_ci } 336cc290419Sopenharmony_ci if (g_backgroundRun) { 337cc290419Sopenharmony_ci return BackgroundRun(); 338cc290419Sopenharmony_ci } 339cc290419Sopenharmony_ci string debugMode; 340cc290419Sopenharmony_ci SystemDepend::GetDevItem("const.debuggable", debugMode); 341cc290419Sopenharmony_ci if (debugMode == "1") { 342cc290419Sopenharmony_ci if (!NeedDropRootPrivileges()) { 343cc290419Sopenharmony_ci Base::PrintMessage("DropRootPrivileges fail, EXITING...\n"); 344cc290419Sopenharmony_ci return -1; 345cc290419Sopenharmony_ci } 346cc290419Sopenharmony_ci WRITE_LOG(LOG_INFO, "HdcDaemon run as root mode."); 347cc290419Sopenharmony_ci } else { 348cc290419Sopenharmony_ci WRITE_LOG(LOG_INFO, "HdcDaemon run as user mode."); 349cc290419Sopenharmony_ci } 350cc290419Sopenharmony_ci 351cc290419Sopenharmony_ci Base::InitProcess(); 352cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "HdcDaemon main run"); 353cc290419Sopenharmony_ci HdcDaemon daemon(false, CheckUvThreadConfig()); 354cc290419Sopenharmony_ci 355cc290419Sopenharmony_ci#ifdef HDC_EMULATOR 356cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART 357cc290419Sopenharmony_ci daemon.InitMod(g_enableTcp, g_enableUsb, g_enableBridge, g_enableUart); 358cc290419Sopenharmony_ci#else 359cc290419Sopenharmony_ci daemon.InitMod(g_enableTcp, g_enableUsb, g_enableBridge); 360cc290419Sopenharmony_ci#endif 361cc290419Sopenharmony_ci#else 362cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART 363cc290419Sopenharmony_ci daemon.InitMod(g_enableTcp, g_enableUsb, g_enableUart); 364cc290419Sopenharmony_ci#else 365cc290419Sopenharmony_ci daemon.InitMod(g_enableTcp, g_enableUsb); 366cc290419Sopenharmony_ci#endif 367cc290419Sopenharmony_ci#endif 368cc290419Sopenharmony_ci daemon.ClearKnownHosts(); 369cc290419Sopenharmony_ci daemon.WorkerPendding(); 370cc290419Sopenharmony_ci bool wantRestart = daemon.WantRestart(); 371cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "Daemon finish wantRestart %d", wantRestart); 372cc290419Sopenharmony_ci // There is no daemon, we can only restart myself. 373cc290419Sopenharmony_ci if (wantRestart) { 374cc290419Sopenharmony_ci // just root can self restart, low privilege will be exit and start by service(root) 375cc290419Sopenharmony_ci WRITE_LOG(LOG_INFO, "Daemon restart"); 376cc290419Sopenharmony_ci RestartDaemon(false); 377cc290419Sopenharmony_ci } 378cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART 379cc290419Sopenharmony_ci // when no usb insert , device will hung here , we don't know why. 380cc290419Sopenharmony_ci // Test the command "smode -r" in uart mode, then execute shell 381cc290419Sopenharmony_ci // hdcd will not really exit until usb plug in 382cc290419Sopenharmony_ci // so we use abort here 383cc290419Sopenharmony_ci _exit(0); 384cc290419Sopenharmony_ci#endif 385cc290419Sopenharmony_ci return 0; 386cc290419Sopenharmony_ci} 387cc290419Sopenharmony_ci#endif 388