@@ -163,8 +163,10 @@ impl RuncFactory {
163163 ( Some ( s) , None )
164164 } else {
165165 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) )
168170 } ;
169171
170172 let resp = init
@@ -178,6 +180,22 @@ impl RuncFactory {
178180 }
179181 return Err ( runtime_error ( bundle, e, "OCI runtime create failed" ) . await ) ;
180182 }
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+ }
181199 copy_io_or_console ( init, socket, pio, init. lifecycle . exit_signal . clone ( ) ) . await ?;
182200 let pid = read_file_to_str ( pid_path) . await ?. parse :: < i32 > ( ) ?;
183201 init. pid = pid;
@@ -232,6 +250,7 @@ impl ProcessFactory<ExecProcess> for RuncExecFactory {
232250 stderr : req. stderr . to_string ( ) ,
233251 terminal : req. terminal ,
234252 } ,
253+ io : None ,
235254 pid : 0 ,
236255 exit_code : 0 ,
237256 exited_at : None ,
@@ -299,6 +318,7 @@ impl ProcessLifecycle<InitProcess> for RuncInitLifecycle {
299318 ) ;
300319 }
301320 }
321+
302322 self . exit_signal . signal ( ) ;
303323 Ok ( ( ) )
304324 }
@@ -434,8 +454,10 @@ impl ProcessLifecycle<ExecProcess> for RuncExecLifecycle {
434454 ( Some ( s) , None )
435455 } else {
436456 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) )
439461 } ;
440462 //TODO checkpoint support
441463 let exec_result = self
@@ -698,7 +720,7 @@ where
698720async fn copy_io_or_console < P > (
699721 p : & mut ProcessTemplate < P > ,
700722 socket : Option < ConsoleSocket > ,
701- pio : Option < ProcessIO > ,
723+ pio : Option < Arc < ProcessIO > > ,
702724 exit_signal : Arc < ExitSignal > ,
703725) -> Result < ( ) > {
704726 if p. stdio . terminal {
@@ -736,6 +758,7 @@ impl Spawner for ShimExecutor {
736758 }
737759 } ;
738760 let pid = child. id ( ) . unwrap ( ) ;
761+
739762 let ( stdout, stderr, exit_code) = tokio:: join!(
740763 read_std( child. stdout) ,
741764 read_std( child. stderr) ,
0 commit comments