@@ -10,13 +10,14 @@ use std::os::fd::AsRawFd;
1010use std:: os:: unix:: net:: UnixListener as StdUnixListener ;
1111use std:: os:: unix:: process:: ExitStatusExt as _;
1212use std:: path:: PathBuf ;
13+ use std:: process:: ExitCode ;
1314use tokio:: net:: UnixListener ;
1415use tokio:: process:: Command ;
1516use tokio:: sync:: watch;
1617use tokio_stream:: wrappers:: WatchStream ;
1718use tokio_stream:: StreamExt as _;
1819
19- pub async fn server_main ( command : PathBuf , command_args : Vec < String > ) -> Result < ( ) > {
20+ pub async fn server_main ( command : PathBuf , command_args : Vec < String > ) -> Result < ExitCode > {
2021 let sock_fd = socket (
2122 AddressFamily :: Vsock ,
2223 SockType :: Stream ,
@@ -43,7 +44,7 @@ pub async fn server_main(command: PathBuf, command_args: Vec<String>) -> Result<
4344 let mut state_rx = WatchStream :: new ( state_rx) ;
4445
4546 let mut server_died = false ;
46- let mut command_exited = false ;
47+ let mut command_exit_code = None ;
4748
4849 loop {
4950 tokio:: select! {
@@ -59,39 +60,40 @@ pub async fn server_main(command: PathBuf, command_args: Vec<String>) -> Result<
5960 server_died = true ;
6061 }
6162 } ,
62- res = & mut command_status, if !command_exited => {
63- match res {
63+ res = & mut command_status, if command_exit_code. is_none( ) => {
64+ command_exit_code = Some ( match res {
65+ Ok ( status) if status. success( ) => ExitCode :: SUCCESS ,
6466 Ok ( status) => {
65- if ! status. success ( ) {
66- if let Some ( code ) = status . code ( ) {
67- eprintln! (
68- "{command:?} process exited with status code: {code}"
69- ) ;
70- } else {
71- eprintln!(
72- "{:?} process terminated by signal: {}" ,
73- command,
74- status
75- . signal( )
76- . expect( "either one of status code or signal should be set" )
77- ) ;
78- }
67+ if let Some ( code ) = status. code ( ) {
68+ eprintln! (
69+ "{command:?} process exited with status code: {code}"
70+ ) ;
71+ ExitCode :: from ( code as u8 )
72+ } else {
73+ eprintln!(
74+ "{:?} process terminated by signal: {}" ,
75+ command,
76+ status
77+ . signal( )
78+ . expect( "either one of status code or signal should be set" )
79+ ) ;
80+ ExitCode :: FAILURE
7981 }
8082 } ,
8183 Err ( err) => {
8284 eprintln!(
8385 "Failed to execute {command:?} as child process: {err}"
8486 ) ;
87+ ExitCode :: FAILURE
8588 } ,
86- }
87- command_exited = true ;
89+ } )
8890 } ,
89- Some ( state) = state_rx. next( ) , if command_exited => {
91+ Some ( state) = state_rx. next( ) , if command_exit_code . is_some ( ) => {
9092 if state. connection_idle( ) && state. child_processes( ) == 0 {
9193 // Server is idle (not currently handling an accepted
9294 // incoming connection) and no more child processes.
9395 // We're done.
94- return Ok ( ( ) ) ;
96+ return Ok ( command_exit_code . unwrap ( ) ) ;
9597 }
9698 println!(
9799 "Waiting for {} other commands launched through this muvm server to exit..." ,
0 commit comments