blob: ad2ff845567b1a5d8daa8c373a694a030f8ee0e5 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include <zencore/process.h>
#include <zencore/zencore.h>
#include <functional>
#include <memory>
#include <string_view>
namespace asio {
class io_context;
}
namespace zen {
/// Create an overlapped pipe pair suitable for async I/O on Windows.
///
/// Unlike CreateStdoutPipe() (which creates anonymous non-overlapped pipes),
/// this creates a named pipe with FILE_FLAG_OVERLAPPED on the read end, so it
/// can be used with asio::windows::stream_handle for fully async reads.
/// The write end is inheritable and suitable for child process redirection.
///
/// On non-Windows platforms this simply delegates to CreateStdoutPipe().
bool CreateOverlappedStdoutPipe(StdoutPipeHandles& OutPipe);
/// Async pipe reader for capturing child process stdout/stderr.
///
/// Takes ownership of a pipe's read end and reads asynchronously:
/// Linux/macOS: non-blocking fd + asio::posix::stream_descriptor
/// Windows: overlapped named pipe + asio::windows::stream_handle
///
/// On Windows the pipe must have been created with CreateOverlappedStdoutPipe()
/// for async I/O to work. Pipes from CreateStdoutPipe() will fail.
///
/// DataCallback is invoked for each chunk read (on the io_context).
/// EofCallback is invoked when the pipe closes (child exited or pipe broken).
class AsyncPipeReader
{
public:
explicit AsyncPipeReader(asio::io_context& IoContext);
~AsyncPipeReader();
AsyncPipeReader(const AsyncPipeReader&) = delete;
AsyncPipeReader& operator=(const AsyncPipeReader&) = delete;
/// Take ownership of the pipe read-end and start async reading.
/// The write end is closed immediately (caller should have already launched
/// the child process). DataCallback receives raw chunks. EofCallback fires
/// once when the pipe reaches EOF.
void Start(StdoutPipeHandles&& Pipe, std::function<void(std::string_view Data)> DataCallback, std::function<void()> EofCallback);
/// Stop reading and close the pipe. Callbacks will not fire after this returns.
void Stop();
private:
struct Impl;
std::unique_ptr<Impl> m_Impl;
};
} // namespace zen
|