13
13
See the License for the specific language governing permissions and
14
14
limitations under the License.
15
15
*/
16
- #[ cfg( not( feature = "async" ) ) ]
17
- use std:: io:: { Read , Write } ;
16
+
18
17
use std:: {
19
18
fmt:: Debug ,
20
19
fs:: { File , OpenOptions } ,
21
20
io:: Result ,
22
- os:: unix:: {
23
- fs:: OpenOptionsExt ,
24
- io:: { AsRawFd , OwnedFd } ,
25
- } ,
21
+ os:: unix:: { fs:: OpenOptionsExt , io:: AsRawFd } ,
26
22
process:: Stdio ,
27
23
sync:: Mutex ,
28
24
} ;
29
25
30
- use log:: debug;
31
26
use nix:: unistd:: { Gid , Uid } ;
32
- #[ cfg( feature = "async" ) ]
33
- use tokio:: io:: { AsyncRead , AsyncWrite } ;
34
- use tokio:: net:: unix:: pipe;
35
-
36
- use crate :: Command ;
37
-
38
- pub trait Io : Debug + Send + Sync {
39
- /// Return write side of stdin
40
- #[ cfg( not( feature = "async" ) ) ]
41
- fn stdin ( & self ) -> Option < Box < dyn Write + Send + Sync > > {
42
- None
43
- }
44
-
45
- /// Return read side of stdout
46
- #[ cfg( not( feature = "async" ) ) ]
47
- fn stdout ( & self ) -> Option < Box < dyn Read + Send > > {
48
- None
49
- }
50
-
51
- /// Return read side of stderr
52
- #[ cfg( not( feature = "async" ) ) ]
53
- fn stderr ( & self ) -> Option < Box < dyn Read + Send > > {
54
- None
55
- }
56
-
57
- /// Return write side of stdin
58
- #[ cfg( feature = "async" ) ]
59
- fn stdin ( & self ) -> Option < Box < dyn AsyncWrite + Send + Sync + Unpin > > {
60
- None
61
- }
62
-
63
- /// Return read side of stdout
64
- #[ cfg( feature = "async" ) ]
65
- fn stdout ( & self ) -> Option < Box < dyn AsyncRead + Send + Sync + Unpin > > {
66
- None
67
- }
68
-
69
- /// Return read side of stderr
70
- #[ cfg( feature = "async" ) ]
71
- fn stderr ( & self ) -> Option < Box < dyn AsyncRead + Send + Sync + Unpin > > {
72
- None
73
- }
74
27
75
- /// Set IO for passed command.
76
- /// Read side of stdin, write side of stdout and write side of stderr should be provided to command.
77
- fn set ( & self , cmd : & mut Command ) -> Result < ( ) > ;
78
-
79
- /// Only close write side (should be stdout/err "from" runc process)
80
- fn close_after_start ( & self ) ;
81
- }
28
+ use crate :: { Command , Io , Pipe , PipedIo } ;
82
29
83
30
#[ derive( Debug , Clone ) ]
84
31
pub struct IOOption {
@@ -97,32 +44,6 @@ impl Default for IOOption {
97
44
}
98
45
}
99
46
100
- /// Struct to represent a pipe that can be used to transfer stdio inputs and outputs.
101
- ///
102
- /// With this Io driver, methods of [crate::Runc] may capture the output/error messages.
103
- /// When one side of the pipe is closed, the state will be represented with [`None`].
104
- #[ derive( Debug ) ]
105
- pub struct Pipe {
106
- rd : OwnedFd ,
107
- wr : OwnedFd ,
108
- }
109
-
110
- #[ derive( Debug ) ]
111
- pub struct PipedIo {
112
- stdin : Option < Pipe > ,
113
- stdout : Option < Pipe > ,
114
- stderr : Option < Pipe > ,
115
- }
116
-
117
- impl Pipe {
118
- fn new ( ) -> std:: io:: Result < Self > {
119
- let ( tx, rx) = pipe:: pipe ( ) ?;
120
- let rd = tx. into_blocking_fd ( ) ?;
121
- let wr = rx. into_blocking_fd ( ) ?;
122
- Ok ( Self { rd, wr } )
123
- }
124
- }
125
-
126
47
impl PipedIo {
127
48
pub fn new ( uid : u32 , gid : u32 , opts : & IOOption ) -> std:: io:: Result < Self > {
128
49
Ok ( Self {
@@ -156,99 +77,6 @@ impl PipedIo {
156
77
}
157
78
}
158
79
159
- impl Io for PipedIo {
160
- #[ cfg( not( feature = "async" ) ) ]
161
- fn stdin ( & self ) -> Option < Box < dyn Write + Send + Sync > > {
162
- self . stdin . as_ref ( ) . and_then ( |pipe| {
163
- pipe. wr
164
- . try_clone ( )
165
- . map ( |x| Box :: new ( x) as Box < dyn Write + Send + Sync > )
166
- . ok ( )
167
- } )
168
- }
169
-
170
- #[ cfg( feature = "async" ) ]
171
- fn stdin ( & self ) -> Option < Box < dyn AsyncWrite + Send + Sync + Unpin > > {
172
- self . stdin . as_ref ( ) . and_then ( |pipe| {
173
- let fd = pipe. wr . as_raw_fd ( ) ;
174
- tokio_pipe:: PipeWrite :: from_raw_fd_checked ( fd)
175
- . map ( |x| Box :: new ( x) as Box < dyn AsyncWrite + Send + Sync + Unpin > )
176
- . ok ( )
177
- } )
178
- }
179
-
180
- #[ cfg( not( feature = "async" ) ) ]
181
- fn stdout ( & self ) -> Option < Box < dyn Read + Send > > {
182
- self . stdout . as_ref ( ) . and_then ( |pipe| {
183
- pipe. rd
184
- . try_clone ( )
185
- . map ( |x| Box :: new ( x) as Box < dyn Read + Send > )
186
- . ok ( )
187
- } )
188
- }
189
-
190
- #[ cfg( feature = "async" ) ]
191
- fn stdout ( & self ) -> Option < Box < dyn AsyncRead + Send + Sync + Unpin > > {
192
- self . stdout . as_ref ( ) . and_then ( |pipe| {
193
- let fd = pipe. rd . as_raw_fd ( ) ;
194
- tokio_pipe:: PipeRead :: from_raw_fd_checked ( fd)
195
- . map ( |x| Box :: new ( x) as Box < dyn AsyncRead + Send + Sync + Unpin > )
196
- . ok ( )
197
- } )
198
- }
199
-
200
- #[ cfg( not( feature = "async" ) ) ]
201
- fn stderr ( & self ) -> Option < Box < dyn Read + Send > > {
202
- self . stderr . as_ref ( ) . and_then ( |pipe| {
203
- pipe. rd
204
- . try_clone ( )
205
- . map ( |x| Box :: new ( x) as Box < dyn Read + Send > )
206
- . ok ( )
207
- } )
208
- }
209
-
210
- #[ cfg( feature = "async" ) ]
211
- fn stderr ( & self ) -> Option < Box < dyn AsyncRead + Send + Sync + Unpin > > {
212
- self . stderr . as_ref ( ) . and_then ( |pipe| {
213
- let fd = pipe. rd . as_raw_fd ( ) ;
214
- tokio_pipe:: PipeRead :: from_raw_fd_checked ( fd)
215
- . map ( |x| Box :: new ( x) as Box < dyn AsyncRead + Send + Sync + Unpin > )
216
- . ok ( )
217
- } )
218
- }
219
-
220
- // Note that this internally use [`std::fs::File`]'s `try_clone()`.
221
- // Thus, the files passed to commands will be not closed after command exit.
222
- fn set ( & self , cmd : & mut Command ) -> std:: io:: Result < ( ) > {
223
- if let Some ( p) = self . stdin . as_ref ( ) {
224
- let pr = p. rd . try_clone ( ) ?;
225
- cmd. stdin ( pr) ;
226
- }
227
-
228
- if let Some ( p) = self . stdout . as_ref ( ) {
229
- let pw = p. wr . try_clone ( ) ?;
230
- cmd. stdout ( pw) ;
231
- }
232
-
233
- if let Some ( p) = self . stderr . as_ref ( ) {
234
- let pw = p. wr . try_clone ( ) ?;
235
- cmd. stdout ( pw) ;
236
- }
237
-
238
- Ok ( ( ) )
239
- }
240
-
241
- fn close_after_start ( & self ) {
242
- if let Some ( p) = self . stdout . as_ref ( ) {
243
- nix:: unistd:: close ( p. wr . as_raw_fd ( ) ) . unwrap_or_else ( |e| debug ! ( "close stdout: {}" , e) ) ;
244
- }
245
-
246
- if let Some ( p) = self . stderr . as_ref ( ) {
247
- nix:: unistd:: close ( p. wr . as_raw_fd ( ) ) . unwrap_or_else ( |e| debug ! ( "close stderr: {}" , e) ) ;
248
- }
249
- }
250
- }
251
-
252
80
/// IO driver to direct output/error messages to /dev/null.
253
81
///
254
82
/// With this Io driver, all methods of [crate::Runc] can't capture the output/error messages.
0 commit comments