1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use std::ffi::CStr;
use std::ptr;
use crate::errno::{Error,Result};
use crate::posix::unistd;
use crate::stdlib::realloc;
use crate::util::zeroed;
pub struct Group {
grp: libc::group,
buf: *mut libc::c_void
}
impl Group {
pub fn gr_name(&self) -> &CStr {
unsafe { CStr::from_ptr(self.grp.gr_name) }
}
pub fn gr_passwd(&self) -> &CStr {
unsafe { CStr::from_ptr(self.grp.gr_passwd) }
}
pub fn gr_gid(&self) -> libc::gid_t {
self.grp.gr_gid
}
pub fn gr_mem(&self) {
unimplemented!("Group.gr_mem() is not implemented")
}
}
impl Drop for Group {
fn drop(&mut self) {
unsafe { libc::free(self.buf); }
}
}
pub fn getgid() -> libc::gid_t {
unsafe { libc::getgid() }
}
pub fn getgrgid(gid: libc::gid_t) -> Result<Option<Group>> {
unsafe {
let mut grp: libc::group = zeroed();
let mut result: *mut libc::group = ptr::null_mut();
let mut bufsize = getgr_r_size_max();
let mut buf = ptr::null_mut();
loop {
buf = realloc(buf, bufsize)?;
let buf_i8 = buf as *mut i8;
let rv = libc::getgrgid_r(gid, &mut grp, buf_i8, bufsize, &mut result);
if !result.is_null() {
break;
}
match rv {
0 => return Ok(None),
_ => {
if rv != libc::ERANGE {
return Err(Error::new(rv));
}
bufsize *= 2;
}
}
}
Ok(Some(Group { grp, buf }))
}
}
fn getgr_r_size_max() -> usize {
use libc::_SC_GETGR_R_SIZE_MAX;
if let Ok(rv) = unistd::sysconf(_SC_GETGR_R_SIZE_MAX) {
return rv as usize;
}
libc::BUFSIZ as usize
}