1
- // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
1
+ // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2
2
// file at the top-level directory of this distribution and at
3
3
// http://rust-lang.org/COPYRIGHT.
4
4
//
@@ -44,13 +44,13 @@ pub trait Program {
44
44
/// Returns the process id of the program
45
45
fn get_id ( & mut self ) -> pid_t ;
46
46
47
- /// Returns an io::Writer that can be used to write to stdin
47
+ /// Returns an io::writer that can be used to write to stdin
48
48
fn input ( & mut self ) -> @io:: Writer ;
49
49
50
- /// Returns an io::Reader that can be used to read from stdout
50
+ /// Returns an io::reader that can be used to read from stdout
51
51
fn output ( & mut self ) -> @io:: Reader ;
52
52
53
- /// Returns an io::Reader that can be used to read from stderr
53
+ /// Returns an io::reader that can be used to read from stderr
54
54
fn err ( & mut self ) -> @io:: Reader ;
55
55
56
56
/// Closes the handle to the child processes standard input
@@ -62,10 +62,7 @@ pub trait Program {
62
62
*/
63
63
fn finish ( & mut self ) -> int ;
64
64
65
- /**
66
- * Forcibly terminate the program. On Posix OSs SIGKILL will be sent
67
- * to the process. On Win32 TerminateProcess(..) will be called.
68
- */
65
+ /// Closes open handles
69
66
fn destroy ( & mut self ) ;
70
67
}
71
68
@@ -175,14 +172,6 @@ fn with_dirp<T>(d: &Option<~str>,
175
172
}
176
173
}
177
174
178
- /// helper function that closes non-NULL files and then makes them NULL
179
- priv unsafe fn fclose_and_null ( f : & mut * libc:: FILE ) {
180
- if * f != 0 as * libc:: FILE {
181
- libc:: fclose ( * f) ;
182
- * f = 0 as * libc:: FILE ;
183
- }
184
- }
185
-
186
175
/**
187
176
* Spawns a process and waits for it to terminate
188
177
*
@@ -203,9 +192,9 @@ pub fn run_program(prog: &str, args: &[~str]) -> int {
203
192
}
204
193
205
194
/**
206
- * Spawns a process and returns a Program
195
+ * Spawns a process and returns a program
207
196
*
208
- * The returned value is a boxed class containing a <Program > object that can
197
+ * The returned value is a boxed class containing a <program > object that can
209
198
* be used for sending and receiving data over the standard file descriptors.
210
199
* The class will ensure that file descriptors are closed properly.
211
200
*
@@ -251,53 +240,28 @@ pub fn start_program(prog: &str, args: &[~str]) -> @Program {
251
240
r. in_fd = invalid_fd;
252
241
}
253
242
}
254
-
255
- fn close_repr_outputs ( r : & mut ProgRepr ) {
256
- unsafe {
257
- fclose_and_null ( & mut r. out_file ) ;
258
- fclose_and_null ( & mut r. err_file ) ;
259
- }
260
- }
261
-
262
243
fn finish_repr ( r : & mut ProgRepr ) -> int {
263
244
if r. finished { return 0 ; }
264
245
r. finished = true ;
265
246
close_repr_input ( & mut * r) ;
266
247
return waitpid ( r. pid ) ;
267
248
}
268
-
269
249
fn destroy_repr ( r : & mut ProgRepr ) {
270
- killpid ( r. pid ) ;
271
- finish_repr ( & mut * r) ;
272
- close_repr_outputs ( & mut * r) ;
273
-
274
- #[ cfg( windows) ]
275
- fn killpid ( pid : pid_t ) {
276
- unsafe {
277
- libc:: funcs:: extra:: kernel32:: TerminateProcess (
278
- cast:: transmute ( pid) , 1 ) ;
279
- }
280
- }
281
-
282
- #[ cfg( unix) ]
283
- fn killpid ( pid : pid_t ) {
284
- unsafe {
285
- libc:: funcs:: posix88:: signal:: kill (
286
- pid, libc:: consts:: os:: posix88:: SIGKILL as c_int ) ;
287
- }
250
+ unsafe {
251
+ finish_repr ( & mut * r) ;
252
+ libc:: fclose ( r. out_file ) ;
253
+ libc:: fclose ( r. err_file ) ;
288
254
}
289
255
}
290
-
291
256
struct ProgRes {
292
257
r : ProgRepr ,
293
258
}
294
259
295
260
impl Drop for ProgRes {
296
261
fn finalize ( & self ) {
297
262
unsafe {
298
- // FIXME #4943: transmute is bad.
299
- finish_repr ( cast:: transmute ( & self . r ) ) ;
300
- close_repr_outputs ( cast:: transmute ( & self . r ) ) ;
263
+ // FIXME #4943: This is bad.
264
+ destroy_repr ( cast:: transmute ( & self . r ) ) ;
301
265
}
302
266
}
303
267
}
@@ -323,7 +287,6 @@ pub fn start_program(prog: &str, args: &[~str]) -> @Program {
323
287
fn finish ( & mut self ) -> int { finish_repr ( & mut self . r ) }
324
288
fn destroy ( & mut self ) { destroy_repr ( & mut self . r ) ; }
325
289
}
326
-
327
290
let mut repr = ProgRepr {
328
291
pid : pid,
329
292
in_fd : pipe_input. out ,
@@ -495,10 +458,8 @@ pub fn waitpid(pid: pid_t) -> int {
495
458
496
459
#[ cfg( test) ]
497
460
mod tests {
498
- use libc;
499
461
use option:: None ;
500
462
use os;
501
- use path:: Path ;
502
463
use run:: { readclose, writeclose} ;
503
464
use run;
504
465
@@ -546,40 +507,6 @@ mod tests {
546
507
assert ! ( status == 1 ) ;
547
508
}
548
509
549
- #[ test]
550
- pub fn test_destroy_once ( ) {
551
- let mut p = run:: start_program ( "echo" , [ ] ) ;
552
- p. destroy ( ) ; // this shouldn't crash (and nor should the destructor)
553
- }
554
-
555
- #[ test]
556
- pub fn test_destroy_twice ( ) {
557
- let mut p = run:: start_program ( "echo" , [ ] ) ;
558
- p. destroy ( ) ; // this shouldnt crash...
559
- p. destroy ( ) ; // ...and nor should this (and nor should the destructor)
560
- }
561
-
562
- #[ test]
563
- #[ cfg( unix) ] // there is no way to sleep on windows from inside libcore...
564
- pub fn test_destroy_actually_kills ( ) {
565
- let path = Path ( "test/core-run-test-destroy-actually-kills.tmp" ) ;
566
-
567
- os:: remove_file ( & path) ;
568
-
569
- let cmd = fmt ! ( "sleep 5 && echo MurderDeathKill > %s" , path. to_str( ) ) ;
570
- let mut p = run:: start_program ( "sh" , [ ~"-c" , cmd] ) ;
571
-
572
- p. destroy ( ) ; // destroy the program before it has a chance to echo its message
573
-
574
- unsafe {
575
- // wait to ensure the program is really destroyed and not just waiting itself
576
- libc:: sleep ( 10 ) ;
577
- }
578
-
579
- // the program should not have had chance to echo its message
580
- assert ! ( !path. exists( ) ) ;
581
- }
582
-
583
510
}
584
511
585
512
// Local Variables:
0 commit comments