VirtualBox

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

Last change on this file since 78003 was 77565, checked in by vboxsync, 6 years ago

darwin/VBoxClient: build fix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.0 KB
Line 
1/** $Id: VBoxClient.cpp 77565 2019-03-05 12:51:42Z vboxsync $ */
2/** @file
3 * VBoxClient - User specific services, Darwin.
4 */
5
6/*
7 * Copyright (C) 2007-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
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/*********************************************************************************************************************************
39* Glogal Variables *
40*********************************************************************************************************************************/
41
42static int g_cVerbosity = 0;
43static PRTLOGGER g_pLogger = NULL;
44
45static VBOXCLIENTSERVICE g_aServices[] =
46{
47 g_ClipboardService
48};
49
50
51/**
52 * Create default logger in order to print output to the specified file.
53 *
54 * @return IPRT status code.
55 */
56static int vbclInitLogger(char *pszLogFileName)
57{
58 static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
59 int rc = RTLogCreateEx(&g_pLogger, RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG, "all", "VBOXCLIENT_RELEASE_LOG",
60 RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX /*cMaxEntriesPerGroup*/,
61 RTLOGDEST_STDOUT,
62 NULL /*pfnPhase*/,
63 pszLogFileName ? 10 : 0 /*cHistory*/,
64 pszLogFileName ? 100 * _1M : 0 /*cbHistoryFileMax*/,
65 pszLogFileName ? RT_SEC_1DAY : 0 /*cSecsHistoryTimeSlot*/,
66 NULL /*pErrInfo*/, "%s", pszLogFileName);
67
68 AssertRCReturn(rc, rc);
69
70 /* Register this logger as the release logger */
71 RTLogRelSetDefaultInstance(g_pLogger);
72
73 /* Explicitly flush the log in case of VBOXCLIENT_RELEASE_LOG=buffered. */
74 RTLogFlush(g_pLogger);
75
76 return VINF_SUCCESS;
77}
78
79
80/**
81 * Destroy logger.
82 */
83static void vbclTermLogger(char *szLogFileName)
84{
85 // Why SIGBUS here?
86 RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
87
88 if (szLogFileName)
89 RTStrFree(szLogFileName);
90}
91
92/**
93 * Displays a verbose message.
94 *
95 * @param iLevel Minimum log level required to display this message.
96 * @param pszFormat The message text.
97 * @param ... Format arguments.
98 */
99void VBoxClientVerbose(int iLevel, const char *pszFormat, ...)
100{
101 if (iLevel > g_cVerbosity)
102 return;
103
104 va_list args;
105 va_start(args, pszFormat);
106 char *psz = NULL;
107 RTStrAPrintfV(&psz, pszFormat, args);
108 va_end(args);
109
110 AssertPtr(psz);
111 LogRel(("%s", psz));
112
113 RTStrFree(psz);
114}
115
116/**
117 * Wait for signals in order to safely terminate process.
118 */
119static void vbclWait(void)
120{
121 sigset_t signalMask;
122 int iSignal;
123
124 /* Register signals that we are waiting for */
125 sigemptyset(&signalMask);
126 sigaddset(&signalMask, SIGHUP);
127 sigaddset(&signalMask, SIGINT);
128 sigaddset(&signalMask, SIGQUIT);
129 sigaddset(&signalMask, SIGABRT);
130 sigaddset(&signalMask, SIGTERM);
131 pthread_sigmask(SIG_BLOCK, &signalMask, NULL);
132
133 /* Ignoring return status */
134 sigwait(&signalMask, &iSignal);
135}
136
137/**
138 * Start registered services.
139 *
140 * @return IPRT status code.
141 */
142static int vbclStartServices(void)
143{
144 int rc;
145 unsigned int iServiceId = 0;
146
147 VBoxClientVerbose(1, "Starting services...\n");
148 for (iServiceId = 0; iServiceId < RT_ELEMENTS(g_aServices); iServiceId++)
149 {
150 VBoxClientVerbose(1, "Starting service: %s\n", g_aServices[iServiceId].pszName);
151 rc = (g_aServices[iServiceId].pfnStart)();
152 if (RT_FAILURE(rc))
153 {
154 VBoxClientVerbose(1, "unable to start service: %s (%Rrc)\n", g_aServices[iServiceId].pszName, rc);
155 VBoxClientVerbose(1, "Rolling back..\n");
156
157 /* Stop running services */
158 do
159 {
160 VBoxClientVerbose(1, "Stopping service: %s\n", g_aServices[iServiceId].pszName);
161 int rcStop = (g_aServices[iServiceId].pfnStop)();
162 if (RT_FAILURE(rcStop))
163 VBoxClientVerbose(1, "unable to stop service: %s (%Rrc)\n", g_aServices[iServiceId].pszName, rcStop);
164 } while (--iServiceId != 0);
165
166 break;
167 }
168 }
169
170 if (RT_SUCCESS(rc))
171 VBoxClientVerbose(1, "Services start completed.\n");
172
173 return rc;
174}
175
176/**
177 * Stop registered services.
178 *
179 * @return IPRT status code.
180 */
181static void vbclStopServices(void)
182{
183 unsigned int iServiceId = 0;
184
185 VBoxClientVerbose(1, "Stopping services...\n");
186 for (iServiceId = 0; iServiceId < RT_ELEMENTS(g_aServices); iServiceId++)
187 {
188 VBoxClientVerbose(1, "Stopping service: %s\n", g_aServices[iServiceId].pszName);
189 int rc = (g_aServices[iServiceId].pfnStop)();
190 if (RT_FAILURE(rc))
191 VBoxClientVerbose(1, "unable to stop service: %s (%Rrc)\n", g_aServices[iServiceId].pszName, rc);
192 }
193 VBoxClientVerbose(1, "Services stop completed\n");
194}
195
196
197static void usage(char *sProgName)
198{
199 RTPrintf("usage: %s [-fvl]\n", sProgName);
200 RTPrintf(" -f\tRun in foreground (default: no)\n", sProgName);
201 RTPrintf(" -v\tIncrease verbosity level (default: no verbosity)\n", sProgName);
202 RTPrintf(" -l\tSpecify log file name (default: no log file)\n", sProgName);
203 exit(1);
204}
205
206int main(int argc, char *argv[])
207{
208 int rc;
209 int c;
210
211 bool fDemonize = true;
212 static char *szLogFileName = NULL;
213
214 /* Parse command line */
215 while((c = getopt(argc, argv, "fvl:")) != -1)
216 {
217 switch(c)
218 {
219 case 'f':
220 fDemonize = false;
221 break;
222 case 'v':
223 g_cVerbosity++;
224 break;
225 case 'l':
226 szLogFileName = RTStrDup(optarg);
227 break;
228
229 default : usage(argv[0]);
230 }
231 }
232
233 /* No more arguments allowed */
234 if ((argc - optind) != 0)
235 usage(argv[0]);
236
237 if (fDemonize)
238 {
239 rc = RTProcDaemonizeUsingFork(true /* fNoChDir */, false /* fNoClose */, NULL);
240 if (RT_FAILURE(rc))
241 {
242 RTPrintf("failed to run into background\n");
243 return 1;
244 }
245 }
246
247 rc = RTR3InitExe(argc, &argv, 0);
248 if (RT_FAILURE(rc))
249 {
250 RTPrintf("RTR3InitExe() failed: (%Rrc)\n", rc);
251 return RTMsgInitFailure(rc);
252 }
253
254 rc = VbglR3Init();
255 if (RT_SUCCESS(rc))
256 {
257 rc = vbclInitLogger(szLogFileName);
258 if (RT_SUCCESS(rc))
259 {
260 rc = vbclStartServices();
261 if (RT_SUCCESS(rc))
262 {
263 vbclWait();
264 vbclStopServices();
265 }
266 else
267 {
268 RTPrintf("failed to start services: (%Rrc)\n", rc);
269 }
270
271 vbclTermLogger(szLogFileName);
272 }
273 else
274 {
275 RTPrintf("failed to start logger: (%Rrc)\n", rc);
276 }
277
278 VbglR3Term();
279 }
280 else
281 {
282 RTPrintf("failed to initialize guest library: (%Rrc)\n", rc);
283 }
284
285 return 0;
286}
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