VirtualBox

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

Last change on this file since 91877 was 90862, checked in by vboxsync, 3 years ago

IPRT,SUPDrv,VMM,++: Bumped major support driver version. Added RTLogSetR0ProgramStart and make the VMM use it when configuring the ring-0 loggers. Removed pfnFlush from the parameter list of RTLogCreateEx[V]. bugref:10086

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