@@ -446,132 +446,129 @@ fn spawn_process_os(config: p::ProcessConfig,
446
446
assert_eq ! ( ret, 0 ) ;
447
447
}
448
448
449
- let pipe = os:: pipe ( ) ;
450
- let mut input = file:: FileDesc :: new ( pipe. input , true ) ;
451
- let mut output = file:: FileDesc :: new ( pipe. out , true ) ;
449
+ let dirp = dir. map ( |p| p. to_c_str ( ) ) ;
450
+ let dirp = dirp. as_ref ( ) . map ( |c| c. with_ref ( |p| p) ) . unwrap_or ( ptr:: null ( ) ) ;
451
+
452
+ with_envp ( env, proc ( envp) {
453
+ with_argv ( config. program , config. args , proc ( argv) unsafe {
454
+ let pipe = os:: pipe ( ) ;
455
+ let mut input = file:: FileDesc :: new ( pipe. input , true ) ;
456
+ let mut output = file:: FileDesc :: new ( pipe. out , true ) ;
457
+
458
+ set_cloexec ( output. fd ( ) ) ;
459
+
460
+ let pid = fork ( ) ;
461
+ if pid < 0 {
462
+ fail ! ( "failure in fork: {}" , os:: last_os_error( ) ) ;
463
+ } else if pid > 0 {
464
+ drop ( output) ;
465
+ let mut bytes = [ 0 , ..4 ] ;
466
+ return match input. inner_read ( bytes) {
467
+ Ok ( 4 ) => {
468
+ let errno = ( bytes[ 0 ] << 24 ) as i32 |
469
+ ( bytes[ 1 ] << 16 ) as i32 |
470
+ ( bytes[ 2 ] << 8 ) as i32 |
471
+ ( bytes[ 3 ] << 0 ) as i32 ;
472
+ Err ( super :: translate_error ( errno, false ) )
473
+ }
474
+ Err ( e) => {
475
+ assert ! ( e. kind == io:: BrokenPipe ||
476
+ e. kind == io:: EndOfFile ,
477
+ "unexpected error: {}" , e) ;
478
+ Ok ( SpawnProcessResult {
479
+ pid : pid,
480
+ handle : ptr:: null ( )
481
+ } )
482
+ }
483
+ Ok ( ..) => fail ! ( "short read on the cloexec pipe" ) ,
484
+ } ;
485
+ }
486
+ drop ( input) ;
487
+
488
+ fn fail ( output : & mut file:: FileDesc ) -> ! {
489
+ let errno = os:: errno ( ) ;
490
+ let bytes = [
491
+ ( errno << 24 ) as u8 ,
492
+ ( errno << 16 ) as u8 ,
493
+ ( errno << 8 ) as u8 ,
494
+ ( errno << 0 ) as u8 ,
495
+ ] ;
496
+ assert ! ( output. inner_write( bytes) . is_ok( ) ) ;
497
+ unsafe { libc:: _exit ( 1 ) }
498
+ }
452
499
453
- unsafe { set_cloexec ( output . fd ( ) ) } ;
500
+ rustrt :: rust_unset_sigprocmask ( ) ;
454
501
455
- unsafe {
456
- let pid = fork ( ) ;
457
- if pid < 0 {
458
- fail ! ( "failure in fork: {}" , os:: last_os_error( ) ) ;
459
- } else if pid > 0 {
460
- drop ( output) ;
461
- let mut bytes = [ 0 , ..4 ] ;
462
- return match input. inner_read ( bytes) {
463
- Ok ( 4 ) => {
464
- let errno = ( bytes[ 0 ] << 24 ) as i32 |
465
- ( bytes[ 1 ] << 16 ) as i32 |
466
- ( bytes[ 2 ] << 8 ) as i32 |
467
- ( bytes[ 3 ] << 0 ) as i32 ;
468
- Err ( super :: translate_error ( errno, false ) )
469
- }
470
- Err ( e) => {
471
- assert ! ( e. kind == io:: BrokenPipe ||
472
- e. kind == io:: EndOfFile ,
473
- "unexpected error: {}" , e) ;
474
- Ok ( SpawnProcessResult {
475
- pid : pid,
476
- handle : ptr:: null ( )
477
- } )
502
+ if in_fd == -1 {
503
+ let _ = libc:: close ( libc:: STDIN_FILENO ) ;
504
+ } else if retry ( || dup2 ( in_fd, 0 ) ) == -1 {
505
+ fail ( & mut output) ;
506
+ }
507
+ if out_fd == -1 {
508
+ let _ = libc:: close ( libc:: STDOUT_FILENO ) ;
509
+ } else if retry ( || dup2 ( out_fd, 1 ) ) == -1 {
510
+ fail ( & mut output) ;
511
+ }
512
+ if err_fd == -1 {
513
+ let _ = libc:: close ( libc:: STDERR_FILENO ) ;
514
+ } else if retry ( || dup2 ( err_fd, 2 ) ) == -1 {
515
+ fail ( & mut output) ;
516
+ }
517
+ // close all other fds
518
+ for fd in range ( 3 , getdtablesize ( ) ) . rev ( ) {
519
+ if fd != output. fd ( ) {
520
+ let _ = close ( fd as c_int ) ;
478
521
}
479
- Ok ( ..) => fail ! ( "short read on the cloexec pipe" ) ,
480
- } ;
481
- }
482
- drop ( input) ;
483
-
484
- fn fail ( output : & mut file:: FileDesc ) -> ! {
485
- let errno = os:: errno ( ) ;
486
- let bytes = [
487
- ( errno << 24 ) as u8 ,
488
- ( errno << 16 ) as u8 ,
489
- ( errno << 8 ) as u8 ,
490
- ( errno << 0 ) as u8 ,
491
- ] ;
492
- assert ! ( output. inner_write( bytes) . is_ok( ) ) ;
493
- unsafe { libc:: _exit ( 1 ) }
494
- }
495
-
496
- rustrt:: rust_unset_sigprocmask ( ) ;
497
-
498
- if in_fd == -1 {
499
- let _ = libc:: close ( libc:: STDIN_FILENO ) ;
500
- } else if retry ( || dup2 ( in_fd, 0 ) ) == -1 {
501
- fail ( & mut output) ;
502
- }
503
- if out_fd == -1 {
504
- let _ = libc:: close ( libc:: STDOUT_FILENO ) ;
505
- } else if retry ( || dup2 ( out_fd, 1 ) ) == -1 {
506
- fail ( & mut output) ;
507
- }
508
- if err_fd == -1 {
509
- let _ = libc:: close ( libc:: STDERR_FILENO ) ;
510
- } else if retry ( || dup2 ( err_fd, 2 ) ) == -1 {
511
- fail ( & mut output) ;
512
- }
513
- // close all other fds
514
- for fd in range ( 3 , getdtablesize ( ) ) . rev ( ) {
515
- if fd != output. fd ( ) {
516
- let _ = close ( fd as c_int ) ;
517
522
}
518
- }
519
523
520
- match config. gid {
521
- Some ( u) => {
522
- if libc:: setgid ( u as libc:: gid_t ) != 0 {
523
- fail ( & mut output) ;
524
+ match config. gid {
525
+ Some ( u) => {
526
+ if libc:: setgid ( u as libc:: gid_t ) != 0 {
527
+ fail ( & mut output) ;
528
+ }
524
529
}
530
+ None => { }
525
531
}
526
- None => { }
527
- }
528
- match config. uid {
529
- Some ( u) => {
530
- // When dropping privileges from root, the `setgroups` call will
531
- // remove any extraneous groups. If we don't call this, then
532
- // even though our uid has dropped, we may still have groups
533
- // that enable us to do super-user things. This will fail if we
534
- // aren't root, so don't bother checking the return value, this
535
- // is just done as an optimistic privilege dropping function.
536
- extern {
537
- fn setgroups ( ngroups : libc:: c_int ,
538
- ptr : * libc:: c_void ) -> libc:: c_int ;
539
- }
540
- let _ = setgroups ( 0 , 0 as * libc:: c_void ) ;
532
+ match config. uid {
533
+ Some ( u) => {
534
+ // When dropping privileges from root, the `setgroups` call will
535
+ // remove any extraneous groups. If we don't call this, then
536
+ // even though our uid has dropped, we may still have groups
537
+ // that enable us to do super-user things. This will fail if we
538
+ // aren't root, so don't bother checking the return value, this
539
+ // is just done as an optimistic privilege dropping function.
540
+ extern {
541
+ fn setgroups ( ngroups : libc:: c_int ,
542
+ ptr : * libc:: c_void ) -> libc:: c_int ;
543
+ }
544
+ let _ = setgroups ( 0 , 0 as * libc:: c_void ) ;
541
545
542
- if libc:: setuid ( u as libc:: uid_t ) != 0 {
543
- fail ( & mut output) ;
546
+ if libc:: setuid ( u as libc:: uid_t ) != 0 {
547
+ fail ( & mut output) ;
548
+ }
544
549
}
550
+ None => { }
551
+ }
552
+ if config. detach {
553
+ // Don't check the error of setsid because it fails if we're the
554
+ // process leader already. We just forked so it shouldn't return
555
+ // error, but ignore it anyway.
556
+ let _ = libc:: setsid ( ) ;
545
557
}
546
- None => { }
547
- }
548
- if config. detach {
549
- // Don't check the error of setsid because it fails if we're the
550
- // process leader already. We just forked so it shouldn't return
551
- // error, but ignore it anyway.
552
- let _ = libc:: setsid ( ) ;
553
- }
554
-
555
- with_dirp ( dir, |dirp| {
556
558
if !dirp. is_null ( ) && chdir ( dirp) == -1 {
557
559
fail ( & mut output) ;
558
560
}
559
- } ) ;
560
-
561
- with_envp ( env, |envp| {
562
561
if !envp. is_null ( ) {
563
562
set_environ ( envp) ;
564
563
}
565
- with_argv ( config. program , config. args , |argv| {
566
- let _ = execvp ( * argv, argv) ;
567
- fail ( & mut output) ;
568
- } )
564
+ let _ = execvp ( * argv, argv) ;
565
+ fail ( & mut output) ;
569
566
} )
570
- }
567
+ } )
571
568
}
572
569
573
570
#[ cfg( unix) ]
574
- fn with_argv < T > ( prog : & str , args : & [ ~str ] , cb : | * * libc:: c_char | -> T ) -> T {
571
+ fn with_argv < T > ( prog : & str , args : & [ ~str ] , cb : proc : ( * * libc:: c_char ) -> T ) -> T {
575
572
use std:: slice;
576
573
577
574
// We can't directly convert `str`s into `*char`s, as someone needs to hold
@@ -597,7 +594,7 @@ fn with_argv<T>(prog: &str, args: &[~str], cb: |**libc::c_char| -> T) -> T {
597
594
}
598
595
599
596
#[ cfg( unix) ]
600
- fn with_envp < T > ( env : Option < ~[ ( ~str , ~str ) ] > , cb : | * c_void| -> T ) -> T {
597
+ fn with_envp < T > ( env : Option < ~[ ( ~str , ~str ) ] > , cb : proc : ( * c_void ) -> T ) -> T {
601
598
use std:: slice;
602
599
603
600
// On posixy systems we can pass a char** for envp, which is a
@@ -645,6 +642,7 @@ fn with_envp<T>(env: Option<~[(~str, ~str)]>, cb: |*mut c_void| -> T) -> T {
645
642
}
646
643
}
647
644
645
+ #[ cfg( windows) ]
648
646
fn with_dirp < T > ( d : Option < & Path > , cb : |* libc:: c_char | -> T ) -> T {
649
647
match d {
650
648
Some ( dir) => dir. with_c_str ( |buf| cb ( buf) ) ,
0 commit comments