@@ -464,7 +464,7 @@ pub fn mkdir<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
464
464
/// fn main() {
465
465
/// let tmp_dir = TempDir::new("test_fifo").unwrap();
466
466
/// let fifo_path = tmp_dir.path().join("foo.pipe");
467
- ///
467
+ ///
468
468
/// // create new fifo and give read, write and execute rights to the owner
469
469
/// match unistd::mkfifo(&fifo_path, stat::S_IRWXU) {
470
470
/// Ok(_) => println!("created {:?}", fifo_path),
@@ -1047,6 +1047,51 @@ pub fn setgid(gid: Gid) -> Result<()> {
1047
1047
Errno :: result ( res) . map ( drop)
1048
1048
}
1049
1049
1050
+ /// Set the list of supplementary group IDs for the calling process.
1051
+ ///
1052
+ /// *Note:* On macOS, `getgroups()` may not return the same group list set by
1053
+ /// calling `setgroups()`. The use of `setgroups()` on macOS is 'highly
1054
+ /// discouraged' by Apple. Developers are referred to the `opendirectoryd`
1055
+ /// daemon and its set of APIs.
1056
+ ///
1057
+ /// [Further reading](http://man7.org/linux/man-pages/man2/getgroups.2.html)
1058
+ ///
1059
+ /// # Examples
1060
+ ///
1061
+ /// `setgroups` can be used when dropping privileges from the root user to a
1062
+ /// specific user and group. For example, given the user `www-data` with UID
1063
+ /// `33` and the group `backup` with the GID `34`, one could switch user as
1064
+ /// follows:
1065
+ /// ```
1066
+ /// let uid = Uid::from_raw(33);
1067
+ /// let gid = Gid::from_raw(34);
1068
+ /// setgroups(&[gid])?;
1069
+ /// setgid(gid)?;
1070
+ /// setuid(uid)?;
1071
+ /// ```
1072
+ pub fn setgroups ( groups : & [ Gid ] ) -> Result < ( ) > {
1073
+ cfg_if ! {
1074
+ if #[ cfg( any( target_os = "dragonfly" ,
1075
+ target_os = "freebsd" ,
1076
+ target_os = "ios" ,
1077
+ target_os = "macos" ,
1078
+ target_os = "netbsd" ,
1079
+ target_os = "openbsd" ) ) ] {
1080
+ type setgroups_ngroups_t = c_int;
1081
+ } else {
1082
+ type setgroups_ngroups_t = size_t;
1083
+ }
1084
+ }
1085
+ // FIXME: On the platforms we currently support, the `Gid` struct has the
1086
+ // same representation in memory as a bare `gid_t`. This is not necessarily
1087
+ // the case on all Rust platforms, though. See RFC 1785.
1088
+ let res = unsafe {
1089
+ libc:: setgroups ( groups. len ( ) as setgroups_ngroups_t , groups. as_ptr ( ) as * const gid_t )
1090
+ } ;
1091
+
1092
+ Errno :: result ( res) . map ( |_| ( ) )
1093
+ }
1094
+
1050
1095
/// Suspend the thread until a signal is received
1051
1096
///
1052
1097
/// See also [pause(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pause.html)
0 commit comments