Skip to content

Commit a75f3fa

Browse files
committed
unistd: groups: Respond to minor PR feedback items
1 parent 57246cf commit a75f3fa

File tree

2 files changed

+29
-27
lines changed

2 files changed

+29
-27
lines changed

src/unistd.rs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ use fcntl::{fcntl, OFlag, O_CLOEXEC, FD_CLOEXEC};
66
use fcntl::FcntlArg::F_SETFD;
77
use 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};
1010
use std::ffi::{CString, CStr, OsString, OsStr};
1111
use std::os::unix::ffi::{OsStringExt, OsStrExt};
1212
use std::os::unix::io::RawFd;
1313
use std::path::{PathBuf};
1414
use void::Void;
1515
use sys::stat::Mode;
16-
use std::fmt;
1716

1817
#[cfg(any(target_os = "android", target_os = "linux"))]
1918
pub 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)
10591058
pub 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);

test/test_unistd.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use nix::unistd::*;
44
use nix::unistd::ForkResult::*;
55
use nix::sys::wait::*;
66
use nix::sys::stat;
7-
use std::{env, iter};
7+
use std::{self, env, iter};
88
use std::ffi::CString;
99
use std::fs::File;
1010
use std::io::Write;
@@ -128,11 +128,10 @@ mod linux_android {
128128
fn test_setgroups() {
129129
// Skip this test when not run as root as `setgroups()` requires root.
130130
if !Uid::current().is_root() {
131-
use std::io;
132-
let stderr = io::stderr();
131+
let stderr = std::io::stderr();
133132
let mut handle = stderr.lock();
134133
writeln!(handle, "test_setgroups requires root privileges. Skipping test.").unwrap();
135-
return
134+
return;
136135
}
137136

138137
#[allow(unused_variables)]
@@ -159,11 +158,10 @@ fn test_initgroups() {
159158
// Skip this test when not run as root as `initgroups()` and `setgroups()`
160159
// require root.
161160
if !Uid::current().is_root() {
162-
use std::io;
163-
let stderr = io::stderr();
161+
let stderr = std::io::stderr();
164162
let mut handle = stderr.lock();
165163
writeln!(handle, "test_initgroups requires root privileges. Skipping test.").unwrap();
166-
return
164+
return;
167165
}
168166

169167
#[allow(unused_variables)]
@@ -175,7 +173,8 @@ fn test_initgroups() {
175173
// It doesn't matter if the root user is not called "root" or if a user
176174
// called "root" doesn't exist. We are just checking that the extra,
177175
// made-up group, `123`, is set.
178-
// FIXME: This only tests half of initgroups' functionality.
176+
// FIXME: Test the other half of initgroups' functionality: whether the
177+
// groups that the user belongs to are also set.
179178
let user = CString::new("root").unwrap();
180179
let group = Gid::from_raw(123);
181180
let group_list = getgrouplist(&user, group).unwrap();

0 commit comments

Comments
 (0)