VirtualBox

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

Last change on this file since 67954 was 62485, checked in by vboxsync, 8 years ago

(C) 2016

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.6 KB
Line 
1/* $Id: NetworkServiceRunner.cpp 62485 2016-07-22 18:36:43Z vboxsync $ */
2/** @file
3 * VirtualBox Main - interface for VBox DHCP server
4 */
5
6/*
7 * Copyright (C) 2009-2016 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::detachFromServer()
72{
73 m->mProcess = NIL_RTPROCESS;
74}
75
76
77int NetworkServiceRunner::start(bool aKillProcOnStop)
78{
79 if (isRunning())
80 return VINF_ALREADY_INITIALIZED;
81
82 const char * args[10*2];
83
84 AssertReturn(m->mOptions.size() < 10, VERR_INTERNAL_ERROR);
85
86 /* get the path to the executable */
87 char exePathBuf[RTPATH_MAX];
88 const char *exePath = RTProcGetExecutablePath(exePathBuf, RTPATH_MAX);
89 char *substrSl = strrchr(exePathBuf, '/');
90 char *substrBs = strrchr(exePathBuf, '\\');
91 char *suffix = substrSl ? substrSl : substrBs;
92
93 if (suffix)
94 {
95 suffix++;
96 strcpy(suffix, m->mProcName);
97 }
98
99 int index = 0;
100
101 args[index++] = exePath;
102
103 std::map<std::string, std::string>::const_iterator it;
104 for(it = m->mOptions.begin(); it != m->mOptions.end(); ++it)
105 {
106 args[index++] = it->first.c_str();
107 args[index++] = it->second.c_str();
108 }
109
110 args[index++] = NULL;
111
112 int rc = RTProcCreate(suffix ? exePath : m->mProcName, args, RTENV_DEFAULT, 0, &m->mProcess);
113 if (RT_FAILURE(rc))
114 m->mProcess = NIL_RTPROCESS;
115
116 m->mKillProcOnStop = aKillProcOnStop;
117 return rc;
118}
119
120
121int NetworkServiceRunner::stop()
122{
123 /*
124 * If the process already terminated, this function will also grab the exit
125 * status and transition the process out of zombie status.
126 */
127 if (!isRunning())
128 return VINF_OBJECT_DESTROYED;
129
130 bool fDoKillProc = true;
131
132 if (!m->mKillProcOnStop)
133 {
134 /*
135 * This is a VBoxSVC Main client. Do NOT kill it but assume it was shut
136 * down politely. Wait up to 1 second until the process is killed before
137 * doing the final hard kill.
138 */
139 int rc = VINF_SUCCESS;
140 for (unsigned int i = 0; i < 100; i++)
141 {
142 rc = RTProcWait(m->mProcess, RTPROCWAIT_FLAGS_NOBLOCK, NULL);
143 if (RT_SUCCESS(rc))
144 break;
145 RTThreadSleep(10);
146 }
147 if (rc != VERR_PROCESS_RUNNING)
148 fDoKillProc = false;
149 }
150
151 if (fDoKillProc)
152 {
153 RTProcTerminate(m->mProcess);
154 int rc = RTProcWait(m->mProcess, RTPROCWAIT_FLAGS_BLOCK, NULL);
155 NOREF(rc);
156 }
157
158 m->mProcess = NIL_RTPROCESS;
159 return VINF_SUCCESS;
160}
161
162bool NetworkServiceRunner::isRunning()
163{
164 if (m->mProcess == NIL_RTPROCESS)
165 return false;
166
167 RTPROCSTATUS status;
168 int rc = RTProcWait(m->mProcess, RTPROCWAIT_FLAGS_NOBLOCK, &status);
169
170 if (rc == VERR_PROCESS_RUNNING)
171 return true;
172
173 m->mProcess = NIL_RTPROCESS;
174 return false;
175}
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