From 9ccdbb5d61741dbeac91a9c50a51ade6d31273e6 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Wed, 6 May 2009 13:23:44 +0000 Subject: [PATCH] * src/vbox/vbox_XPCOMCGlue.[ch]: improve VirtualBox path detection patch by Pritesh Kothari Daniel --- ChangeLog | 5 +++ src/vbox/vbox_XPCOMCGlue.c | 68 ++++++++++++++++++++++++++++++-------- src/vbox/vbox_XPCOMCGlue.h | 3 +- 3 files changed, 61 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 00066af594..4784677c8b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed May 6 15:22:08 CEST 2009 Daniel Veillard + + * src/vbox/vbox_XPCOMCGlue.[ch]: improve VirtualBox path detection + patch by Pritesh Kothari + Tue May 5 10:20:27 EDT 2009 Cole Robinson * src/qemu_driver.c: Don't throw away StartVM errors when diff --git a/src/vbox/vbox_XPCOMCGlue.c b/src/vbox/vbox_XPCOMCGlue.c index bcda3ce474..258663a58c 100644 --- a/src/vbox/vbox_XPCOMCGlue.c +++ b/src/vbox/vbox_XPCOMCGlue.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "vbox_XPCOMCGlue.h" @@ -61,41 +62,72 @@ /** The dlopen handle for VBoxXPCOMC. */ void *g_hVBoxXPCOMC = NULL; /** The last load error. */ +char g_szVBoxErrMsg[256]; +/** Pointer to the VBoxXPCOMC function table. */ PCVBOXXPCOM g_pVBoxFuncs = NULL; /** Pointer to VBoxGetXPCOMCFunctions for the loaded VBoxXPCOMC so/dylib/dll. */ PFNVBOXGETXPCOMCFUNCTIONS g_pfnGetFunctions = NULL; +/** + * Wrapper for setting g_szVBoxErrMsg. Can be an empty stub. + * + * @param fAlways When 0 the g_szVBoxErrMsg is only set if empty. + * @param pszFormat The format string. + * @param ... The arguments. + */ +static void setErrMsg(int fAlways, const char *pszFormat, ...) +{ +#ifndef LIBVIRT_VERSION + if ( fAlways + || !g_szVBoxErrMsg[0]) + { + va_list va; + va_start(va, pszFormat); + vsnprintf(g_szVBoxErrMsg, sizeof(g_szVBoxErrMsg), pszFormat, va); + va_end(va); + } +#else /* libvirt */ + (void)fAlways; + (void)pszFormat; +#endif /* libvirt */ +} + + /** * Try load VBoxXPCOMC.so/dylib/dll from the specified location and resolve all * the symbols we need. * * @returns 0 on success, -1 on failure. - * @param pszHome The director where to try load VBoxXPCOMC from. Can be NULL. - * @param fSetAppHome Whether to set the VBOX_APP_HOME env.var. or not (boolean). + * @param pszHome The director where to try load VBoxXPCOMC from. Can + * be NULL. + * @param fSetAppHome Whether to set the VBOX_APP_HOME env.var. or not + * (boolean). */ static int tryLoadOne(const char *pszHome, int fSetAppHome) { size_t cchHome = pszHome ? strlen(pszHome) : 0; size_t cbBufNeeded; - char szBuf[4096]; + char szName[4096]; int rc = -1; /* * Construct the full name. */ cbBufNeeded = cchHome + sizeof("/" DYNLIB_NAME); - if (cbBufNeeded > sizeof(szBuf)) + if (cbBufNeeded > sizeof(szName)) { + setErrMsg(1, "path buffer too small: %u bytes needed", + (unsigned)cbBufNeeded); return -1; } if (cchHome) { - memcpy(szBuf, pszHome, cchHome); - szBuf[cchHome] = '/'; + memcpy(szName, pszHome, cchHome); + szName[cchHome] = '/'; cchHome++; } - memcpy(&szBuf[cchHome], DYNLIB_NAME, sizeof(DYNLIB_NAME)); + memcpy(&szName[cchHome], DYNLIB_NAME, sizeof(DYNLIB_NAME)); /* * Try load it by that name, setting the VBOX_APP_HOME first (for now). @@ -108,7 +140,7 @@ static int tryLoadOne(const char *pszHome, int fSetAppHome) else unsetenv("VBOX_APP_HOME"); } - g_hVBoxXPCOMC = dlopen(szBuf, RTLD_NOW | RTLD_LOCAL); + g_hVBoxXPCOMC = dlopen(szName, RTLD_NOW | RTLD_LOCAL); if (g_hVBoxXPCOMC) { PFNVBOXGETXPCOMCFUNCTIONS pfnGetFunctions; @@ -120,15 +152,21 @@ static int tryLoadOne(const char *pszHome, int fSetAppHome) if (g_pVBoxFuncs) { g_pfnGetFunctions = pfnGetFunctions; - rc = 0; + return 0; } + + /* bail out */ + setErrMsg(1, "%.80s: pfnGetFunctions(%#x) failed", + szName, VBOX_XPCOMC_VERSION); } - if (rc != 0) - { - dlclose(g_hVBoxXPCOMC); - g_hVBoxXPCOMC = NULL; - } + else + setErrMsg(1, "dlsym(%.80s/%.32s): %.128s", + szName, VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME, dlerror()); + dlclose(g_hVBoxXPCOMC); + g_hVBoxXPCOMC = NULL; } + else + setErrMsg(0, "dlopen(%.80s): %.160s", szName, dlerror()); return rc; } @@ -156,6 +194,7 @@ int VBoxCGlueInit(void) /* * Try the known standard locations. */ + g_szVBoxErrMsg[0] = '\0'; #if defined(__gnu__linux__) || defined(__linux__) if (tryLoadOne("/opt/VirtualBox", 1) == 0) return 0; @@ -201,5 +240,6 @@ void VBoxCGlueTerm(void) } g_pVBoxFuncs = NULL; g_pfnGetFunctions = NULL; + memset(g_szVBoxErrMsg, 0, sizeof(g_szVBoxErrMsg)); } diff --git a/src/vbox/vbox_XPCOMCGlue.h b/src/vbox/vbox_XPCOMCGlue.h index cf2e947e4e..f93adaf1da 100644 --- a/src/vbox/vbox_XPCOMCGlue.h +++ b/src/vbox/vbox_XPCOMCGlue.h @@ -29,6 +29,7 @@ #ifndef ___VBoxXPCOMC_cglue_h #define ___VBoxXPCOMC_cglue_h +/* This has to be the oldest version we support. */ #include "vbox_CAPI_v2_2.h" #ifdef __cplusplus @@ -39,7 +40,7 @@ extern "C" { extern void *g_hVBoxXPCOMC; /** The last load error. */ extern char g_szVBoxErrMsg[256]; -/** Pointer to the VBoxXPCOMC function table. */ +/** Pointer to the VBoxXPCOMC function table. */ extern PCVBOXXPCOM g_pVBoxFuncs; /** Pointer to VBoxGetXPCOMCFunctions for the loaded VBoxXPCOMC so/dylib/dll. */ extern PFNVBOXGETXPCOMCFUNCTIONS g_pfnGetFunctions;