|
9 | 9 | #include "lldb/Host/Host.h"
|
10 | 10 | #include "TestingSupport/SubsystemRAII.h"
|
11 | 11 | #include "lldb/Host/FileSystem.h"
|
| 12 | +#include "lldb/Host/Pipe.h" |
12 | 13 | #include "lldb/Host/ProcessLaunchInfo.h"
|
13 | 14 | #include "lldb/Utility/ProcessInfo.h"
|
14 | 15 | #include "llvm/Support/CommandLine.h"
|
15 | 16 | #include "llvm/Support/FileSystem.h"
|
| 17 | +#include "llvm/ADT/Twine.h" |
16 | 18 | #include "llvm/Testing/Support/Error.h"
|
17 | 19 | #include "gtest/gtest.h"
|
18 | 20 | #include <future>
|
19 | 21 |
|
20 |
| -using namespace lldb_private; |
21 |
| -using namespace llvm; |
22 |
| - |
23 | 22 | // From TestMain.cpp.
|
24 | 23 | extern const char *TestMainArgv0;
|
25 | 24 |
|
| 25 | +using namespace lldb_private; |
| 26 | +using namespace llvm; |
| 27 | + |
26 | 28 | static cl::opt<uint64_t> test_arg("test-arg");
|
27 | 29 |
|
28 | 30 | TEST(Host, WaitStatusFormat) {
|
@@ -87,3 +89,41 @@ TEST(Host, LaunchProcessSetsArgv0) {
|
87 | 89 | ASSERT_THAT_ERROR(Host::LaunchProcess(info).takeError(), Succeeded());
|
88 | 90 | ASSERT_THAT(exit_status.get_future().get(), 0);
|
89 | 91 | }
|
| 92 | + |
| 93 | +#ifdef LLVM_ON_UNIX |
| 94 | +TEST(Host, LaunchProcessDuplicatesHandle) { |
| 95 | + static constexpr llvm::StringLiteral test_msg("Hello subprocess!"); |
| 96 | + |
| 97 | + SubsystemRAII<FileSystem> subsystems; |
| 98 | + |
| 99 | + if (test_arg) { |
| 100 | + Pipe pipe(LLDB_INVALID_PIPE, (lldb::pipe_t)test_arg.getValue()); |
| 101 | + llvm::Expected<size_t> bytes_written = |
| 102 | + pipe.Write(test_msg.data(), test_msg.size()); |
| 103 | + if (bytes_written && *bytes_written == test_msg.size()) |
| 104 | + exit(0); |
| 105 | + exit(1); |
| 106 | + } |
| 107 | + Pipe pipe; |
| 108 | + ASSERT_THAT_ERROR(pipe.CreateNew(/*child_process_inherit=*/false).takeError(), |
| 109 | + llvm::Succeeded()); |
| 110 | + ProcessLaunchInfo info; |
| 111 | + info.SetExecutableFile(FileSpec(TestMainArgv0), |
| 112 | + /*add_exe_file_as_first_arg=*/true); |
| 113 | + info.GetArguments().AppendArgument( |
| 114 | + "--gtest_filter=Host.LaunchProcessDuplicatesHandle"); |
| 115 | + info.GetArguments().AppendArgument( |
| 116 | + ("--test-arg=" + llvm::Twine((uint64_t)pipe.GetWritePipe())).str()); |
| 117 | + info.AppendDuplicateFileAction((uint64_t)pipe.GetWritePipe(), |
| 118 | + (uint64_t)pipe.GetWritePipe()); |
| 119 | + info.SetMonitorProcessCallback(&ProcessLaunchInfo::NoOpMonitorCallback); |
| 120 | + ASSERT_THAT_ERROR(Host::LaunchProcess(info).takeError(), llvm::Succeeded()); |
| 121 | + pipe.CloseWriteFileDescriptor(); |
| 122 | + |
| 123 | + char msg[100]; |
| 124 | + llvm::Expected<size_t> bytes_read = |
| 125 | + pipe.Read(msg, sizeof(msg), std::chrono::seconds(10)); |
| 126 | + ASSERT_THAT_EXPECTED(bytes_read, llvm::Succeeded()); |
| 127 | + ASSERT_EQ(llvm::StringRef(msg, *bytes_read), test_msg); |
| 128 | +} |
| 129 | +#endif |
0 commit comments