diff options
Diffstat (limited to 'lib/server/LocalProcessStream.cpp')
-rw-r--r-- | lib/server/LocalProcessStream.cpp | 82 |
1 files changed, 74 insertions, 8 deletions
diff --git a/lib/server/LocalProcessStream.cpp b/lib/server/LocalProcessStream.cpp index 7b8e78c6..f694fa58 100644 --- a/lib/server/LocalProcessStream.cpp +++ b/lib/server/LocalProcessStream.cpp @@ -1,4 +1,4 @@ -// distribution boxbackup-0.10 (svn version: 494) +// distribution boxbackup-0.11rc1 (svn version: 2023_2024) // // Copyright (c) 2003 - 2006 // Ben Summers and contributors. All rights reserved. @@ -56,10 +56,15 @@ #endif #include "LocalProcessStream.h" -#include "SocketStream.h" #include "autogen_ServerException.h" #include "Utils.h" +#ifdef WIN32 + #include "FileStream.h" +#else + #include "SocketStream.h" +#endif + #include "MemLeakFindOn.h" #define MAX_ARGUMENTS 64 @@ -68,19 +73,22 @@ // // Function // Name: LocalProcessStream(const char *, pid_t &) -// Purpose: Run a new process, and return a stream giving access to it's -// stdin and stdout. Returns the PID of the new process -- this -// must be waited on at some point to avoid zombies. +// Purpose: Run a new process, and return a stream giving access +// to its stdin and stdout (stdout and stderr on +// Win32). Returns the PID of the new process -- this +// must be waited on at some point to avoid zombies +// (except on Win32). // Created: 12/3/04 // // -------------------------------------------------------------------------- std::auto_ptr<IOStream> LocalProcessStream(const char *CommandLine, pid_t &rPidOut) { +#ifndef WIN32 + // Split up command std::vector<std::string> command; SplitString(std::string(CommandLine), ' ', command); -#ifndef WIN32 // Build arguments char *args[MAX_ARGUMENTS + 4]; { @@ -139,10 +147,68 @@ std::auto_ptr<IOStream> LocalProcessStream(const char *CommandLine, pid_t &rPidO // Return the stream object and PID rPidOut = pid; return stream; + #else // WIN32 - ::syslog(LOG_ERR, "vfork not implemented - LocalProcessStream.cpp"); - std::auto_ptr<IOStream> stream; + + SECURITY_ATTRIBUTES secAttr; + secAttr.nLength = sizeof(SECURITY_ATTRIBUTES); + secAttr.bInheritHandle = TRUE; + secAttr.lpSecurityDescriptor = NULL; + + HANDLE writeInChild, readFromChild; + if(!CreatePipe(&readFromChild, &writeInChild, &secAttr, 0)) + { + BOX_ERROR("Failed to CreatePipe for child process: " << + GetErrorMessage(GetLastError())); + THROW_EXCEPTION(ServerException, SocketPairFailed) + } + SetHandleInformation(readFromChild, HANDLE_FLAG_INHERIT, 0); + + PROCESS_INFORMATION procInfo; + STARTUPINFO startupInfo; + + ZeroMemory(&procInfo, sizeof(procInfo)); + ZeroMemory(&startupInfo, sizeof(startupInfo)); + startupInfo.cb = sizeof(startupInfo); + startupInfo.hStdError = writeInChild; + startupInfo.hStdOutput = writeInChild; + startupInfo.hStdInput = INVALID_HANDLE_VALUE; + startupInfo.dwFlags |= STARTF_USESTDHANDLES; + + CHAR* commandLineCopy = (CHAR*)malloc(strlen(CommandLine) + 1); + strcpy(commandLineCopy, CommandLine); + + BOOL result = CreateProcess(NULL, + commandLineCopy, // command line + NULL, // process security attributes + NULL, // primary thread security attributes + TRUE, // handles are inherited + 0, // creation flags + NULL, // use parent's environment + NULL, // use parent's current directory + &startupInfo, // STARTUPINFO pointer + &procInfo); // receives PROCESS_INFORMATION + + free(commandLineCopy); + + if(!result) + { + BOX_ERROR("Failed to CreateProcess: '" << CommandLine << + "': " << GetErrorMessage(GetLastError())); + CloseHandle(writeInChild); + CloseHandle(readFromChild); + THROW_EXCEPTION(ServerException, ServerForkError) + } + + CloseHandle(procInfo.hProcess); + CloseHandle(procInfo.hThread); + CloseHandle(writeInChild); + + rPidOut = (int)(procInfo.dwProcessId); + + std::auto_ptr<IOStream> stream(new FileStream(readFromChild)); return stream; + #endif // ! WIN32 } |