VirtualBox

source: vbox/trunk/src/VBox/Main/cbinding/VBoxXPCOMCGlue.c@ 26270

Last change on this file since 26270 was 19052, checked in by vboxsync, 16 years ago

VBoxXPCOMCGlue.c: dlopen errors are less important than the other ones.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.3 KB
Line 
1/* $Revision: 19052 $ */
2/** @file
3 * Glue code for dynamically linking to VBoxXPCOMC.
4 */
5
6/*
7 * Copyright (C) 2008-2009 Sun Microsystems, Inc.
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31/*******************************************************************************
32* Header Files *
33*******************************************************************************/
34#include <stdio.h>
35#include <string.h>
36#include <stdlib.h>
37#include <stdarg.h>
38#include <dlfcn.h>
39
40#include "VBoxXPCOMCGlue.h"
41
42
43/*******************************************************************************
44* Defined Constants And Macros *
45*******************************************************************************/
46#if defined(__linux__) || defined(__linux_gnu__) || defined(__sun__) || defined(__FreeBSD__)
47# define DYNLIB_NAME "VBoxXPCOMC.so"
48#elif defined(__APPLE__)
49# define DYNLIB_NAME "VBoxXPCOMC.dylib"
50#elif defined(_MSC_VER) || defined(__OS2__)
51# define DYNLIB_NAME "VBoxXPCOMC.dll"
52#else
53# error "Port me"
54#endif
55
56
57/*******************************************************************************
58* Global Variables *
59*******************************************************************************/
60/** The dlopen handle for VBoxXPCOMC. */
61void *g_hVBoxXPCOMC = NULL;
62/** The last load error. */
63char g_szVBoxErrMsg[256];
64/** Pointer to the VBoxXPCOMC function table. */
65PCVBOXXPCOM g_pVBoxFuncs = NULL;
66/** Pointer to VBoxGetXPCOMCFunctions for the loaded VBoxXPCOMC so/dylib/dll. */
67PFNVBOXGETXPCOMCFUNCTIONS g_pfnGetFunctions = NULL;
68
69
70/**
71 * Wrapper for setting g_szVBoxErrMsg. Can be an empty stub.
72 *
73 * @param fAlways When 0 the g_szVBoxErrMsg is only set if empty.
74 * @param pszFormat The format string.
75 * @param ... The arguments.
76 */
77static void setErrMsg(int fAlways, const char *pszFormat, ...)
78{
79 if ( fAlways
80 || !g_szVBoxErrMsg[0])
81 {
82 va_list va;
83 va_start(va, pszFormat);
84 vsnprintf(g_szVBoxErrMsg, sizeof(g_szVBoxErrMsg), pszFormat, va);
85 va_end(va);
86 }
87}
88
89
90/**
91 * Try load VBoxXPCOMC.so/dylib/dll from the specified location and resolve all
92 * the symbols we need.
93 *
94 * @returns 0 on success, -1 on failure.
95 * @param pszHome The director where to try load VBoxXPCOMC from. Can
96 * be NULL.
97 * @param fSetAppHome Whether to set the VBOX_APP_HOME env.var. or not
98 * (boolean).
99 */
100static int tryLoadOne(const char *pszHome, int fSetAppHome)
101{
102 size_t cchHome = pszHome ? strlen(pszHome) : 0;
103 size_t cbBufNeeded;
104 char szName[4096];
105 int rc = -1;
106
107 /*
108 * Construct the full name.
109 */
110 cbBufNeeded = cchHome + sizeof("/" DYNLIB_NAME);
111 if (cbBufNeeded > sizeof(szName))
112 {
113 setErrMsg(1, "path buffer too small: %u bytes needed",
114 (unsigned)cbBufNeeded);
115 return -1;
116 }
117 if (cchHome)
118 {
119 memcpy(szName, pszHome, cchHome);
120 szName[cchHome] = '/';
121 cchHome++;
122 }
123 memcpy(&szName[cchHome], DYNLIB_NAME, sizeof(DYNLIB_NAME));
124
125 /*
126 * Try load it by that name, setting the VBOX_APP_HOME first (for now).
127 * Then resolve and call the function table getter.
128 */
129 if (fSetAppHome)
130 {
131 if (pszHome)
132 setenv("VBOX_APP_HOME", pszHome, 1 /* always override */);
133 else
134 unsetenv("VBOX_APP_HOME");
135 }
136 g_hVBoxXPCOMC = dlopen(szName, RTLD_NOW | RTLD_LOCAL);
137 if (g_hVBoxXPCOMC)
138 {
139 PFNVBOXGETXPCOMCFUNCTIONS pfnGetFunctions;
140 pfnGetFunctions = (PFNVBOXGETXPCOMCFUNCTIONS)
141 dlsym(g_hVBoxXPCOMC, VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME);
142 if (pfnGetFunctions)
143 {
144 g_pVBoxFuncs = pfnGetFunctions(VBOX_XPCOMC_VERSION);
145 if (g_pVBoxFuncs)
146 {
147 g_pfnGetFunctions = pfnGetFunctions;
148 return 0;
149 }
150
151 /* bail out */
152 setErrMsg(1, "%.80s: pfnGetFunctions(%#x) failed",
153 szName, VBOX_XPCOMC_VERSION);
154 }
155 else
156 setErrMsg(1, "dlsym(%.80s/%.32s): %.128s",
157 szName, VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME, dlerror());
158 dlclose(g_hVBoxXPCOMC);
159 g_hVBoxXPCOMC = NULL;
160 }
161 else
162 setErrMsg(0, "dlopen(%.80s): %.160s", szName, dlerror());
163 return rc;
164}
165
166
167/**
168 * Tries to locate and load VBoxXPCOMC.so/dylib/dll, resolving all the related
169 * function pointers.
170 *
171 * @returns 0 on success, -1 on failure.
172 *
173 * @remark This should be considered moved into a separate glue library since
174 * its its going to be pretty much the same for any user of VBoxXPCOMC
175 * and it will just cause trouble to have duplicate versions of this
176 * source code all around the place.
177 */
178int VBoxCGlueInit(void)
179{
180 /*
181 * If the user specifies the location, try only that.
182 */
183 const char *pszHome = getenv("VBOX_APP_HOME");
184 if (pszHome)
185 return tryLoadOne(pszHome, 0);
186
187 /*
188 * Try the known standard locations.
189 */
190 g_szVBoxErrMsg[0] = '\0';
191#if defined(__gnu__linux__) || defined(__linux__)
192 if (tryLoadOne("/opt/VirtualBox", 1) == 0)
193 return 0;
194 if (tryLoadOne("/usr/lib/virtualbox", 1) == 0)
195 return 0;
196#elif defined(__sun__)
197 if (tryLoadOne("/opt/VirtualBox/amd64", 1) == 0)
198 return 0;
199 if (tryLoadOne("/opt/VirtualBox/i386", 1) == 0)
200 return 0;
201#elif defined(__APPLE__)
202 if (tryLoadOne("/Application/VirtualBox.app/Contents/MacOS", 1) == 0)
203 return 0;
204#elif defined(__FreeBSD__)
205 if (tryLoadOne("/usr/local/lib/virtualbox", 1) == 0)
206 return 0;
207#else
208# error "port me"
209#endif
210
211 /*
212 * Finally try the dynamic linker search path.
213 */
214 if (tryLoadOne(NULL, 1) == 0)
215 return 0;
216
217 /* No luck, return failure. */
218 return -1;
219}
220
221
222/**
223 * Terminate the C glue library.
224 */
225void VBoxCGlueTerm(void)
226{
227 if (g_hVBoxXPCOMC)
228 {
229#if 0 /* VBoxRT.so doesn't like being reloaded. See @bugref{3725}. */
230 dlclose(g_hVBoxXPCOMC);
231#endif
232 g_hVBoxXPCOMC = NULL;
233 }
234 g_pVBoxFuncs = NULL;
235 g_pfnGetFunctions = NULL;
236 memset(g_szVBoxErrMsg, 0, sizeof(g_szVBoxErrMsg));
237}
238
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