11//! Handle process life-time and message passing for proc-macro client
22
33use std:: {
4- io:: { self , BufRead , BufReader , Write } ,
4+ io:: { self , BufRead , BufReader , Read , Write } ,
55 process:: { Child , ChildStdin , ChildStdout , Command , Stdio } ,
6+ sync:: Arc ,
67} ;
78
89use paths:: { AbsPath , AbsPathBuf } ;
@@ -15,9 +16,11 @@ use crate::{
1516
1617#[ derive( Debug ) ]
1718pub ( crate ) struct ProcMacroProcessSrv {
18- _process : Process ,
19+ process : Process ,
1920 stdin : ChildStdin ,
2021 stdout : BufReader < ChildStdout > ,
22+ /// Populated when the server exits.
23+ server_exited : Option < ServerError > ,
2124 version : u32 ,
2225 mode : SpanMode ,
2326}
@@ -29,9 +32,10 @@ impl ProcMacroProcessSrv {
2932 let ( stdin, stdout) = process. stdio ( ) . expect ( "couldn't access child stdio" ) ;
3033
3134 io:: Result :: Ok ( ProcMacroProcessSrv {
32- _process : process,
35+ process,
3336 stdin,
3437 stdout,
38+ server_exited : None ,
3539 version : 0 ,
3640 mode : SpanMode :: Id ,
3741 } )
@@ -105,8 +109,35 @@ impl ProcMacroProcessSrv {
105109 }
106110
107111 pub ( crate ) fn send_task ( & mut self , req : Request ) -> Result < Response , ServerError > {
112+ if let Some ( server_error) = & self . server_exited {
113+ return Err ( server_error. clone ( ) ) ;
114+ }
115+
108116 let mut buf = String :: new ( ) ;
109- send_request ( & mut self . stdin , & mut self . stdout , req, & mut buf)
117+ send_request ( & mut self . stdin , & mut self . stdout , req, & mut buf) . map_err ( |e| {
118+ if e. io . as_ref ( ) . map ( |it| it. kind ( ) ) == Some ( io:: ErrorKind :: BrokenPipe ) {
119+ match self . process . child . try_wait ( ) {
120+ Ok ( None ) => e,
121+ Ok ( Some ( status) ) => {
122+ let mut msg = String :: new ( ) ;
123+ if !status. success ( ) {
124+ if let Some ( stderr) = self . process . child . stderr . as_mut ( ) {
125+ _ = stderr. read_to_string ( & mut msg) ;
126+ }
127+ }
128+ let server_error = ServerError {
129+ message : format ! ( "server exited with {status}: {msg}" ) ,
130+ io : None ,
131+ } ;
132+ self . server_exited = Some ( server_error. clone ( ) ) ;
133+ server_error
134+ }
135+ Err ( _) => e,
136+ }
137+ } else {
138+ e
139+ }
140+ } )
110141 }
111142}
112143
@@ -145,9 +176,13 @@ fn send_request(
145176 req : Request ,
146177 buf : & mut String ,
147178) -> Result < Response , ServerError > {
148- req. write ( & mut writer)
149- . map_err ( |err| ServerError { message : "failed to write request" . into ( ) , io : Some ( err) } ) ?;
150- let res = Response :: read ( & mut reader, buf)
151- . map_err ( |err| ServerError { message : "failed to read response" . into ( ) , io : Some ( err) } ) ?;
179+ req. write ( & mut writer) . map_err ( |err| ServerError {
180+ message : "failed to write request" . into ( ) ,
181+ io : Some ( Arc :: new ( err) ) ,
182+ } ) ?;
183+ let res = Response :: read ( & mut reader, buf) . map_err ( |err| ServerError {
184+ message : "failed to read response" . into ( ) ,
185+ io : Some ( Arc :: new ( err) ) ,
186+ } ) ?;
152187 res. ok_or_else ( || ServerError { message : "server exited" . into ( ) , io : None } )
153188}
0 commit comments