/****************************************************************************
*
* Copyright (C) 2000-2001 RealNetworks, Inc. All rights reserved.
*
* This program is free software. It may be distributed under the terms
* in the file LICENSE, found in the top level of the source distribution.
*
*/
#include "app.h"
#include "dbg.h"
#include "resolver.h"
#ifdef _UNIX
#include <signal.h>
#endif
CApp* g_pApp = NULL;
#ifdef _UNIX
extern pthread_key_t g_keyself;
#endif
#ifdef _WIN32
extern DWORD g_tlsself;
#endif
/*****************************************************************************
*
* CApp
*
*****************************************************************************/
CApp::CApp( int argc, char** argv ) :
m_argc(argc),
m_argv(argv)
{
g_pApp = this;
atexit( dump_alloc_heaps );
#ifdef _UNIX
pthread_key_create( &g_keyself, NULL );
pthread_setspecific( g_keyself, this );
#endif
#ifdef _WIN32
g_tlsself = ::TlsAlloc();
::TlsSetValue( g_tlsself, this );
#endif
}
CApp::~CApp( void )
{
#ifdef _UNIX
pthread_key_delete( g_keyself );
#endif
#ifdef _WIN32
::TlsFree( g_tlsself );
#endif
}
void CApp::Run( void )
{
CEventThread::Run();
}
bool CApp::Init( void )
{
#ifdef _WIN32
WSADATA wd;
int res = ::WSAStartup( MAKEWORD(2,0), &wd );
if( res != 0 || wd.wVersion < MAKEWORD(2,0) )
{
dbgout( "Cannot start winsock 2.0" );
return false;
}
#endif
// init CResolver
CResolver::GetResolver();
return true;
}
int CApp::Exit( void )
{
#ifdef _WIN32
::WSACleanup();
#endif
delete CResolver::GetResolver();
return 0;
}
/*
* Become process lead and detach from tty
* Code lifted from fetchmail 5.0.0
*/
void CApp::Daemonize( void )
{
#ifdef _UNIX
/* Ignore BSD terminal stop signals */
#ifdef SIGTTOU
signal(SIGTTOU, SIG_IGN);
#endif
#ifdef SIGTTIN
signal(SIGTTIN, SIG_IGN);
#endif
#ifdef SIGTSTP
signal(SIGTSTP, SIG_IGN);
#endif
/* Change to root dir so we don't hold any mount points open */
if( chdir( "/" ) != 0 )
{
dbgout( "chdir failed (%s)", strerror(errno) );
}
/* In case we were not started in the background, fork and let
the parent exit. Guarantees that the child is not a process
group leader */
pid_t childpid;
if( (childpid = fork()) < 0 )
{
dbgout( "fork failed (%s)", strerror(errno) );
return;
}
else if( childpid > 0 )
{
exit( 0 ); /* parent */
}
/* Make ourselves the leader of a new process group with no
controlling terminal */
/* POSIX makes this soooo easy to do */
if( setsid() < 0 )
{
dbgout( "setsid failed (%s)", strerror(errno) );
return;
}
/* lose controlling tty */
signal( SIGHUP, SIG_IGN );
if( (childpid = fork()) < 0 )
{
dbgout( "fork failed (%s)", strerror(errno) );
return;
}
else if( childpid > 0 )
{
exit( 0 ); /* parent */
}
#endif
}
syntax highlighted by Code2HTML, v. 0.9.1