summaryrefslogtreecommitdiff
path: root/src/VBox/Runtime/r3/init.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Runtime/r3/init.cpp')
-rw-r--r--src/VBox/Runtime/r3/init.cpp157
1 files changed, 122 insertions, 35 deletions
diff --git a/src/VBox/Runtime/r3/init.cpp b/src/VBox/Runtime/r3/init.cpp
index 8c3699d1..1f680bf2 100644
--- a/src/VBox/Runtime/r3/init.cpp
+++ b/src/VBox/Runtime/r3/init.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2009 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -66,11 +66,11 @@
#endif
#include <stdlib.h>
+#include "init.h"
#include "internal/alignmentchecks.h"
#include "internal/path.h"
#include "internal/process.h"
#include "internal/thread.h"
-#include "internal/thread.h"
#include "internal/time.h"
@@ -92,6 +92,9 @@ DECLHIDDEN(size_t) g_cchrtProcDir;
/** The offset of the process name into g_szrtProcExePath. */
DECLHIDDEN(size_t) g_offrtProcName;
+/** The IPRT init flags. */
+static uint32_t g_fInitFlags;
+
/** The argument count of the program. */
static int g_crtArgs = -1;
/** The arguments of the program (UTF-8). This is "leaked". */
@@ -139,6 +142,15 @@ RTDATADECL(bool) g_fRTAlignmentChecks = false;
#endif
+#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) || defined(RT_OS_HAIKU) \
+ || defined(RT_OS_LINUX) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS) /** @todo add host init hooks everywhere. */
+/* Stubs */
+DECLHIDDEN(int) rtR3InitNativeFirst(uint32_t fFlags) { return VINF_SUCCESS; }
+DECLHIDDEN(int) rtR3InitNativeFinal(uint32_t fFlags) { return VINF_SUCCESS; }
+DECLHIDDEN(void) rtR3InitNativeObtrusive(void) { }
+#endif
+
+
/**
* atexit callback.
*
@@ -228,7 +240,7 @@ static int rtR3InitProgramPath(const char *pszProgramPath)
* Parse the name.
*/
ssize_t offName;
- g_cchrtProcExePath = RTPathParse(g_szrtProcExePath, &g_cchrtProcDir, &offName, NULL);
+ g_cchrtProcExePath = RTPathParseSimple(g_szrtProcExePath, &g_cchrtProcDir, &offName, NULL);
g_offrtProcName = offName;
return VINF_SUCCESS;
}
@@ -265,31 +277,74 @@ static int rtR3InitArgv(uint32_t fFlags, int cArgs, char ***ppapszArgs)
return VINF_SUCCESS;
}
- /*
- * Convert the arguments.
- */
- char **papszArgs = (char **)RTMemAllocZ((cArgs + 1) * sizeof(char *));
- if (!papszArgs)
- return VERR_NO_MEMORY;
-
- for (int i = 0; i < cArgs; i++)
+ if (!(fFlags & RTR3INIT_FLAGS_UTF8_ARGV))
{
- int rc = RTStrCurrentCPToUtf8(&papszArgs[i], papszOrgArgs[i]);
- if (RT_FAILURE(rc))
+ /*
+ * Convert the arguments.
+ */
+ char **papszArgs = (char **)RTMemAllocZ((cArgs + 1) * sizeof(char *));
+ if (!papszArgs)
+ return VERR_NO_MEMORY;
+
+#ifdef RT_OS_WINDOWS
+ /* HACK ALERT! Try convert from unicode versions if possible.
+ Unfortunately for us, __wargv is only initialized if we have a
+ unicode main function. So, we have to use CommandLineToArgvW to get
+ something similar. It should do the same conversion... :-) */
+ int cArgsW = -1;
+ PWSTR *papwszArgs = NULL;
+ if ( papszOrgArgs == __argv
+ && cArgs == __argc
+ && (papwszArgs = CommandLineToArgvW(GetCommandLineW(), &cArgsW)) != NULL )
{
- while (i--)
- RTStrFree(papszArgs[i]);
- RTMemFree(papszArgs);
- return rc;
+ AssertMsg(cArgsW == cArgs, ("%d vs %d\n", cArgsW, cArgs));
+ for (int i = 0; i < cArgs; i++)
+ {
+ int rc = RTUtf16ToUtf8(papwszArgs[i], &papszArgs[i]);
+ if (RT_FAILURE(rc))
+ {
+ while (i--)
+ RTStrFree(papszArgs[i]);
+ RTMemFree(papszArgs);
+ LocalFree(papwszArgs);
+ return rc;
+ }
+ }
+ LocalFree(papwszArgs);
+ }
+ else
+#endif
+ {
+ for (int i = 0; i < cArgs; i++)
+ {
+ int rc = RTStrCurrentCPToUtf8(&papszArgs[i], papszOrgArgs[i]);
+ if (RT_FAILURE(rc))
+ {
+ while (i--)
+ RTStrFree(papszArgs[i]);
+ RTMemFree(papszArgs);
+ return rc;
+ }
+ }
}
- }
- papszArgs[cArgs] = NULL;
- g_papszrtOrgArgs = papszOrgArgs;
- g_papszrtArgs = papszArgs;
- g_crtArgs = cArgs;
+ papszArgs[cArgs] = NULL;
- *ppapszArgs = papszArgs;
+ g_papszrtOrgArgs = papszOrgArgs;
+ g_papszrtArgs = papszArgs;
+ g_crtArgs = cArgs;
+
+ *ppapszArgs = papszArgs;
+ }
+ else
+ {
+ /*
+ * The arguments are already UTF-8, no conversion needed.
+ */
+ g_papszrtOrgArgs = papszOrgArgs;
+ g_papszrtArgs = papszOrgArgs;
+ g_crtArgs = cArgs;
+ }
}
return VINF_SUCCESS;
@@ -316,6 +371,19 @@ static void rtR3SigChildHandler(int iSignal)
static int rtR3InitBody(uint32_t fFlags, int cArgs, char ***papszArgs, const char *pszProgramPath)
{
/*
+ * Early native initialization.
+ */
+ int rc = rtR3InitNativeFirst(fFlags);
+ AssertMsgRCReturn(rc, ("rtR3InitNativeFirst failed with %Rrc\n", rc), rc);
+
+ /*
+ * Disable error popups.
+ */
+#if defined(RT_OS_OS2) /** @todo move to private code. */
+ DosError(FERR_DISABLEHARDERR);
+#endif
+
+ /*
* Init C runtime locale before we do anything that may end up converting
* paths or we'll end up using the "C" locale for path conversion.
*/
@@ -331,14 +399,9 @@ static int rtR3InitBody(uint32_t fFlags, int cArgs, char ***papszArgs, const cha
#endif
/*
- * Disable error popups.
+ * Save the init flags.
*/
-#ifdef RT_OS_WINDOWS
- UINT fOldErrMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
- SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX | fOldErrMode);
-#elif defined(RT_OS_OS2)
- DosError(FERR_DISABLEHARDERR);
-#endif
+ g_fInitFlags |= fFlags;
#if !defined(IN_GUEST) && !defined(RT_NO_GIP)
# ifdef VBOX
@@ -363,7 +426,7 @@ static int rtR3InitBody(uint32_t fFlags, int cArgs, char ***papszArgs, const cha
* This must be done before everything else or else we'll call into threading
* without having initialized TLS entries and suchlike.
*/
- int rc = rtThreadInit();
+ rc = rtThreadInit();
AssertMsgRCReturn(rc, ("Failed to initialize threads, rc=%Rrc!\n", rc), rc);
#if !defined(IN_GUEST) && !defined(RT_NO_GIP)
@@ -465,6 +528,12 @@ static int rtR3InitBody(uint32_t fFlags, int cArgs, char ***papszArgs, const cha
IPRT_ALIGNMENT_CHECKS_ENABLE();
#endif
+ /*
+ * Final native initialization.
+ */
+ rc = rtR3InitNativeFinal(fFlags);
+ AssertMsgRCReturn(rc, ("rtR3InitNativeFinal failed with %Rrc\n", rc), rc);
+
return VINF_SUCCESS;
}
@@ -483,7 +552,10 @@ static int rtR3InitBody(uint32_t fFlags, int cArgs, char ***papszArgs, const cha
static int rtR3Init(uint32_t fFlags, int cArgs, char ***papszArgs, const char *pszProgramPath)
{
/* no entry log flow, because prefixes and thread may freak out. */
- Assert(!(fFlags & ~(RTR3INIT_FLAGS_DLL | RTR3INIT_FLAGS_SUPLIB)));
+ Assert(!(fFlags & ~( RTR3INIT_FLAGS_DLL
+ | RTR3INIT_FLAGS_SUPLIB
+ | RTR3INIT_FLAGS_UNOBTRUSIVE
+ | RTR3INIT_FLAGS_UTF8_ARGV)));
Assert(!(fFlags & RTR3INIT_FLAGS_DLL) || cArgs == 0);
/*
@@ -499,12 +571,23 @@ static int rtR3Init(uint32_t fFlags, int cArgs, char ***papszArgs, const char *p
Assert(!g_fInitializing);
#if !defined(IN_GUEST) && !defined(RT_NO_GIP)
if (fFlags & RTR3INIT_FLAGS_SUPLIB)
+ {
SUPR3Init(NULL);
+ g_fInitFlags |= RTR3INIT_FLAGS_SUPLIB;
+ }
#endif
- if (!pszProgramPath)
- return VINF_SUCCESS;
- int rc = rtR3InitProgramPath(pszProgramPath);
+ if ( !(fFlags & RTR3INIT_FLAGS_UNOBTRUSIVE)
+ && (g_fInitFlags & RTR3INIT_FLAGS_UNOBTRUSIVE))
+ {
+ g_fInitFlags &= ~RTR3INIT_FLAGS_UNOBTRUSIVE;
+ rtR3InitNativeObtrusive();
+ rtThreadReInitObtrusive();
+ }
+
+ int rc = VINF_SUCCESS;
+ if (pszProgramPath)
+ rc = rtR3InitProgramPath(pszProgramPath);
if (RT_SUCCESS(rc))
rc = rtR3InitArgv(fFlags, cArgs, papszArgs);
return rc;
@@ -557,6 +640,10 @@ RTR3DECL(int) RTR3InitEx(uint32_t iVersion, uint32_t fFlags, int cArgs, char ***
return rtR3Init(fFlags, cArgs, papszArgs, pszProgramPath);
}
+RTR3DECL(bool) RTR3InitIsUnobtrusive(void)
+{
+ return RT_BOOL(g_fInitFlags & RTR3INIT_FLAGS_UNOBTRUSIVE);
+}
#if 0 /** @todo implement RTR3Term. */
RTR3DECL(void) RTR3Term(void)