16
16
17
17
#include < cstring>
18
18
#include < functional>
19
+ #include < memory>
19
20
#include < mutex>
20
21
#include < utility>
21
22
#include < vector>
22
23
23
24
#include " ray/util/compat.h"
24
25
#include " ray/util/pipe_logger.h"
26
+ #include " ray/util/scoped_dup2_wrapper.h"
25
27
#include " ray/util/util.h"
26
28
27
29
#if defined(_WIN32)
@@ -36,72 +38,39 @@ namespace {
36
38
struct RedirectionHandleWrapper {
37
39
RedirectionFileHandle redirection_file_handle;
38
40
// Used for restoration.
39
- MEMFD_TYPE_NON_UNIQUE saved_stream_handle ;
41
+ std::unique_ptr<ScopedDup2Wrapper> scoped_dup2_wrapper ;
40
42
};
41
43
42
44
// TODO(hjiang): Revisit later, should be able to save some heap allocation with
43
45
// absl::InlinedVector.
44
46
//
45
47
// Maps from original stream file handle (i.e. stdout/stderr) to its stream redirector.
46
- absl::flat_hash_map<int , RedirectionHandleWrapper> redirection_file_handles;
48
+ absl::flat_hash_map<MEMFD_TYPE_NON_UNIQUE, RedirectionHandleWrapper>
49
+ redirection_file_handles;
47
50
48
51
// Block synchronize on stream redirection related completion, should be call **EXACTLY
49
52
// ONCE** at program termination.
50
53
std::once_flag stream_exit_once_flag;
51
54
void SyncOnStreamRedirection () {
52
- for (auto &[stream_fd, handle] : redirection_file_handles) {
53
- // Restore old stream fd.
54
- #if defined(__APPLE__) || defined(__linux__)
55
- RAY_CHECK_NE (dup2 (handle.saved_stream_handle , stream_fd), -1 )
56
- << " Fails to restore file descriptor " << strerror (errno);
57
- #elif defined(_WIN32)
58
- int duped_fd = _open_osfhandle (reinterpret_cast <intptr_t >(handle.saved_stream_handle ),
59
- _O_WRONLY);
60
- RAY_CHECK_NE (_dup2 (duped_fd, stream_fd), -1 ) << " Fails to duplicate file descriptor." ;
61
- #endif
62
-
55
+ for (auto &[_, handle] : redirection_file_handles) {
56
+ handle.scoped_dup2_wrapper = nullptr ;
63
57
handle.redirection_file_handle .Close ();
64
58
}
65
59
}
66
60
67
61
// Redirect the given [stream_fd] based on the specified option.
68
- void RedirectStream (int stream_fd, const StreamRedirectionOption &opt) {
62
+ void RedirectStream (MEMFD_TYPE_NON_UNIQUE stream_fd, const StreamRedirectionOption &opt) {
69
63
std::call_once (stream_exit_once_flag, []() {
70
64
RAY_CHECK_EQ (std::atexit (SyncOnStreamRedirection), 0 )
71
65
<< " Fails to register stream redirection termination hook." ;
72
66
});
73
67
74
68
RedirectionFileHandle handle = CreateRedirectionFileHandle (opt);
75
-
76
- #if defined(__APPLE__) || defined(__linux__)
77
- // Duplicate stream fd for later restoration.
78
- MEMFD_TYPE_NON_UNIQUE duped_stream_fd = dup (stream_fd);
79
- RAY_CHECK_NE (duped_stream_fd, -1 )
80
- << " Fails to duplicate stream fd " << stream_fd << " because " << strerror (errno);
81
-
82
- RAY_CHECK_NE (dup2 (handle.GetWriteHandle (), stream_fd), -1 )
83
- << " Fails to duplicate file descriptor " << strerror (errno);
84
- #elif defined(_WIN32)
85
- // Duplicate stream fd for later restoration.
86
- MEMFD_TYPE_NON_UNIQUE duped_stream_fd;
87
- BOOL result = DuplicateHandle (GetCurrentProcess (),
88
- (HANDLE)_get_osfhandle (stream_fd),
89
- GetCurrentProcess (),
90
- &duped_stream_fd,
91
- 0 ,
92
- FALSE ,
93
- DUPLICATE_SAME_ACCESS);
94
- RAY_CHECK (result);
95
-
96
- int pipe_write_fd =
97
- _open_osfhandle (reinterpret_cast <intptr_t >(handle.GetWriteHandle ()), _O_WRONLY);
98
- RAY_CHECK_NE (_dup2 (pipe_write_fd, stream_fd), -1 )
99
- << " Fails to duplicate file descriptor." ;
100
- #endif
69
+ auto scoped_dup2_wrapper = ScopedDup2Wrapper::New (handle.GetWriteHandle (), stream_fd);
101
70
102
71
RedirectionHandleWrapper handle_wrapper;
103
72
handle_wrapper.redirection_file_handle = std::move (handle);
104
- handle_wrapper.saved_stream_handle = duped_stream_fd ;
73
+ handle_wrapper.scoped_dup2_wrapper = std::move (scoped_dup2_wrapper) ;
105
74
106
75
const bool is_new =
107
76
redirection_file_handles.emplace (stream_fd, std::move (handle_wrapper)).second ;
@@ -118,10 +87,10 @@ void FlushOnRedirectedStream(int stream_fd) {
118
87
} // namespace
119
88
120
89
void RedirectStdout (const StreamRedirectionOption &opt) {
121
- RedirectStream (GetStdoutFd (), opt);
90
+ RedirectStream (GetStdoutHandle (), opt);
122
91
}
123
92
void RedirectStderr (const StreamRedirectionOption &opt) {
124
- RedirectStream (GetStderrFd (), opt);
93
+ RedirectStream (GetStderrHandle (), opt);
125
94
}
126
95
void FlushOnRedirectedStdout () { FlushOnRedirectedStream (GetStdoutFd ()); }
127
96
void FlushOnRedirectedStderr () { FlushOnRedirectedStream (GetStderrFd ()); }
0 commit comments