Browse Source

Merge topic 'execute_process-output_file-directory' into release-3.28

35f031e3b2 execute_process(): Restore opening files relative to WORKING_DIRECTORY

Acked-by: Kitware Robot <[email protected]>
Merge-request: !8883
Brad King 2 years ago
parent
commit
ec916350db

+ 44 - 18
Source/cmExecuteProcessCommand.cxx

@@ -112,9 +112,27 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
     return false;
   }
 
-  if (!status.GetMakefile().CanIWriteThisFile(arguments.OutputFile)) {
-    status.SetError("attempted to output into a file: " +
-                    arguments.OutputFile + " into a source directory.");
+  std::string inputFilename = arguments.InputFile;
+  std::string outputFilename = arguments.OutputFile;
+  std::string errorFilename = arguments.ErrorFile;
+  if (!arguments.WorkingDirectory.empty()) {
+    if (!inputFilename.empty()) {
+      inputFilename = cmSystemTools::CollapseFullPath(
+        inputFilename, arguments.WorkingDirectory);
+    }
+    if (!outputFilename.empty()) {
+      outputFilename = cmSystemTools::CollapseFullPath(
+        outputFilename, arguments.WorkingDirectory);
+    }
+    if (!errorFilename.empty()) {
+      errorFilename = cmSystemTools::CollapseFullPath(
+        errorFilename, arguments.WorkingDirectory);
+    }
+  }
+
+  if (!status.GetMakefile().CanIWriteThisFile(outputFilename)) {
+    status.SetError("attempted to output into a file: " + outputFilename +
+                    " into a source directory.");
     cmSystemTools::SetFatalErrorOccurred();
     return false;
   }
@@ -162,20 +180,24 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
 
   // Check the output variables.
   std::unique_ptr<FILE, int (*)(FILE*)> inputFile(nullptr, fclose);
-  if (!arguments.InputFile.empty()) {
-    inputFile.reset(cmsys::SystemTools::Fopen(arguments.InputFile, "rb"));
-    builder.SetExternalStream(cmUVProcessChainBuilder::Stream_INPUT,
-                              cm_fileno(inputFile.get()));
+  if (!inputFilename.empty()) {
+    inputFile.reset(cmsys::SystemTools::Fopen(inputFilename, "rb"));
+    if (inputFile) {
+      builder.SetExternalStream(cmUVProcessChainBuilder::Stream_INPUT,
+                                cm_fileno(inputFile.get()));
+    }
   } else {
     builder.SetExternalStream(cmUVProcessChainBuilder::Stream_INPUT,
                               cm_fileno(stdin));
   }
 
   std::unique_ptr<FILE, int (*)(FILE*)> outputFile(nullptr, fclose);
-  if (!arguments.OutputFile.empty()) {
-    outputFile.reset(cmsys::SystemTools::Fopen(arguments.OutputFile, "wb"));
-    builder.SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT,
-                              cm_fileno(outputFile.get()));
+  if (!outputFilename.empty()) {
+    outputFile.reset(cmsys::SystemTools::Fopen(outputFilename, "wb"));
+    if (outputFile) {
+      builder.SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT,
+                                cm_fileno(outputFile.get()));
+    }
   } else {
     if (arguments.OutputVariable == arguments.ErrorVariable &&
         !arguments.ErrorVariable.empty()) {
@@ -186,14 +208,18 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
   }
 
   std::unique_ptr<FILE, int (*)(FILE*)> errorFile(nullptr, fclose);
-  if (!arguments.ErrorFile.empty()) {
-    if (arguments.ErrorFile == arguments.OutputFile) {
-      builder.SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR,
-                                cm_fileno(outputFile.get()));
+  if (!errorFilename.empty()) {
+    if (errorFilename == outputFilename) {
+      if (outputFile) {
+        builder.SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR,
+                                  cm_fileno(outputFile.get()));
+      }
     } else {
-      errorFile.reset(cmsys::SystemTools::Fopen(arguments.ErrorFile, "wb"));
-      builder.SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR,
-                                cm_fileno(errorFile.get()));
+      errorFile.reset(cmsys::SystemTools::Fopen(errorFilename, "wb"));
+      if (errorFile) {
+        builder.SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR,
+                                  cm_fileno(errorFile.get()));
+      }
     }
   } else if (arguments.ErrorVariable.empty() ||
              (!arguments.ErrorVariable.empty() &&

+ 13 - 0
Tests/RunCMake/execute_process/InOutErrDirectory.cmake

@@ -0,0 +1,13 @@
+file(MAKE_DIRECTORY dir)
+file(WRITE dir/in.txt "This is a test")
+execute_process(COMMAND ${PRINT_STDIN_EXE} WORKING_DIRECTORY dir INPUT_FILE in.txt OUTPUT_FILE out.txt ERROR_FILE err.txt)
+if(NOT EXISTS dir/out.txt)
+  message(SEND_ERROR "Did not create dir/out.txt")
+endif()
+file(READ dir/out.txt out)
+if(NOT out STREQUAL "This is a test")
+  message(SEND_ERROR "Did not read dir/in.txt")
+endif()
+if(NOT EXISTS dir/err.txt)
+  message(SEND_ERROR "Did not create dir/err.txt")
+endif()

+ 5 - 0
Tests/RunCMake/execute_process/RunCMakeTest.cmake

@@ -35,6 +35,11 @@ run_cmake_command(LastCommandError ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/La
 run_cmake_command(LastCommandTimeout ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/LastCommandTimeout.cmake)
 run_cmake_command(LastCommandGood ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/LastCommandGood.cmake)
 run_cmake_command(Stdin ${CMAKE_COMMAND} -DPRINT_STDIN_EXE=${PRINT_STDIN_EXE} -P ${RunCMake_SOURCE_DIR}/Stdin.cmake)
+run_cmake_command(StdinNoexist ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/StdinNoexist.cmake)
+run_cmake_command(StdoutNoexist ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/StdoutNoexist.cmake)
+run_cmake_command(StderrNoexist ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/StderrNoexist.cmake)
+run_cmake_command(StdoutStderrNoexist ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/StderrNoexist.cmake)
+run_cmake_command(InOutErrDirectory ${CMAKE_COMMAND} -DPRINT_STDIN_EXE=${PRINT_STDIN_EXE} -P ${RunCMake_SOURCE_DIR}/InOutErrDirectory.cmake)
 
 if(UNIX AND Python_EXECUTABLE)
   run_cmake_command(AnyCommandAbnormalExit ${CMAKE_COMMAND} -DPython_EXECUTABLE=${Python_EXECUTABLE} -P ${RunCMake_SOURCE_DIR}/AnyCommandAbnormalExit.cmake)

+ 1 - 0
Tests/RunCMake/execute_process/StderrNoexist.cmake

@@ -0,0 +1 @@
+execute_process(COMMAND ${CMAKE_COMMAND} -E true ERROR_FILE noexist/error.txt)

+ 1 - 0
Tests/RunCMake/execute_process/StdinNoexist.cmake

@@ -0,0 +1 @@
+execute_process(COMMAND ${CMAKE_COMMAND} -E true INPUT_FILE noexist/input.txt)

+ 1 - 0
Tests/RunCMake/execute_process/StdouStderrNoexist.cmake

@@ -0,0 +1 @@
+execute_process(COMMAND ${CMAKE_COMMAND} -E true OUTPUT_FILE noexist/merged.txt ERROR_FILE noexist/merged.txt)

+ 1 - 0
Tests/RunCMake/execute_process/StdoutNoexist.cmake

@@ -0,0 +1 @@
+execute_process(COMMAND ${CMAKE_COMMAND} -E true OUTPUT_FILE noexist/output.txt)