VirtualBox

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

Last change on this file since 88390 was 83716, checked in by vboxsync, 5 years ago

darwin/VBoxClient: VBoxClient.cpp:usage() SEGVs dereferencing an uninitialized thread due to calling RTPrintf() before RTR3InitExe()

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