summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzethra <jediben97@gmail.com>2016-10-31 13:48:44 -0400
committerzethra <jediben97@gmail.com>2016-10-31 13:48:44 -0400
commitc0d6829cc43ffd37d535de0465018cb3b05af753 (patch)
tree152d6c259da5b6d3aeab84c0689ebe03bb082774 /src
parent18c85d5022f7abfea07724eaea0f6e3d77aaf733 (diff)
parent652e730f106fd3c103ba7549e64a7c992a72f11a (diff)
downloadnix-c0d6829cc43ffd37d535de0465018cb3b05af753.zip
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs13
-rw-r--r--src/sys/event.rs7
-rw-r--r--src/unistd.rs127
3 files changed, 132 insertions, 15 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 8dbf9fe0..ab8339ef 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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| {