summaryrefslogtreecommitdiff
path: root/src/unistd.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/unistd.rs')
-rw-r--r--src/unistd.rs73
1 files changed, 59 insertions, 14 deletions
diff --git a/src/unistd.rs b/src/unistd.rs
index 81333b74..7a1c56c7 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -818,6 +818,7 @@ pub fn write(fd: RawFd, buf: &[u8]) -> Result<usize> {
}
/// Directive that tells [`lseek`] and [`lseek64`] what the offset is relative to.
+///
/// [`lseek`]: ./fn.lseek.html
/// [`lseek64`]: ./fn.lseek64.html
#[repr(i32)]
@@ -850,7 +851,7 @@ pub enum Whence {
/// Move the read/write file offset.
///
-/// See also [lseek(2)(http://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html)
+/// See also [lseek(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html)
pub fn lseek(fd: RawFd, offset: libc::off_t, whence: Whence) -> Result<libc::off_t> {
let res = unsafe { libc::lseek(fd, offset, whence as i32) };
@@ -879,10 +880,22 @@ pub fn pipe() -> Result<(RawFd, RawFd)> {
}
}
-// libc only defines `pipe2` in `libc::notbsd`.
-#[cfg(any(target_os = "linux",
- target_os = "android",
- target_os = "emscripten"))]
+/// Like `pipe`, but allows setting certain file descriptor flags.
+///
+/// The following flags are supported, and will be set atomically as the pipe is
+/// created:
+///
+/// `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors.
+/// `O_NONBLOCK`: Set the non-blocking flag for the ends of the pipe.
+///
+/// See also [pipe(2)](http://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 = "linux",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
let mut fds: [c_int; 2] = unsafe { mem::uninitialized() };
@@ -893,9 +906,18 @@ pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
Ok((fds[0], fds[1]))
}
-#[cfg(not(any(target_os = "linux",
- target_os = "android",
- target_os = "emscripten")))]
+/// Like `pipe`, but allows setting certain file descriptor flags.
+///
+/// The following flags are supported, and will be set after the pipe is
+/// created:
+///
+/// `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors.
+/// `O_NONBLOCK`: Set the non-blocking flag for the ends of the pipe.
+#[cfg(any(target_os = "ios", target_os = "macos"))]
+#[deprecated(
+ since="0.10.0",
+ note="pipe2(2) is not actually atomic on these platforms. Use pipe(2) and fcntl(2) instead"
+)]
pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
let mut fds: [c_int; 2] = unsafe { mem::uninitialized() };
@@ -908,9 +930,7 @@ pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
Ok((fds[0], fds[1]))
}
-#[cfg(not(any(target_os = "linux",
- target_os = "android",
- target_os = "emscripten")))]
+#[cfg(any(target_os = "ios", target_os = "macos"))]
fn pipe2_setflags(fd1: RawFd, fd2: RawFd, flags: OFlag) -> Result<()> {
use fcntl::FdFlag;
use fcntl::FcntlArg::F_SETFL;
@@ -1127,12 +1147,24 @@ pub fn getgroups() -> Result<Vec<Gid>> {
/// specific user and group. For example, given the user `www-data` with UID
/// `33` and the group `backup` with the GID `34`, one could switch the user as
/// follows:
-/// ```
+///
+/// ```rust,no_run
+/// # use std::error::Error;
+/// # use nix::unistd::*;
+/// #
+/// # fn try_main() -> Result<(), Box<Error>> {
/// let uid = Uid::from_raw(33);
/// let gid = Gid::from_raw(34);
/// setgroups(&[gid])?;
/// setgid(gid)?;
/// setuid(uid)?;
+/// #
+/// # Ok(())
+/// # }
+/// #
+/// # fn main() {
+/// # try_main().unwrap();
+/// # }
/// ```
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
pub fn setgroups(groups: &[Gid]) -> Result<()> {
@@ -1248,13 +1280,26 @@ pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
/// UID and GID for the user in the system's password database (usually found
/// in `/etc/passwd`). If the `www-data` user's UID and GID were `33` and `33`,
/// respectively, one could switch the user as follows:
-/// ```
+///
+/// ```rust,no_run
+/// # use std::error::Error;
+/// # use std::ffi::CString;
+/// # use nix::unistd::*;
+/// #
+/// # fn try_main() -> Result<(), Box<Error>> {
/// let user = CString::new("www-data").unwrap();
/// let uid = Uid::from_raw(33);
/// let gid = Gid::from_raw(33);
/// initgroups(&user, gid)?;
/// setgid(gid)?;
/// setuid(uid)?;
+/// #
+/// # Ok(())
+/// # }
+/// #
+/// # fn main() {
+/// # try_main().unwrap();
+/// # }
/// ```
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
pub fn initgroups(user: &CStr, group: Gid) -> Result<()> {
@@ -1283,7 +1328,7 @@ pub fn pause() -> Result<()> {
/// Suspend execution for an interval of time
///
-/// See also [sleep(2)(http://pubs.opengroup.org/onlinepubs/009695399/functions/sleep.html#tag_03_705_05)
+/// See also [sleep(2)](http://pubs.opengroup.org/onlinepubs/009695399/functions/sleep.html#tag_03_705_05)
// Per POSIX, does not fail
#[inline]
pub fn sleep(seconds: libc::c_uint) -> c_uint {