@@ -40,6 +40,9 @@ pub struct Process {
40
40
41
41
/// None until finish() is called.
42
42
exit_code : Option < p:: ProcessExit > ,
43
+
44
+ /// Manually delivered signal
45
+ exit_signal : Option < int > ,
43
46
}
44
47
45
48
impl Process {
@@ -107,7 +110,12 @@ impl Process {
107
110
108
111
match res {
109
112
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
+ } ,
111
119
ret_io) )
112
120
}
113
121
Err ( e) => Err ( e)
@@ -127,6 +135,14 @@ impl rtio::RtioProcess for Process {
127
135
Some ( code) => code,
128
136
None => {
129
137
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
+ } ;
130
146
self . exit_code = Some ( code) ;
131
147
code
132
148
}
@@ -157,7 +173,14 @@ impl rtio::RtioProcess for Process {
157
173
} ) ,
158
174
None => { }
159
175
}
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
+ }
161
184
}
162
185
}
163
186
@@ -256,31 +279,37 @@ fn spawn_process_os(config: p::ProcessConfig,
256
279
257
280
let cur_proc = GetCurrentProcess ( ) ;
258
281
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
+ }
266
291
}
267
292
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
+ }
275
302
}
276
303
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
+ }
284
313
}
285
314
286
315
let cmd = make_command_line ( config. program , config. args ) ;
@@ -307,9 +336,9 @@ fn spawn_process_os(config: p::ProcessConfig,
307
336
} )
308
337
} ) ;
309
338
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 ) ; }
313
342
314
343
match create_err {
315
344
Some ( err) => return Err ( err) ,
0 commit comments