@@ -6,14 +6,13 @@ use fcntl::{fcntl, OFlag, O_CLOEXEC, FD_CLOEXEC};
6
6
use fcntl:: FcntlArg :: F_SETFD ;
7
7
use libc:: { self , c_char, c_void, c_int, c_long, c_uint, size_t, pid_t, off_t,
8
8
uid_t, gid_t, mode_t} ;
9
- use std:: mem;
9
+ use std:: { self , fmt , mem} ;
10
10
use std:: ffi:: { CString , CStr , OsString , OsStr } ;
11
11
use std:: os:: unix:: ffi:: { OsStringExt , OsStrExt } ;
12
12
use std:: os:: unix:: io:: RawFd ;
13
13
use std:: path:: { PathBuf } ;
14
14
use void:: Void ;
15
15
use sys:: stat:: Mode ;
16
- use std:: fmt;
17
16
18
17
#[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
19
18
pub use self :: pivot_root:: * ;
@@ -1058,32 +1057,32 @@ pub fn setgid(gid: Gid) -> Result<()> {
1058
1057
/// [Further reading](http://pubs.opengroup.org/onlinepubs/009695399/functions/getgroups.html)
1059
1058
pub fn getgroups ( ) -> Result < Vec < Gid > > {
1060
1059
// 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 ( ) ) } ;
1064
1061
1065
1062
// Now actually get the groups. We try multiple times in case the number of
1066
1063
// 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 ) ;
1069
1066
loop {
1070
1067
// FIXME: On the platforms we currently support, the `Gid` struct has
1071
1068
// the same representation in memory as a bare `gid_t`. This is not
1072
1069
// 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
+ } ;
1074
1073
1075
1074
match Errno :: result ( ret) {
1076
1075
Ok ( s) => {
1077
1076
unsafe { groups. set_len ( s as usize ) } ;
1078
1077
return Ok ( groups) ;
1079
1078
} ,
1080
1079
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.
1083
1083
let cap = groups. capacity ( ) ;
1084
1084
unsafe { groups. set_len ( cap) } ;
1085
1085
groups. reserve ( 1 ) ;
1086
- size = groups. capacity ( ) as c_int ;
1087
1086
} ,
1088
1087
Err ( e) => return Err ( e)
1089
1088
}
@@ -1103,7 +1102,7 @@ pub fn getgroups() -> Result<Vec<Gid>> {
1103
1102
///
1104
1103
/// `setgroups` can be used when dropping privileges from the root user to a
1105
1104
/// 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
1107
1106
/// follows:
1108
1107
/// ```
1109
1108
/// let uid = Uid::from_raw(33);
@@ -1135,9 +1134,10 @@ pub fn setgroups(groups: &[Gid]) -> Result<()> {
1135
1134
Errno :: result ( res) . map ( |_| ( ) )
1136
1135
}
1137
1136
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.
1141
1141
///
1142
1142
/// [Further reading](http://man7.org/linux/man-pages/man3/getgrouplist.3.html)
1143
1143
///
@@ -1173,6 +1173,7 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
1173
1173
groups. as_mut_ptr ( ) as * mut getgrouplist_group_t ,
1174
1174
& mut ngroups)
1175
1175
} ;
1176
+
1176
1177
// BSD systems only return 0 or -1, Linux returns ngroups on success.
1177
1178
if ret >= 0 {
1178
1179
unsafe { groups. set_len ( ngroups as usize ) } ;
@@ -1199,9 +1200,11 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
1199
1200
}
1200
1201
}
1201
1202
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.
1205
1208
///
1206
1209
/// [Further reading](http://man7.org/linux/man-pages/man3/initgroups.3.html)
1207
1210
///
@@ -1211,7 +1214,7 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
1211
1214
/// another user. For example, given the user `www-data`, we could look up the
1212
1215
/// UID and GID for the user in the system's password database (usually found
1213
1216
/// 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:
1215
1218
/// ```
1216
1219
/// let user = CString::new("www-data").unwrap();
1217
1220
/// let uid = Uid::from_raw(33);
0 commit comments