diff options
author | zethra <jediben97@gmail.com> | 2016-10-31 13:48:44 -0400 |
---|---|---|
committer | zethra <jediben97@gmail.com> | 2016-10-31 13:48:44 -0400 |
commit | c0d6829cc43ffd37d535de0465018cb3b05af753 (patch) | |
tree | 152d6c259da5b6d3aeab84c0689ebe03bb082774 | |
parent | 18c85d5022f7abfea07724eaea0f6e3d77aaf733 (diff) | |
parent | 652e730f106fd3c103ba7549e64a7c992a72f11a (diff) | |
download | nix-c0d6829cc43ffd37d535de0465018cb3b05af753.zip |
Merge remote-tracking branch 'upstream/master'
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | src/lib.rs | 13 | ||||
-rw-r--r-- | src/sys/event.rs | 7 | ||||
-rw-r--r-- | src/unistd.rs | 127 |
4 files changed, 134 insertions, 15 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index b8ae74ca..c87b045e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Changed - The minimum supported version of rustc is now 1.7.0. ([#444](https://github.com/nix-rust/nix/pull/444)) +- Implement `Send` for `KEvent` + ([#442](https://github.com/nix-rust/nix/pull/442)) - Changed `KEvent` to an opaque structure that may only be modified by its constructor and the `ev_set` method. ([#415](https://github.com/nix-rust/nix/pull/415)) @@ -77,8 +77,16 @@ use std::fmt; use std::error; use libc::PATH_MAX; +/// Nix Result Type pub type Result<T> = result::Result<T, Error>; +/// Nix Error Type +/// +/// The nix error type provides a common way of dealing with +/// various system system/libc calls that might fail. Each +/// error has a corresponding errno (usually the one from the +/// underlying OS) to which it can be mapped in addition to +/// implementing other common traits. #[derive(Clone, Copy, Debug, PartialEq)] pub enum Error { Sys(errno::Errno), @@ -86,18 +94,23 @@ pub enum Error { } impl Error { + + /// Create a nix Error from a given errno pub fn from_errno(errno: errno::Errno) -> Error { Error::Sys(errno) } + /// Get the current errno and convert it to a nix Error pub fn last() -> Error { Error::Sys(errno::Errno::last()) } + /// Create a new invalid argument error (`EINVAL`) pub fn invalid_argument() -> Error { Error::Sys(errno::EINVAL) } + /// Get the errno associated with this error pub fn errno(&self) -> errno::Errno { match *self { Error::Sys(errno) => errno, diff --git a/src/sys/event.rs b/src/sys/event.rs index d44963db..68528c9e 100644 --- a/src/sys/event.rs +++ b/src/sys/event.rs @@ -191,6 +191,13 @@ pub fn kqueue() -> Result<RawFd> { Errno::result(res) } + +// KEvent can't derive Send because on some operating systems, udata is defined +// as a void*. However, KEvent's public API always treats udata as a uintptr_t, +// which is safe to Send. +unsafe impl Send for KEvent { +} + impl KEvent { pub fn new(ident: uintptr_t, filter: EventFilter, flags: EventFlag, fflags:FilterFlag, data: intptr_t, udata: uintptr_t) -> KEvent { diff --git a/src/unistd.rs b/src/unistd.rs index 951722cd..771a50fb 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -15,15 +15,20 @@ use sys::stat::Mode; #[cfg(any(target_os = "linux", target_os = "android"))] pub use self::linux::*; +/// Represents the successful result of calling `fork` +/// +/// When `fork` is called, the process continues execution in the parent process +/// and in the new child. This return type can be examined to determine whether +/// you are now executing in the parent process or in the child. #[derive(Clone, Copy)] pub enum ForkResult { - Parent { - child: pid_t - }, - Child + Parent { child: pid_t }, + Child, } impl ForkResult { + + /// Return `true` if this is the child process of the `fork()` #[inline] pub fn is_child(&self) -> bool { match *self { @@ -32,12 +37,40 @@ impl ForkResult { } } + /// Returns `true` if this is the parent process of the `fork()` #[inline] pub fn is_parent(&self) -> bool { !self.is_child() } } +/// Create a new child process duplicating the parent process ([see +/// fork(2)](http://man7.org/linux/man-pages/man2/fork.2.html)). +/// +/// After calling the fork system call (successfully) two processes will +/// be created that are identical with the exception of their pid and the +/// return value of this function. As an example: +/// +/// ```no_run +/// use nix::unistd::{fork, ForkResult}; +/// +/// match fork() { +/// Ok(ForkResult::Parent { child, .. }) => { +/// println!("Continuing execution in parent process, new child has pid: {}", child); +/// } +/// Ok(ForkResult::Child) => println!("I'm a new child process"), +/// Err(e) => println!("Fork failed"), +/// } +/// ``` +/// +/// This will print something like the following (order indeterministic). The +/// thing to note is that you end up with two processes continuing execution +/// immediately after the fork call but with different match arms. +/// +/// ```text +/// Continuing execution in parent process, new child has pid: 1234 +/// I'm a new child process +/// ``` #[inline] pub fn fork() -> Result<ForkResult> { use self::ForkResult::*; @@ -45,18 +78,39 @@ pub fn fork() -> Result<ForkResult> { Errno::result(res).map(|res| match res { 0 => Child, - res => Parent { child: res } + res => Parent { child: res }, }) } +/// Get the pid of this process (see +/// [getpid(2)](http://man7.org/linux/man-pages/man2/getpid.2.html)). +/// +/// Since you are running code, there is always a pid to return, so there +/// is no error case that needs to be handled. #[inline] pub fn getpid() -> pid_t { - unsafe { libc::getpid() } // no error handling, according to man page: "These functions are always successful." + unsafe { libc::getpid() } } + +/// Get the pid of this processes' parent (see +/// [getpid(2)](http://man7.org/linux/man-pages/man2/getpid.2.html)). +/// +/// There is always a parent pid to return, so there is no error case that needs +/// to be handled. #[inline] pub fn getppid() -> pid_t { unsafe { libc::getppid() } // no error handling, according to man page: "These functions are always successful." } + +/// Set a process group ID (see +/// [setpgid(2)](http://man7.org/linux/man-pages/man2/setpgid.2.html)). +/// +/// Set the process group id (PGID) of a particular process. If a pid of zero +/// is specified, then the pid of the calling process is used. Process groups +/// may be used to group together a set of processes in order for the OS to +/// apply some operations across the group. +/// +/// `setsid()` may be used to create a new process group. #[inline] pub fn setpgid(pid: pid_t, pgid: pid_t) -> Result<()> { let res = unsafe { libc::setpgid(pid, pgid) }; @@ -68,23 +122,39 @@ pub fn getpgid(pid: Option<pid_t>) -> Result<pid_t> { Errno::result(res) } +/// Create new session and set process group id (see +/// [setsid(2)](http://man7.org/linux/man-pages/man2/setsid.2.html)). #[inline] -pub fn tcgetgrp(fd: c_int) -> Result<pid_t> { - let res = unsafe { libc::tcgetpgrp(fd) }; - Errno::result(res) -} -#[inline] -pub fn tcsetpgrp(fd: c_int, pgrp: pid_t) -> Result<c_int> { - let res = unsafe { libc::tcsetpgrp(fd, pgrp) }; - Errno::result(res) +pub fn setsid() -> Result<pid_t> { + Errno::result(unsafe { libc::setsid() }) } +/// Get the caller's thread ID (see +/// [gettid(2)](http://man7.org/linux/man-pages/man2/gettid.2.html). +/// +/// This function is only available on Linux based systems. In a single +/// threaded process, the main thread will have the same ID as the process. In +/// a multithreaded process, each thread will have a unique thread id but the +/// same process ID. +/// +/// No error handling is required as a thread id should always exist for any +/// process, even if threads are not being used. #[cfg(any(target_os = "linux", target_os = "android"))] #[inline] pub fn gettid() -> pid_t { - unsafe { libc::syscall(libc::SYS_gettid) as pid_t } // no error handling, according to man page: "These functions are always successful." + unsafe { libc::syscall(libc::SYS_gettid) as pid_t } } +/// Create a copy of the specified file descriptor (see +/// [dup(2)](http://man7.org/linux/man-pages/man2/dup.2.html)). +/// +/// The new file descriptor will be have a new index but refer to the same +/// resource as the old file descriptor and the old and new file descriptors may +/// be used interchangeably. The new and old file descriptor share the same +/// underlying resource, offset, and file status flags. The actual index used +/// for the file descriptor will be the lowest fd index that is available. +/// +/// The two file descriptors do not share file descriptor flags (e.g. `FD_CLOEXEC`). #[inline] pub fn dup(oldfd: RawFd) -> Result<RawFd> { let res = unsafe { libc::dup(oldfd) }; @@ -92,6 +162,12 @@ pub fn dup(oldfd: RawFd) -> Result<RawFd> { Errno::result(res) } +/// Create a copy of the specified file descriptor using the specified fd (see +/// [dup(2)](http://man7.org/linux/man-pages/man2/dup.2.html)). +/// +/// This function behaves similar to `dup()` except that it will try to use the +/// specified fd instead of allocating a new one. See the man pages for more +/// detail on the exact behavior of this function. #[inline] pub fn dup2(oldfd: RawFd, newfd: RawFd) -> Result<RawFd> { let res = unsafe { libc::dup2(oldfd, newfd) }; @@ -99,6 +175,11 @@ pub fn dup2(oldfd: RawFd, newfd: RawFd) -> Result<RawFd> { Errno::result(res) } +/// Create a new copy of the specified file descriptor using the specified fd +/// and flags (see [dup(2)](http://man7.org/linux/man-pages/man2/dup.2.html)). +/// +/// This function behaves similar to `dup2()` but allows for flags to be +/// specified. pub fn dup3(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> { dup3_polyfill(oldfd, newfd, flags) } @@ -121,6 +202,11 @@ fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> { Ok(fd) } +/// Change the current working directory of the calling process (see +/// [chdir(2)](http://man7.org/linux/man-pages/man2/chdir.2.html)). +/// +/// This function may fail in a number of different scenarios. See the man +/// pages for additional details on possible failure cases. #[inline] pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> { let res = try!(path.with_nix_path(|cstr| { @@ -224,6 +310,17 @@ pub fn getcwd() -> Result<PathBuf> { } } +/// Change the ownership of the file at `path` to be owned by the specified +/// `owner` (user) and `group` (see +/// [chown(2)](http://man7.org/linux/man-pages/man2/lchown.2.html)). +/// +/// The owner/group for the provided path name will not be modified if `None` is +/// provided for that argument. Ownership change will be attempted for the path +/// only if `Some` owner/group is provided. +/// +/// This call may fail under a number of different situations. See [the man +/// pages](http://man7.org/linux/man-pages/man2/lchown.2.html#ERRORS) for +/// additional details. #[inline] pub fn chown<P: ?Sized + NixPath>(path: &P, owner: Option<uid_t>, group: Option<gid_t>) -> Result<()> { let res = try!(path.with_nix_path(|cstr| { |