+ Added an *almost* unix-like fork system for windows. Insp will create a secondary process now if nofork isn't specified and pipe its console output back to the originator's. If there is an error during startup, it will show too.

* Fixed m_spanningtree project (cmd_rsquit was missing)

git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@7255 e03df62e-2008-0410-955e-edbf42e46eb7
This commit is contained in:
burlex 2007-06-08 21:17:17 +00:00
parent 69d081ad2b
commit 548162d094
2 changed files with 101 additions and 19 deletions

View File

@ -42,8 +42,80 @@
#include <dlfcn.h>
#include <getopt.h>
#else
#include <conio.h>
bool g_starting = true;
static DWORD owner_processid = 0;
bool WindowsForkStart(InspIRCd * Instance)
{
/* Windows implementation of fork() :P */
// Build the command line arguments.
string command_line;
for(int i = 0; i < Instance->Config->argc; ++i)
command_line += Instance->Config->argv[i];
char module[MAX_PATH];
if(!GetModuleFileName(NULL, module, MAX_PATH))
return false;
STARTUPINFO startupinfo;
PROCESS_INFORMATION procinfo;
ZeroMemory(&startupinfo, sizeof(STARTUPINFO));
ZeroMemory(&procinfo, sizeof(PROCESS_INFORMATION));
// Fill in the startup info struct
GetStartupInfo(&startupinfo);
// Create the "startup" event
HANDLE fork_event = CreateEvent(0, TRUE, FALSE, "InspStartup");
if(!fork_event)
{
printf("CreateEvent: %s\n", dlerror());
return false;
}
// Launch our "forked" process.
BOOL bSuccess = CreateProcess ( module, module,
0, // PROCESS_SECURITY_ATTRIBUTES
0, // THREAD_SECURITY_ATTRIBUTES
TRUE, // We went to inherit handles.
CREATE_SUSPENDED | // Suspend the primary thread of the new process
CREATE_PRESERVE_CODE_AUTHZ_LEVEL, // Allow us full access to the process
0, // ENVIRONMENT
0, // CURRENT_DIRECTORY
&startupinfo, // startup info
&procinfo); // process info
if(!bSuccess)
return false;
// Set the owner process id in the target process.
SIZE_T written = 0;
DWORD pid = GetCurrentProcessId();
if(!WriteProcessMemory(procinfo.hProcess, &owner_processid, &pid, sizeof(DWORD), &written) || written != sizeof(DWORD))
return false;
// Resume the other thread (let it start)
ResumeThread(procinfo.hThread);
// Wait for the new process to kill us. If there is some error, the new process will end and we will end up at the next line.
WaitForSingleObject(procinfo.hProcess, INFINITE);
// If we hit this it means startup failed. :(
return true;
}
void WindowsForkKillOwner(InspIRCd * Instance)
{
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, owner_processid);
if(!hProcess || !owner_processid)
exit(1);
// die die die
if(!TerminateProcess(hProcess, 0))
exit(1);
CloseHandle(hProcess);
}
#endif
using irc::sockets::NonBlocking;
@ -354,12 +426,6 @@ std::string InspIRCd::GetRevision()
InspIRCd::InspIRCd(int argc, char** argv)
: ModCount(-1), GlobalCulls(this)
{
#ifdef WINDOWS
ClearConsole();
WSADATA wsadata;
WSAStartup(MAKEWORD(2,0), &wsadata);
#endif
int found_ports = 0;
FailedPortList pl;
int do_version = 0, do_nofork = 0, do_debug = 0, do_nolog = 0, do_root = 0; /* flag variables */
@ -436,6 +502,20 @@ InspIRCd::InspIRCd(int argc, char** argv)
Exit(EXIT_STATUS_NOERROR);
}
#ifdef WIN32
// Handle forking
if(!do_nofork && !owner_processid)
{
if(WindowsForkStart(this))
Exit(0);
}
// Set up winsock
WSADATA wsadata;
WSAStartup(MAKEWORD(2,0), &wsadata);
#endif
if (!ServerConfig::FileExists(this->ConfigFileName))
{
printf("ERROR: Cannot open config file: %s\nExiting...\n", this->ConfigFileName);
@ -559,22 +639,18 @@ InspIRCd::InspIRCd(int argc, char** argv)
Log(DEFAULT,"Keeping pseudo-tty open as we are running in the foreground.");
}
}
#else
InitIPC();
if(!Config->nofork)
{
WindowsForkKillOwner(this);
FreeConsole();
}
#endif
printf("\nInspIRCd is now running!\n");
Log(DEFAULT,"Startup complete.");
this->WritePID(Config->PID);
#ifdef WINDOWS
InitIPC();
g_starting = false;
// remove the console if in no-fork
if(!Config->nofork)
FreeConsole();
#endif
}
std::string InspIRCd::GetVersionString()

View File

@ -234,6 +234,9 @@
<File
RelativePath="..\src\modules\m_spanningtree\resolvers.cpp">
</File>
<File
RelativePath="..\src\modules\m_spanningtree\rsquit.cpp">
</File>
<File
RelativePath="..\src\modules\m_spanningtree\timesynctimer.cpp">
</File>
@ -269,6 +272,9 @@
<File
RelativePath="..\src\modules\m_spanningtree\resolvers.h">
</File>
<File
RelativePath="..\src\modules\m_spanningtree\rsquit.h">
</File>
<File
RelativePath="..\src\modules\m_spanningtree\timesynctimer.h">
</File>