mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 12:07:46 +00:00
getgroups: Handle race conditions properly
This commit is contained in:
parent
412a81e7bf
commit
b125159535
1 changed files with 22 additions and 13 deletions
|
@ -72,19 +72,28 @@ extern "C" {
|
||||||
/// > to be used in a further call to getgroups().
|
/// > to be used in a further call to getgroups().
|
||||||
#[cfg(not(target_os = "redox"))]
|
#[cfg(not(target_os = "redox"))]
|
||||||
pub fn get_groups() -> IOResult<Vec<gid_t>> {
|
pub fn get_groups() -> IOResult<Vec<gid_t>> {
|
||||||
let ngroups = unsafe { getgroups(0, ptr::null_mut()) };
|
loop {
|
||||||
if ngroups == -1 {
|
let ngroups = match unsafe { getgroups(0, ptr::null_mut()) } {
|
||||||
return Err(IOError::last_os_error());
|
-1 => return Err(IOError::last_os_error()),
|
||||||
}
|
// Not just optimization; 0 would mess up the next call
|
||||||
let mut groups = vec![0; ngroups.try_into().unwrap()];
|
0 => return Ok(Vec::new()),
|
||||||
let ngroups = unsafe { getgroups(ngroups, groups.as_mut_ptr()) };
|
n => n,
|
||||||
if ngroups == -1 {
|
};
|
||||||
Err(IOError::last_os_error())
|
|
||||||
} else {
|
let mut groups = vec![0; ngroups.try_into().unwrap()];
|
||||||
let ngroups = ngroups.try_into().unwrap();
|
let res = unsafe { getgroups(ngroups, groups.as_mut_ptr()) };
|
||||||
assert!(ngroups <= groups.len());
|
if res == -1 {
|
||||||
groups.truncate(ngroups);
|
let err = IOError::last_os_error();
|
||||||
Ok(groups)
|
if err.raw_os_error() == Some(libc::EINVAL) {
|
||||||
|
// Number of groups changed, retry
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
groups.truncate(ngroups.try_into().unwrap());
|
||||||
|
return Ok(groups);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue