mirror of
https://github.com/pocoproject/poco.git
synced 2025-05-29 07:25:53 +02:00
fixed #549: Memory allocation is not safe between fork() and execve()
This commit is contained in:
parent
7b11e14624
commit
b620c25278
@ -149,6 +149,20 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg
|
|||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
// We must not allocated memory after fork(),
|
||||||
|
// therefore allocate all required buffers first.
|
||||||
|
std::vector<char> envChars = getEnvironmentVariablesBuffer(env);
|
||||||
|
std::vector<char*> argv(args.size() + 2);
|
||||||
|
int i = 0;
|
||||||
|
argv[i++] = const_cast<char*>(command.c_str());
|
||||||
|
for (ArgsImpl::const_iterator it = args.begin(); it != args.end(); ++it)
|
||||||
|
{
|
||||||
|
argv[i++] = const_cast<char*>(it->c_str());
|
||||||
|
}
|
||||||
|
argv[i] = NULL;
|
||||||
|
|
||||||
|
const char* pInitialDirectory = initialDirectory.empty() ? 0 : initialDirectory.c_str();
|
||||||
|
|
||||||
int pid = fork();
|
int pid = fork();
|
||||||
if (pid < 0)
|
if (pid < 0)
|
||||||
{
|
{
|
||||||
@ -156,15 +170,22 @@ ProcessHandleImpl* ProcessImpl::launchByForkExecImpl(const std::string& command,
|
|||||||
}
|
}
|
||||||
else if (pid == 0)
|
else if (pid == 0)
|
||||||
{
|
{
|
||||||
if (!initialDirectory.empty())
|
if (pInitialDirectory)
|
||||||
{
|
{
|
||||||
if (chdir(initialDirectory.c_str()) != 0)
|
if (chdir(pInitialDirectory) != 0)
|
||||||
{
|
{
|
||||||
_exit(72);
|
_exit(72);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setEnvironmentVariables(env);
|
// set environment variables
|
||||||
|
char* p = &envChars[0];
|
||||||
|
while (*p)
|
||||||
|
{
|
||||||
|
putenv(p);
|
||||||
|
while (*p) ++p;
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
// setup redirection
|
// setup redirection
|
||||||
if (inPipe)
|
if (inPipe)
|
||||||
@ -179,15 +200,11 @@ ProcessHandleImpl* ProcessImpl::launchByForkExecImpl(const std::string& command,
|
|||||||
if (errPipe) errPipe->close(Pipe::CLOSE_BOTH);
|
if (errPipe) errPipe->close(Pipe::CLOSE_BOTH);
|
||||||
// close all open file descriptors other than stdin, stdout, stderr
|
// close all open file descriptors other than stdin, stdout, stderr
|
||||||
for (int i = 3; i < getdtablesize(); ++i)
|
for (int i = 3; i < getdtablesize(); ++i)
|
||||||
|
{
|
||||||
close(i);
|
close(i);
|
||||||
|
}
|
||||||
|
|
||||||
char** argv = new char*[args.size() + 2];
|
execvp(argv[0], &argv[0]);
|
||||||
int i = 0;
|
|
||||||
argv[i++] = const_cast<char*>(command.c_str());
|
|
||||||
for (ArgsImpl::const_iterator it = args.begin(); it != args.end(); ++it)
|
|
||||||
argv[i++] = const_cast<char*>(it->c_str());
|
|
||||||
argv[i] = NULL;
|
|
||||||
execvp(command.c_str(), argv);
|
|
||||||
_exit(72);
|
_exit(72);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user