@@ -40,6 +40,9 @@ pub struct Process {
4040
4141 /// None until finish() is called.
4242 exit_code : Option < p:: ProcessExit > ,
43+
44+ /// Manually delivered signal
45+ exit_signal : Option < int > ,
4346}
4447
4548impl Process {
@@ -107,7 +110,12 @@ impl Process {
107110
108111 match res {
109112 Ok ( res) => {
110- Ok ( ( Process { pid : res. pid , handle : res. handle , exit_code : None } ,
113+ Ok ( ( Process {
114+ pid : res. pid ,
115+ handle : res. handle ,
116+ exit_code : None ,
117+ exit_signal : None ,
118+ } ,
111119 ret_io) )
112120 }
113121 Err ( e) => Err ( e)
@@ -127,6 +135,14 @@ impl rtio::RtioProcess for Process {
127135 Some ( code) => code,
128136 None => {
129137 let code = waitpid ( self . pid ) ;
138+ // On windows, waitpid will never return a signal. If a signal
139+ // was successfully delivered to the process, however, we can
140+ // consider it as having died via a signal.
141+ let code = match self . exit_signal {
142+ None => code,
143+ Some ( signal) if cfg ! ( windows) => p:: ExitSignal ( signal) ,
144+ Some ( ..) => code,
145+ } ;
130146 self . exit_code = Some ( code) ;
131147 code
132148 }
@@ -157,7 +173,14 @@ impl rtio::RtioProcess for Process {
157173 } ) ,
158174 None => { }
159175 }
160- return unsafe { killpid ( self . pid , signum) } ;
176+
177+ // A successfully delivered signal that isn't 0 (just a poll for being
178+ // alive) is recorded for windows (see wait())
179+ match unsafe { killpid ( self . pid , signum) } {
180+ Ok ( ( ) ) if signum == 0 => Ok ( ( ) ) ,
181+ Ok ( ( ) ) => { self . exit_signal = Some ( signum) ; Ok ( ( ) ) }
182+ Err ( e) => Err ( e) ,
183+ }
161184 }
162185}
163186
@@ -256,31 +279,37 @@ fn spawn_process_os(config: p::ProcessConfig,
256279
257280 let cur_proc = GetCurrentProcess ( ) ;
258281
259- let orig_std_in = get_osfhandle ( in_fd) as HANDLE ;
260- if orig_std_in == INVALID_HANDLE_VALUE as HANDLE {
261- fail ! ( "failure in get_osfhandle: {}" , os:: last_os_error( ) ) ;
262- }
263- if DuplicateHandle ( cur_proc, orig_std_in, cur_proc, & mut si. hStdInput ,
264- 0 , TRUE , DUPLICATE_SAME_ACCESS ) == FALSE {
265- fail ! ( "failure in DuplicateHandle: {}" , os:: last_os_error( ) ) ;
282+ if in_fd != -1 {
283+ let orig_std_in = get_osfhandle ( in_fd) as HANDLE ;
284+ if orig_std_in == INVALID_HANDLE_VALUE as HANDLE {
285+ fail ! ( "failure in get_osfhandle: {}" , os:: last_os_error( ) ) ;
286+ }
287+ if DuplicateHandle ( cur_proc, orig_std_in, cur_proc, & mut si. hStdInput ,
288+ 0 , TRUE , DUPLICATE_SAME_ACCESS ) == FALSE {
289+ fail ! ( "failure in DuplicateHandle: {}" , os:: last_os_error( ) ) ;
290+ }
266291 }
267292
268- let orig_std_out = get_osfhandle ( out_fd) as HANDLE ;
269- if orig_std_out == INVALID_HANDLE_VALUE as HANDLE {
270- fail ! ( "failure in get_osfhandle: {}" , os:: last_os_error( ) ) ;
271- }
272- if DuplicateHandle ( cur_proc, orig_std_out, cur_proc, & mut si. hStdOutput ,
273- 0 , TRUE , DUPLICATE_SAME_ACCESS ) == FALSE {
274- fail ! ( "failure in DuplicateHandle: {}" , os:: last_os_error( ) ) ;
293+ if out_fd != -1 {
294+ let orig_std_out = get_osfhandle ( out_fd) as HANDLE ;
295+ if orig_std_out == INVALID_HANDLE_VALUE as HANDLE {
296+ fail ! ( "failure in get_osfhandle: {}" , os:: last_os_error( ) ) ;
297+ }
298+ if DuplicateHandle ( cur_proc, orig_std_out, cur_proc, & mut si. hStdOutput ,
299+ 0 , TRUE , DUPLICATE_SAME_ACCESS ) == FALSE {
300+ fail ! ( "failure in DuplicateHandle: {}" , os:: last_os_error( ) ) ;
301+ }
275302 }
276303
277- let orig_std_err = get_osfhandle ( err_fd) as HANDLE ;
278- if orig_std_err == INVALID_HANDLE_VALUE as HANDLE {
279- fail ! ( "failure in get_osfhandle: {}" , os:: last_os_error( ) ) ;
280- }
281- if DuplicateHandle ( cur_proc, orig_std_err, cur_proc, & mut si. hStdError ,
282- 0 , TRUE , DUPLICATE_SAME_ACCESS ) == FALSE {
283- fail ! ( "failure in DuplicateHandle: {}" , os:: last_os_error( ) ) ;
304+ if err_fd != -1 {
305+ let orig_std_err = get_osfhandle ( err_fd) as HANDLE ;
306+ if orig_std_err == INVALID_HANDLE_VALUE as HANDLE {
307+ fail ! ( "failure in get_osfhandle: {}" , os:: last_os_error( ) ) ;
308+ }
309+ if DuplicateHandle ( cur_proc, orig_std_err, cur_proc, & mut si. hStdError ,
310+ 0 , TRUE , DUPLICATE_SAME_ACCESS ) == FALSE {
311+ fail ! ( "failure in DuplicateHandle: {}" , os:: last_os_error( ) ) ;
312+ }
284313 }
285314
286315 let cmd = make_command_line ( config. program , config. args ) ;
@@ -307,9 +336,9 @@ fn spawn_process_os(config: p::ProcessConfig,
307336 } )
308337 } ) ;
309338
310- assert ! ( CloseHandle ( si. hStdInput) != 0 ) ;
311- assert ! ( CloseHandle ( si. hStdOutput) != 0 ) ;
312- assert ! ( CloseHandle ( si. hStdError) != 0 ) ;
339+ if in_fd != - 1 { assert ! ( CloseHandle ( si. hStdInput) != 0 ) ; }
340+ if out_fd != - 1 { assert ! ( CloseHandle ( si. hStdOutput) != 0 ) ; }
341+ if err_fd != - 1 { assert ! ( CloseHandle ( si. hStdError) != 0 ) ; }
313342
314343 match create_err {
315344 Some ( err) => return Err ( err) ,
0 commit comments