@@ -7,7 +7,7 @@ use fcntl::FcntlArg::F_SETFD;
77use libc:: { self , c_char, c_void, c_int, c_long, c_uint, size_t, pid_t, off_t,
88 uid_t, gid_t, mode_t, PATH_MAX } ;
99use std:: { fmt, mem, ptr} ;
10- use std:: ffi:: { CString , CStr , OsString , OsStr } ;
10+ use std:: ffi:: { CStr , OsString , OsStr } ;
1111use std:: os:: unix:: ffi:: { OsStringExt , OsStrExt } ;
1212use std:: os:: unix:: io:: RawFd ;
1313use std:: path:: PathBuf ;
@@ -675,10 +675,9 @@ pub fn fchownat<P: ?Sized + NixPath>(
675675 Errno :: result ( res) . map ( drop)
676676}
677677
678- fn to_exec_array ( args : & [ CString ] ) -> Vec < * const c_char > {
679- let mut args_p: Vec < * const c_char > = args. iter ( ) . map ( |s| s. as_ptr ( ) ) . collect ( ) ;
680- args_p. push ( ptr:: null ( ) ) ;
681- args_p
678+ fn to_exec_array ( args : & [ & CStr ] ) -> Vec < * const c_char > {
679+ use std:: iter:: once;
680+ args. iter ( ) . map ( |s| s. as_ptr ( ) ) . chain ( once ( ptr:: null ( ) ) ) . collect ( )
682681}
683682
684683/// Replace the current process image with a new one (see
@@ -688,7 +687,7 @@ fn to_exec_array(args: &[CString]) -> Vec<*const c_char> {
688687/// performs the same action but does not allow for customization of the
689688/// environment for the new process.
690689#[ inline]
691- pub fn execv ( path : & CString , argv : & [ CString ] ) -> Result < Void > {
690+ pub fn execv ( path : & CStr , argv : & [ & CStr ] ) -> Result < Void > {
692691 let args_p = to_exec_array ( argv) ;
693692
694693 unsafe {
@@ -712,7 +711,7 @@ pub fn execv(path: &CString, argv: &[CString]) -> Result<Void> {
712711/// in the `args` list is an argument to the new process. Each element in the
713712/// `env` list should be a string in the form "key=value".
714713#[ inline]
715- pub fn execve ( path : & CString , args : & [ CString ] , env : & [ CString ] ) -> Result < Void > {
714+ pub fn execve ( path : & CStr , args : & [ & CStr ] , env : & [ & CStr ] ) -> Result < Void > {
716715 let args_p = to_exec_array ( args) ;
717716 let env_p = to_exec_array ( env) ;
718717
@@ -733,7 +732,7 @@ pub fn execve(path: &CString, args: &[CString], env: &[CString]) -> Result<Void>
733732/// would not work if "bash" was specified for the path argument, but `execvp`
734733/// would assuming that a bash executable was on the system `PATH`.
735734#[ inline]
736- pub fn execvp ( filename : & CString , args : & [ CString ] ) -> Result < Void > {
735+ pub fn execvp ( filename : & CStr , args : & [ & CStr ] ) -> Result < Void > {
737736 let args_p = to_exec_array ( args) ;
738737
739738 unsafe {
@@ -753,7 +752,7 @@ pub fn execvp(filename: &CString, args: &[CString]) -> Result<Void> {
753752#[ cfg( any( target_os = "haiku" ,
754753 target_os = "linux" ,
755754 target_os = "openbsd" ) ) ]
756- pub fn execvpe ( filename : & CString , args : & [ CString ] , env : & [ CString ] ) -> Result < Void > {
755+ pub fn execvpe ( filename : & CStr , args : & [ & CStr ] , env : & [ & CStr ] ) -> Result < Void > {
757756 let args_p = to_exec_array ( args) ;
758757 let env_p = to_exec_array ( env) ;
759758
@@ -781,7 +780,7 @@ pub fn execvpe(filename: &CString, args: &[CString], env: &[CString]) -> Result<
781780 target_os = "linux" ,
782781 target_os = "freebsd" ) ) ]
783782#[ inline]
784- pub fn fexecve ( fd : RawFd , args : & [ CString ] , env : & [ CString ] ) -> Result < Void > {
783+ pub fn fexecve ( fd : RawFd , args : & [ & CStr ] , env : & [ & CStr ] ) -> Result < Void > {
785784 let args_p = to_exec_array ( args) ;
786785 let env_p = to_exec_array ( env) ;
787786
@@ -804,8 +803,8 @@ pub fn fexecve(fd: RawFd, args: &[CString], env: &[CString]) -> Result<Void> {
804803/// is referenced as a file descriptor to the base directory plus a path.
805804#[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
806805#[ inline]
807- pub fn execveat ( dirfd : RawFd , pathname : & CString , args : & [ CString ] ,
808- env : & [ CString ] , flags : super :: fcntl:: AtFlags ) -> Result < Void > {
806+ pub fn execveat ( dirfd : RawFd , pathname : & CStr , args : & [ & CStr ] ,
807+ env : & [ & CStr ] , flags : super :: fcntl:: AtFlags ) -> Result < Void > {
809808 let args_p = to_exec_array ( args) ;
810809 let env_p = to_exec_array ( env) ;
811810
@@ -1486,19 +1485,8 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
14861485 // BSD systems will still fill the groups buffer with as many
14871486 // groups as possible, but Linux manpages do not mention this
14881487 // behavior.
1489-
1490- let cap = groups. capacity ( ) ;
1491- if cap >= ngroups_max as usize {
1492- // We already have the largest capacity we can, give up
1493- return Err ( Error :: invalid_argument ( ) ) ;
1494- }
1495-
1496- // Reserve space for at least ngroups
1497- groups. reserve ( ngroups as usize ) ;
1498-
1499- // Even if the buffer gets resized to bigger than ngroups_max,
1500- // don't ever ask for more than ngroups_max groups
1501- ngroups = min ( ngroups_max, groups. capacity ( ) as c_int ) ;
1488+ reserve_double_buffer_size ( & mut groups, ngroups_max as usize )
1489+ . or_else ( |_| Err ( Error :: invalid_argument ( ) ) ) ?;
15021490 }
15031491 }
15041492}
0 commit comments