src/cxx_supportlib/ProcessManagement/Spawn.cpp in passenger-5.3.4 vs src/cxx_supportlib/ProcessManagement/Spawn.cpp in passenger-5.3.5
- old
+ new
@@ -1,8 +1,8 @@
/*
* Phusion Passenger - https://www.phusionpassenger.com/
- * Copyright (c) 2010-2017 Phusion Holding B.V.
+ * Copyright (c) 2010-2018 Phusion Holding B.V.
*
* "Passenger", "Phusion Passenger" and "Union Station" are registered
* trademarks of Phusion Holding B.V.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -31,10 +31,11 @@
#include <signal.h>
#include <boost/thread.hpp>
#include <oxt/system_calls.hpp>
#include <string>
+#include <algorithm>
#include <cerrno>
#include <ProcessManagement/Spawn.h>
#include <ProcessManagement/Utils.h>
#include <StaticString.h>
@@ -108,11 +109,11 @@
}
}
void
runCommandAndCaptureOutput(const char **command, SubprocessInfo &info,
- string &output, bool killSubprocessOnInterruption,
+ SubprocessOutput &output, size_t maxSize, bool killSubprocessOnInterruption,
const boost::function<void ()> &afterFork,
const boost::function<void (const char **command, int errcode)> &onExecFail)
{
pid_t waitRet;
int e, waitStatus;
@@ -138,19 +139,21 @@
_exit(1);
} else if (info.pid == -1) {
e = errno;
throw SystemException("Cannot fork() a new process", e);
} else {
- bool done = false;
+ size_t totalRead = 0;
+ output.eof = false;
p[1].close();
- while (!done) {
+ while (totalRead < maxSize) {
char buf[1024 * 4];
ssize_t ret;
try {
- ret = syscalls::read(p[0], buf, sizeof(buf));
+ ret = syscalls::read(p[0], buf,
+ std::min<size_t>(sizeof(buf), maxSize - totalRead));
} catch (const boost::thread_interrupted &) {
if (killSubprocessOnInterruption) {
boost::this_thread::disable_syscall_interruption dsi;
syscalls::kill(SIGKILL, info.pid);
syscalls::waitpid(info.pid, NULL, 0);
@@ -164,12 +167,16 @@
syscalls::kill(SIGKILL, info.pid);
syscalls::waitpid(info.pid, NULL, 0);
}
throw SystemException(string("Cannot read output from the '") +
command[0] + "' command", e);
+ } else if (ret == 0) {
+ output.eof = true;
+ break;
+ } else {
+ totalRead += ret;
+ output.data.append(buf, ret);
}
- done = ret == 0;
- output.append(buf, ret);
}
p[0].close();
try {
waitRet = syscalls::waitpid(info.pid, &waitStatus, 0);