VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/NetworkServiceRunner.cpp@ 78501

Last change on this file since 78501 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.7 KB
Line 
1/* $Id: NetworkServiceRunner.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * VirtualBox Main - interface for VBox DHCP server
4 */
5
6/*
7 * Copyright (C) 2009-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include <map>
19#include <string>
20#include "NetworkServiceRunner.h"
21#include <iprt/process.h>
22#include <iprt/param.h>
23#include <iprt/env.h>
24#include <iprt/log.h>
25#include <iprt/thread.h>
26
27
28const std::string NetworkServiceRunner::kNsrKeyName = "--name";
29const std::string NetworkServiceRunner::kNsrKeyNetwork = "--network";
30const std::string NetworkServiceRunner::kNsrKeyTrunkType = "--trunk-type";
31const std::string NetworkServiceRunner::kNsrTrunkName = "--trunk-name";
32const std::string NetworkServiceRunner::kNsrMacAddress = "--mac-address";
33const std::string NetworkServiceRunner::kNsrIpAddress = "--ip-address";
34const std::string NetworkServiceRunner::kNsrIpNetmask = "--netmask";
35const std::string NetworkServiceRunner::kNsrKeyNeedMain = "--need-main";
36
37struct NetworkServiceRunner::Data
38{
39 Data(const char* aProcName)
40 : mProcName(aProcName)
41 , mProcess(NIL_RTPROCESS)
42 , mKillProcOnStop(false)
43 {}
44 const char *mProcName;
45 RTPROCESS mProcess;
46 std::map<std::string, std::string> mOptions;
47 bool mKillProcOnStop;
48};
49
50NetworkServiceRunner::NetworkServiceRunner(const char *aProcName)
51{
52 m = new NetworkServiceRunner::Data(aProcName);
53}
54
55
56NetworkServiceRunner::~NetworkServiceRunner()
57{
58 stop();
59 delete m;
60 m = NULL;
61}
62
63
64int NetworkServiceRunner::setOption(const std::string& key, const std::string& val)
65{
66 m->mOptions.insert(std::map<std::string, std::string>::value_type(key, val));
67 return VINF_SUCCESS;
68}
69
70
71void NetworkServiceRunner::clearOptions()
72{
73 m->mOptions.clear();
74}
75
76
77void NetworkServiceRunner::detachFromServer()
78{
79 m->mProcess = NIL_RTPROCESS;
80}
81
82
83int NetworkServiceRunner::start(bool aKillProcOnStop)
84{
85 if (isRunning())
86 return VINF_ALREADY_INITIALIZED;
87
88 const char * args[10*2];
89
90 AssertReturn(m->mOptions.size() < 10, VERR_INTERNAL_ERROR);
91
92 /* get the path to the executable */
93 char exePathBuf[RTPATH_MAX];
94 const char *exePath = RTProcGetExecutablePath(exePathBuf, RTPATH_MAX);
95 char *substrSl = strrchr(exePathBuf, '/');
96 char *substrBs = strrchr(exePathBuf, '\\');
97 char *suffix = substrSl ? substrSl : substrBs;
98
99 if (suffix)
100 {
101 suffix++;
102 strcpy(suffix, m->mProcName);
103 }
104
105 int index = 0;
106
107 args[index++] = exePath;
108
109 std::map<std::string, std::string>::const_iterator it;
110 for(it = m->mOptions.begin(); it != m->mOptions.end(); ++it)
111 {
112 args[index++] = it->first.c_str();
113 args[index++] = it->second.c_str();
114 }
115
116 args[index++] = NULL;
117
118 int rc = RTProcCreate(suffix ? exePath : m->mProcName, args, RTENV_DEFAULT, 0, &m->mProcess);
119 if (RT_FAILURE(rc))
120 m->mProcess = NIL_RTPROCESS;
121
122 m->mKillProcOnStop = aKillProcOnStop;
123 return rc;
124}
125
126
127int NetworkServiceRunner::stop()
128{
129 /*
130 * If the process already terminated, this function will also grab the exit
131 * status and transition the process out of zombie status.
132 */
133 if (!isRunning())
134 return VINF_OBJECT_DESTROYED;
135
136 bool fDoKillProc = true;
137
138 if (!m->mKillProcOnStop)
139 {
140 /*
141 * This is a VBoxSVC Main client. Do NOT kill it but assume it was shut
142 * down politely. Wait up to 1 second until the process is killed before
143 * doing the final hard kill.
144 */
145 int rc = VINF_SUCCESS;
146 for (unsigned int i = 0; i < 100; i++)
147 {
148 rc = RTProcWait(m->mProcess, RTPROCWAIT_FLAGS_NOBLOCK, NULL);
149 if (RT_SUCCESS(rc))
150 break;
151 RTThreadSleep(10);
152 }
153 if (rc != VERR_PROCESS_RUNNING)
154 fDoKillProc = false;
155 }
156
157 if (fDoKillProc)
158 {
159 RTProcTerminate(m->mProcess);
160 int rc = RTProcWait(m->mProcess, RTPROCWAIT_FLAGS_BLOCK, NULL);
161 NOREF(rc);
162 }
163
164 m->mProcess = NIL_RTPROCESS;
165 return VINF_SUCCESS;
166}
167
168bool NetworkServiceRunner::isRunning()
169{
170 if (m->mProcess == NIL_RTPROCESS)
171 return false;
172
173 RTPROCSTATUS status;
174 int rc = RTProcWait(m->mProcess, RTPROCWAIT_FLAGS_NOBLOCK, &status);
175
176 if (rc == VERR_PROCESS_RUNNING)
177 return true;
178
179 m->mProcess = NIL_RTPROCESS;
180 return false;
181}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette