mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-19 00:46:03 +01:00
feat(Process): Add options to disable STDIO in child process #3867
This commit is contained in:
parent
feee864950
commit
4ceb731bba
@ -98,7 +98,7 @@ public:
|
||||
/// Returns the number of seconds spent by the
|
||||
/// current process in user and kernel mode.
|
||||
|
||||
static ProcessHandle launch(const std::string& command, const Args& args);
|
||||
static ProcessHandle launch(const std::string& command, const Args& args, int options = 0);
|
||||
/// Creates a new process for the given command and returns
|
||||
/// a ProcessHandle of the new process. The given arguments are
|
||||
/// passed to the command on the command line.
|
||||
@ -106,7 +106,8 @@ public:
|
||||
static ProcessHandle launch(
|
||||
const std::string& command,
|
||||
const Args& args,
|
||||
const std::string& initialDirectory);
|
||||
const std::string& initialDirectory,
|
||||
int options = 0);
|
||||
/// Creates a new process for the given command and returns
|
||||
/// a ProcessHandle of the new process. The given arguments are
|
||||
/// passed to the command on the command line.
|
||||
@ -117,7 +118,8 @@ public:
|
||||
const Args& args,
|
||||
Pipe* inPipe,
|
||||
Pipe* outPipe,
|
||||
Pipe* errPipe);
|
||||
Pipe* errPipe,
|
||||
int options = 0);
|
||||
/// Creates a new process for the given command and returns
|
||||
/// a ProcessHandle of the new process. The given arguments are
|
||||
/// passed to the command on the command line.
|
||||
@ -150,7 +152,8 @@ public:
|
||||
const std::string& initialDirectory,
|
||||
Pipe* inPipe,
|
||||
Pipe* outPipe,
|
||||
Pipe* errPipe);
|
||||
Pipe* errPipe,
|
||||
int options = 0);
|
||||
/// Creates a new process for the given command and returns
|
||||
/// a ProcessHandle of the new process. The given arguments are
|
||||
/// passed to the command on the command line.
|
||||
@ -184,7 +187,8 @@ public:
|
||||
Pipe* inPipe,
|
||||
Pipe* outPipe,
|
||||
Pipe* errPipe,
|
||||
const Env& env);
|
||||
const Env& env,
|
||||
int options = 0);
|
||||
/// Creates a new process for the given command and returns
|
||||
/// a ProcessHandle of the new process. The given arguments are
|
||||
/// passed to the command on the command line.
|
||||
@ -202,7 +206,8 @@ public:
|
||||
Pipe* inPipe,
|
||||
Pipe* outPipe,
|
||||
Pipe* errPipe,
|
||||
const Env& env);
|
||||
const Env& env,
|
||||
int options = 0);
|
||||
/// Creates a new process for the given command and returns
|
||||
/// a ProcessHandle of the new process. The given arguments are
|
||||
/// passed to the command on the command line.
|
||||
|
44
Foundation/include/Poco/ProcessOptions.h
Normal file
44
Foundation/include/Poco/ProcessOptions.h
Normal file
@ -0,0 +1,44 @@
|
||||
//
|
||||
// ProcessOptions.h
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Processes
|
||||
// Module: ProcessOptions
|
||||
//
|
||||
// Definition of the ProcessOptions class.
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#ifndef Foundation_ProcessOptions_INCLUDED
|
||||
#define Foundation_ProcessOptions_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Foundation.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
enum ProcessOptions
|
||||
/// Options to configure child process behavior.
|
||||
{
|
||||
PROCESS_CLOSE_STDIN = 1,
|
||||
/// Causes the child process STDIN to be closed.
|
||||
|
||||
PROCESS_CLOSE_STDOUT = 2,
|
||||
/// Causes the child process STDOUT to be closed.
|
||||
|
||||
PROCESS_CLOSE_STDERR = 4,
|
||||
/// Causes the child process STDERR to be closed.
|
||||
};
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
#endif // Foundation_ProcessOptions_INCLUDED
|
@ -62,7 +62,8 @@ public:
|
||||
Pipe* inPipe,
|
||||
Pipe* outPipe,
|
||||
Pipe* errPipe,
|
||||
const EnvImpl& env);
|
||||
const EnvImpl& env,
|
||||
int options = 0);
|
||||
static void killImpl(ProcessHandleImpl& handle);
|
||||
static void killImpl(PIDImpl pid);
|
||||
static bool isRunningImpl(const ProcessHandleImpl& handle);
|
||||
@ -77,7 +78,8 @@ private:
|
||||
Pipe* inPipe,
|
||||
Pipe* outPipe,
|
||||
Pipe* errPipe,
|
||||
const EnvImpl& env);
|
||||
const EnvImpl& env,
|
||||
int options = 0);
|
||||
};
|
||||
|
||||
|
||||
|
@ -68,7 +68,8 @@ public:
|
||||
Pipe* inPipe,
|
||||
Pipe* outPipe,
|
||||
Pipe* errPipe,
|
||||
const EnvImpl& env);
|
||||
const EnvImpl& env,
|
||||
int options = 0);
|
||||
static void killImpl(ProcessHandleImpl& handle);
|
||||
static void killImpl(PIDImpl pid);
|
||||
static bool isRunningImpl(const ProcessHandleImpl& handle);
|
||||
|
@ -68,7 +68,8 @@ public:
|
||||
Pipe* inPipe,
|
||||
Pipe* outPipe,
|
||||
Pipe* errPipe,
|
||||
const EnvImpl& env);
|
||||
const EnvImpl& env,
|
||||
int options = 0);
|
||||
static void killImpl(ProcessHandleImpl& handle);
|
||||
static void killImpl(PIDImpl pid);
|
||||
static bool isRunningImpl(const ProcessHandleImpl& handle);
|
||||
|
@ -119,50 +119,50 @@ int ProcessHandle::tryWait() const
|
||||
//
|
||||
// Process
|
||||
//
|
||||
ProcessHandle Process::launch(const std::string& command, const Args& args)
|
||||
ProcessHandle Process::launch(const std::string& command, const Args& args, int options)
|
||||
{
|
||||
std::string initialDirectory;
|
||||
Env env;
|
||||
return ProcessHandle(launchImpl(command, args, initialDirectory, 0, 0, 0, env));
|
||||
return ProcessHandle(launchImpl(command, args, initialDirectory, 0, 0, 0, env, options));
|
||||
}
|
||||
|
||||
|
||||
ProcessHandle Process::launch(const std::string& command, const Args& args, const std::string& initialDirectory)
|
||||
ProcessHandle Process::launch(const std::string& command, const Args& args, const std::string& initialDirectory, int options)
|
||||
{
|
||||
Env env;
|
||||
return ProcessHandle(launchImpl(command, args, initialDirectory, 0, 0, 0, env));
|
||||
return ProcessHandle(launchImpl(command, args, initialDirectory, 0, 0, 0, env, options));
|
||||
}
|
||||
|
||||
|
||||
ProcessHandle Process::launch(const std::string& command, const Args& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe)
|
||||
ProcessHandle Process::launch(const std::string& command, const Args& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, int options)
|
||||
{
|
||||
poco_assert (inPipe == 0 || (inPipe != outPipe && inPipe != errPipe));
|
||||
std::string initialDirectory;
|
||||
Env env;
|
||||
return ProcessHandle(launchImpl(command, args, initialDirectory, inPipe, outPipe, errPipe, env));
|
||||
return ProcessHandle(launchImpl(command, args, initialDirectory, inPipe, outPipe, errPipe, env, options));
|
||||
}
|
||||
|
||||
|
||||
ProcessHandle Process::launch(const std::string& command, const Args& args, const std::string& initialDirectory, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe)
|
||||
ProcessHandle Process::launch(const std::string& command, const Args& args, const std::string& initialDirectory, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, int options)
|
||||
{
|
||||
poco_assert (inPipe == 0 || (inPipe != outPipe && inPipe != errPipe));
|
||||
Env env;
|
||||
return ProcessHandle(launchImpl(command, args, initialDirectory, inPipe, outPipe, errPipe, env));
|
||||
return ProcessHandle(launchImpl(command, args, initialDirectory, inPipe, outPipe, errPipe, env, options));
|
||||
}
|
||||
|
||||
|
||||
ProcessHandle Process::launch(const std::string& command, const Args& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, const Env& env)
|
||||
ProcessHandle Process::launch(const std::string& command, const Args& args, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, const Env& env, int options)
|
||||
{
|
||||
poco_assert (inPipe == 0 || (inPipe != outPipe && inPipe != errPipe));
|
||||
std::string initialDirectory;
|
||||
return ProcessHandle(launchImpl(command, args, initialDirectory, inPipe, outPipe, errPipe, env));
|
||||
return ProcessHandle(launchImpl(command, args, initialDirectory, inPipe, outPipe, errPipe, env, options));
|
||||
}
|
||||
|
||||
|
||||
ProcessHandle Process::launch(const std::string& command, const Args& args, const std::string& initialDirectory, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, const Env& env)
|
||||
ProcessHandle Process::launch(const std::string& command, const Args& args, const std::string& initialDirectory, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, const Env& env, int options)
|
||||
{
|
||||
poco_assert (inPipe == 0 || (inPipe != outPipe && inPipe != errPipe));
|
||||
return ProcessHandle(launchImpl(command, args, initialDirectory, inPipe, outPipe, errPipe, env));
|
||||
return ProcessHandle(launchImpl(command, args, initialDirectory, inPipe, outPipe, errPipe, env, options));
|
||||
}
|
||||
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/ProcessOptions.h"
|
||||
#include "Poco/Process_UNIX.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
@ -112,7 +113,7 @@ void ProcessImpl::timesImpl(long& userTime, long& kernelTime)
|
||||
}
|
||||
|
||||
|
||||
ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const ArgsImpl& args, const std::string& initialDirectory, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, const EnvImpl& env)
|
||||
ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const ArgsImpl& args, const std::string& initialDirectory, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, const EnvImpl& env, int options)
|
||||
{
|
||||
#if defined(__QNX__)
|
||||
if (initialDirectory.empty())
|
||||
@ -156,21 +157,24 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg
|
||||
throw SystemException("cannot spawn", command);
|
||||
|
||||
if (inPipe) inPipe->close(Pipe::CLOSE_READ);
|
||||
if (options & PROCESS_CLOSE_STDIN) close(STDIN_FILENO);
|
||||
if (outPipe) outPipe->close(Pipe::CLOSE_WRITE);
|
||||
if (options & PROCESS_CLOSE_STDOUT) close(STDOUT_FILENO);
|
||||
if (errPipe) errPipe->close(Pipe::CLOSE_WRITE);
|
||||
if (options & PROCESS_CLOSE_STDERR) close(STDERR_FILENO);
|
||||
return new ProcessHandleImpl(pid);
|
||||
}
|
||||
else
|
||||
{
|
||||
return launchByForkExecImpl(command, args, initialDirectory, inPipe, outPipe, errPipe, env);
|
||||
return launchByForkExecImpl(command, args, initialDirectory, inPipe, outPipe, errPipe, env, options);
|
||||
}
|
||||
#else
|
||||
return launchByForkExecImpl(command, args, initialDirectory, inPipe, outPipe, errPipe, env);
|
||||
return launchByForkExecImpl(command, args, initialDirectory, inPipe, outPipe, errPipe, env, options);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
ProcessHandleImpl* ProcessImpl::launchByForkExecImpl(const std::string& command, const ArgsImpl& args, const std::string& initialDirectory, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, const EnvImpl& env)
|
||||
ProcessHandleImpl* ProcessImpl::launchByForkExecImpl(const std::string& command, const ArgsImpl& args, const std::string& initialDirectory, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, const EnvImpl& env, int options)
|
||||
{
|
||||
#if !defined(POCO_NO_FORK_EXEC)
|
||||
// On some systems, sysconf(_SC_OPEN_MAX) returns a ridiculously high number,
|
||||
@ -222,11 +226,15 @@ ProcessHandleImpl* ProcessImpl::launchByForkExecImpl(const std::string& command,
|
||||
dup2(inPipe->readHandle(), STDIN_FILENO);
|
||||
inPipe->close(Pipe::CLOSE_BOTH);
|
||||
}
|
||||
if (options & PROCESS_CLOSE_STDIN) close(STDIN_FILENO);
|
||||
|
||||
// outPipe and errPipe may be the same, so we dup first and close later
|
||||
if (outPipe) dup2(outPipe->writeHandle(), STDOUT_FILENO);
|
||||
if (errPipe) dup2(errPipe->writeHandle(), STDERR_FILENO);
|
||||
if (outPipe) outPipe->close(Pipe::CLOSE_BOTH);
|
||||
if (options & PROCESS_CLOSE_STDOUT) close(STDOUT_FILENO);
|
||||
if (errPipe) errPipe->close(Pipe::CLOSE_BOTH);
|
||||
if (options & PROCESS_CLOSE_STDERR) close(STDERR_FILENO);
|
||||
// close all open file descriptors other than stdin, stdout, stderr
|
||||
long fdMax = sysconf(_SC_OPEN_MAX);
|
||||
// on some systems, sysconf(_SC_OPEN_MAX) returns a ridiculously high number
|
||||
|
@ -12,6 +12,7 @@
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/ProcessOptions.h"
|
||||
#include "Poco/Process_WIN32U.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
@ -227,7 +228,7 @@ std::string ProcessImpl::escapeArg(const std::string& arg)
|
||||
}
|
||||
|
||||
|
||||
ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const ArgsImpl& args, const std::string& initialDirectory, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, const EnvImpl& env)
|
||||
ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const ArgsImpl& args, const std::string& initialDirectory, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, const EnvImpl& env, int options)
|
||||
{
|
||||
std::string commandLine = escapeArg(command);
|
||||
for (const auto& a: args)
|
||||
@ -279,6 +280,8 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg
|
||||
{
|
||||
startupInfo.hStdInput = 0;
|
||||
}
|
||||
if (options & PROCESS_CLOSE_STDIN) CloseHandle(GetStdHandle(STD_INPUT_HANDLE));
|
||||
|
||||
// outPipe may be the same as errPipe, so we duplicate first and close later.
|
||||
if (outPipe)
|
||||
{
|
||||
@ -309,7 +312,9 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg
|
||||
startupInfo.hStdError = 0;
|
||||
}
|
||||
if (outPipe) outPipe->close(Pipe::CLOSE_WRITE);
|
||||
if (options & PROCESS_CLOSE_STDOUT) CloseHandle(GetStdHandle(STD_OUTPUT_HANDLE));
|
||||
if (errPipe) errPipe->close(Pipe::CLOSE_WRITE);
|
||||
if (options & PROCESS_CLOSE_STDERR) CloseHandle(GetStdHandle(STD_ERROR_HANDLE));
|
||||
|
||||
if (mustInheritHandles)
|
||||
{
|
||||
|
@ -118,7 +118,7 @@ void ProcessImpl::timesImpl(long& userTime, long& kernelTime)
|
||||
}
|
||||
|
||||
|
||||
ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const ArgsImpl& args, const std::string& initialDirectory, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, const EnvImpl& env)
|
||||
ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const ArgsImpl& args, const std::string& initialDirectory, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, const EnvImpl& env, int options)
|
||||
{
|
||||
std::wstring ucommand;
|
||||
UnicodeConverter::toUTF16(command, ucommand);
|
||||
|
Loading…
x
Reference in New Issue
Block a user