@@ -163,8 +163,10 @@ impl RuncFactory {
163
163
( Some ( s) , None )
164
164
} else {
165
165
let pio = create_io ( & id, opts. io_uid , opts. io_gid , stdio) ?;
166
- create_opts. io = pio. io . as_ref ( ) . cloned ( ) ;
167
- ( None , Some ( pio) )
166
+ let ref_pio = Arc :: new ( pio) ;
167
+ create_opts. io = ref_pio. io . clone ( ) ;
168
+ init. io = Some ( ref_pio. clone ( ) ) ;
169
+ ( None , Some ( ref_pio) )
168
170
} ;
169
171
170
172
let resp = init
@@ -178,6 +180,22 @@ impl RuncFactory {
178
180
}
179
181
return Err ( runtime_error ( bundle, e, "OCI runtime create failed" ) . await ) ;
180
182
}
183
+ if !init. stdio . stdin . is_empty ( ) {
184
+ let stdin_clone = init. stdio . stdin . clone ( ) ;
185
+ let stdin_w = init. stdin . clone ( ) ;
186
+ // Open the write side in advance to make sure read side will not block,
187
+ // open it in another thread otherwise it will block too.
188
+ tokio:: spawn ( async move {
189
+ if let Ok ( stdin_w_file) = OpenOptions :: new ( )
190
+ . write ( true )
191
+ . open ( stdin_clone. as_str ( ) )
192
+ . await
193
+ {
194
+ let mut lock_guard = stdin_w. lock ( ) . unwrap ( ) ;
195
+ * lock_guard = Some ( stdin_w_file) ;
196
+ }
197
+ } ) ;
198
+ }
181
199
copy_io_or_console ( init, socket, pio, init. lifecycle . exit_signal . clone ( ) ) . await ?;
182
200
let pid = read_file_to_str ( pid_path) . await ?. parse :: < i32 > ( ) ?;
183
201
init. pid = pid;
@@ -232,6 +250,7 @@ impl ProcessFactory<ExecProcess> for RuncExecFactory {
232
250
stderr : req. stderr . to_string ( ) ,
233
251
terminal : req. terminal ,
234
252
} ,
253
+ io : None ,
235
254
pid : 0 ,
236
255
exit_code : 0 ,
237
256
exited_at : None ,
@@ -299,6 +318,7 @@ impl ProcessLifecycle<InitProcess> for RuncInitLifecycle {
299
318
) ;
300
319
}
301
320
}
321
+
302
322
self . exit_signal . signal ( ) ;
303
323
Ok ( ( ) )
304
324
}
@@ -434,8 +454,10 @@ impl ProcessLifecycle<ExecProcess> for RuncExecLifecycle {
434
454
( Some ( s) , None )
435
455
} else {
436
456
let pio = create_io ( & p. id , self . io_uid , self . io_gid , & p. stdio ) ?;
437
- exec_opts. io = pio. io . as_ref ( ) . cloned ( ) ;
438
- ( None , Some ( pio) )
457
+ let ref_pio = Arc :: new ( pio) ;
458
+ exec_opts. io = ref_pio. io . clone ( ) ;
459
+ p. io = Some ( ref_pio. clone ( ) ) ;
460
+ ( None , Some ( ref_pio) )
439
461
} ;
440
462
//TODO checkpoint support
441
463
let exec_result = self
@@ -698,7 +720,7 @@ where
698
720
async fn copy_io_or_console < P > (
699
721
p : & mut ProcessTemplate < P > ,
700
722
socket : Option < ConsoleSocket > ,
701
- pio : Option < ProcessIO > ,
723
+ pio : Option < Arc < ProcessIO > > ,
702
724
exit_signal : Arc < ExitSignal > ,
703
725
) -> Result < ( ) > {
704
726
if p. stdio . terminal {
@@ -736,6 +758,7 @@ impl Spawner for ShimExecutor {
736
758
}
737
759
} ;
738
760
let pid = child. id ( ) . unwrap ( ) ;
761
+
739
762
let ( stdout, stderr, exit_code) = tokio:: join!(
740
763
read_std( child. stdout) ,
741
764
read_std( child. stderr) ,
0 commit comments