init.cpp revision 9de6f266bd63e9eb633ae367927c1919f9bc6fa5
/* $Id$ */
/** @file
* IPRT - Init Ring-3.
*/
/*
* Copyright (C) 2006-2009 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#define LOG_GROUP RTLOGGROUP_DEFAULT
#ifdef RT_OS_WINDOWS
# include <process.h>
#else
# include <unistd.h>
# ifndef RT_OS_OS2
# include <pthread.h>
# include <signal.h>
# include <errno.h>
# define IPRT_USE_SIG_CHILD_DUMMY
# endif
#endif
#ifdef RT_OS_OS2
# include <InnoTekLIBC/fork.h>
#endif
#include <locale.h>
#include <iprt/initterm.h>
#endif
#include <stdlib.h>
#include "internal/alignmentchecks.h"
/*******************************************************************************
* Global Variables *
*******************************************************************************/
/** The number of calls to RTR3Init. */
/** Whether we're currently initializing the IPRT. */
static bool volatile g_fInitializing = false;
/** The process path.
* This is used by RTPathExecDir and RTProcGetExecutableName and set by rtProcInitName. */
char g_szrtProcExePath[RTPATH_MAX];
/** The length of g_szrtProcExePath. */
/** The length of directory path component of g_szrtProcExePath. */
/** The offset of the process name into g_szrtProcExePath. */
/**
* Program start nanosecond TS.
*/
/**
* Program start microsecond TS.
*/
/**
* Program start millisecond TS.
*/
/**
* The process identifier of the running process.
*/
/**
* The current process priority.
*/
#ifdef IPRT_WITH_ALIGNMENT_CHECKS
/**
* Whether alignment checks are enabled.
* This is set if the environment variable IPRT_ALIGNMENT_CHECKS is 1.
*/
RTDATADECL(bool) g_fRTAlignmentChecks = false;
#endif
/**
* atexit callback.
*
* This makes sure any loggers are flushed and will later also work the
* termination callback chain.
*/
static void rtR3ExitCallback(void)
{
if (g_cUsers > 0)
{
if (pLogger)
if (pLogger)
}
}
#ifndef RT_OS_WINDOWS
/**
* Fork callback, child context.
*/
static void rtR3ForkChildCallback(void)
{
g_ProcessSelf = getpid();
}
#endif /* RT_OS_WINDOWS */
#ifdef RT_OS_OS2
/** Low-level fork callback for OS/2. */
{
return 0;
}
#endif /* RT_OS_OS2 */
/**
* Internal worker which initializes or re-initializes the
* program path, name and directory globals.
*
* @returns IPRT status code.
* @param pszProgramPath The program path, NULL if not specified.
*/
static int rtR3InitProgramPath(const char *pszProgramPath)
{
/*
* We're reserving 32 bytes here for file names as what not.
*/
if (!pszProgramPath)
{
if (RT_FAILURE(rc))
return rc;
}
else
{
}
/*
* Parse the name.
*/
return VINF_SUCCESS;
}
#ifdef IPRT_USE_SIG_CHILD_DUMMY
/**
* Dummy SIGCHILD handler.
*
* Assigned on rtR3Init only when SIGCHILD handler is set SIGIGN or SIGDEF to
* ensure waitpid works properly for the terminated processes.
*/
static void rtR3SigChildHandler(int iSignal)
{
}
#endif /* IPRT_USE_SIG_CHILD_DUMMY */
/**
* rtR3Init worker.
*/
{
/*
* The Process ID.
*/
#ifdef _MSC_VER
#else
g_ProcessSelf = getpid();
#endif
# ifdef VBOX
/*
* This MUST be done as the very first thing, before any file is opened.
* The log is opened on demand, but the first log entries may be caused
* by rtThreadInit() below.
*/
if ( pszDisableHostCache != NULL
{
}
# endif /* VBOX */
#endif /* !IN_GUEST && !RT_NO_GIP */
/*
* Thread Thread database and adopt the caller thread as 'main'.
* This must be done before everything else or else we'll call into threading
* without having initialized TLS entries and suchlike.
*/
int rc = rtThreadInit();
if (fInitSUPLib)
{
/*
* Init GIP first.
* (The more time for updates before real use, the better.)
*/
}
#endif
/*
* The executable path, name and directory.
*/
/*
* The threading is initialized we can safely sleep a bit if GIP
* needs some time to update itself updating.
*/
if (fInitSUPLib && g_pSUPGlobalInfoPage)
{
RTThreadSleep(20);
RTTimeNanoTS();
}
#endif
/*
* Init the program start TSes.
* Do that here to be sure that the GIP time was properly updated the 1st time.
*/
/*
* The remainder cannot easily be undone, so it has to go last.
*/
/* Init C runtime locale. */
/* Fork and exit callbacks. */
#if !defined(RT_OS_WINDOWS) && !defined(RT_OS_OS2)
#endif
#ifdef IPRT_USE_SIG_CHILD_DUMMY
/*
* SIGCHLD must not be ignored (that's default), otherwise posix compliant waitpid
* implementations won't work right.
*/
for (;;)
{
if ( rc != 0
)
break;
/* Try install dummy handler. */
if ( rc != 0
)
break;
/* Race during dynamic load, restore and try again... */
}
#endif /* IPRT_USE_SIG_CHILD_DUMMY */
#ifdef IPRT_WITH_ALIGNMENT_CHECKS
/*
* Enable alignment checks.
*/
&& pszAlignmentChecks[0] == '1'
if (g_fRTAlignmentChecks)
#endif
return VINF_SUCCESS;
}
/**
* Internal initialization worker.
*
* @returns IPRT status code.
* @param fInitSUPLib Whether to call SUPR3Init.
* @param pszProgramPath The program path, NULL if not specified.
*/
{
/* no entry log flow, because prefixes and thread may freak out. */
/*
* Do reference counting, only initialize the first time around.
*
* We are ASSUMING that nobody will be able to race RTR3Init calls when the
* first one, the real init, is running (second assertion).
*/
if (cUsers != 1)
{
if (fInitSUPLib)
#endif
if (!pszProgramPath)
return VINF_SUCCESS;
return rtR3InitProgramPath(pszProgramPath);
}
ASMAtomicWriteBool(&g_fInitializing, true);
/*
* Do the initialization.
*/
if (RT_FAILURE(rc))
{
/* failure */
ASMAtomicWriteBool(&g_fInitializing, false);
return rc;
}
/* success */
LogFlow(("RTR3Init: returns VINF_SUCCESS\n"));
ASMAtomicWriteBool(&g_fInitializing, false);
return VINF_SUCCESS;
}
{
}
{
}
{
}
RTR3DECL(int) RTR3InitAndSUPLib(void)
{
}
{
}
#if 0 /** @todo implement RTR3Term. */
{
}
#endif