@@ -66,35 +66,33 @@ impl Process {
66
66
-> Result < ( Process , ~[ Option < file:: FileDesc > ] ) , io:: IoError >
67
67
{
68
68
// right now we only handle stdin/stdout/stderr.
69
- if config. io . len ( ) > 3 {
69
+ if config. extra_io . len ( ) > 0 {
70
70
return Err ( super :: unimpl ( ) ) ;
71
71
}
72
72
73
- fn get_io ( io : & [ p:: StdioContainer ] ,
74
- ret : & mut ~[ Option < file:: FileDesc > ] ,
75
- idx : uint ) -> ( Option < os:: Pipe > , c_int ) {
76
- if idx >= io. len ( ) { return ( None , -1 ) ; }
77
- ret. push ( None ) ;
78
- match io[ idx] {
79
- p:: Ignored => ( None , -1 ) ,
80
- p:: InheritFd ( fd) => ( None , fd) ,
73
+ fn get_io ( io : p:: StdioContainer , ret : & mut ~[ Option < file:: FileDesc > ] )
74
+ -> ( Option < os:: Pipe > , c_int )
75
+ {
76
+ match io {
77
+ p:: Ignored => { ret. push ( None ) ; ( None , -1 ) }
78
+ p:: InheritFd ( fd) => { ret. push ( None ) ; ( None , fd) }
81
79
p:: CreatePipe ( readable, _writable) => {
82
80
let pipe = os:: pipe ( ) ;
83
81
let ( theirs, ours) = if readable {
84
82
( pipe. input , pipe. out )
85
83
} else {
86
84
( pipe. out , pipe. input )
87
85
} ;
88
- ret[ idx ] = Some ( file:: FileDesc :: new ( ours, true ) ) ;
86
+ ret. push ( Some ( file:: FileDesc :: new ( ours, true ) ) ) ;
89
87
( Some ( pipe) , theirs)
90
88
}
91
89
}
92
90
}
93
91
94
92
let mut ret_io = ~[ ] ;
95
- let ( in_pipe, in_fd) = get_io ( config. io , & mut ret_io, 0 ) ;
96
- let ( out_pipe, out_fd) = get_io ( config. io , & mut ret_io, 1 ) ;
97
- let ( err_pipe, err_fd) = get_io ( config. io , & mut ret_io, 2 ) ;
93
+ let ( in_pipe, in_fd) = get_io ( config. stdin , & mut ret_io) ;
94
+ let ( out_pipe, out_fd) = get_io ( config. stdout , & mut ret_io) ;
95
+ let ( err_pipe, err_fd) = get_io ( config. stderr , & mut ret_io) ;
98
96
99
97
let env = config. env . map ( |a| a. to_owned ( ) ) ;
100
98
let cwd = config. cwd . map ( |a| Path :: new ( a) ) ;
@@ -115,6 +113,10 @@ impl Process {
115
113
Err ( e) => Err ( e)
116
114
}
117
115
}
116
+
117
+ pub fn kill ( pid : libc:: pid_t , signum : int ) -> IoResult < ( ) > {
118
+ unsafe { killpid ( pid, signum) }
119
+ }
118
120
}
119
121
120
122
impl rtio:: RtioProcess for Process {
@@ -144,34 +146,58 @@ impl rtio::RtioProcess for Process {
144
146
None => { }
145
147
}
146
148
return unsafe { killpid ( self . pid , signum) } ;
149
+ }
150
+ }
147
151
148
- #[ cfg( windows) ]
149
- unsafe fn killpid ( pid : pid_t , signal : int ) -> Result < ( ) , io:: IoError > {
150
- match signal {
151
- io:: process:: PleaseExitSignal | io:: process:: MustDieSignal => {
152
- let ret = libc:: TerminateProcess ( pid as libc:: HANDLE , 1 ) ;
153
- super :: mkerr_winbool ( ret)
154
- }
155
- _ => Err ( io:: IoError {
152
+ impl Drop for Process {
153
+ fn drop ( & mut self ) {
154
+ free_handle ( self . handle ) ;
155
+ }
156
+ }
157
+
158
+ #[ cfg( windows) ]
159
+ unsafe fn killpid ( pid : pid_t , signal : int ) -> Result < ( ) , io:: IoError > {
160
+ let handle = libc:: OpenProcess ( libc:: PROCESS_TERMINATE |
161
+ libc:: PROCESS_QUERY_INFORMATION ,
162
+ libc:: FALSE , pid as libc:: DWORD ) ;
163
+ if handle. is_null ( ) {
164
+ return Err ( super :: last_error ( ) )
165
+ }
166
+ let ret = match signal {
167
+ // test for existence on signal 0
168
+ 0 => {
169
+ let mut status = 0 ;
170
+ let ret = libc:: GetExitCodeProcess ( handle, & mut status) ;
171
+ if ret == 0 {
172
+ Err ( super :: last_error ( ) )
173
+ } else if status != libc:: STILL_ACTIVE {
174
+ Err ( io:: IoError {
156
175
kind : io:: OtherIoError ,
157
- desc : "unsupported signal on windows " ,
176
+ desc : "process no longer alive " ,
158
177
detail : None ,
159
178
} )
179
+ } else {
180
+ Ok ( ( ) )
160
181
}
161
182
}
162
-
163
- #[ cfg( not( windows) ) ]
164
- unsafe fn killpid ( pid : pid_t , signal : int ) -> Result < ( ) , io:: IoError > {
165
- let r = libc:: funcs:: posix88:: signal:: kill ( pid, signal as c_int ) ;
166
- super :: mkerr_libc ( r)
183
+ io:: process:: PleaseExitSignal | io:: process:: MustDieSignal => {
184
+ let ret = libc:: TerminateProcess ( handle, 1 ) ;
185
+ super :: mkerr_winbool ( ret)
167
186
}
168
- }
187
+ _ => Err ( io:: IoError {
188
+ kind : io:: OtherIoError ,
189
+ desc : "unsupported signal on windows" ,
190
+ detail : None ,
191
+ } )
192
+ } ;
193
+ let _ = libc:: CloseHandle ( handle) ;
194
+ return ret;
169
195
}
170
196
171
- impl Drop for Process {
172
- fn drop ( & mut self ) {
173
- free_handle ( self . handle ) ;
174
- }
197
+ # [ cfg ( not ( windows ) ) ]
198
+ unsafe fn killpid ( pid : pid_t , signal : int ) -> Result < ( ) , io :: IoError > {
199
+ let r = libc :: funcs :: posix88 :: signal :: kill ( pid , signal as c_int ) ;
200
+ super :: mkerr_libc ( r )
175
201
}
176
202
177
203
struct SpawnProcessResult {
@@ -536,10 +562,10 @@ fn spawn_process_os(config: p::ProcessConfig,
536
562
if !envp. is_null ( ) {
537
563
set_environ ( envp) ;
538
564
}
539
- } ) ;
540
- with_argv ( config . program , config . args , | argv| {
541
- let _ = execvp ( * argv , argv ) ;
542
- fail ( & mut output ) ;
565
+ with_argv ( config . program , config . args , |argv| {
566
+ let _ = execvp ( * argv, argv ) ;
567
+ fail ( & mut output ) ;
568
+ } )
543
569
} )
544
570
}
545
571
}
0 commit comments