Przeglądaj źródła

Merge topic 'cmuvprocesschain-input-file'

e329704546 cmUVProcessChain: Add support for SetExternalStream(Stream_INPUT)

Acked-by: Kitware Robot <[email protected]>
Acked-by: buildbot <[email protected]>
Merge-request: !8552
Brad King 2 lat temu
rodzic
commit
09028bed4c

+ 22 - 5
Source/cmUVProcessChain.cxx

@@ -64,6 +64,7 @@ struct cmUVProcessChain::InternalData
 
 
   cm::uv_loop_ptr Loop;
   cm::uv_loop_ptr Loop;
 
 
+  StreamData<std::ostream> InputStreamData;
   StreamData<std::istream> OutputStreamData;
   StreamData<std::istream> OutputStreamData;
   StreamData<std::istream> ErrorStreamData;
   StreamData<std::istream> ErrorStreamData;
   cm::uv_pipe_ptr TempOutputPipe;
   cm::uv_pipe_ptr TempOutputPipe;
@@ -134,9 +135,6 @@ cmUVProcessChainBuilder& cmUVProcessChainBuilder::SetExternalStream(
 {
 {
   switch (stdio) {
   switch (stdio) {
     case Stream_INPUT:
     case Stream_INPUT:
-      // FIXME
-      break;
-
     case Stream_OUTPUT:
     case Stream_OUTPUT:
     case Stream_ERROR: {
     case Stream_ERROR: {
       auto& streamData = this->Stdio[stdio];
       auto& streamData = this->Stdio[stdio];
@@ -184,6 +182,25 @@ bool cmUVProcessChain::InternalData::Prepare(
 {
 {
   this->Builder = builder;
   this->Builder = builder;
 
 
+  auto const& input =
+    this->Builder->Stdio[cmUVProcessChainBuilder::Stream_INPUT];
+  auto& inputData = this->InputStreamData;
+  switch (input.Type) {
+    case cmUVProcessChainBuilder::None:
+      inputData.Stdio.flags = UV_IGNORE;
+      break;
+
+    case cmUVProcessChainBuilder::Builtin: {
+      // FIXME
+      break;
+    }
+
+    case cmUVProcessChainBuilder::External:
+      inputData.Stdio.flags = UV_INHERIT_FD;
+      inputData.Stdio.data.fd = input.FileDescriptor;
+      break;
+  }
+
   auto const& error =
   auto const& error =
     this->Builder->Stdio[cmUVProcessChainBuilder::Stream_ERROR];
     this->Builder->Stdio[cmUVProcessChainBuilder::Stream_ERROR];
   auto& errorData = this->ErrorStreamData;
   auto& errorData = this->ErrorStreamData;
@@ -328,10 +345,10 @@ void cmUVProcessChain::InternalData::SpawnProcess(
   }
   }
 
 
   std::array<uv_stdio_container_t, 3> stdio;
   std::array<uv_stdio_container_t, 3> stdio;
-  stdio[0] = uv_stdio_container_t();
   if (first) {
   if (first) {
-    stdio[0].flags = UV_IGNORE;
+    stdio[0] = this->InputStreamData.Stdio;
   } else {
   } else {
+    stdio[0] = uv_stdio_container_t();
     stdio[0].flags = UV_INHERIT_STREAM;
     stdio[0].flags = UV_INHERIT_STREAM;
     stdio[0].data.stream = process.InputPipe;
     stdio[0].data.stream = process.InputPipe;
   }
   }

+ 1 - 0
Tests/CMakeLib/CMakeLists.txt

@@ -63,6 +63,7 @@ if(WIN32)
 endif()
 endif()
 
 
 configure_file(testXMLParser.h.in testXMLParser.h @ONLY)
 configure_file(testXMLParser.h.in testXMLParser.h @ONLY)
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testUVProcessChainInput.txt" "HELLO WORLD!")
 
 
 create_test_sourcelist(CMakeLib_TEST_SRCS CMakeLibTests.cxx ${CMakeLib_TESTS})
 create_test_sourcelist(CMakeLib_TEST_SRCS CMakeLibTests.cxx ${CMakeLib_TESTS})
 add_executable(CMakeLibTests ${CMakeLib_TEST_SRCS})
 add_executable(CMakeLibTests ${CMakeLib_TEST_SRCS})

+ 33 - 0
Tests/CMakeLib/testUVProcessChain.cxx

@@ -1,5 +1,6 @@
 #include <algorithm>
 #include <algorithm>
 #include <csignal>
 #include <csignal>
+#include <cstdio>
 #include <functional>
 #include <functional>
 #include <iostream>
 #include <iostream>
 #include <sstream>
 #include <sstream>
@@ -615,6 +616,33 @@ bool testUVProcessChainSpawnFail(const char* helperCommand)
   return true;
   return true;
 }
 }
 
 
+bool testUVProcessChainInputFile(const char* helperCommand)
+{
+  std::unique_ptr<FILE, int (*)(FILE*)> f(
+    fopen("testUVProcessChainInput.txt", "rb"), fclose);
+
+  cmUVProcessChainBuilder builder;
+  builder.AddCommand({ helperCommand, "dedup" })
+    .SetExternalStream(cmUVProcessChainBuilder::Stream_INPUT, fileno(f.get()))
+    .SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT);
+
+  auto chain = builder.Start();
+
+  if (!chain.Wait()) {
+    std::cout << "Wait() timed out" << std::endl;
+    return false;
+  }
+
+  std::string output = getInput(*chain.OutputStream());
+  if (output != "HELO WRD!") {
+    std::cout << "Output was \"" << output << "\", expected \"HELO WRD!\""
+              << std::endl;
+    return false;
+  }
+
+  return true;
+}
+
 int testUVProcessChain(int argc, char** const argv)
 int testUVProcessChain(int argc, char** const argv)
 {
 {
   if (argc < 2) {
   if (argc < 2) {
@@ -657,5 +685,10 @@ int testUVProcessChain(int argc, char** const argv)
     return -1;
     return -1;
   }
   }
 
 
+  if (!testUVProcessChainInputFile(argv[1])) {
+    std::cout << "While executing testUVProcessChainInputFile().\n";
+    return -1;
+  }
+
   return 0;
   return 0;
 }
 }