aboutsummaryrefslogtreecommitdiff
path: root/src/unistd.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/unistd.rs')
-rw-r--r--src/unistd.rs1578
1 files changed, 1086 insertions, 492 deletions
diff --git a/src/unistd.rs b/src/unistd.rs
index ca07b34..bb9f1c1 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -35,6 +35,7 @@ use std::ffi::{CString, OsStr};
use std::os::unix::ffi::OsStrExt;
use std::os::unix::ffi::OsStringExt;
use std::os::unix::io::RawFd;
+use std::os::unix::io::{AsFd, AsRawFd};
use std::path::PathBuf;
use std::{fmt, mem, ptr};
@@ -217,7 +218,6 @@ impl fmt::Display for Pid {
}
}
-
/// Represents the successful result of calling `fork`
///
/// When `fork` is called, the process continues execution in the parent process
@@ -230,7 +230,6 @@ pub enum ForkResult {
}
impl ForkResult {
-
/// Return `true` if this is the child process of the `fork()`
#[inline]
pub fn is_child(self) -> bool {
@@ -478,9 +477,8 @@ fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
/// pages for additional details on possible failure cases.
#[inline]
pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe { libc::chdir(cstr.as_ptr()) }
- })?;
+ let res =
+ path.with_nix_path(|cstr| unsafe { libc::chdir(cstr.as_ptr()) })?;
Errno::result(res).map(drop)
}
@@ -527,8 +525,8 @@ pub fn fchdir(dirfd: RawFd) -> Result<()> {
/// ```
#[inline]
pub fn mkdir<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe { libc::mkdir(cstr.as_ptr(), mode.bits() as mode_t) }
+ let res = path.with_nix_path(|cstr| unsafe {
+ libc::mkdir(cstr.as_ptr(), mode.bits() as mode_t)
})?;
Errno::result(res).map(drop)
@@ -566,8 +564,8 @@ pub fn mkdir<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
#[inline]
#[cfg(not(target_os = "redox"))] // RedoxFS does not support fifo yet
pub fn mkfifo<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe { libc::mkfifo(cstr.as_ptr(), mode.bits() as mode_t) }
+ let res = path.with_nix_path(|cstr| unsafe {
+ libc::mkfifo(cstr.as_ptr(), mode.bits() as mode_t)
})?;
Errno::result(res).map(drop)
@@ -585,9 +583,17 @@ pub fn mkfifo<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
// mkfifoat is not implemented in OSX or android
#[inline]
#[cfg(not(any(
- target_os = "macos", target_os = "ios", target_os = "haiku",
- target_os = "android", target_os = "redox")))]
-pub fn mkfifoat<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P, mode: Mode) -> Result<()> {
+ target_os = "macos",
+ target_os = "ios",
+ target_os = "haiku",
+ target_os = "android",
+ target_os = "redox"
+)))]
+pub fn mkfifoat<P: ?Sized + NixPath>(
+ dirfd: Option<RawFd>,
+ path: &P,
+ mode: Mode,
+) -> Result<()> {
let res = path.with_nix_path(|cstr| unsafe {
libc::mkfifoat(at_rawfd(dirfd), cstr.as_ptr(), mode.bits() as mode_t)
})?;
@@ -608,19 +614,17 @@ pub fn mkfifoat<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P, mode: Mode)
pub fn symlinkat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
path1: &P1,
dirfd: Option<RawFd>,
- path2: &P2) -> Result<()> {
- let res =
- path1.with_nix_path(|path1| {
- path2.with_nix_path(|path2| {
- unsafe {
- libc::symlinkat(
- path1.as_ptr(),
- dirfd.unwrap_or(libc::AT_FDCWD),
- path2.as_ptr()
- )
- }
- })
- })??;
+ path2: &P2,
+) -> Result<()> {
+ let res = path1.with_nix_path(|path1| {
+ path2.with_nix_path(|path2| unsafe {
+ libc::symlinkat(
+ path1.as_ptr(),
+ dirfd.unwrap_or(libc::AT_FDCWD),
+ path2.as_ptr(),
+ )
+ })
+ })??;
Errno::result(res).map(drop)
}
}
@@ -670,7 +674,9 @@ pub fn getcwd() -> Result<PathBuf> {
// To safely handle this we start with a reasonable size (512 bytes)
// and double the buffer size upon every error
if !libc::getcwd(ptr, buf.capacity()).is_null() {
- let len = CStr::from_ptr(buf.as_ptr() as *const c_char).to_bytes().len();
+ let len = CStr::from_ptr(buf.as_ptr() as *const c_char)
+ .to_bytes()
+ .len();
buf.set_len(len);
buf.shrink_to_fit();
return Ok(PathBuf::from(OsString::from_vec(buf)));
@@ -680,7 +686,7 @@ pub fn getcwd() -> Result<PathBuf> {
if error != Errno::ERANGE {
return Err(error);
}
- }
+ }
// Trigger the internal buffer resizing logic.
reserve_double_buffer_size(&mut buf, PATH_MAX as usize)?;
@@ -695,13 +701,15 @@ feature! {
/// Computes the raw UID and GID values to pass to a `*chown` call.
// The cast is not unnecessary on all platforms.
#[allow(clippy::unnecessary_cast)]
-fn chown_raw_ids(owner: Option<Uid>, group: Option<Gid>) -> (libc::uid_t, libc::gid_t) {
+fn chown_raw_ids(owner: Option<Uid>, group: Option<Gid>) -> (uid_t, gid_t) {
// According to the POSIX specification, -1 is used to indicate that owner and group
// are not to be changed. Since uid_t and gid_t are unsigned types, we have to wrap
// around to get -1.
- let uid = owner.map(Into::into)
+ let uid = owner
+ .map(Into::into)
.unwrap_or_else(|| (0 as uid_t).wrapping_sub(1));
- let gid = group.map(Into::into)
+ let gid = group
+ .map(Into::into)
.unwrap_or_else(|| (0 as gid_t).wrapping_sub(1));
(uid, gid)
}
@@ -714,7 +722,11 @@ fn chown_raw_ids(owner: Option<Uid>, group: Option<Gid>) -> (libc::uid_t, libc::
/// provided for that argument. Ownership change will be attempted for the path
/// only if `Some` owner/group is provided.
#[inline]
-pub fn chown<P: ?Sized + NixPath>(path: &P, owner: Option<Uid>, group: Option<Gid>) -> Result<()> {
+pub fn chown<P: ?Sized + NixPath>(
+ path: &P,
+ owner: Option<Uid>,
+ group: Option<Gid>,
+) -> Result<()> {
let res = path.with_nix_path(|cstr| {
let (uid, gid) = chown_raw_ids(owner, group);
unsafe { libc::chown(cstr.as_ptr(), uid, gid) }
@@ -773,15 +785,19 @@ pub fn fchownat<P: ?Sized + NixPath>(
group: Option<Gid>,
flag: FchownatFlags,
) -> Result<()> {
- let atflag =
- match flag {
- FchownatFlags::FollowSymlink => AtFlags::empty(),
- FchownatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW,
- };
+ let atflag = match flag {
+ FchownatFlags::FollowSymlink => AtFlags::empty(),
+ FchownatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW,
+ };
let res = path.with_nix_path(|cstr| unsafe {
let (uid, gid) = chown_raw_ids(owner, group);
- libc::fchownat(at_rawfd(dirfd), cstr.as_ptr(), uid, gid,
- atflag.bits() as libc::c_int)
+ libc::fchownat(
+ at_rawfd(dirfd),
+ cstr.as_ptr(),
+ uid,
+ gid,
+ atflag.bits() as libc::c_int,
+ )
})?;
Errno::result(res).map(drop)
@@ -808,14 +824,11 @@ fn to_exec_array<S: AsRef<CStr>>(args: &[S]) -> Vec<*const c_char> {
pub fn execv<S: AsRef<CStr>>(path: &CStr, argv: &[S]) -> Result<Infallible> {
let args_p = to_exec_array(argv);
- unsafe {
- libc::execv(path.as_ptr(), args_p.as_ptr())
- };
+ unsafe { libc::execv(path.as_ptr(), args_p.as_ptr()) };
Err(Errno::last())
}
-
/// Replace the current process image with a new one (see
/// [execve(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)).
///
@@ -829,13 +842,15 @@ pub fn execv<S: AsRef<CStr>>(path: &CStr, argv: &[S]) -> Result<Infallible> {
/// in the `args` list is an argument to the new process. Each element in the
/// `env` list should be a string in the form "key=value".
#[inline]
-pub fn execve<SA: AsRef<CStr>, SE: AsRef<CStr>>(path: &CStr, args: &[SA], env: &[SE]) -> Result<Infallible> {
+pub fn execve<SA: AsRef<CStr>, SE: AsRef<CStr>>(
+ path: &CStr,
+ args: &[SA],
+ env: &[SE],
+) -> Result<Infallible> {
let args_p = to_exec_array(args);
let env_p = to_exec_array(env);
- unsafe {
- libc::execve(path.as_ptr(), args_p.as_ptr(), env_p.as_ptr())
- };
+ unsafe { libc::execve(path.as_ptr(), args_p.as_ptr(), env_p.as_ptr()) };
Err(Errno::last())
}
@@ -850,12 +865,13 @@ pub fn execve<SA: AsRef<CStr>, SE: AsRef<CStr>>(path: &CStr, args: &[SA], env: &
/// would not work if "bash" was specified for the path argument, but `execvp`
/// would assuming that a bash executable was on the system `PATH`.
#[inline]
-pub fn execvp<S: AsRef<CStr>>(filename: &CStr, args: &[S]) -> Result<Infallible> {
+pub fn execvp<S: AsRef<CStr>>(
+ filename: &CStr,
+ args: &[S],
+) -> Result<Infallible> {
let args_p = to_exec_array(args);
- unsafe {
- libc::execvp(filename.as_ptr(), args_p.as_ptr())
- };
+ unsafe { libc::execvp(filename.as_ptr(), args_p.as_ptr()) };
Err(Errno::last())
}
@@ -867,10 +883,12 @@ pub fn execvp<S: AsRef<CStr>>(filename: &CStr, args: &[S]) -> Result<Infallible>
/// This functions like a combination of `execvp(2)` and `execve(2)` to pass an
/// environment and have a search path. See these two for additional
/// information.
-#[cfg(any(target_os = "haiku",
- target_os = "linux",
- target_os = "openbsd"))]
-pub fn execvpe<SA: AsRef<CStr>, SE: AsRef<CStr>>(filename: &CStr, args: &[SA], env: &[SE]) -> Result<Infallible> {
+#[cfg(any(target_os = "haiku", target_os = "linux", target_os = "openbsd"))]
+pub fn execvpe<SA: AsRef<CStr>, SE: AsRef<CStr>>(
+ filename: &CStr,
+ args: &[SA],
+ env: &[SE],
+) -> Result<Infallible> {
let args_p = to_exec_array(args);
let env_p = to_exec_array(env);
@@ -891,18 +909,22 @@ pub fn execvpe<SA: AsRef<CStr>, SE: AsRef<CStr>>(filename: &CStr, args: &[SA], e
///
/// This function is similar to `execve`, except that the program to be executed
/// is referenced as a file descriptor instead of a path.
-#[cfg(any(target_os = "android",
- target_os = "linux",
- target_os = "dragonfly",
- target_os = "freebsd"))]
+#[cfg(any(
+ target_os = "android",
+ target_os = "linux",
+ target_os = "dragonfly",
+ target_os = "freebsd"
+))]
#[inline]
-pub fn fexecve<SA: AsRef<CStr> ,SE: AsRef<CStr>>(fd: RawFd, args: &[SA], env: &[SE]) -> Result<Infallible> {
+pub fn fexecve<SA: AsRef<CStr>, SE: AsRef<CStr>>(
+ fd: RawFd,
+ args: &[SA],
+ env: &[SE],
+) -> Result<Infallible> {
let args_p = to_exec_array(args);
let env_p = to_exec_array(env);
- unsafe {
- libc::fexecve(fd, args_p.as_ptr(), env_p.as_ptr())
- };
+ unsafe { libc::fexecve(fd, args_p.as_ptr(), env_p.as_ptr()) };
Err(Errno::last())
}
@@ -919,14 +941,25 @@ pub fn fexecve<SA: AsRef<CStr> ,SE: AsRef<CStr>>(fd: RawFd, args: &[SA], env: &[
/// is referenced as a file descriptor to the base directory plus a path.
#[cfg(any(target_os = "android", target_os = "linux"))]
#[inline]
-pub fn execveat<SA: AsRef<CStr>,SE: AsRef<CStr>>(dirfd: RawFd, pathname: &CStr, args: &[SA],
- env: &[SE], flags: super::fcntl::AtFlags) -> Result<Infallible> {
+pub fn execveat<SA: AsRef<CStr>, SE: AsRef<CStr>>(
+ dirfd: RawFd,
+ pathname: &CStr,
+ args: &[SA],
+ env: &[SE],
+ flags: super::fcntl::AtFlags,
+) -> Result<Infallible> {
let args_p = to_exec_array(args);
let env_p = to_exec_array(env);
unsafe {
- libc::syscall(libc::SYS_execveat, dirfd, pathname.as_ptr(),
- args_p.as_ptr(), env_p.as_ptr(), flags);
+ libc::syscall(
+ libc::SYS_execveat,
+ dirfd,
+ pathname.as_ptr(),
+ args_p.as_ptr(),
+ env_p.as_ptr(),
+ flags,
+ );
};
Err(Errno::last())
@@ -957,14 +990,16 @@ pub fn execveat<SA: AsRef<CStr>,SE: AsRef<CStr>>(dirfd: RawFd, pathname: &CStr,
/// descriptors will remain identical after daemonizing.
/// * `noclose = false`: The process' stdin, stdout, and stderr will point to
/// `/dev/null` after daemonizing.
-#[cfg(any(target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris"))]
+#[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "solaris"
+))]
pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> {
let res = unsafe { libc::daemon(nochdir as c_int, noclose as c_int) };
Errno::result(res).map(drop)
@@ -990,6 +1025,7 @@ pub fn sethostname<S: AsRef<OsStr>>(name: S) -> Result<()> {
target_os = "illumos",
target_os = "ios",
target_os = "macos",
+ target_os = "aix",
target_os = "solaris", ))] {
type sethostname_len_t = c_int;
} else {
@@ -1106,23 +1142,27 @@ pub enum Whence {
/// Specify an offset relative to the next location in the file greater than or
/// equal to offset that contains some data. If offset points to
/// some data, then the file offset is set to offset.
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ ))]
SeekData = libc::SEEK_DATA,
/// Specify an offset relative to the next hole in the file greater than
/// or equal to offset. If offset points into the middle of a hole, then
/// the file offset should be set to offset. If there is no hole past offset,
/// then the file offset should be adjusted to the end of the file (i.e., there
/// is an implicit hole at the end of any file).
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris"))]
- SeekHole = libc::SEEK_HOLE
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ ))]
+ SeekHole = libc::SEEK_HOLE,
}
/// Move the read/write file offset.
@@ -1135,7 +1175,11 @@ pub fn lseek(fd: RawFd, offset: off_t, whence: Whence) -> Result<off_t> {
}
#[cfg(any(target_os = "linux", target_os = "android"))]
-pub fn lseek64(fd: RawFd, offset: libc::off64_t, whence: Whence) -> Result<libc::off64_t> {
+pub fn lseek64(
+ fd: RawFd,
+ offset: libc::off64_t,
+ whence: Whence,
+) -> Result<libc::off64_t> {
let res = unsafe { libc::lseek64(fd, offset, whence as i32) };
Errno::result(res).map(|r| r as libc::off64_t)
@@ -1163,27 +1207,34 @@ feature! {
/// created:
///
/// - `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors.
-#[cfg_attr(target_os = "linux", doc = "- `O_DIRECT`: Create a pipe that performs I/O in \"packet\" mode.")]
-#[cfg_attr(target_os = "netbsd", doc = "- `O_NOSIGPIPE`: Return `EPIPE` instead of raising `SIGPIPE`.")]
+#[cfg_attr(
+ target_os = "linux",
+ doc = "- `O_DIRECT`: Create a pipe that performs I/O in \"packet\" mode."
+)]
+#[cfg_attr(
+ target_os = "netbsd",
+ doc = "- `O_NOSIGPIPE`: Return `EPIPE` instead of raising `SIGPIPE`."
+)]
/// - `O_NONBLOCK`: Set the non-blocking flag for the ends of the pipe.
///
/// See also [pipe(2)](https://man7.org/linux/man-pages/man2/pipe.2.html)
-#[cfg(any(target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "redox",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris"))]
+#[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "emscripten",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "redox",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "solaris"
+))]
pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
let mut fds = mem::MaybeUninit::<[c_int; 2]>::uninit();
- let res = unsafe {
- libc::pipe2(fds.as_mut_ptr() as *mut c_int, flags.bits())
- };
+ let res =
+ unsafe { libc::pipe2(fds.as_mut_ptr() as *mut c_int, flags.bits()) };
Errno::result(res)?;
@@ -1196,11 +1247,8 @@ pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
/// [truncate(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html)
#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
pub fn truncate<P: ?Sized + NixPath>(path: &P, len: off_t) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe {
- libc::truncate(cstr.as_ptr(), len)
- }
- })?;
+ let res = path
+ .with_nix_path(|cstr| unsafe { libc::truncate(cstr.as_ptr(), len) })?;
Errno::result(res).map(drop)
}
@@ -1209,8 +1257,8 @@ pub fn truncate<P: ?Sized + NixPath>(path: &P, len: off_t) -> Result<()> {
///
/// See also
/// [ftruncate(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html)
-pub fn ftruncate(fd: RawFd, len: off_t) -> Result<()> {
- Errno::result(unsafe { libc::ftruncate(fd, len) }).map(drop)
+pub fn ftruncate<Fd: AsFd>(fd: Fd, len: off_t) -> Result<()> {
+ Errno::result(unsafe { libc::ftruncate(fd.as_fd().as_raw_fd(), len) }).map(drop)
}
pub fn isatty(fd: RawFd) -> Result<bool> {
@@ -1224,7 +1272,7 @@ pub fn isatty(fd: RawFd) -> Result<bool> {
Errno::ENOTTY => Ok(false),
err => Err(err),
}
- }
+ }
}
}
@@ -1256,40 +1304,31 @@ pub fn linkat<P: ?Sized + NixPath>(
newpath: &P,
flag: LinkatFlags,
) -> Result<()> {
+ let atflag = match flag {
+ LinkatFlags::SymlinkFollow => AtFlags::AT_SYMLINK_FOLLOW,
+ LinkatFlags::NoSymlinkFollow => AtFlags::empty(),
+ };
- let atflag =
- match flag {
- LinkatFlags::SymlinkFollow => AtFlags::AT_SYMLINK_FOLLOW,
- LinkatFlags::NoSymlinkFollow => AtFlags::empty(),
- };
-
- let res =
- oldpath.with_nix_path(|oldcstr| {
- newpath.with_nix_path(|newcstr| {
- unsafe {
- libc::linkat(
- at_rawfd(olddirfd),
- oldcstr.as_ptr(),
- at_rawfd(newdirfd),
- newcstr.as_ptr(),
- atflag.bits() as libc::c_int
- )
- }
- })
- })??;
+ let res = oldpath.with_nix_path(|oldcstr| {
+ newpath.with_nix_path(|newcstr| unsafe {
+ libc::linkat(
+ at_rawfd(olddirfd),
+ oldcstr.as_ptr(),
+ at_rawfd(newdirfd),
+ newcstr.as_ptr(),
+ atflag.bits() as libc::c_int,
+ )
+ })
+ })??;
Errno::result(res).map(drop)
}
-
/// Remove a directory entry
///
/// See also [unlink(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html)
pub fn unlink<P: ?Sized + NixPath>(path: &P) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe {
- libc::unlink(cstr.as_ptr())
- }
- })?;
+ let res =
+ path.with_nix_path(|cstr| unsafe { libc::unlink(cstr.as_ptr()) })?;
Errno::result(res).map(drop)
}
@@ -1316,26 +1355,25 @@ pub fn unlinkat<P: ?Sized + NixPath>(
path: &P,
flag: UnlinkatFlags,
) -> Result<()> {
- let atflag =
- match flag {
- UnlinkatFlags::RemoveDir => AtFlags::AT_REMOVEDIR,
- UnlinkatFlags::NoRemoveDir => AtFlags::empty(),
- };
- let res = path.with_nix_path(|cstr| {
- unsafe {
- libc::unlinkat(at_rawfd(dirfd), cstr.as_ptr(), atflag.bits() as libc::c_int)
- }
+ let atflag = match flag {
+ UnlinkatFlags::RemoveDir => AtFlags::AT_REMOVEDIR,
+ UnlinkatFlags::NoRemoveDir => AtFlags::empty(),
+ };
+ let res = path.with_nix_path(|cstr| unsafe {
+ libc::unlinkat(
+ at_rawfd(dirfd),
+ cstr.as_ptr(),
+ atflag.bits() as libc::c_int,
+ )
})?;
Errno::result(res).map(drop)
}
-
#[inline]
#[cfg(not(target_os = "fuchsia"))]
pub fn chroot<P: ?Sized + NixPath>(path: &P) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe { libc::chroot(cstr.as_ptr()) }
- })?;
+ let res =
+ path.with_nix_path(|cstr| unsafe { libc::chroot(cstr.as_ptr()) })?;
Errno::result(res).map(drop)
}
@@ -1379,15 +1417,17 @@ pub fn fsync(fd: RawFd) -> Result<()> {
///
/// See also
/// [fdatasync(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html)
-#[cfg(any(target_os = "linux",
- target_os = "android",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "fuchsia",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "illumos",
- target_os = "solaris"))]
+#[cfg(any(
+ target_os = "linux",
+ target_os = "android",
+ target_os = "emscripten",
+ target_os = "freebsd",
+ target_os = "fuchsia",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "illumos",
+ target_os = "solaris"
+))]
#[inline]
pub fn fdatasync(fd: RawFd) -> Result<()> {
let res = unsafe { libc::fdatasync(fd) };
@@ -1539,27 +1579,31 @@ pub fn getgroups() -> Result<Vec<Gid>> {
// Now actually get the groups. We try multiple times in case the number of
// groups has changed since the first call to getgroups() and the buffer is
// now too small.
- let mut groups = Vec::<Gid>::with_capacity(Errno::result(ngroups)? as usize);
+ let mut groups =
+ Vec::<Gid>::with_capacity(Errno::result(ngroups)? as usize);
loop {
// FIXME: On the platforms we currently support, the `Gid` struct has
// the same representation in memory as a bare `gid_t`. This is not
// necessarily the case on all Rust platforms, though. See RFC 1785.
let ngroups = unsafe {
- libc::getgroups(groups.capacity() as c_int, groups.as_mut_ptr() as *mut gid_t)
+ libc::getgroups(
+ groups.capacity() as c_int,
+ groups.as_mut_ptr() as *mut gid_t,
+ )
};
match Errno::result(ngroups) {
Ok(s) => {
unsafe { groups.set_len(s as usize) };
return Ok(groups);
- },
+ }
Err(Errno::EINVAL) => {
// EINVAL indicates that the buffer size was too
// small, resize it up to ngroups_max as limit.
reserve_double_buffer_size(&mut groups, ngroups_max)
.or(Err(Errno::EINVAL))?;
- },
- Err(e) => return Err(e)
+ }
+ Err(e) => return Err(e),
}
}
}
@@ -1595,17 +1639,23 @@ pub fn getgroups() -> Result<Vec<Gid>> {
/// #
/// # try_main().unwrap();
/// ```
-#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox", target_os = "haiku")))]
+#[cfg(not(any(
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "redox",
+ target_os = "haiku"
+)))]
pub fn setgroups(groups: &[Gid]) -> Result<()> {
cfg_if! {
- if #[cfg(any(target_os = "dragonfly",
+ if #[cfg(any(target_os = "aix",
+ target_os = "dragonfly",
target_os = "freebsd",
target_os = "illumos",
target_os = "ios",
target_os = "macos",
target_os = "netbsd",
- target_os = "illumos",
- target_os = "openbsd"))] {
+ target_os = "openbsd",
+ target_os = "solaris"))] {
type setgroups_ngroups_t = c_int;
} else {
type setgroups_ngroups_t = size_t;
@@ -1615,7 +1665,10 @@ pub fn setgroups(groups: &[Gid]) -> Result<()> {
// same representation in memory as a bare `gid_t`. This is not necessarily
// the case on all Rust platforms, though. See RFC 1785.
let res = unsafe {
- libc::setgroups(groups.len() as setgroups_ngroups_t, groups.as_ptr() as *const gid_t)
+ libc::setgroups(
+ groups.len() as setgroups_ngroups_t,
+ groups.as_ptr() as *const gid_t,
+ )
};
Errno::result(res).map(drop)
@@ -1641,10 +1694,13 @@ pub fn setgroups(groups: &[Gid]) -> Result<()> {
/// and `setgroups()`. Additionally, while some implementations will return a
/// partial list of groups when `NGROUPS_MAX` is exceeded, this implementation
/// will only ever return the complete list or else an error.
-#[cfg(not(any(target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "redox")))]
+#[cfg(not(any(
+ target_os = "aix",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "redox"
+)))]
pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
let ngroups_max = match sysconf(SysconfVar::NGROUPS_MAX) {
Ok(Some(n)) => n as c_int,
@@ -1663,10 +1719,12 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
loop {
let mut ngroups = groups.capacity() as i32;
let ret = unsafe {
- libc::getgrouplist(user.as_ptr(),
- gid as getgrouplist_group_t,
- groups.as_mut_ptr() as *mut getgrouplist_group_t,
- &mut ngroups)
+ libc::getgrouplist(
+ user.as_ptr(),
+ gid as getgrouplist_group_t,
+ groups.as_mut_ptr() as *mut getgrouplist_group_t,
+ &mut ngroups,
+ )
};
// BSD systems only return 0 or -1, Linux returns ngroups on success.
@@ -1722,7 +1780,12 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
/// #
/// # try_main().unwrap();
/// ```
-#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox", target_os = "haiku")))]
+#[cfg(not(any(
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "redox",
+ target_os = "haiku"
+)))]
pub fn initgroups(user: &CStr, group: Gid) -> Result<()> {
cfg_if! {
if #[cfg(any(target_os = "ios", target_os = "macos"))] {
@@ -1732,7 +1795,8 @@ pub fn initgroups(user: &CStr, group: Gid) -> Result<()> {
}
}
let gid: gid_t = group.into();
- let res = unsafe { libc::initgroups(user.as_ptr(), gid as initgroups_group_t) };
+ let res =
+ unsafe { libc::initgroups(user.as_ptr(), gid as initgroups_group_t) };
Errno::result(res).map(drop)
}
@@ -1776,8 +1840,8 @@ pub mod alarm {
//!
//! Scheduling an alarm and waiting for the signal:
//!
-#![cfg_attr(target_os = "redox", doc = " ```rust,ignore")]
-#![cfg_attr(not(target_os = "redox"), doc = " ```rust")]
+ #![cfg_attr(target_os = "redox", doc = " ```rust,ignore")]
+ #![cfg_attr(not(target_os = "redox"), doc = " ```rust")]
//! use std::time::{Duration, Instant};
//!
//! use nix::unistd::{alarm, pause};
@@ -1853,17 +1917,16 @@ feature! {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
pub mod acct {
- use crate::{Result, NixPath};
use crate::errno::Errno;
+ use crate::{NixPath, Result};
use std::ptr;
/// Enable process accounting
///
/// See also [acct(2)](https://linux.die.net/man/2/acct)
pub fn enable<P: ?Sized + NixPath>(filename: &P) -> Result<()> {
- let res = filename.with_nix_path(|cstr| {
- unsafe { libc::acct(cstr.as_ptr()) }
- })?;
+ let res = filename
+ .with_nix_path(|cstr| unsafe { libc::acct(cstr.as_ptr()) })?;
Errno::result(res).map(drop)
}
@@ -1905,7 +1968,8 @@ feature! {
/// ```
#[inline]
pub fn mkstemp<P: ?Sized + NixPath>(template: &P) -> Result<(RawFd, PathBuf)> {
- let mut path = template.with_nix_path(|path| {path.to_bytes_with_nul().to_owned()})?;
+ let mut path =
+ template.with_nix_path(|path| path.to_bytes_with_nul().to_owned())?;
let p = path.as_mut_ptr() as *mut _;
let fd = unsafe { libc::mkstemp(p) };
let last = path.pop(); // drop the trailing nul
@@ -1939,8 +2003,14 @@ feature! {
#[repr(i32)]
#[non_exhaustive]
pub enum PathconfVar {
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "linux",
- target_os = "netbsd", target_os = "openbsd", target_os = "redox"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "linux",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "redox"
+ ))]
/// Minimum number of bits needed to represent, as a signed integer value,
/// the maximum size of a regular file allowed in the specified directory.
#[cfg_attr(docsrs, doc(cfg(all())))]
@@ -1964,42 +2034,86 @@ pub enum PathconfVar {
/// Maximum number of bytes that is guaranteed to be atomic when writing to
/// a pipe.
PIPE_BUF = libc::_PC_PIPE_BUF,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "illumos",
- target_os = "linux", target_os = "netbsd", target_os = "openbsd",
- target_os = "redox", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "redox",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Symbolic links can be created.
POSIX2_SYMLINKS = libc::_PC_2_SYMLINKS,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "linux", target_os = "openbsd", target_os = "redox"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "linux",
+ target_os = "openbsd",
+ target_os = "redox"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Minimum number of bytes of storage actually allocated for any portion of
/// a file.
POSIX_ALLOC_SIZE_MIN = libc::_PC_ALLOC_SIZE_MIN,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "linux", target_os = "openbsd"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "linux",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Recommended increment for file transfer sizes between the
/// `POSIX_REC_MIN_XFER_SIZE` and `POSIX_REC_MAX_XFER_SIZE` values.
POSIX_REC_INCR_XFER_SIZE = libc::_PC_REC_INCR_XFER_SIZE,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "linux", target_os = "openbsd", target_os = "redox"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "linux",
+ target_os = "openbsd",
+ target_os = "redox"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Maximum recommended file transfer size.
POSIX_REC_MAX_XFER_SIZE = libc::_PC_REC_MAX_XFER_SIZE,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "linux", target_os = "openbsd", target_os = "redox"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "linux",
+ target_os = "openbsd",
+ target_os = "redox"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Minimum recommended file transfer size.
POSIX_REC_MIN_XFER_SIZE = libc::_PC_REC_MIN_XFER_SIZE,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "linux", target_os = "openbsd", target_os = "redox"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "linux",
+ target_os = "openbsd",
+ target_os = "redox"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Recommended file transfer buffer alignment.
POSIX_REC_XFER_ALIGN = libc::_PC_REC_XFER_ALIGN,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "illumos", target_os = "linux", target_os = "netbsd",
- target_os = "openbsd", target_os = "redox", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "redox",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Maximum number of bytes in a symbolic link.
SYMLINK_MAX = libc::_PC_SYMLINK_MAX,
@@ -2013,23 +2127,45 @@ pub enum PathconfVar {
/// This symbol shall be defined to be the value of a character that shall
/// disable terminal special character handling.
_POSIX_VDISABLE = libc::_PC_VDISABLE,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "illumos", target_os = "linux", target_os = "openbsd",
- target_os = "redox", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "openbsd",
+ target_os = "redox",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Asynchronous input or output operations may be performed for the
/// associated file.
_POSIX_ASYNC_IO = libc::_PC_ASYNC_IO,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "illumos", target_os = "linux", target_os = "openbsd",
- target_os = "redox", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "openbsd",
+ target_os = "redox",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Prioritized input or output operations may be performed for the
/// associated file.
_POSIX_PRIO_IO = libc::_PC_PRIO_IO,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "illumos", target_os = "linux", target_os = "netbsd",
- target_os = "openbsd", target_os = "redox", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "redox",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Synchronized input or output operations may be performed for the
/// associated file.
@@ -2037,7 +2173,7 @@ pub enum PathconfVar {
#[cfg(any(target_os = "dragonfly", target_os = "openbsd"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The resolution in nanoseconds for all file timestamps.
- _POSIX_TIMESTAMP_RESOLUTION = libc::_PC_TIMESTAMP_RESOLUTION
+ _POSIX_TIMESTAMP_RESOLUTION = libc::_PC_TIMESTAMP_RESOLUTION,
}
/// Like `pathconf`, but works with file descriptors instead of paths (see
@@ -2093,12 +2229,13 @@ pub fn fpathconf(fd: RawFd, var: PathconfVar) -> Result<Option<c_long>> {
/// - `Ok(None)`: the variable has no limit (for limit variables) or is
/// unsupported (for option variables)
/// - `Err(x)`: an error occurred
-pub fn pathconf<P: ?Sized + NixPath>(path: &P, var: PathconfVar) -> Result<Option<c_long>> {
- let raw = path.with_nix_path(|cstr| {
- unsafe {
- Errno::clear();
- libc::pathconf(cstr.as_ptr(), var as c_int)
- }
+pub fn pathconf<P: ?Sized + NixPath>(
+ path: &P,
+ var: PathconfVar,
+) -> Result<Option<c_long>> {
+ let raw = path.with_nix_path(|cstr| unsafe {
+ Errno::clear();
+ libc::pathconf(cstr.as_ptr(), var as c_int)
})?;
if raw == -1 {
if errno::errno() == 0 {
@@ -2145,9 +2282,15 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
AIO_MAX = libc::_SC_AIO_MAX,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The maximum amount by which a process can decrease its asynchronous I/O
/// priority level from its own scheduling priority.
@@ -2192,9 +2335,17 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
EXPR_NEST_MAX = libc::_SC_EXPR_NEST_MAX,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Maximum length of a host name (not including the terminating null) as
/// returned from the `gethostname` function
@@ -2235,14 +2386,28 @@ pub enum SysconfVar {
/// A value one greater than the maximum value that the system may assign to
/// a newly-created file descriptor.
OPEN_MAX = libc::_SC_OPEN_MAX,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Advisory Information option.
_POSIX_ADVISORY_INFO = libc::_SC_ADVISORY_INFO,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports barriers.
_POSIX_BARRIERS = libc::_SC_BARRIERS,
@@ -2250,15 +2415,31 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_ASYNCHRONOUS_IO = libc::_SC_ASYNCHRONOUS_IO,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports clock selection.
_POSIX_CLOCK_SELECTION = libc::_SC_CLOCK_SELECTION,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Process CPU-Time Clocks option.
_POSIX_CPUTIME = libc::_SC_CPUTIME,
@@ -2266,9 +2447,16 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_FSYNC = libc::_SC_FSYNC,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the IPv6 option.
_POSIX_IPV6 = libc::_SC_IPV6,
@@ -2300,9 +2488,17 @@ pub enum SysconfVar {
#[cfg(not(target_os = "redox"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_MONOTONIC_CLOCK = libc::_SC_MONOTONIC_CLOCK,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "illumos", target_os = "ios", target_os="linux",
- target_os = "macos", target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Prioritized Input and Output option.
_POSIX_PRIORITIZED_IO = libc::_SC_PRIORITIZED_IO,
@@ -2310,27 +2506,56 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_PRIORITY_SCHEDULING = libc::_SC_PRIORITY_SCHEDULING,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Raw Sockets option.
_POSIX_RAW_SOCKETS = libc::_SC_RAW_SOCKETS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports read-write locks.
_POSIX_READER_WRITER_LOCKS = libc::_SC_READER_WRITER_LOCKS,
- #[cfg(any(target_os = "android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os = "openbsd"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports realtime signals.
_POSIX_REALTIME_SIGNALS = libc::_SC_REALTIME_SIGNALS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "illumos",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "solaris"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Regular Expression Handling option.
_POSIX_REGEXP = libc::_SC_REGEXP,
@@ -2346,31 +2571,59 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_SHARED_MEMORY_OBJECTS = libc::_SC_SHARED_MEMORY_OBJECTS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the POSIX shell.
_POSIX_SHELL = libc::_SC_SHELL,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Spawn option.
_POSIX_SPAWN = libc::_SC_SPAWN,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports spin locks.
_POSIX_SPIN_LOCKS = libc::_SC_SPIN_LOCKS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Process Sporadic Server option.
_POSIX_SPORADIC_SERVER = libc::_SC_SPORADIC_SERVER,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_SS_REPL_MAX = libc::_SC_SS_REPL_MAX,
/// The implementation supports the Synchronized Input and Output option.
@@ -2385,8 +2638,13 @@ pub enum SysconfVar {
#[cfg(not(target_os = "redox"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_THREAD_ATTR_STACKSIZE = libc::_SC_THREAD_ATTR_STACKSIZE,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Thread CPU-Time Clocks option.
_POSIX_THREAD_CPUTIME = libc::_SC_THREAD_CPUTIME,
@@ -2403,18 +2661,32 @@ pub enum SysconfVar {
#[cfg(not(target_os = "redox"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_THREAD_PRIORITY_SCHEDULING = libc::_SC_THREAD_PRIORITY_SCHEDULING,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Thread Process-Shared Synchronization
/// option.
_POSIX_THREAD_PROCESS_SHARED = libc::_SC_THREAD_PROCESS_SHARED,
- #[cfg(any(target_os="dragonfly", target_os="linux", target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "linux",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Robust Mutex Priority Inheritance option.
_POSIX_THREAD_ROBUST_PRIO_INHERIT = libc::_SC_THREAD_ROBUST_PRIO_INHERIT,
- #[cfg(any(target_os="dragonfly", target_os="linux", target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "linux",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Robust Mutex Priority Protection option.
_POSIX_THREAD_ROBUST_PRIO_PROTECT = libc::_SC_THREAD_ROBUST_PRIO_PROTECT,
@@ -2422,8 +2694,14 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_THREAD_SAFE_FUNCTIONS = libc::_SC_THREAD_SAFE_FUNCTIONS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Thread Sporadic Server option.
_POSIX_THREAD_SPORADIC_SERVER = libc::_SC_THREAD_SPORADIC_SERVER,
@@ -2431,8 +2709,14 @@ pub enum SysconfVar {
#[cfg(not(target_os = "redox"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_THREADS = libc::_SC_THREADS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports timeouts.
_POSIX_TIMEOUTS = libc::_SC_TIMEOUTS,
@@ -2440,44 +2724,90 @@ pub enum SysconfVar {
#[cfg(not(target_os = "redox"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_TIMERS = libc::_SC_TIMERS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Trace option.
_POSIX_TRACE = libc::_SC_TRACE,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Trace Event Filter option.
_POSIX_TRACE_EVENT_FILTER = libc::_SC_TRACE_EVENT_FILTER,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_TRACE_EVENT_NAME_MAX = libc::_SC_TRACE_EVENT_NAME_MAX,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Trace Inherit option.
_POSIX_TRACE_INHERIT = libc::_SC_TRACE_INHERIT,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Trace Log option.
_POSIX_TRACE_LOG = libc::_SC_TRACE_LOG,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_TRACE_NAME_MAX = libc::_SC_TRACE_NAME_MAX,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_TRACE_SYS_MAX = libc::_SC_TRACE_SYS_MAX,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX_TRACE_USER_EVENT_MAX = libc::_SC_TRACE_USER_EVENT_MAX,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Typed Memory Objects option.
_POSIX_TYPED_MEMORY_OBJECTS = libc::_SC_TYPED_MEMORY_OBJECTS,
@@ -2485,31 +2815,55 @@ pub enum SysconfVar {
/// to which the implementation conforms. For implementations conforming to
/// POSIX.1-2008, the value shall be 200809L.
_POSIX_VERSION = libc::_SC_VERSION,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation provides a C-language compilation environment with
/// 32-bit `int`, `long`, `pointer`, and `off_t` types.
_POSIX_V6_ILP32_OFF32 = libc::_SC_V6_ILP32_OFF32,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation provides a C-language compilation environment with
/// 32-bit `int`, `long`, and pointer types and an `off_t` type using at
/// least 64 bits.
_POSIX_V6_ILP32_OFFBIG = libc::_SC_V6_ILP32_OFFBIG,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation provides a C-language compilation environment with
/// 32-bit `int` and 64-bit `long`, `pointer`, and `off_t` types.
_POSIX_V6_LP64_OFF64 = libc::_SC_V6_LP64_OFF64,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation provides a C-language compilation environment with an
/// `int` type using at least 32 bits and `long`, pointer, and `off_t` types
@@ -2540,40 +2894,76 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_POSIX2_LOCALEDEF = libc::_SC_2_LOCALEDEF,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Batch Environment Services and Utilities
/// option.
_POSIX2_PBS = libc::_SC_2_PBS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Batch Accounting option.
_POSIX2_PBS_ACCOUNTING = libc::_SC_2_PBS_ACCOUNTING,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Batch Checkpoint/Restart option.
_POSIX2_PBS_CHECKPOINT = libc::_SC_2_PBS_CHECKPOINT,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Locate Batch Job Request option.
_POSIX2_PBS_LOCATE = libc::_SC_2_PBS_LOCATE,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Batch Job Message Request option.
_POSIX2_PBS_MESSAGE = libc::_SC_2_PBS_MESSAGE,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Track Batch Job Request option.
_POSIX2_PBS_TRACK = libc::_SC_2_PBS_TRACK,
@@ -2609,28 +2999,52 @@ pub enum SysconfVar {
PTHREAD_THREADS_MAX = libc::_SC_THREAD_THREADS_MAX,
#[cfg(not(target_os = "haiku"))]
RE_DUP_MAX = libc::_SC_RE_DUP_MAX,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
RTSIG_MAX = libc::_SC_RTSIG_MAX,
#[cfg(not(target_os = "redox"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
SEM_NSEMS_MAX = libc::_SC_SEM_NSEMS_MAX,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
SEM_VALUE_MAX = libc::_SC_SEM_VALUE_MAX,
- #[cfg(any(target_os = "android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os = "openbsd"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
SIGQUEUE_MAX = libc::_SC_SIGQUEUE_MAX,
STREAM_MAX = libc::_SC_STREAM_MAX,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
SYMLOOP_MAX = libc::_SC_SYMLOOP_MAX,
#[cfg(not(target_os = "redox"))]
@@ -2638,33 +3052,63 @@ pub enum SysconfVar {
TIMER_MAX = libc::_SC_TIMER_MAX,
TTY_NAME_MAX = libc::_SC_TTY_NAME_MAX,
TZNAME_MAX = libc::_SC_TZNAME_MAX,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the X/Open Encryption Option Group.
_XOPEN_CRYPT = libc::_SC_XOPEN_CRYPT,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the Issue 4, Version 2 Enhanced
/// Internationalization Option Group.
_XOPEN_ENH_I18N = libc::_SC_XOPEN_ENH_I18N,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_XOPEN_LEGACY = libc::_SC_XOPEN_LEGACY,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the X/Open Realtime Option Group.
_XOPEN_REALTIME = libc::_SC_XOPEN_REALTIME,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the X/Open Realtime Threads Option Group.
_XOPEN_REALTIME_THREADS = libc::_SC_XOPEN_REALTIME_THREADS,
@@ -2673,36 +3117,54 @@ pub enum SysconfVar {
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
_XOPEN_SHM = libc::_SC_XOPEN_SHM,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the XSI STREAMS Option Group.
_XOPEN_STREAMS = libc::_SC_XOPEN_STREAMS,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// The implementation supports the XSI option
_XOPEN_UNIX = libc::_SC_XOPEN_UNIX,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
+ #[cfg(any(
+ target_os = "android",
+ target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "openbsd"
+ ))]
#[cfg_attr(docsrs, doc(cfg(all())))]
/// Integer value indicating version of the X/Open Portability Guide to
/// which the implementation conforms.
_XOPEN_VERSION = libc::_SC_XOPEN_VERSION,
/// The number of pages of physical memory. Note that it is possible for
/// the product of this value to overflow.
- #[cfg(any(target_os="android", target_os="linux"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
_PHYS_PAGES = libc::_SC_PHYS_PAGES,
/// The number of currently available pages of physical memory.
- #[cfg(any(target_os="android", target_os="linux"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
_AVPHYS_PAGES = libc::_SC_AVPHYS_PAGES,
/// The number of processors configured.
- #[cfg(any(target_os="android", target_os="linux"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
_NPROCESSORS_CONF = libc::_SC_NPROCESSORS_CONF,
/// The number of processors currently online (available).
- #[cfg(any(target_os="android", target_os="linux"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
_NPROCESSORS_ONLN = libc::_SC_NPROCESSORS_ONLN,
}
@@ -2739,28 +3201,29 @@ pub fn sysconf(var: SysconfVar) -> Result<Option<c_long>> {
}
}
-feature! {
-#![feature = "fs"]
-
#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(feature = "fs")]
mod pivot_root {
- use crate::{Result, NixPath};
use crate::errno::Errno;
+ use crate::{NixPath, Result};
pub fn pivot_root<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
- new_root: &P1, put_old: &P2) -> Result<()> {
+ new_root: &P1,
+ put_old: &P2,
+ ) -> Result<()> {
let res = new_root.with_nix_path(|new_root| {
- put_old.with_nix_path(|put_old| {
- unsafe {
- libc::syscall(libc::SYS_pivot_root, new_root.as_ptr(), put_old.as_ptr())
- }
+ put_old.with_nix_path(|put_old| unsafe {
+ libc::syscall(
+ libc::SYS_pivot_root,
+ new_root.as_ptr(),
+ put_old.as_ptr(),
+ )
})
})??;
Errno::result(res).map(drop)
}
}
-}
#[cfg(any(
target_os = "android",
@@ -2773,9 +3236,9 @@ mod setres {
feature! {
#![feature = "user"]
- use crate::Result;
+ use super::{Gid, Uid};
use crate::errno::Errno;
- use super::{Uid, Gid};
+ use crate::Result;
/// Sets the real, effective, and saved uid.
/// ([see setresuid(2)](https://man7.org/linux/man-pages/man2/setresuid.2.html))
@@ -2788,7 +3251,8 @@ mod setres {
/// Err is returned if the user doesn't have permission to set this UID.
#[inline]
pub fn setresuid(ruid: Uid, euid: Uid, suid: Uid) -> Result<()> {
- let res = unsafe { libc::setresuid(ruid.into(), euid.into(), suid.into()) };
+ let res =
+ unsafe { libc::setresuid(ruid.into(), euid.into(), suid.into()) };
Errno::result(res).map(drop)
}
@@ -2804,7 +3268,8 @@ mod setres {
/// Err is returned if the user doesn't have permission to set this GID.
#[inline]
pub fn setresgid(rgid: Gid, egid: Gid, sgid: Gid) -> Result<()> {
- let res = unsafe { libc::setresgid(rgid.into(), egid.into(), sgid.into()) };
+ let res =
+ unsafe { libc::setresgid(rgid.into(), egid.into(), sgid.into()) };
Errno::result(res).map(drop)
}
@@ -2822,16 +3287,16 @@ mod getres {
feature! {
#![feature = "user"]
- use crate::Result;
+ use super::{Gid, Uid};
use crate::errno::Errno;
- use super::{Uid, Gid};
+ use crate::Result;
/// Real, effective and saved user IDs.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct ResUid {
pub real: Uid,
pub effective: Uid,
- pub saved: Uid
+ pub saved: Uid,
}
/// Real, effective and saved group IDs.
@@ -2839,7 +3304,7 @@ mod getres {
pub struct ResGid {
pub real: Gid,
pub effective: Gid,
- pub saved: Gid
+ pub saved: Gid,
}
/// Gets the real, effective, and saved user IDs.
@@ -2858,7 +3323,11 @@ mod getres {
let mut suid = libc::uid_t::max_value();
let res = unsafe { libc::getresuid(&mut ruid, &mut euid, &mut suid) };
- Errno::result(res).map(|_| ResUid{ real: Uid(ruid), effective: Uid(euid), saved: Uid(suid) })
+ Errno::result(res).map(|_| ResUid {
+ real: Uid(ruid),
+ effective: Uid(euid),
+ saved: Uid(suid),
+ })
}
/// Gets the real, effective, and saved group IDs.
@@ -2877,7 +3346,11 @@ mod getres {
let mut sgid = libc::gid_t::max_value();
let res = unsafe { libc::getresgid(&mut rgid, &mut egid, &mut sgid) };
- Errno::result(res).map(|_| ResGid { real: Gid(rgid), effective: Gid(egid), saved: Gid(sgid) } )
+ Errno::result(res).map(|_| ResGid {
+ real: Gid(rgid),
+ effective: Gid(egid),
+ saved: Gid(sgid),
+ })
}
}
}
@@ -2904,10 +3377,8 @@ feature! {
/// Checks the file named by `path` for accessibility according to the flags given by `amode`
/// See [access(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html)
pub fn access<P: ?Sized + NixPath>(path: &P, amode: AccessFlags) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe {
- libc::access(cstr.as_ptr(), amode.bits)
- }
+ let res = path.with_nix_path(|cstr| unsafe {
+ libc::access(cstr.as_ptr(), amode.bits())
})?;
Errno::result(res).map(drop)
}
@@ -2923,11 +3394,19 @@ pub fn access<P: ?Sized + NixPath>(path: &P, amode: AccessFlags) -> Result<()> {
/// [faccessat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/faccessat.html)
// redox: does not appear to support the *at family of syscalls.
#[cfg(not(target_os = "redox"))]
-pub fn faccessat<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P, mode: AccessFlags, flags: AtFlags) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe {
- libc::faccessat(at_rawfd(dirfd), cstr.as_ptr(), mode.bits(), flags.bits())
- }
+pub fn faccessat<P: ?Sized + NixPath>(
+ dirfd: Option<RawFd>,
+ path: &P,
+ mode: AccessFlags,
+ flags: AtFlags,
+) -> Result<()> {
+ let res = path.with_nix_path(|cstr| unsafe {
+ libc::faccessat(
+ at_rawfd(dirfd),
+ cstr.as_ptr(),
+ mode.bits(),
+ flags.bits(),
+ )
})?;
Errno::result(res).map(drop)
}
@@ -2945,10 +3424,8 @@ pub fn faccessat<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P, mode: Acce
target_os = "dragonfly"
))]
pub fn eaccess<P: ?Sized + NixPath>(path: &P, mode: AccessFlags) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe {
- libc::eaccess(cstr.as_ptr(), mode.bits)
- }
+ let res = path.with_nix_path(|cstr| unsafe {
+ libc::eaccess(cstr.as_ptr(), mode.bits())
})?;
Errno::result(res).map(drop)
}
@@ -2982,32 +3459,41 @@ pub struct User {
/// Path to shell
pub shell: PathBuf,
/// Login class
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
+ #[cfg(not(any(
+ target_os = "aix",
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
#[cfg_attr(docsrs, doc(cfg(all())))]
pub class: CString,
/// Last password change
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
+ #[cfg(not(any(
+ target_os = "aix",
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
#[cfg_attr(docsrs, doc(cfg(all())))]
pub change: libc::time_t,
/// Expiration time of account
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
+ #[cfg(not(any(
+ target_os = "aix",
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
#[cfg_attr(docsrs, doc(cfg(all())))]
- pub expire: libc::time_t
+ pub expire: libc::time_t,
}
#[cfg(not(target_os = "redox"))] //RedoxFS does not support passwd
@@ -3015,35 +3501,74 @@ impl From<&libc::passwd> for User {
fn from(pw: &libc::passwd) -> User {
unsafe {
User {
- name: if pw.pw_name.is_null() { Default::default() } else { CStr::from_ptr(pw.pw_name).to_string_lossy().into_owned() },
- passwd: if pw.pw_passwd.is_null() { Default::default() } else { CString::new(CStr::from_ptr(pw.pw_passwd).to_bytes()).unwrap() },
- #[cfg(not(all(target_os = "android", target_pointer_width = "32")))]
- gecos: if pw.pw_gecos.is_null() { Default::default() } else { CString::new(CStr::from_ptr(pw.pw_gecos).to_bytes()).unwrap() },
- dir: if pw.pw_dir.is_null() { Default::default() } else { PathBuf::from(OsStr::from_bytes(CStr::from_ptr(pw.pw_dir).to_bytes())) },
- shell: if pw.pw_shell.is_null() { Default::default() } else { PathBuf::from(OsStr::from_bytes(CStr::from_ptr(pw.pw_shell).to_bytes())) },
+ name: if pw.pw_name.is_null() {
+ Default::default()
+ } else {
+ CStr::from_ptr(pw.pw_name).to_string_lossy().into_owned()
+ },
+ passwd: if pw.pw_passwd.is_null() {
+ Default::default()
+ } else {
+ CString::new(CStr::from_ptr(pw.pw_passwd).to_bytes())
+ .unwrap()
+ },
+ #[cfg(not(all(
+ target_os = "android",
+ target_pointer_width = "32"
+ )))]
+ gecos: if pw.pw_gecos.is_null() {
+ Default::default()
+ } else {
+ CString::new(CStr::from_ptr(pw.pw_gecos).to_bytes())
+ .unwrap()
+ },
+ dir: if pw.pw_dir.is_null() {
+ Default::default()
+ } else {
+ PathBuf::from(OsStr::from_bytes(
+ CStr::from_ptr(pw.pw_dir).to_bytes(),
+ ))
+ },
+ shell: if pw.pw_shell.is_null() {
+ Default::default()
+ } else {
+ PathBuf::from(OsStr::from_bytes(
+ CStr::from_ptr(pw.pw_shell).to_bytes(),
+ ))
+ },
uid: Uid::from_raw(pw.pw_uid),
gid: Gid::from_raw(pw.pw_gid),
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
- class: CString::new(CStr::from_ptr(pw.pw_class).to_bytes()).unwrap(),
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
+ #[cfg(not(any(
+ target_os = "aix",
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
+ class: CString::new(CStr::from_ptr(pw.pw_class).to_bytes())
+ .unwrap(),
+ #[cfg(not(any(
+ target_os = "aix",
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
change: pw.pw_change,
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
- expire: pw.pw_expire
+ #[cfg(not(any(
+ target_os = "aix",
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
+ expire: pw.pw_expire,
}
}
}
@@ -3067,32 +3592,44 @@ impl From<User> for libc::passwd {
Self {
pw_name: name,
pw_passwd: u.passwd.into_raw(),
- #[cfg(not(all(target_os = "android", target_pointer_width = "32")))]
+ #[cfg(not(all(
+ target_os = "android",
+ target_pointer_width = "32"
+ )))]
pw_gecos: u.gecos.into_raw(),
pw_dir: dir,
pw_shell: shell,
pw_uid: u.uid.0,
pw_gid: u.gid.0,
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
+ #[cfg(not(any(
+ target_os = "aix",
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
pw_class: u.class.into_raw(),
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
+ #[cfg(not(any(
+ target_os = "aix",
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
pw_change: u.change,
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
+ #[cfg(not(any(
+ target_os = "aix",
+ target_os = "android",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "solaris"
+ )))]
pw_expire: u.expire,
#[cfg(target_os = "illumos")]
pw_age: CString::new("").unwrap().into_raw(),
@@ -3106,12 +3643,19 @@ impl From<User> for libc::passwd {
#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
impl User {
- fn from_anything<F>(f: F) -> Result<Option<Self>>
+ /// # Safety
+ ///
+ /// If `f` writes to its `*mut *mut libc::passwd` parameter, then it must
+ /// also initialize the value pointed to by its `*mut libc::group`
+ /// parameter.
+ unsafe fn from_anything<F>(f: F) -> Result<Option<Self>>
where
- F: Fn(*mut libc::passwd,
- *mut c_char,
- libc::size_t,
- *mut *mut libc::passwd) -> libc::c_int
+ F: Fn(
+ *mut libc::passwd,
+ *mut c_char,
+ libc::size_t,
+ *mut *mut libc::passwd,
+ ) -> libc::c_int,
{
let buflimit = 1048576;
let bufsize = match sysconf(SysconfVar::GETPW_R_SIZE_MAX) {
@@ -3124,12 +3668,19 @@ impl User {
let mut res = ptr::null_mut();
loop {
- let error = f(pwd.as_mut_ptr(), cbuf.as_mut_ptr(), cbuf.capacity(), &mut res);
+ let error = f(
+ pwd.as_mut_ptr(),
+ cbuf.as_mut_ptr(),
+ cbuf.capacity(),
+ &mut res,
+ );
if error == 0 {
if res.is_null() {
return Ok(None);
} else {
- let pwd = unsafe { pwd.assume_init() };
+ // SAFETY: `f` guarantees that `pwd` is initialized if `res`
+ // is not null.
+ let pwd = pwd.assume_init();
return Ok(Some(User::from(&pwd)));
}
} else if Errno::last() == Errno::ERANGE {
@@ -3155,15 +3706,19 @@ impl User {
/// assert_eq!(res.name, "root");
/// ```
pub fn from_uid(uid: Uid) -> Result<Option<Self>> {
- User::from_anything(|pwd, cbuf, cap, res| {
- unsafe { libc::getpwuid_r(uid.0, pwd, cbuf, cap, res) }
- })
+ // SAFETY: `getpwuid_r` will write to `res` if it initializes the value
+ // at `pwd`.
+ unsafe {
+ User::from_anything(|pwd, cbuf, cap, res| {
+ libc::getpwuid_r(uid.0, pwd, cbuf, cap, res)
+ })
+ }
}
/// Get a user by name.
///
/// Internally, this function calls
- /// [getpwnam_r(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html)
+ /// [getpwnam_r(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwnam_r.html)
///
/// # Examples
///
@@ -3178,9 +3733,13 @@ impl User {
Ok(c_str) => c_str,
Err(_nul_error) => return Ok(None),
};
- User::from_anything(|pwd, cbuf, cap, res| {
- unsafe { libc::getpwnam_r(name.as_ptr(), pwd, cbuf, cap, res) }
- })
+ // SAFETY: `getpwnam_r` will write to `res` if it initializes the value
+ // at `pwd`.
+ unsafe {
+ User::from_anything(|pwd, cbuf, cap, res| {
+ libc::getpwnam_r(name.as_ptr(), pwd, cbuf, cap, res)
+ })
+ }
}
}
@@ -3195,7 +3754,7 @@ pub struct Group {
/// Group ID
pub gid: Gid,
/// List of Group members
- pub mem: Vec<String>
+ pub mem: Vec<String>,
}
#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
@@ -3203,10 +3762,23 @@ impl From<&libc::group> for Group {
fn from(gr: &libc::group) -> Group {
unsafe {
Group {
- name: CStr::from_ptr(gr.gr_name).to_string_lossy().into_owned(),
- passwd: CString::new(CStr::from_ptr(gr.gr_passwd).to_bytes()).unwrap(),
+ name: if gr.gr_name.is_null() {
+ Default::default()
+ } else {
+ CStr::from_ptr(gr.gr_name).to_string_lossy().into_owned()
+ },
+ passwd: if gr.gr_passwd.is_null() {
+ Default::default()
+ } else {
+ CString::new(CStr::from_ptr(gr.gr_passwd).to_bytes())
+ .unwrap()
+ },
gid: Gid::from_raw(gr.gr_gid),
- mem: Group::members(gr.gr_mem)
+ mem: if gr.gr_mem.is_null() {
+ Default::default()
+ } else {
+ Group::members(gr.gr_mem)
+ },
}
}
}
@@ -3230,12 +3802,19 @@ impl Group {
ret
}
- fn from_anything<F>(f: F) -> Result<Option<Self>>
+ /// # Safety
+ ///
+ /// If `f` writes to its `*mut *mut libc::group` parameter, then it must
+ /// also initialize the value pointed to by its `*mut libc::group`
+ /// parameter.
+ unsafe fn from_anything<F>(f: F) -> Result<Option<Self>>
where
- F: Fn(*mut libc::group,
- *mut c_char,
- libc::size_t,
- *mut *mut libc::group) -> libc::c_int
+ F: Fn(
+ *mut libc::group,
+ *mut c_char,
+ libc::size_t,
+ *mut *mut libc::group,
+ ) -> libc::c_int,
{
let buflimit = 1048576;
let bufsize = match sysconf(SysconfVar::GETGR_R_SIZE_MAX) {
@@ -3248,12 +3827,19 @@ impl Group {
let mut res = ptr::null_mut();
loop {
- let error = f(grp.as_mut_ptr(), cbuf.as_mut_ptr(), cbuf.capacity(), &mut res);
+ let error = f(
+ grp.as_mut_ptr(),
+ cbuf.as_mut_ptr(),
+ cbuf.capacity(),
+ &mut res,
+ );
if error == 0 {
if res.is_null() {
return Ok(None);
} else {
- let grp = unsafe { grp.assume_init() };
+ // SAFETY: `f` guarantees that `grp` is initialized if `res`
+ // is not null.
+ let grp = grp.assume_init();
return Ok(Some(Group::from(&grp)));
}
} else if Errno::last() == Errno::ERANGE {
@@ -3281,9 +3867,13 @@ impl Group {
/// assert!(res.name == "root");
/// ```
pub fn from_gid(gid: Gid) -> Result<Option<Self>> {
- Group::from_anything(|grp, cbuf, cap, res| {
- unsafe { libc::getgrgid_r(gid.0, grp, cbuf, cap, res) }
- })
+ // SAFETY: `getgrgid_r` will write to `res` if it initializes the value
+ // at `grp`.
+ unsafe {
+ Group::from_anything(|grp, cbuf, cap, res| {
+ libc::getgrgid_r(gid.0, grp, cbuf, cap, res)
+ })
+ }
}
/// Get a group by name.
@@ -3306,9 +3896,13 @@ impl Group {
Ok(c_str) => c_str,
Err(_nul_error) => return Ok(None),
};
- Group::from_anything(|grp, cbuf, cap, res| {
- unsafe { libc::getgrnam_r(name.as_ptr(), grp, cbuf, cap, res) }
- })
+ // SAFETY: `getgrnam_r` will write to `res` if it initializes the value
+ // at `grp`.
+ unsafe {
+ Group::from_anything(|grp, cbuf, cap, res| {
+ libc::getgrnam_r(name.as_ptr(), grp, cbuf, cap, res)
+ })
+ }
}
}
}