summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md6
-rw-r--r--README.md2
-rw-r--r--nix-test/build.rs2
-rw-r--r--src/fcntl.rs40
-rw-r--r--src/mqueue.rs20
-rw-r--r--src/poll.rs2
-rw-r--r--src/pty.rs6
-rw-r--r--src/sys/aio.rs42
-rw-r--r--src/sys/pthread.rs2
-rw-r--r--src/sys/select.rs6
-rw-r--r--src/sys/signal.rs4
-rw-r--r--src/sys/socket/mod.rs35
-rw-r--r--src/unistd.rs180
-rw-r--r--test/sys/test_aio.rs24
-rw-r--r--test/test_fcntl.rs15
-rw-r--r--test/test_unistd.rs18
16 files changed, 319 insertions, 85 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0a0ee113..13a7104b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -30,6 +30,12 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Added socket option variant that enables the timestamp socket
control message: `nix::sys::socket::sockopt::ReceiveTimestamp`
([#663](https://github.com/nix-rust/nix/pull/663))
+- Added more accessor methods for `AioCb`
+ ([#773](https://github.com/nix-rust/nix/pull/773))
+- Add nix::sys::fallocate
+ ([#768](https:://github.com/nix-rust/nix/pull/768))
+- Added `nix::unistd::mkfifo`.
+ ([#602](https://github.com/nix-rust/nix/pull/774))
### Changed
- Renamed existing `ptrace` wrappers to encourage namespacing ([#692](https://github.com/nix-rust/nix/pull/692))
diff --git a/README.md b/README.md
index 3fd19a92..5146d57c 100644
--- a/README.md
+++ b/README.md
@@ -54,6 +54,7 @@ Tier 1:
* arm-unknown-linux-gnueabi
* armv7-unknown-linux-gnueabihf
* i686-apple-darwin
+ * i686-unknown-freebsd
* i686-unknown-linux-gnu
* i686-unknown-linux-musl
* mips-unknown-linux-gnu
@@ -77,7 +78,6 @@ Tier 2:
* armv7s-apple-ios
* i386-apple-ios
* i686-linux-android (requires Rust >= 1.18)
- * i686-unknown-freebsd
* powerpc-unknown-linux-gnu
* s390x-unknown-linux-gnu
* x86_64-apple-ios
diff --git a/nix-test/build.rs b/nix-test/build.rs
index 0c18e1c8..5d1b1bba 100644
--- a/nix-test/build.rs
+++ b/nix-test/build.rs
@@ -13,7 +13,7 @@ pub fn main() {
"UNKNOWN"
};
- gcc::Config::new()
+ gcc::Build::new()
.file("src/const.c")
.file("src/sizes.c")
.define(os, None)
diff --git a/src/fcntl.rs b/src/fcntl.rs
index 003c316c..f99036d6 100644
--- a/src/fcntl.rs
+++ b/src/fcntl.rs
@@ -341,3 +341,43 @@ pub fn vmsplice(fd: RawFd, iov: &[IoVec<&[u8]>], flags: SpliceFFlags) -> Result<
Errno::result(ret).map(|r| r as usize)
}
+#[cfg(any(target_os = "linux"))]
+libc_bitflags!(
+ /// Mode argument flags for fallocate determining operation performed on a given range.
+ pub struct FallocateFlags: libc::c_int {
+ /// File size is not changed.
+ ///
+ /// offset + len can be greater than file size.
+ FALLOC_FL_KEEP_SIZE;
+ /// Deallocates space by creating a hole.
+ ///
+ /// Must be ORed with FALLOC_FL_KEEP_SIZE. Byte range starts at offset and continues for len bytes.
+ FALLOC_FL_PUNCH_HOLE;
+ /// Removes byte range from a file without leaving a hole.
+ ///
+ /// Byte range to collapse starts at offset and continues for len bytes.
+ FALLOC_FL_COLLAPSE_RANGE;
+ /// Zeroes space in specified byte range.
+ ///
+ /// Byte range starts at offset and continues for len bytes.
+ FALLOC_FL_ZERO_RANGE;
+ /// Increases file space by inserting a hole within the file size.
+ ///
+ /// Does not overwrite existing data. Hole starts at offset and continues for len bytes.
+ FALLOC_FL_INSERT_RANGE;
+ /// Shared file data extants are made private to the file.
+ ///
+ /// Gaurantees that a subsequent write will not fail due to lack of space.
+ FALLOC_FL_UNSHARE_RANGE;
+ }
+);
+
+/// Manipulates file space.
+///
+/// Allows the caller to directly manipulate the allocated disk space for the
+/// file referred to by fd.
+#[cfg(any(target_os = "linux"))]
+pub fn fallocate(fd: RawFd, mode: FallocateFlags, offset: libc::off_t, len: libc::off_t) -> Result<c_int> {
+ let res = unsafe { libc::fallocate(fd, mode.bits(), offset, len) };
+ Errno::result(res)
+}
diff --git a/src/mqueue.rs b/src/mqueue.rs
index af4ebe77..b4a791c9 100644
--- a/src/mqueue.rs
+++ b/src/mqueue.rs
@@ -63,6 +63,9 @@ impl MqAttr {
}
+/// Open a message queue
+///
+/// See also [mq_open(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_open.html)
pub fn mq_open(name: &CString,
oflag: MQ_OFlag,
mode: Mode,
@@ -80,16 +83,25 @@ pub fn mq_open(name: &CString,
Errno::result(res)
}
+/// Remove a message queue
+///
+/// See also [mq_unlink(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_unlink.html)
pub fn mq_unlink(name: &CString) -> Result<()> {
let res = unsafe { libc::mq_unlink(name.as_ptr()) };
Errno::result(res).map(drop)
}
+/// Close a message queue
+///
+/// See also [mq_close(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_close.html)
pub fn mq_close(mqdes: mqd_t) -> Result<()> {
let res = unsafe { libc::mq_close(mqdes) };
Errno::result(res).map(drop)
}
+/// Receive a message from a message queue
+///
+/// See also [mq_receive(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html)
pub fn mq_receive(mqdes: mqd_t, message: &mut [u8], msg_prio: &mut u32) -> Result<usize> {
let len = message.len() as size_t;
let res = unsafe {
@@ -101,6 +113,9 @@ pub fn mq_receive(mqdes: mqd_t, message: &mut [u8], msg_prio: &mut u32) -> Resul
Errno::result(res).map(|r| r as usize)
}
+/// Send a message to a message queue
+///
+/// See also [mq_send(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html)
pub fn mq_send(mqdes: mqd_t, message: &[u8], msq_prio: u32) -> Result<()> {
let res = unsafe {
libc::mq_send(mqdes,
@@ -111,6 +126,9 @@ pub fn mq_send(mqdes: mqd_t, message: &[u8], msq_prio: u32) -> Result<()> {
Errno::result(res).map(drop)
}
+/// Get message queue attributes
+///
+/// See also [mq_getattr(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_getattr.html)
pub fn mq_getattr(mqd: mqd_t) -> Result<MqAttr> {
let mut attr = unsafe { mem::uninitialized::<libc::mq_attr>() };
let res = unsafe { libc::mq_getattr(mqd, &mut attr) };
@@ -121,7 +139,7 @@ pub fn mq_getattr(mqd: mqd_t) -> Result<MqAttr> {
/// Returns the old attributes
/// It is recommend to use the `mq_set_nonblock()` and `mq_remove_nonblock()` convenience functions as they are easier to use
///
-/// [Further reading](http://man7.org/linux/man-pages/man3/mq_setattr.3.html)
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_setattr.html)
pub fn mq_setattr(mqd: mqd_t, newattr: &MqAttr) -> Result<MqAttr> {
let mut attr = unsafe { mem::uninitialized::<libc::mq_attr>() };
let res = unsafe { libc::mq_setattr(mqd, &newattr.mq_attr as *const libc::mq_attr, &mut attr) };
diff --git a/src/poll.rs b/src/poll.rs
index 25ff170f..30a46688 100644
--- a/src/poll.rs
+++ b/src/poll.rs
@@ -91,7 +91,7 @@ libc_bitflags! {
}
/// `poll` waits for one of a set of file descriptors to become ready to perform I/O.
-/// ([`poll(2)`](http://man7.org/linux/man-pages/man2/poll.2.html))
+/// ([`poll(2)`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html))
///
/// `fds` contains all [`PollFd`](struct.PollFd.html) to poll.
/// The function will return as soon as any event occur for any of these `PollFd`s.
diff --git a/src/pty.rs b/src/pty.rs
index e6b33aa2..98443d61 100644
--- a/src/pty.rs
+++ b/src/pty.rs
@@ -61,7 +61,7 @@ impl Drop for PtyMaster {
}
/// Grant access to a slave pseudoterminal (see
-/// [grantpt(3)](http://man7.org/linux/man-pages/man3/grantpt.3.html))
+/// [grantpt(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/grantpt.html))
///
/// `grantpt()` changes the mode and owner of the slave pseudoterminal device corresponding to the
/// master pseudoterminal referred to by `fd`. This is a necessary step towards opening the slave.
@@ -75,7 +75,7 @@ pub fn grantpt(fd: &PtyMaster) -> Result<()> {
}
/// Open a pseudoterminal device (see
-/// [posix_openpt(3)](http://man7.org/linux/man-pages/man3/posix_openpt.3.html))
+/// [posix_openpt(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_openpt.html))
///
/// `posix_openpt()` returns a file descriptor to an existing unused pseuterminal master device.
///
@@ -176,7 +176,7 @@ pub fn ptsname_r(fd: &PtyMaster) -> Result<String> {
}
/// Unlock a pseudoterminal master/slave pseudoterminal pair (see
-/// [unlockpt(3)](http://man7.org/linux/man-pages/man3/unlockpt.3.html))
+/// [unlockpt(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlockpt.html))
///
/// `unlockpt()` unlocks the slave pseudoterminal device corresponding to the master pseudoterminal
/// referred to by `fd`. This must be called before trying to open the slave side of a
diff --git a/src/sys/aio.rs b/src/sys/aio.rs
index 22bd3959..4be0da7b 100644
--- a/src/sys/aio.rs
+++ b/src/sys/aio.rs
@@ -84,6 +84,11 @@ pub struct AioCb<'a> {
}
impl<'a> AioCb<'a> {
+ /// Returns the underlying file descriptor associated with the `AioCb`
+ pub fn fd(&self) -> RawFd {
+ self.aiocb.aio_fildes
+ }
+
/// Constructs a new `AioCb` with no associated buffer.
///
/// The resulting `AioCb` structure is suitable for use with `AioCb::fsync`.
@@ -239,6 +244,38 @@ impl<'a> AioCb<'a> {
})
}
+ /// Returns the `aiocb`'s `LioOpcode` field
+ ///
+ /// If the value cannot be represented as an `LioOpcode`, returns `None`
+ /// instead.
+ pub fn lio_opcode(&self) -> Option<LioOpcode> {
+ match self.aiocb.aio_lio_opcode {
+ libc::LIO_READ => Some(LioOpcode::LIO_READ),
+ libc::LIO_WRITE => Some(LioOpcode::LIO_WRITE),
+ libc::LIO_NOP => Some(LioOpcode::LIO_NOP),
+ _ => None
+ }
+ }
+
+ /// Returns the requested length of the aio operation in bytes
+ ///
+ /// This method returns the *requested* length of the operation. To get the
+ /// number of bytes actually read or written by a completed operation, use
+ /// `aio_return` instead.
+ pub fn nbytes(&self) -> usize {
+ self.aiocb.aio_nbytes
+ }
+
+ /// Returns the file offset stored in the `AioCb`
+ pub fn offset(&self) -> off_t {
+ self.aiocb.aio_offset
+ }
+
+ /// Returns the priority of the `AioCb`
+ pub fn priority(&self) -> libc::c_int {
+ self.aiocb.aio_reqprio
+ }
+
/// Asynchronously reads from a file descriptor into a buffer
pub fn read(&mut self) -> Result<()> {
assert!(self.mutable, "Can't read into an immutable buffer");
@@ -250,6 +287,11 @@ impl<'a> AioCb<'a> {
})
}
+ /// Returns the `SigEvent` stored in the `AioCb`
+ pub fn sigevent(&self) -> SigEvent {
+ SigEvent::from(&self.aiocb.aio_sigevent)
+ }
+
/// Retrieve return status of an asynchronous operation. Should only be
/// called once for each `AioCb`, after `AioCb::error` indicates that it has
/// completed. The result is the same as for `read`, `write`, of `fsync`.
diff --git a/src/sys/pthread.rs b/src/sys/pthread.rs
index 83b4669a..d533946b 100644
--- a/src/sys/pthread.rs
+++ b/src/sys/pthread.rs
@@ -3,7 +3,7 @@ use libc::{self, pthread_t};
pub type Pthread = pthread_t;
/// Obtain ID of the calling thread (see
-/// [pthread_self(3)](http://man7.org/linux/man-pages/man3/pthread_self.3.html)
+/// [pthread_self(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_self.html)
///
/// The thread ID returned by pthread_self() is not the same thing as
/// the kernel thread ID returned by a call to gettid(2).
diff --git a/src/sys/select.rs b/src/sys/select.rs
index 07190fa1..252fa6bc 100644
--- a/src/sys/select.rs
+++ b/src/sys/select.rs
@@ -66,7 +66,7 @@ impl FdSet {
}
}
-/// Monitors file descriptors for readiness (see [select(2)]).
+/// Monitors file descriptors for readiness
///
/// Returns the total number of ready file descriptors in all sets. The sets are changed so that all
/// file descriptors that are ready for the given operation are set.
@@ -84,7 +84,9 @@ impl FdSet {
/// * `timeout`: Maximum time to wait for descriptors to become ready (`None` to block
/// indefinitely).
///
-/// [select(2)]: http://man7.org/linux/man-pages/man2/select.2.html
+/// # References
+///
+/// [select(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html)
/// [`FdSet::highest`]: struct.FdSet.html#method.highest
pub fn select<'a, N, R, W, E, T>(nfds: N,
readfds: R,
diff --git a/src/sys/signal.rs b/src/sys/signal.rs
index c53b5f5c..b22b665c 100644
--- a/src/sys/signal.rs
+++ b/src/sys/signal.rs
@@ -419,8 +419,8 @@ pub unsafe fn sigaction(signal: Signal, sigaction: &SigAction) -> Result<SigActi
///
/// If both `set` and `oldset` is None, this function is a no-op.
///
-/// For more information, visit the [pthread_sigmask](http://man7.org/linux/man-pages/man3/pthread_sigmask.3.html),
-/// or [sigprocmask](http://man7.org/linux/man-pages/man2/sigprocmask.2.html) man pages.
+/// For more information, visit the [pthread_sigmask](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_sigmask.html),
+/// or [sigprocmask](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html) man pages.
pub fn pthread_sigmask(how: SigmaskHow,
set: Option<&SigSet>,
oldset: Option<&mut SigSet>) -> Result<()> {
diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs
index baddf34e..e333f005 100644
--- a/src/sys/socket/mod.rs
+++ b/src/sys/socket/mod.rs
@@ -165,7 +165,7 @@ libc_bitflags!{
/// file descriptor using the `SCM_RIGHTS` operation (described in
/// [unix(7)](https://linux.die.net/man/7/unix)).
/// This flag is useful for the same reasons as the `O_CLOEXEC` flag of
- /// [open(2)](https://linux.die.net/man/2/open).
+ /// [open(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html).
///
/// Only used in [`recvmsg`](fn.recvmsg.html) function.
#[cfg(any(target_os = "linux", target_os = "android"))]
@@ -548,7 +548,7 @@ pub fn recvmsg<'a, T>(fd: RawFd, iov: &[IoVec<&mut [u8]>], cmsg_buffer: Option<&
/// protocols may exist, in which case a particular protocol must be
/// specified in this manner.
///
-/// [Further reading](http://man7.org/linux/man-pages/man2/socket.2.html)
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html)
pub fn socket<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: T) -> Result<RawFd> {
let mut ty = ty as c_int;
let protocol = match protocol.into() {
@@ -590,7 +590,7 @@ pub fn socket<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType
/// Create a pair of connected sockets
///
-/// [Further reading](http://man7.org/linux/man-pages/man2/socketpair.2.html)
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/socketpair.html)
pub fn socketpair<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, protocol: T,
flags: SockFlag) -> Result<(RawFd, RawFd)> {
let mut ty = ty as c_int;
@@ -636,7 +636,7 @@ pub fn socketpair<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: Sock
/// Listen for connections on a socket
///
-/// [Further reading](http://man7.org/linux/man-pages/man2/listen.2.html)
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html)
pub fn listen(sockfd: RawFd, backlog: usize) -> Result<()> {
let res = unsafe { libc::listen(sockfd, backlog as c_int) };
@@ -645,7 +645,7 @@ pub fn listen(sockfd: RawFd, backlog: usize) -> Result<()> {
/// Bind a name to a socket
///
-/// [Further reading](http://man7.org/linux/man-pages/man2/bind.2.html)
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html)
#[cfg(not(all(target_os="android", target_pointer_width="64")))]
pub fn bind(fd: RawFd, addr: &SockAddr) -> Result<()> {
let res = unsafe {
@@ -673,7 +673,7 @@ pub fn bind(fd: RawFd, addr: &SockAddr) -> Result<()> {
/// Accept a connection on a socket
///
-/// [Further reading](http://man7.org/linux/man-pages/man2/accept.2.html)
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html)
pub fn accept(sockfd: RawFd) -> Result<RawFd> {
let res = unsafe { libc::accept(sockfd, ptr::null_mut(), ptr::null_mut()) };
@@ -727,7 +727,7 @@ fn accept4_polyfill(sockfd: RawFd, flags: SockFlag) -> Result<RawFd> {
/// Initiate a connection on a socket
///
-/// [Further reading](http://man7.org/linux/man-pages/man2/connect.2.html)
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html)
pub fn connect(fd: RawFd, addr: &SockAddr) -> Result<()> {
let res = unsafe {
let (ptr, len) = addr.as_ffi_pair();
@@ -740,7 +740,7 @@ pub fn connect(fd: RawFd, addr: &SockAddr) -> Result<()> {
/// Receive data from a connection-oriented socket. Returns the number of
/// bytes read
///
-/// [Further reading](http://man7.org/linux/man-pages/man2/recv.2.html)
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html)
pub fn recv(sockfd: RawFd, buf: &mut [u8], flags: MsgFlags) -> Result<usize> {
unsafe {
let ret = ffi::recv(
@@ -756,7 +756,7 @@ pub fn recv(sockfd: RawFd, buf: &mut [u8], flags: MsgFlags) -> Result<usize> {
/// Receive data from a connectionless or connection-oriented socket. Returns
/// the number of bytes read and the socket address of the sender.
///
-/// [Further reading](http://man7.org/linux/man-pages/man2/recvmsg.2.html)
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html)
pub fn recvfrom(sockfd: RawFd, buf: &mut [u8]) -> Result<(usize, SockAddr)> {
unsafe {
let addr: sockaddr_storage = mem::zeroed();
@@ -775,6 +775,9 @@ pub fn recvfrom(sockfd: RawFd, buf: &mut [u8]) -> Result<(usize, SockAddr)> {
}
}
+/// Send a message to a socket
+///
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html)
pub fn sendto(fd: RawFd, buf: &[u8], addr: &SockAddr, flags: MsgFlags) -> Result<usize> {
let ret = unsafe {
let (ptr, len) = addr.as_ffi_pair();
@@ -786,7 +789,7 @@ pub fn sendto(fd: RawFd, buf: &[u8], addr: &SockAddr, flags: MsgFlags) -> Result
/// Send data to a connection-oriented socket. Returns the number of bytes read
///
-/// [Further reading](http://man7.org/linux/man-pages/man2/send.2.html)
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html)
pub fn send(fd: RawFd, buf: &[u8], flags: MsgFlags) -> Result<usize> {
let ret = unsafe {
libc::send(fd, buf.as_ptr() as *const c_void, buf.len() as size_t, flags.bits())
@@ -819,7 +822,7 @@ pub struct ucred {
/// The protocol level at which to get / set socket options. Used as an
/// argument to `getsockopt` and `setsockopt`.
///
-/// [Further reading](http://man7.org/linux/man-pages/man2/setsockopt.2.html)
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html)
#[repr(i32)]
pub enum SockLevel {
Socket = libc::SOL_SOCKET,
@@ -851,21 +854,21 @@ pub trait SetSockOpt : Copy {
/// Get the current value for the requested socket option
///
-/// [Further reading](http://man7.org/linux/man-pages/man2/getsockopt.2.html)
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html)
pub fn getsockopt<O: GetSockOpt>(fd: RawFd, opt: O) -> Result<O::Val> {
opt.get(fd)
}
/// Sets the value for the requested socket option
///
-/// [Further reading](http://man7.org/linux/man-pages/man2/setsockopt.2.html)
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html)
pub fn setsockopt<O: SetSockOpt>(fd: RawFd, opt: O, val: &O::Val) -> Result<()> {
opt.set(fd, val)
}
/// Get the address of the peer connected to the socket `fd`.
///
-/// [Further reading](http://man7.org/linux/man-pages/man2/getpeername.2.html)
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html)
pub fn getpeername(fd: RawFd) -> Result<SockAddr> {
unsafe {
let addr: sockaddr_storage = mem::uninitialized();
@@ -881,7 +884,7 @@ pub fn getpeername(fd: RawFd) -> Result<SockAddr> {
/// Get the current address to which the socket `fd` is bound.
///
-/// [Further reading](http://man7.org/linux/man-pages/man2/getsockname.2.html)
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html)
pub fn getsockname(fd: RawFd) -> Result<SockAddr> {
unsafe {
let addr: sockaddr_storage = mem::uninitialized();
@@ -946,7 +949,7 @@ pub enum Shutdown {
/// Shut down part of a full-duplex connection.
///
-/// [Further reading](http://man7.org/linux/man-pages/man2/shutdown.2.html)
+/// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html)
pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> {
unsafe {
use libc::shutdown;
diff --git a/src/unistd.rs b/src/unistd.rs
index fad51272..401357d3 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -169,7 +169,7 @@ impl ForkResult {
}
/// Create a new child process duplicating the parent process ([see
-/// fork(2)](http://man7.org/linux/man-pages/man2/fork.2.html)).
+/// fork(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html)).
///
/// After calling the fork system call (successfully) two processes will
/// be created that are identical with the exception of their pid and the
@@ -219,7 +219,7 @@ pub fn fork() -> Result<ForkResult> {
}
/// Get the pid of this process (see
-/// [getpid(2)](http://man7.org/linux/man-pages/man2/getpid.2.html)).
+/// [getpid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpid.html)).
///
/// Since you are running code, there is always a pid to return, so there
/// is no error case that needs to be handled.
@@ -229,7 +229,7 @@ pub fn getpid() -> Pid {
}
/// Get the pid of this processes' parent (see
-/// [getpid(2)](http://man7.org/linux/man-pages/man2/getpid.2.html)).
+/// [getpid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getppid.html)).
///
/// There is always a parent pid to return, so there is no error case that needs
/// to be handled.
@@ -239,7 +239,7 @@ pub fn getppid() -> Pid {
}
/// Set a process group ID (see
-/// [setpgid(2)](http://man7.org/linux/man-pages/man2/setpgid.2.html)).
+/// [setpgid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgid.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
@@ -259,7 +259,7 @@ pub fn getpgid(pid: Option<Pid>) -> Result<Pid> {
}
/// Create new session and set process group id (see
-/// [setsid(2)](http://man7.org/linux/man-pages/man2/setsid.2.html)).
+/// [setsid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsid.html)).
#[inline]
pub fn setsid() -> Result<Pid> {
Errno::result(unsafe { libc::setsid() }).map(Pid)
@@ -267,7 +267,7 @@ pub fn setsid() -> Result<Pid> {
/// Get the terminal foreground process group (see
-/// [tcgetpgrp(3)](http://man7.org/linux/man-pages/man3/tcgetpgrp.3.html)).
+/// [tcgetpgrp(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetpgrp.html)).
///
/// Get the group process id (GPID) of the foreground process group on the
/// terminal associated to file descriptor (FD).
@@ -277,7 +277,7 @@ pub fn tcgetpgrp(fd: c_int) -> Result<Pid> {
Errno::result(res).map(Pid)
}
/// Set the terminal foreground process group (see
-/// [tcgetpgrp(3)](http://man7.org/linux/man-pages/man3/tcgetpgrp.3.html)).
+/// [tcgetpgrp(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsetpgrp.html)).
///
/// Get the group process id (PGID) to the foreground process group on the
/// terminal associated to file descriptor (FD).
@@ -289,7 +289,7 @@ pub fn tcsetpgrp(fd: c_int, pgrp: Pid) -> Result<()> {
/// Get the group id of the calling process (see
-///[getpgrp(3)](http://man7.org/linux/man-pages/man3/getpgrp.3p.html)).
+///[getpgrp(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgrp.html)).
///
/// Get the process group id (PGID) of the calling process.
/// According to the man page it is always successful.
@@ -315,7 +315,7 @@ pub fn gettid() -> Pid {
}
/// Create a copy of the specified file descriptor (see
-/// [dup(2)](http://man7.org/linux/man-pages/man2/dup.2.html)).
+/// [dup(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.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
@@ -332,7 +332,7 @@ pub fn dup(oldfd: RawFd) -> Result<RawFd> {
}
/// 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)).
+/// [dup(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.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
@@ -372,7 +372,7 @@ fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
}
/// Change the current working directory of the calling process (see
-/// [chdir(2)](http://man7.org/linux/man-pages/man2/chdir.2.html)).
+/// [chdir(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html)).
///
/// This function may fail in a number of different scenarios. See the man
/// pages for additional details on possible failure cases.
@@ -387,7 +387,7 @@ pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
/// Change the current working directory of the process to the one
/// given as an open file descriptor (see
-/// [fchdir(2)](http://man7.org/linux/man-pages/man2/fchdir.2.html)).
+/// [fchdir(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchdir.html)).
///
/// This function may fail in a number of different scenarios. See the man
/// pages for additional details on possible failure cases.
@@ -398,7 +398,7 @@ pub fn fchdir(dirfd: RawFd) -> Result<()> {
Errno::result(res).map(drop)
}
-/// Creates new directory `path` with access rights `mode`.
+/// Creates new directory `path` with access rights `mode`. (see [mkdir(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdir.html))
///
/// # Errors
///
@@ -408,9 +408,6 @@ pub fn fchdir(dirfd: RawFd) -> Result<()> {
/// - the path already exists
/// - the path name is too long (longer than `PATH_MAX`, usually 4096 on linux, 1024 on OS X)
///
-/// For a full list consult
-/// [man mkdir(2)](http://man7.org/linux/man-pages/man2/mkdir.2.html#ERRORS)
-///
/// # Example
///
/// ```rust
@@ -441,6 +438,49 @@ pub fn mkdir<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
Errno::result(res).map(drop)
}
+/// Creates new fifo special file (named pipe) with path `path` and access rights `mode`.
+///
+/// # Errors
+///
+/// There are several situations where mkfifo might fail:
+///
+/// - current user has insufficient rights in the parent directory
+/// - the path already exists
+/// - the path name is too long (longer than `PATH_MAX`, usually 4096 on linux, 1024 on OS X)
+///
+/// For a full list consult
+/// [posix specification](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifo.html)
+///
+/// # Example
+///
+/// ```rust
+/// extern crate tempdir;
+/// extern crate nix;
+///
+/// use nix::unistd;
+/// use nix::sys::stat;
+/// use tempdir::TempDir;
+///
+/// fn main() {
+/// let tmp_dir = TempDir::new("test_fifo").unwrap();
+/// let fifo_path = tmp_dir.path().join("foo.pipe");
+///
+/// // create new fifo and give read, write and execute rights to the owner
+/// match unistd::mkfifo(&fifo_path, stat::S_IRWXU) {
+/// Ok(_) => println!("created {:?}", fifo_path),
+/// Err(err) => println!("Error creating fifo: {}", err),
+/// }
+/// }
+/// ```
+#[inline]
+pub fn mkfifo<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
+ let res = try!(path.with_nix_path(|cstr| {
+ unsafe { libc::mkfifo(cstr.as_ptr(), mode.bits() as mode_t) }
+ }));
+
+ Errno::result(res).map(drop)
+}
+
/// Returns the current directory as a PathBuf
///
/// Err is returned if the current user doesn't have the permission to read or search a component
@@ -494,15 +534,11 @@ 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)).
+/// [chown(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/chown.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>, group: Option<Gid>) -> Result<()> {
let res = try!(path.with_nix_path(|cstr| {
@@ -527,7 +563,7 @@ fn to_exec_array(args: &[CString]) -> Vec<*const c_char> {
}
/// Replace the current process image with a new one (see
-/// [exec(3)](http://man7.org/linux/man-pages/man3/exec.3.html)).
+/// [exec(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)).
///
/// See the `::nix::unistd::execve` system call for additional details. `execv`
/// performs the same action but does not allow for customization of the
@@ -545,18 +581,13 @@ pub fn execv(path: &CString, argv: &[CString]) -> Result<Void> {
/// Replace the current process image with a new one (see
-/// [execve(2)](http://man7.org/linux/man-pages/man2/execve.2.html)).
+/// [execve(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)).
///
/// The execve system call allows for another process to be "called" which will
/// replace the current process image. That is, this process becomes the new
/// command that is run. On success, this function will not return. Instead,
/// the new program will run until it exits.
///
-/// If an error occurs, this function will return with an indication of the
-/// cause of failure. See
-/// [execve(2)#errors](http://man7.org/linux/man-pages/man2/execve.2.html#ERRORS)
-/// for a list of potential problems that maight cause execv to fail.
-///
/// `::nix::unistd::execv` and `::nix::unistd::execve` take as arguments a slice
/// of `::std::ffi::CString`s for `args` and `env` (for `execve`). Each element
/// in the `args` list is an argument to the new process. Each element in the
@@ -575,9 +606,9 @@ pub fn execve(path: &CString, args: &[CString], env: &[CString]) -> Result<Void>
/// Replace the current process image with a new one and replicate shell `PATH`
/// searching behavior (see
-/// [exec(3)](http://man7.org/linux/man-pages/man3/exec.3.html)).
+/// [exec(3)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)).
///
-/// See `::nix::unistd::execve` for additoinal details. `execvp` behaves the
+/// See `::nix::unistd::execve` for additional details. `execvp` behaves the
/// same as execv except that it will examine the `PATH` environment variables
/// for file names not specified with a leading slash. For example, `execv`
/// would not work if "bash" was specified for the path argument, but `execvp`
@@ -603,13 +634,6 @@ pub fn execvp(filename: &CString, args: &[CString]) -> Result<Void> {
///
/// This function is similar to `execve`, except that the program to be executed
/// is referenced as a file descriptor instead of a path.
-///
-/// # Errors
-///
-/// If an error occurs, this function will return with an indication of the
-/// cause of failure. See
-/// [fexecve(2)#errors](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fexecve.html#tag_16_111_05)
-/// for a list of error conditions.
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
target_os = "netbsd", target_os = "openbsd", target_os = "linux"))]
#[inline]
@@ -649,19 +673,13 @@ pub fn fexecve(fd: RawFd, args: &[CString], env: &[CString]) -> Result<Void> {
/// descriptors will remain identical after daemonizing.
/// * `noclose = false`: The process' stdin, stdout, and stderr will point to
/// `/dev/null` after daemonizing.
-///
-/// The underlying implementation (in libc) calls both
-/// [fork(2)](http://man7.org/linux/man-pages/man2/fork.2.html) and
-/// [setsid(2)](http://man7.org/linux/man-pages/man2/setsid.2.html) and, as
-/// such, error that could be returned by either of those functions could also
-/// show up as errors here.
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)
}
/// Set the system host name (see
-/// [gethostname(2)](http://man7.org/linux/man-pages/man2/gethostname.2.html)).
+/// [sethostname(2)](http://man7.org/linux/man-pages/man2/gethostname.2.html)).
///
/// Given a name, attempt to update the system host name to the given string.
/// On some systems, the host name is limited to as few as 64 bytes. An error
@@ -688,7 +706,7 @@ pub fn sethostname<S: AsRef<OsStr>>(name: S) -> Result<()> {
/// Get the host name and store it in the provided buffer, returning a pointer
/// the CStr in that buffer on success (see
-/// [gethostname(2)](http://man7.org/linux/man-pages/man2/gethostname.2.html)).
+/// [gethostname(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html)).
///
/// This function call attempts to get the host name for the running system and
/// store it in a provided buffer. The buffer will be populated with bytes up
@@ -722,7 +740,8 @@ pub fn gethostname<'a>(buffer: &'a mut [u8]) -> Result<&'a CStr> {
/// Be aware that many Rust types implicitly close-on-drop, including
/// `std::fs::File`. Explicitly closing them with this method too can result in
/// a double-close condition, which can cause confusing `EBADF` errors in
-/// seemingly unrelated code. Caveat programmer.
+/// seemingly unrelated code. Caveat programmer. See also
+/// [close(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html).
///
/// # Examples
///
@@ -756,12 +775,18 @@ pub fn close(fd: RawFd) -> Result<()> {
Errno::result(res).map(drop)
}
+/// Read from a raw file descriptor.
+///
+/// See also [read(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html)
pub fn read(fd: RawFd, buf: &mut [u8]) -> Result<usize> {
let res = unsafe { libc::read(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t) };
Errno::result(res).map(|r| r as usize)
}
+/// Write to a raw file descriptor.
+///
+/// See also [write(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html)
pub fn write(fd: RawFd, buf: &[u8]) -> Result<usize> {
let res = unsafe { libc::write(fd, buf.as_ptr() as *const c_void, buf.len() as size_t) };
@@ -799,6 +824,9 @@ pub enum Whence {
SeekHole = libc::SEEK_HOLE
}
+/// Move the read/write file offset.
+///
+/// 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) };
@@ -812,6 +840,9 @@ pub fn lseek64(fd: RawFd, offset: libc::off64_t, whence: Whence) -> Result<libc:
Errno::result(res).map(|r| r as libc::off64_t)
}
+/// Create an interprocess channel.
+///
+/// See also [pipe(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pipe.html)
pub fn pipe() -> Result<(RawFd, RawFd)> {
unsafe {
let mut fds: [c_int; 2] = mem::uninitialized();
@@ -884,6 +915,10 @@ fn pipe2_setflags(fd1: RawFd, fd2: RawFd, flags: OFlag) -> Result<()> {
}
}
+/// Truncate a file to a specified length
+///
+/// See also
+/// [ftruncate(2)](http://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)
}
@@ -905,6 +940,9 @@ pub fn isatty(fd: RawFd) -> Result<bool> {
}
}
+/// Remove a directory entry
+///
+/// See also [unlink(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html)
pub fn unlink<P: ?Sized + NixPath>(path: &P) -> Result<()> {
let res = try!(path.with_nix_path(|cstr| {
unsafe {
@@ -923,6 +961,9 @@ pub fn chroot<P: ?Sized + NixPath>(path: &P) -> Result<()> {
Errno::result(res).map(drop)
}
+/// Synchronize changes to a file
+///
+/// See also [fsync(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html)
#[inline]
pub fn fsync(fd: RawFd) -> Result<()> {
let res = unsafe { libc::fsync(fd) };
@@ -930,6 +971,10 @@ pub fn fsync(fd: RawFd) -> Result<()> {
Errno::result(res).map(drop)
}
+/// Synchronize the data of a file
+///
+/// See also
+/// [fdatasync(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html)
// `fdatasync(2) is in POSIX, but in libc it is only defined in `libc::notbsd`.
// TODO: exclude only Apple systems after https://github.com/rust-lang/libc/pull/211
#[cfg(any(target_os = "linux",
@@ -942,32 +987,49 @@ pub fn fdatasync(fd: RawFd) -> Result<()> {
Errno::result(res).map(drop)
}
-// POSIX requires that getuid, geteuid, getgid, getegid are always successful,
-// so no need to check return value or errno. See:
-// - http://pubs.opengroup.org/onlinepubs/9699919799/functions/getuid.html
-// - http://pubs.opengroup.org/onlinepubs/9699919799/functions/geteuid.html
-// - http://pubs.opengroup.org/onlinepubs/9699919799/functions/getgid.html
-// - http://pubs.opengroup.org/onlinepubs/9699919799/functions/geteuid.html
+/// Get a real user ID
+///
+/// See also [getuid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getuid.html)
+// POSIX requires that getuid is always successful, so no need to check return
+// value or errno.
#[inline]
pub fn getuid() -> Uid {
Uid(unsafe { libc::getuid() })
}
+/// Get the effective user ID
+///
+/// See also [geteuid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/geteuid.html)
+// POSIX requires that geteuid is always successful, so no need to check return
+// value or errno.
#[inline]
pub fn geteuid() -> Uid {
Uid(unsafe { libc::geteuid() })
}
+/// Get the real group ID
+///
+/// See also [getgid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getgid.html)
+// POSIX requires that getgid is always successful, so no need to check return
+// value or errno.
#[inline]
pub fn getgid() -> Gid {
Gid(unsafe { libc::getgid() })
}
+/// Get the effective group ID
+///
+/// See also [getegid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getegid.html)
+// POSIX requires that getegid is always successful, so no need to check return
+// value or errno.
#[inline]
pub fn getegid() -> Gid {
Gid(unsafe { libc::getegid() })
}
+/// Set the user ID
+///
+/// See also [setuid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setuid.html)
#[inline]
pub fn setuid(uid: Uid) -> Result<()> {
let res = unsafe { libc::setuid(uid.into()) };
@@ -975,6 +1037,9 @@ pub fn setuid(uid: Uid) -> Result<()> {
Errno::result(res).map(drop)
}
+/// Set the user ID
+///
+/// See also [setgid(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/setgid.html)
#[inline]
pub fn setgid(gid: Gid) -> Result<()> {
let res = unsafe { libc::setgid(gid.into()) };
@@ -982,6 +1047,9 @@ pub fn setgid(gid: Gid) -> Result<()> {
Errno::result(res).map(drop)
}
+/// Suspend the thread until a signal is received
+///
+/// See also [pause(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pause.html)
#[inline]
pub fn pause() -> Result<()> {
let res = unsafe { libc::pause() };
@@ -989,9 +1057,11 @@ pub fn pause() -> Result<()> {
Errno::result(res).map(drop)
}
+/// Suspend execution for an interval of time
+///
+/// See also [sleep(2)(http://pubs.opengroup.org/onlinepubs/009695399/functions/sleep.html#tag_03_705_05)
+// Per POSIX, does not fail
#[inline]
-// Per POSIX, does not fail:
-// http://pubs.opengroup.org/onlinepubs/009695399/functions/sleep.html#tag_03_705_05
pub fn sleep(seconds: libc::c_uint) -> c_uint {
unsafe { libc::sleep(seconds) }
}
@@ -1004,6 +1074,8 @@ pub fn sleep(seconds: libc::c_uint) -> c_uint {
/// Err is returned either if no temporary filename could be created or the template doesn't
/// end with XXXXXX
///
+/// See also [mkstemp(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mkstemp.html)
+///
/// # Example
///
/// ```rust
diff --git a/test/sys/test_aio.rs b/test/sys/test_aio.rs
index 67fd0850..630dff9a 100644
--- a/test/sys/test_aio.rs
+++ b/test/sys/test_aio.rs
@@ -13,7 +13,7 @@ use std::{thread, time};
use tempfile::tempfile;
// Helper that polls an AioCb for completion or error
-fn poll_aio(mut aiocb: &mut AioCb) -> Result<()> {
+fn poll_aio(aiocb: &mut AioCb) -> Result<()> {
loop {
let err = aiocb.error();
if err != Err(Error::from(Errno::EINPROGRESS)) { return err; };
@@ -21,6 +21,28 @@ fn poll_aio(mut aiocb: &mut AioCb) -> Result<()> {
}
}
+#[test]
+fn test_accessors() {
+ let mut rbuf = vec![0; 4];
+ let aiocb = AioCb::from_mut_slice( 1001,
+ 2, //offset
+ &mut rbuf,
+ 42, //priority
+ SigevNotify::SigevSignal {
+ signal: Signal::SIGUSR2,
+ si_value: 99
+ },
+ LioOpcode::LIO_NOP);
+ assert_eq!(1001, aiocb.fd());
+ assert_eq!(Some(LioOpcode::LIO_NOP), aiocb.lio_opcode());
+ assert_eq!(4, aiocb.nbytes());
+ assert_eq!(2, aiocb.offset());
+ assert_eq!(42, aiocb.priority());
+ let sev = aiocb.sigevent().sigevent();
+ assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo);
+ assert_eq!(99, sev.sigev_value.sival_ptr as i64);
+}
+
// Tests AioCb.cancel. We aren't trying to test the OS's implementation, only our
// bindings. So it's sufficient to check that AioCb.cancel returned any
// AioCancelStat value.
diff --git a/test/test_fcntl.rs b/test/test_fcntl.rs
index 43bfc091..d171b91d 100644
--- a/test/test_fcntl.rs
+++ b/test/test_fcntl.rs
@@ -54,11 +54,11 @@ mod linux_android {
use libc::loff_t;
- use nix::fcntl::{SpliceFFlags, splice, tee, vmsplice};
+ use nix::fcntl::{SpliceFFlags, FallocateFlags, fallocate, splice, tee, vmsplice};
use nix::sys::uio::IoVec;
use nix::unistd::{close, pipe, read, write};
- use tempfile::tempfile;
+ use tempfile::{tempfile, NamedTempFile};
#[test]
fn test_splice() {
@@ -131,4 +131,15 @@ mod linux_android {
close(wr).unwrap();
}
+ #[test]
+ fn test_fallocate() {
+ let tmp = NamedTempFile::new().unwrap();
+
+ let fd = tmp.as_raw_fd();
+ fallocate(fd, FallocateFlags::empty(), 0, 100).unwrap();
+
+ // Check if we read exactly 100 bytes
+ let mut buf = [0u8; 200];
+ assert_eq!(100, read(fd, &mut buf).unwrap());
+ }
}
diff --git a/test/test_unistd.rs b/test/test_unistd.rs
index adf73579..627eb09b 100644
--- a/test/test_unistd.rs
+++ b/test/test_unistd.rs
@@ -86,6 +86,24 @@ fn test_mkstemp_directory() {
}
#[test]
+fn test_mkfifo() {
+ let tempdir = TempDir::new("nix-test_mkfifo").unwrap();
+ let mkfifo_fifo = tempdir.path().join("mkfifo_fifo");
+
+ mkfifo(&mkfifo_fifo, stat::S_IRUSR).unwrap();
+
+ let stats = stat::stat(&mkfifo_fifo).unwrap();
+ let typ = stat::SFlag::from_bits_truncate(stats.st_mode);
+ assert!(typ == stat::S_IFIFO);
+}
+
+#[test]
+fn test_mkfifo_directory() {
+ // mkfifo should fail if a directory is given
+ assert!(mkfifo(&env::temp_dir(), stat::S_IRUSR).is_err());
+}
+
+#[test]
fn test_getpid() {
let pid: ::libc::pid_t = getpid().into();
let ppid: ::libc::pid_t = getppid().into();