|
|
@@ -17,6 +17,12 @@
|
|
|
|
|
|
#include <cm3p/uv.h>
|
|
|
|
|
|
+#ifndef _WIN32
|
|
|
+# include <fcntl.h>
|
|
|
+
|
|
|
+# include "cm_fileno.hxx"
|
|
|
+#endif
|
|
|
+
|
|
|
#include "cmArgumentParser.h"
|
|
|
#include "cmExecutionStatus.h"
|
|
|
#include "cmList.h"
|
|
|
@@ -35,6 +41,20 @@ bool cmExecuteProcessCommandIsWhitespace(char c)
|
|
|
return (cmIsSpace(c) || c == '\n' || c == '\r');
|
|
|
}
|
|
|
|
|
|
+FILE* FopenCLOEXEC(std::string const& path, const char* mode)
|
|
|
+{
|
|
|
+ FILE* f = cmsys::SystemTools::Fopen(path, mode);
|
|
|
+#ifndef _WIN32
|
|
|
+ if (f) {
|
|
|
+ if (fcntl(cm_fileno(f), F_SETFD, FD_CLOEXEC) < 0) {
|
|
|
+ fclose(f);
|
|
|
+ f = nullptr;
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ return f;
|
|
|
+}
|
|
|
+
|
|
|
void cmExecuteProcessCommandFixText(std::vector<char>& output,
|
|
|
bool strip_trailing_whitespace);
|
|
|
void cmExecuteProcessCommandAppend(std::vector<char>& output, const char* data,
|
|
|
@@ -178,7 +198,7 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
|
|
|
// Check the output variables.
|
|
|
std::unique_ptr<FILE, int (*)(FILE*)> inputFile(nullptr, fclose);
|
|
|
if (!inputFilename.empty()) {
|
|
|
- inputFile.reset(cmsys::SystemTools::Fopen(inputFilename, "rb"));
|
|
|
+ inputFile.reset(FopenCLOEXEC(inputFilename, "rb"));
|
|
|
if (inputFile) {
|
|
|
builder.SetExternalStream(cmUVProcessChainBuilder::Stream_INPUT,
|
|
|
inputFile.get());
|
|
|
@@ -189,7 +209,7 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
|
|
|
|
|
|
std::unique_ptr<FILE, int (*)(FILE*)> outputFile(nullptr, fclose);
|
|
|
if (!outputFilename.empty()) {
|
|
|
- outputFile.reset(cmsys::SystemTools::Fopen(outputFilename, "wb"));
|
|
|
+ outputFile.reset(FopenCLOEXEC(outputFilename, "wb"));
|
|
|
if (outputFile) {
|
|
|
builder.SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT,
|
|
|
outputFile.get());
|
|
|
@@ -211,7 +231,7 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
|
|
|
outputFile.get());
|
|
|
}
|
|
|
} else {
|
|
|
- errorFile.reset(cmsys::SystemTools::Fopen(errorFilename, "wb"));
|
|
|
+ errorFile.reset(FopenCLOEXEC(errorFilename, "wb"));
|
|
|
if (errorFile) {
|
|
|
builder.SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR,
|
|
|
errorFile.get());
|