VirtualBox

source: vbox/trunk/src/VBox/Additions/darwin/VBoxClient/VBoxClient.cpp@ 51287

Last change on this file since 51287 was 48573, checked in by vboxsync, 11 years ago

darwin/VBoxClient.cpp: g_aService isn't declared as array of arrays of VBOXCLIENTSERVICEs.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.8 KB
Line 
1/** $Id: VBoxClient.cpp 48573 2013-09-20 07:24:16Z vboxsync $ */
2/** @file
3 * VBoxClient - User specific services, Darwin.
4 */
5
6/*
7 * Copyright (C) 2007-2013 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
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include <stdio.h>
23#include <signal.h>
24#include <unistd.h>
25#include <stdlib.h>
26
27#include <VBox/log.h>
28#include <VBox/VBoxGuestLib.h>
29#include <iprt/stream.h>
30#include <iprt/initterm.h>
31#include <iprt/message.h>
32#include <iprt/process.h>
33#include <iprt/string.h>
34
35#include "VBoxClientInternal.h"
36
37/*******************************************************************************
38* Glogal Variables *
39*******************************************************************************/
40
41static int g_cVerbosity = 0;
42static PRTLOGGER g_pLogger = NULL;
43
44static VBOXCLIENTSERVICE g_aServices[] =
45{
46 g_ClipboardService
47};
48
49
50/**
51 * Create default logger in order to print output to the specified file.
52 *
53 * @return IPRT status code.
54 */
55static int vbclInitLogger(char *szLogFileName)
56{
57 int rc;
58
59 uint32_t fFlags = RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG;
60 static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
61 uint32_t fDestFlags = RTLOGDEST_STDOUT;
62
63 rc = RTLogCreateEx(&g_pLogger,
64 fFlags, /* Logger instance flags, a combination of the RTLOGFLAGS_* values */
65 "all", /* The initial group settings */
66 "VBOXCLIENT_RELEASE_LOG", /* Base name for the environment variables for this instance */
67 RT_ELEMENTS(s_apszGroups), /* Number of groups in the array */
68 s_apszGroups, /* Pointer to array of groups. This must stick around for the life of the logger instance */
69 fDestFlags, /* The destination flags */
70 NULL, /* Callback function for starting logging and for ending or starting a new file for log history rotation */
71 szLogFileName ? 10 : 0, /* Number of old log files to keep when performing log history rotation */
72 szLogFileName ? 100 * _1M : 0, /* Maximum size of log file when performing history rotation */
73 szLogFileName ? RT_SEC_1DAY : 0, /* Maximum time interval per log file when performing history rotation */
74 0, /* A buffer which is filled with an error message if something fails */
75 0, /* The size of the error message buffer */
76 szLogFileName /* Log filename format string */
77 );
78
79 AssertReturn(RT_SUCCESS(rc), rc);
80
81 /* Register this logger as the release logger */
82 RTLogRelSetDefaultInstance(g_pLogger);
83
84 /* Explicitly flush the log in case of VBOXCLIENT_RELEASE_LOG=buffered. */
85 RTLogFlush(g_pLogger);
86
87 return rc;
88}
89
90
91/**
92 * Destroy logger.
93 */
94static void vbclTermLogger(char *szLogFileName)
95{
96 // Why SIGBUS here?
97 RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
98
99 if (szLogFileName)
100 RTStrFree(szLogFileName);
101}
102
103/**
104 * Displays a verbose message.
105 *
106 * @param iLevel Minimum log level required to display this message.
107 * @param pszFormat The message text.
108 * @param ... Format arguments.
109 */
110void VBoxClientVerbose(int iLevel, const char *pszFormat, ...)
111{
112 if (iLevel > g_cVerbosity)
113 return;
114
115 va_list args;
116 va_start(args, pszFormat);
117 char *psz = NULL;
118 RTStrAPrintfV(&psz, pszFormat, args);
119 va_end(args);
120
121 AssertPtr(psz);
122 LogRel(("%s", psz));
123
124 RTStrFree(psz);
125}
126
127/**
128 * Wait for signals in order to safely terminate process.
129 */
130static void vbclWait(void)
131{
132 sigset_t signalMask;
133 int iSignal;
134
135 /* Register signals that we are waiting for */
136 sigemptyset(&signalMask);
137 sigaddset(&signalMask, SIGHUP);
138 sigaddset(&signalMask, SIGINT);
139 sigaddset(&signalMask, SIGQUIT);
140 sigaddset(&signalMask, SIGABRT);
141 sigaddset(&signalMask, SIGTERM);
142 pthread_sigmask(SIG_BLOCK, &signalMask, NULL);
143
144 /* Ignoring return status */
145 sigwait(&signalMask, &iSignal);
146}
147
148/**
149 * Start registered services.
150 *
151 * @return IPRT status code.
152 */
153static int vbclStartServices(void)
154{
155 int rc;
156 unsigned int iServiceId = 0;
157
158 VBoxClientVerbose(1, "Starting services...\n");
159 for (iServiceId = 0; iServiceId < RT_ELEMENTS(g_aServices); iServiceId++)
160 {
161 VBoxClientVerbose(1, "Starting service: %s\n", g_aServices[iServiceId].pszName);
162 rc = (g_aServices[iServiceId].pfnStart)();
163 if (RT_FAILURE(rc))
164 {
165 VBoxClientVerbose(1, "unable to start service: %s (%Rrc)\n", g_aServices[iServiceId].pszName, rc);
166 VBoxClientVerbose(1, "Rolling back..\n");
167
168 /* Stop running services */
169 do
170 {
171 VBoxClientVerbose(1, "Stopping service: %s\n", g_aServices[iServiceId].pszName);
172 int rcStop = (g_aServices[iServiceId].pfnStop)();
173 if (RT_FAILURE(rcStop))
174 VBoxClientVerbose(1, "unable to stop service: %s (%Rrc)\n", g_aServices[iServiceId].pszName, rcStop);
175 } while (--iServiceId != 0);
176
177 break;
178 }
179 }
180
181 if (RT_SUCCESS(rc))
182 VBoxClientVerbose(1, "Services start completed.\n");
183
184 return rc;
185}
186
187/**
188 * Stop registered services.
189 *
190 * @return IPRT status code.
191 */
192static void vbclStopServices(void)
193{
194 unsigned int iServiceId = 0;
195
196 VBoxClientVerbose(1, "Stopping services...\n");
197 for (iServiceId = 0; iServiceId < RT_ELEMENTS(g_aServices); iServiceId++)
198 {
199 VBoxClientVerbose(1, "Stopping service: %s\n", g_aServices[iServiceId].pszName);
200 int rc = (g_aServices[iServiceId].pfnStop)();
201 if (RT_FAILURE(rc))
202 VBoxClientVerbose(1, "unable to stop service: %s (%Rrc)\n", g_aServices[iServiceId].pszName, rc);
203 }
204 VBoxClientVerbose(1, "Services stop completed\n");
205}
206
207
208static void usage(char *sProgName)
209{
210 RTPrintf("usage: %s [-fvl]\n", sProgName);
211 RTPrintf(" -f\tRun in foreground (default: no)\n", sProgName);
212 RTPrintf(" -v\tIncrease verbosity level (default: no verbosity)\n", sProgName);
213 RTPrintf(" -l\tSpecify log file name (default: no log file)\n", sProgName);
214 exit(1);
215}
216
217int main(int argc, char *argv[])
218{
219 int rc;
220 int c;
221
222 bool fDemonize = true;
223 static char *szLogFileName = NULL;
224
225 /* Parse command line */
226 while((c = getopt(argc, argv, "fvl:")) != -1)
227 {
228 switch(c)
229 {
230 case 'f':
231 fDemonize = false;
232 break;
233 case 'v':
234 g_cVerbosity++;
235 break;
236 case 'l':
237 szLogFileName = RTStrDup(optarg);
238 break;
239
240 default : usage(argv[0]);
241 }
242 }
243
244 /* No more arguments allowed */
245 if ((argc - optind) != 0)
246 usage(argv[0]);
247
248 if (fDemonize)
249 {
250 rc = RTProcDaemonizeUsingFork(true /* fNoChDir */, false /* fNoClose */, NULL);
251 if (RT_FAILURE(rc))
252 {
253 RTPrintf("failed to run into background\n");
254 return 1;
255 }
256 }
257
258 rc = RTR3InitExe(argc, &argv, 0);
259 if (RT_FAILURE(rc))
260 {
261 RTPrintf("RTR3InitExe() failed: (%Rrc)\n", rc);
262 return RTMsgInitFailure(rc);
263 }
264
265 rc = VbglR3Init();
266 if (RT_SUCCESS(rc))
267 {
268 rc = vbclInitLogger(szLogFileName);
269 if (RT_SUCCESS(rc))
270 {
271 rc = vbclStartServices();
272 if (RT_SUCCESS(rc))
273 {
274 vbclWait();
275 vbclStopServices();
276 }
277 else
278 {
279 RTPrintf("failed to start services: (%Rrc)\n", rc);
280 }
281
282 vbclTermLogger(szLogFileName);
283 }
284 else
285 {
286 RTPrintf("failed to start logger: (%Rrc)\n", rc);
287 }
288
289 VbglR3Term();
290 }
291 else
292 {
293 RTPrintf("failed to initialize guest library: (%Rrc)\n", rc);
294 }
295
296 return 0;
297}
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