VirtualBox

source: vbox/trunk/src/VBox/Main/linux/server_module.cpp@ 4044

Last change on this file since 4044 was 3668, checked in by vboxsync, 17 years ago

replace underscore symbols in Main/

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 9.1 KB
Line 
1/** @file
2 *
3 * XPCOM server process hepler module implementation functions
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
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 as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22#ifdef RT_OS_OS2
23# include <prproces.h>
24#endif
25
26#include <nsMemory.h>
27#include <nsString.h>
28#include <nsCOMPtr.h>
29#include <nsIFile.h>
30#include <nsIGenericFactory.h>
31#include <nsIServiceManagerUtils.h>
32#include <nsICategoryManager.h>
33#include <nsDirectoryServiceDefs.h>
34
35#include <ipcIService.h>
36#include <ipcIDConnectService.h>
37#include <ipcCID.h>
38#include <ipcdclient.h>
39
40// official XPCOM headers don't define it yet
41#define IPC_DCONNECTSERVICE_CONTRACTID \
42 "@mozilla.org/ipc/dconnect-service;1"
43
44// generated file
45#include <VirtualBox_XPCOM.h>
46
47#include "linux/server.h"
48#include "Logging.h"
49
50#include <VBox/err.h>
51
52#include <iprt/param.h>
53#include <iprt/path.h>
54#include <iprt/process.h>
55#include <iprt/thread.h>
56
57#include <string.h>
58
59
60/// @todo move this to RT headers (and use them in MachineImpl.cpp as well)
61#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
62#define HOSTSUFF_EXE ".exe"
63#else /* !RT_OS_WINDOWS */
64#define HOSTSUFF_EXE ""
65#endif /* !RT_OS_WINDOWS */
66
67
68/** Name of the server executable. */
69const char VBoxSVC_exe[] = RTPATH_SLASH_STR "VBoxSVC" HOSTSUFF_EXE;
70
71enum
72{
73 /** Amount of time to wait for the server to establish a connection, ms */
74 VBoxSVC_Timeout = 30000,
75 /** How often to perform a connection check, ms */
76 VBoxSVC_WaitSlice = 100,
77};
78
79/**
80 * Full path to the VBoxSVC executable.
81 */
82static char VBoxSVCPath [RTPATH_MAX];
83static bool IsVBoxSVCPathSet = false;
84
85/*
86 * The following macros define the method necessary to provide a list of
87 * interfaces implemented by the VirtualBox component. Note that this must be
88 * in sync with macros used for VirtualBox in server.cpp for the same purpose.
89 */
90
91NS_DECL_CLASSINFO (VirtualBox)
92NS_IMPL_CI_INTERFACE_GETTER1 (VirtualBox, IVirtualBox)
93
94/**
95 * VirtualBox component constructor.
96 *
97 * This constructor is responsible for starting the VirtualBox server
98 * process, connecting to it, and redirecting the constructor request to the
99 * VirtualBox component defined on the server.
100 */
101static NS_IMETHODIMP
102VirtualBoxConstructor (nsISupports *aOuter, REFNSIID aIID,
103 void **aResult)
104{
105 LogFlowFuncEnter();
106
107 nsresult rc = NS_OK;
108 int vrc = VINF_SUCCESS;
109
110 do
111 {
112 *aResult = NULL;
113 if (NULL != aOuter)
114 {
115 rc = NS_ERROR_NO_AGGREGATION;
116 break;
117 }
118
119 if (!IsVBoxSVCPathSet)
120 {
121 /* Get the directory containing XPCOM components -- the VBoxSVC
122 * executable is expected in the parent directory. */
123 nsCOMPtr <nsIProperties> dirServ = do_GetService (NS_DIRECTORY_SERVICE_CONTRACTID, &rc);
124 if (NS_SUCCEEDED (rc))
125 {
126 nsCOMPtr <nsIFile> componentDir;
127 rc = dirServ->Get (NS_XPCOM_COMPONENT_DIR,
128 NS_GET_IID (nsIFile), getter_AddRefs (componentDir));
129
130 if (NS_SUCCEEDED (rc))
131 {
132 nsCAutoString path;
133 componentDir->GetNativePath (path);
134
135 LogFlowFunc (("components path = \"%s\"\n", path.get()));
136 AssertBreak (path.Length() + strlen (VBoxSVC_exe) < RTPATH_MAX,
137 rc = NS_ERROR_FAILURE);
138
139 strcpy (VBoxSVCPath, path.get());
140 RTPathStripFilename (VBoxSVCPath);
141 strcat (VBoxSVCPath, VBoxSVC_exe);
142
143 IsVBoxSVCPathSet = true;
144 }
145 }
146 if (NS_FAILED (rc))
147 break;
148 }
149
150 nsCOMPtr <ipcIService> ipcServ = do_GetService (IPC_SERVICE_CONTRACTID, &rc);
151 if (NS_FAILED (rc))
152 break;
153
154 /* connect to the VBoxSVC server process */
155
156 bool startedOnce = false;
157 unsigned timeLeft = VBoxSVC_Timeout;
158
159 do
160 {
161 LogFlowFunc (("Resolving server name \"%s\"...\n", VBOXSVC_IPC_NAME));
162
163 PRUint32 serverID = 0;
164 rc = ipcServ->ResolveClientName (VBOXSVC_IPC_NAME, &serverID);
165 if (NS_FAILED (rc))
166 {
167 LogFlowFunc (("Starting server...\n", VBoxSVCPath));
168
169 startedOnce = true;
170
171#ifdef RT_OS_OS2
172 char *const args[] = { VBoxSVCPath, "--automate", 0 };
173 /* use NSPR because we want the process to be detached right
174 * at startup (it isn't possible to detach it later on) */
175 PRStatus rv = PR_CreateProcessDetached (VBoxSVCPath,
176 args, NULL, 0);
177 if (rv != PR_SUCCESS)
178 {
179 rc = NS_ERROR_FAILURE;
180 break;
181 }
182#else
183 const char *args[] = { VBoxSVCPath, "--automate", 0 };
184 RTPROCESS pid = NIL_RTPROCESS;
185 vrc = RTProcCreate (VBoxSVCPath, args, NULL, 0, &pid);
186 if (VBOX_FAILURE (vrc))
187 {
188 rc = NS_ERROR_FAILURE;
189 break;
190 }
191#endif
192
193 /* wait for the server process to establish a connection */
194 do
195 {
196 RTThreadSleep (VBoxSVC_WaitSlice);
197 rc = ipcServ->ResolveClientName (VBOXSVC_IPC_NAME, &serverID);
198 if (NS_SUCCEEDED (rc))
199 break;
200 if (timeLeft <= VBoxSVC_WaitSlice)
201 {
202 timeLeft = 0;
203 break;
204 }
205 timeLeft -= VBoxSVC_WaitSlice;
206 }
207 while (1);
208
209 if (!timeLeft)
210 {
211 rc = IPC_ERROR_WOULD_BLOCK;
212 break;
213 }
214 }
215
216 LogFlowFunc (("Connecting to server (ID=%d)...\n", serverID));
217
218 nsCOMPtr <ipcIDConnectService> dconServ =
219 do_GetService (IPC_DCONNECTSERVICE_CONTRACTID, &rc);
220 if (NS_FAILED (rc))
221 break;
222
223 rc = dconServ->CreateInstance (serverID,
224 (nsCID) NS_VIRTUALBOX_CID,
225 aIID, aResult);
226 if (NS_SUCCEEDED (rc))
227 break;
228
229 /* It's possible that the server gets shut down after we
230 * successfully resolve the server name but before it
231 * receives our CreateInstance() request. So, check for the
232 * name again, and restart the cycle if it fails. */
233 if (!startedOnce)
234 {
235 nsresult rc2 =
236 ipcServ->ResolveClientName (VBOXSVC_IPC_NAME, &serverID);
237 if (NS_SUCCEEDED (rc2))
238 break;
239 }
240 else
241 break;
242 }
243 while (1);
244 }
245 while (0);
246
247 LogFlowFunc (("rc=%08X, vrc=%Vrc\n", rc, vrc));
248 LogFlowFuncLeave();
249
250 return rc;
251}
252
253#if 0
254/// @todo not really necessary for the moment
255/**
256 *
257 * @param aCompMgr
258 * @param aPath
259 * @param aLoaderStr
260 * @param aType
261 * @param aInfo
262 *
263 * @return
264 */
265static NS_IMETHODIMP
266VirtualBoxRegistration (nsIComponentManager *aCompMgr,
267 nsIFile *aPath,
268 const char *aLoaderStr,
269 const char *aType,
270 const nsModuleComponentInfo *aInfo)
271{
272 nsCAutoString modulePath;
273 aPath->GetNativePath (modulePath);
274 nsCAutoString moduleTarget;
275 aPath->GetNativeTarget (moduleTarget);
276
277 LogFlowFunc (("aPath=%s, aTarget=%s, aLoaderStr=%s, aType=%s\n",
278 modulePath.get(), moduleTarget.get(), aLoaderStr, aType));
279
280 nsresult rc = NS_OK;
281
282 return rc;
283}
284#endif
285
286/**
287 * Component definition table.
288 * Lists all components defined in this module.
289 */
290static const nsModuleComponentInfo components[] =
291{
292 {
293 "VirtualBox component", // description
294 NS_VIRTUALBOX_CID, NS_VIRTUALBOX_CONTRACTID, // CID/ContractID
295 VirtualBoxConstructor, // constructor function
296 NULL, /* VirtualBoxRegistration, */ // registration function
297 NULL, // deregistration function
298 NULL, // destructor function
299 /// @todo
300 NS_CI_INTERFACE_GETTER_NAME(VirtualBox), // interfaces function
301 NULL, // language helper
302 /// @todo
303 &NS_CLASSINFO_NAME(VirtualBox) // global class info & flags
304 }
305};
306
307NS_IMPL_NSGETMODULE (VirtualBox_Server_Module, components)
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