@@ -7,10 +7,10 @@ use io_lifetimes::OwnedFd;
7
7
use std:: fs:: File ;
8
8
use std:: io;
9
9
use std:: os:: unix:: io:: { AsRawFd , FromRawFd , IntoRawFd , RawFd } ;
10
+ use std:: pin:: Pin ;
10
11
use std:: process;
11
-
12
- use std:: convert:: TryFrom ;
13
- use std:: convert:: TryInto ;
12
+ use std:: task:: { Context , Poll } ;
13
+ use tokio:: io:: { AsyncRead , AsyncWrite , ReadBuf } ;
14
14
15
15
pub ( crate ) unsafe fn dup ( raw_fd : RawFd ) -> Result < OwnedFd , Error > {
16
16
let res = libc:: dup ( raw_fd) ;
@@ -101,40 +101,44 @@ impl_from_for_stdio!(process::ChildStdin);
101
101
impl_from_for_stdio ! ( process:: ChildStdout ) ;
102
102
impl_from_for_stdio ! ( process:: ChildStderr ) ;
103
103
104
+ impl_from_for_stdio ! ( ChildStdin ) ;
105
+ impl_from_for_stdio ! ( ChildStdout ) ;
106
+ impl_from_for_stdio ! ( ChildStderr ) ;
107
+
104
108
impl_from_for_stdio ! ( File ) ;
105
109
106
110
macro_rules! impl_try_from_tokio_process_child_for_stdio {
107
- ( $type: ident, $wrapper : ty ) => {
111
+ ( $type: ident) => {
108
112
impl TryFrom <tokio:: process:: $type> for Stdio {
109
113
type Error = Error ;
110
114
111
115
fn try_from( arg: tokio:: process:: $type) -> Result <Self , Self :: Error > {
112
- let wrapper: $wrapper = arg. try_into( ) ?;
116
+ let wrapper: $type = arg. try_into( ) ?;
113
117
Ok ( wrapper. 0 . into( ) )
114
118
}
115
119
}
116
120
} ;
117
121
}
118
122
119
- impl_try_from_tokio_process_child_for_stdio ! ( ChildStdin , ChildInputWrapper ) ;
120
- impl_try_from_tokio_process_child_for_stdio ! ( ChildStdout , ChildOutputWrapper ) ;
121
- impl_try_from_tokio_process_child_for_stdio ! ( ChildStderr , ChildOutputWrapper ) ;
123
+ impl_try_from_tokio_process_child_for_stdio ! ( ChildStdin ) ;
124
+ impl_try_from_tokio_process_child_for_stdio ! ( ChildStdout ) ;
125
+ impl_try_from_tokio_process_child_for_stdio ! ( ChildStderr ) ;
122
126
123
127
/// Input for the remote child.
124
- pub type ChildStdin = tokio_pipe:: PipeWrite ;
128
+ #[ derive( Debug ) ]
129
+ pub struct ChildStdin ( tokio_pipe:: PipeWrite ) ;
125
130
126
131
/// Stdout for the remote child.
127
- pub type ChildStdout = tokio_pipe:: PipeRead ;
132
+ #[ derive( Debug ) ]
133
+ pub struct ChildStdout ( tokio_pipe:: PipeRead ) ;
128
134
129
135
/// Stderr for the remote child.
130
- pub type ChildStderr = tokio_pipe:: PipeRead ;
131
-
132
- pub ( crate ) struct ChildInputWrapper ( pub ( crate ) ChildStdin ) ;
133
- pub ( crate ) struct ChildOutputWrapper ( pub ( crate ) ChildStderr ) ;
136
+ #[ derive( Debug ) ]
137
+ pub struct ChildStderr ( tokio_pipe:: PipeRead ) ;
134
138
135
139
macro_rules! impl_from_impl_child_io {
136
- ( process, $type: ident, $wrapper : ty) => {
137
- impl TryFrom <tokio:: process:: $type> for $wrapper {
140
+ ( process, $type: ident, $inner : ty) => {
141
+ impl TryFrom <tokio:: process:: $type> for $type {
138
142
type Error = Error ;
139
143
140
144
fn try_from( arg: tokio:: process:: $type) -> Result <Self , Self :: Error > {
@@ -143,15 +147,15 @@ macro_rules! impl_from_impl_child_io {
143
147
// safety: arg.as_raw_fd() is guaranteed to return a valid fd.
144
148
let fd = unsafe { dup( fd) } ?. into_raw_fd( ) ;
145
149
Ok ( Self (
146
- $type :: from_raw_fd_checked( fd) . map_err( Error :: ChildIo ) ?,
150
+ <$inner> :: from_raw_fd_checked( fd) . map_err( Error :: ChildIo ) ?,
147
151
) )
148
152
}
149
153
}
150
154
} ;
151
155
152
- ( native_mux, $type: ident, $wrapper : ty ) => {
156
+ ( native_mux, $type: ident) => {
153
157
#[ cfg( feature = "native-mux" ) ]
154
- impl TryFrom <native_mux_impl:: $type> for $wrapper {
158
+ impl TryFrom <native_mux_impl:: $type> for $type {
155
159
type Error = Error ;
156
160
157
161
fn try_from( arg: native_mux_impl:: $type) -> Result <Self , Self :: Error > {
@@ -161,9 +165,85 @@ macro_rules! impl_from_impl_child_io {
161
165
} ;
162
166
}
163
167
164
- impl_from_impl_child_io ! ( process, ChildStdin , ChildInputWrapper ) ;
165
- impl_from_impl_child_io ! ( process, ChildStdout , ChildOutputWrapper ) ;
166
- impl_from_impl_child_io ! ( process, ChildStderr , ChildOutputWrapper ) ;
168
+ impl_from_impl_child_io ! ( process, ChildStdin , tokio_pipe:: PipeWrite ) ;
169
+ impl_from_impl_child_io ! ( process, ChildStdout , tokio_pipe:: PipeRead ) ;
170
+ impl_from_impl_child_io ! ( process, ChildStderr , tokio_pipe:: PipeRead ) ;
171
+
172
+ impl_from_impl_child_io ! ( native_mux, ChildStdin ) ;
173
+ impl_from_impl_child_io ! ( native_mux, ChildStdout ) ;
174
+ impl_from_impl_child_io ! ( native_mux, ChildStderr ) ;
175
+
176
+ macro_rules! impl_child_stdio {
177
+ ( AsRawFd , $type: ty) => {
178
+ impl AsRawFd for $type {
179
+ fn as_raw_fd( & self ) -> RawFd {
180
+ self . 0 . as_raw_fd( )
181
+ }
182
+ }
183
+ } ;
184
+
185
+ ( IntoRawFd , $type: ty) => {
186
+ impl IntoRawFd for $type {
187
+ fn into_raw_fd( self ) -> RawFd {
188
+ self . 0 . into_raw_fd( )
189
+ }
190
+ }
191
+ } ;
192
+
193
+ ( AsyncRead , $type: ty) => {
194
+ impl_child_stdio!( AsRawFd , $type) ;
195
+ impl_child_stdio!( IntoRawFd , $type) ;
196
+
197
+ impl AsyncRead for $type {
198
+ fn poll_read(
199
+ mut self : Pin <& mut Self >,
200
+ cx: & mut Context <' _>,
201
+ buf: & mut ReadBuf <' _>,
202
+ ) -> Poll <io:: Result <( ) >> {
203
+ Pin :: new( & mut self . 0 ) . poll_read( cx, buf)
204
+ }
205
+ }
206
+ } ;
207
+
208
+ ( AsyncWrite , $type: ty) => {
209
+ impl_child_stdio!( AsRawFd , $type) ;
210
+ impl_child_stdio!( IntoRawFd , $type) ;
211
+
212
+ impl AsyncWrite for $type {
213
+ fn poll_write(
214
+ mut self : Pin <& mut Self >,
215
+ cx: & mut Context <' _>,
216
+ buf: & [ u8 ] ,
217
+ ) -> Poll <io:: Result <usize >> {
218
+ Pin :: new( & mut self . 0 ) . poll_write( cx, buf)
219
+ }
220
+
221
+ fn poll_flush( mut self : Pin <& mut Self >, cx: & mut Context <' _>) -> Poll <io:: Result <( ) >> {
222
+ Pin :: new( & mut self . 0 ) . poll_flush( cx)
223
+ }
224
+
225
+ fn poll_shutdown(
226
+ mut self : Pin <& mut Self >,
227
+ cx: & mut Context <' _>,
228
+ ) -> Poll <io:: Result <( ) >> {
229
+ Pin :: new( & mut self . 0 ) . poll_shutdown( cx)
230
+ }
231
+
232
+ fn poll_write_vectored(
233
+ mut self : Pin <& mut Self >,
234
+ cx: & mut Context <' _>,
235
+ bufs: & [ io:: IoSlice <' _>] ,
236
+ ) -> Poll <io:: Result <usize >> {
237
+ Pin :: new( & mut self . 0 ) . poll_write_vectored( cx, bufs)
238
+ }
239
+
240
+ fn is_write_vectored( & self ) -> bool {
241
+ self . 0 . is_write_vectored( )
242
+ }
243
+ }
244
+ } ;
245
+ }
167
246
168
- impl_from_impl_child_io ! ( native_mux, ChildStdin , ChildInputWrapper ) ;
169
- impl_from_impl_child_io ! ( native_mux, ChildStdout , ChildOutputWrapper ) ;
247
+ impl_child_stdio ! ( AsyncWrite , ChildStdin ) ;
248
+ impl_child_stdio ! ( AsyncRead , ChildStdout ) ;
249
+ impl_child_stdio ! ( AsyncRead , ChildStderr ) ;
0 commit comments