@@ -6,14 +6,13 @@ use fcntl::{fcntl, OFlag, O_CLOEXEC, FD_CLOEXEC};
66use 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} ;
9- use std:: mem;
9+ use std:: { self , fmt , mem} ;
1010use std:: ffi:: { CString , CStr , OsString , OsStr } ;
1111use std:: os:: unix:: ffi:: { OsStringExt , OsStrExt } ;
1212use std:: os:: unix:: io:: RawFd ;
1313use std:: path:: { PathBuf } ;
1414use void:: Void ;
1515use sys:: stat:: Mode ;
16- use std:: fmt;
1716
1817#[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
1918pub use self :: pivot_root:: * ;
@@ -1058,32 +1057,32 @@ pub fn setgid(gid: Gid) -> Result<()> {
10581057/// [Further reading](http://pubs.opengroup.org/onlinepubs/009695399/functions/getgroups.html)
10591058pub fn getgroups ( ) -> Result < Vec < Gid > > {
10601059 // First get the number of groups so we can size our Vec
1061- use std:: ptr;
1062- let ret = unsafe { libc:: getgroups ( 0 , ptr:: null_mut ( ) ) } ;
1063- let mut size = Errno :: result ( ret) ?;
1060+ let ret = unsafe { libc:: getgroups ( 0 , std:: ptr:: null_mut ( ) ) } ;
10641061
10651062 // Now actually get the groups. We try multiple times in case the number of
10661063 // groups has changed since the first call to getgroups() and the buffer is
1067- // now too small
1068- let mut groups = Vec :: < Gid > :: with_capacity ( size as usize ) ;
1064+ // now too small.
1065+ let mut groups = Vec :: < Gid > :: with_capacity ( Errno :: result ( ret ) ? as usize ) ;
10691066 loop {
10701067 // FIXME: On the platforms we currently support, the `Gid` struct has
10711068 // the same representation in memory as a bare `gid_t`. This is not
10721069 // necessarily the case on all Rust platforms, though. See RFC 1785.
1073- let ret = unsafe { libc:: getgroups ( size, groups. as_mut_ptr ( ) as * mut gid_t ) } ;
1070+ let ret = unsafe {
1071+ libc:: getgroups ( groups. capacity ( ) as c_int , groups. as_mut_ptr ( ) as * mut gid_t )
1072+ } ;
10741073
10751074 match Errno :: result ( ret) {
10761075 Ok ( s) => {
10771076 unsafe { groups. set_len ( s as usize ) } ;
10781077 return Ok ( groups) ;
10791078 } ,
10801079 Err ( Error :: Sys ( Errno :: EINVAL ) ) => {
1081- // EINVAL indicates that size was too small, so trigger a
1082- // resize of the groups Vec and try again...
1080+ // EINVAL indicates that the buffer size was too small. Trigger
1081+ // the internal buffer resizing logic of `Vec` by requiring
1082+ // more space than the current capacity.
10831083 let cap = groups. capacity ( ) ;
10841084 unsafe { groups. set_len ( cap) } ;
10851085 groups. reserve ( 1 ) ;
1086- size = groups. capacity ( ) as c_int ;
10871086 } ,
10881087 Err ( e) => return Err ( e)
10891088 }
@@ -1103,7 +1102,7 @@ pub fn getgroups() -> Result<Vec<Gid>> {
11031102///
11041103/// `setgroups` can be used when dropping privileges from the root user to a
11051104/// specific user and group. For example, given the user `www-data` with UID
1106- /// `33` and the group `backup` with the GID `34`, one could switch user as
1105+ /// `33` and the group `backup` with the GID `34`, one could switch the user as
11071106/// follows:
11081107/// ```
11091108/// let uid = Uid::from_raw(33);
@@ -1135,9 +1134,10 @@ pub fn setgroups(groups: &[Gid]) -> Result<()> {
11351134 Errno :: result ( res) . map ( |_| ( ) )
11361135}
11371136
1138- /// Calculate the supplementary group access list. Gets the group IDs of all
1139- /// groups that `user` is a member of. The additional group `group` is also
1140- /// added to the list.
1137+ /// Calculate the supplementary group access list.
1138+ ///
1139+ /// Gets the group IDs of all groups that `user` is a member of. The additional
1140+ /// group `group` is also added to the list.
11411141///
11421142/// [Further reading](http://man7.org/linux/man-pages/man3/getgrouplist.3.html)
11431143///
@@ -1173,6 +1173,7 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
11731173 groups. as_mut_ptr ( ) as * mut getgrouplist_group_t ,
11741174 & mut ngroups)
11751175 } ;
1176+
11761177 // BSD systems only return 0 or -1, Linux returns ngroups on success.
11771178 if ret >= 0 {
11781179 unsafe { groups. set_len ( ngroups as usize ) } ;
@@ -1199,9 +1200,11 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
11991200 }
12001201}
12011202
1202- /// Initialize the supplementary group access list. Sets the supplementary
1203- /// group IDs for the calling process using all groups that `user` is a member
1204- /// of. The additional group `group` is also added to the list.
1203+ /// Initialize the supplementary group access list.
1204+ ///
1205+ /// Sets the supplementary group IDs for the calling process using all groups
1206+ /// that `user` is a member of. The additional group `group` is also added to
1207+ /// the list.
12051208///
12061209/// [Further reading](http://man7.org/linux/man-pages/man3/initgroups.3.html)
12071210///
@@ -1211,7 +1214,7 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
12111214/// another user. For example, given the user `www-data`, we could look up the
12121215/// UID and GID for the user in the system's password database (usually found
12131216/// in `/etc/passwd`). If the `www-data` user's UID and GID were `33` and `33`,
1214- /// respectively, one could switch user as follows:
1217+ /// respectively, one could switch the user as follows:
12151218/// ```
12161219/// let user = CString::new("www-data").unwrap();
12171220/// let uid = Uid::from_raw(33);
0 commit comments