summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sched.rs6
-rw-r--r--src/sys/inotify.rs28
-rw-r--r--src/sys/sendfile.rs62
-rw-r--r--src/sys/statvfs.rs6
-rw-r--r--src/sys/timerfd.rs44
-rw-r--r--src/sys/uio.rs28
-rw-r--r--test/sys/test_uio.rs29
-rw-r--r--test/test_sendfile.rs31
8 files changed, 128 insertions, 106 deletions
diff --git a/src/sched.rs b/src/sched.rs
index d5b1233c..0515e30f 100644
--- a/src/sched.rs
+++ b/src/sched.rs
@@ -16,7 +16,7 @@ mod sched_linux_like {
use libc::{self, c_int, c_void};
use std::mem;
use std::option::Option;
- use std::os::unix::io::RawFd;
+ use std::os::unix::io::{AsFd, AsRawFd};
// For some functions taking with a parameter of type CloneFlags,
// only a subset of these flags have an effect.
@@ -136,8 +136,8 @@ mod sched_linux_like {
/// reassociate thread with a namespace
///
/// See also [setns(2)](https://man7.org/linux/man-pages/man2/setns.2.html)
- pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> {
- let res = unsafe { libc::setns(fd, nstype.bits()) };
+ pub fn setns<Fd: AsFd>(fd: Fd, nstype: CloneFlags) -> Result<()> {
+ let res = unsafe { libc::setns(fd.as_fd().as_raw_fd(), nstype.bits()) };
Errno::result(res).map(drop)
}
diff --git a/src/sys/inotify.rs b/src/sys/inotify.rs
index 84356ec7..2398c16e 100644
--- a/src/sys/inotify.rs
+++ b/src/sys/inotify.rs
@@ -32,7 +32,7 @@ use libc::{c_char, c_int};
use std::ffi::{CStr, OsStr, OsString};
use std::mem::{size_of, MaybeUninit};
use std::os::unix::ffi::OsStrExt;
-use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
+use std::os::unix::io::{AsRawFd, FromRawFd, OwnedFd, RawFd};
use std::ptr;
libc_bitflags! {
@@ -101,9 +101,9 @@ libc_bitflags! {
/// An inotify instance. This is also a file descriptor, you can feed it to
/// other interfaces consuming file descriptors, epoll for example.
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug)]
pub struct Inotify {
- fd: RawFd,
+ fd: OwnedFd,
}
/// This object is returned when you create a new watch on an inotify instance.
@@ -143,7 +143,7 @@ impl Inotify {
pub fn init(flags: InitFlags) -> Result<Inotify> {
let res = Errno::result(unsafe { libc::inotify_init1(flags.bits()) });
- res.map(|fd| Inotify { fd })
+ res.map(|fd| Inotify { fd: unsafe { OwnedFd::from_raw_fd(fd) } })
}
/// Adds a new watch on the target file or directory.
@@ -152,12 +152,12 @@ impl Inotify {
///
/// For more information see, [inotify_add_watch(2)](https://man7.org/linux/man-pages/man2/inotify_add_watch.2.html).
pub fn add_watch<P: ?Sized + NixPath>(
- self,
+ &self,
path: &P,
mask: AddWatchFlags,
) -> Result<WatchDescriptor> {
let res = path.with_nix_path(|cstr| unsafe {
- libc::inotify_add_watch(self.fd, cstr.as_ptr(), mask.bits())
+ libc::inotify_add_watch(self.fd.as_raw_fd(), cstr.as_ptr(), mask.bits())
})?;
Errno::result(res).map(|wd| WatchDescriptor { wd })
@@ -169,7 +169,7 @@ impl Inotify {
/// Returns an EINVAL error if the watch descriptor is invalid.
///
/// For more information see, [inotify_rm_watch(2)](https://man7.org/linux/man-pages/man2/inotify_rm_watch.2.html).
- pub fn rm_watch(self, wd: WatchDescriptor) -> Result<()> {
+ pub fn rm_watch(&self, wd: WatchDescriptor) -> Result<()> {
cfg_if! {
if #[cfg(target_os = "linux")] {
let arg = wd.wd;
@@ -177,7 +177,7 @@ impl Inotify {
let arg = wd.wd as u32;
}
}
- let res = unsafe { libc::inotify_rm_watch(self.fd, arg) };
+ let res = unsafe { libc::inotify_rm_watch(self.fd.as_raw_fd(), arg) };
Errno::result(res).map(drop)
}
@@ -188,14 +188,14 @@ impl Inotify {
///
/// Returns as many events as available. If the call was non blocking and no
/// events could be read then the EAGAIN error is returned.
- pub fn read_events(self) -> Result<Vec<InotifyEvent>> {
+ pub fn read_events(&self) -> Result<Vec<InotifyEvent>> {
let header_size = size_of::<libc::inotify_event>();
const BUFSIZ: usize = 4096;
let mut buffer = [0u8; BUFSIZ];
let mut events = Vec::new();
let mut offset = 0;
- let nread = read(self.fd, &mut buffer)?;
+ let nread = read(self.fd.as_raw_fd(), &mut buffer)?;
while (nread - offset) >= header_size {
let event = unsafe {
@@ -235,14 +235,8 @@ impl Inotify {
}
}
-impl AsRawFd for Inotify {
- fn as_raw_fd(&self) -> RawFd {
- self.fd
- }
-}
-
impl FromRawFd for Inotify {
unsafe fn from_raw_fd(fd: RawFd) -> Self {
- Inotify { fd }
+ Inotify { fd: OwnedFd::from_raw_fd(fd) }
}
}
diff --git a/src/sys/sendfile.rs b/src/sys/sendfile.rs
index fb293a4e..9f3c333f 100644
--- a/src/sys/sendfile.rs
+++ b/src/sys/sendfile.rs
@@ -1,7 +1,7 @@
//! Send data from a file to a socket, bypassing userland.
use cfg_if::cfg_if;
-use std::os::unix::io::RawFd;
+use std::os::unix::io::{AsFd, AsRawFd};
use std::ptr;
use libc::{self, off_t};
@@ -23,16 +23,23 @@ use crate::Result;
/// For more information, see [the sendfile(2) man page.](https://man7.org/linux/man-pages/man2/sendfile.2.html)
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn sendfile(
- out_fd: RawFd,
- in_fd: RawFd,
+pub fn sendfile<F1: AsFd, F2: AsFd>(
+ out_fd: F1,
+ in_fd: F2,
offset: Option<&mut off_t>,
count: usize,
) -> Result<usize> {
let offset = offset
.map(|offset| offset as *mut _)
.unwrap_or(ptr::null_mut());
- let ret = unsafe { libc::sendfile(out_fd, in_fd, offset, count) };
+ let ret = unsafe {
+ libc::sendfile(
+ out_fd.as_fd().as_raw_fd(),
+ in_fd.as_fd().as_raw_fd(),
+ offset,
+ count,
+ )
+ };
Errno::result(ret).map(|r| r as usize)
}
@@ -50,16 +57,23 @@ pub fn sendfile(
/// For more information, see [the sendfile(2) man page.](https://man7.org/linux/man-pages/man2/sendfile.2.html)
#[cfg(target_os = "linux")]
#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn sendfile64(
- out_fd: RawFd,
- in_fd: RawFd,
+pub fn sendfile64<F1: AsFd, F2: AsFd>(
+ out_fd: F1,
+ in_fd: F2,
offset: Option<&mut libc::off64_t>,
count: usize,
) -> Result<usize> {
let offset = offset
.map(|offset| offset as *mut _)
.unwrap_or(ptr::null_mut());
- let ret = unsafe { libc::sendfile64(out_fd, in_fd, offset, count) };
+ let ret = unsafe {
+ libc::sendfile64(
+ out_fd.as_fd().as_raw_fd(),
+ in_fd.as_fd().as_raw_fd(),
+ offset,
+ count,
+ )
+ };
Errno::result(ret).map(|r| r as usize)
}
@@ -156,9 +170,9 @@ cfg_if! {
/// For more information, see
/// [the sendfile(2) man page.](https://www.freebsd.org/cgi/man.cgi?query=sendfile&sektion=2)
#[allow(clippy::too_many_arguments)]
- pub fn sendfile(
- in_fd: RawFd,
- out_sock: RawFd,
+ pub fn sendfile<F1: AsFd, F2: AsFd>(
+ in_fd: F1,
+ out_sock: F2,
offset: off_t,
count: Option<usize>,
headers: Option<&[&[u8]]>,
@@ -175,8 +189,8 @@ cfg_if! {
let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers));
let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr);
let return_code = unsafe {
- libc::sendfile(in_fd,
- out_sock,
+ libc::sendfile(in_fd.as_fd().as_raw_fd(),
+ out_sock.as_fd().as_raw_fd(),
offset,
count.unwrap_or(0),
hdtr_ptr as *mut libc::sf_hdtr,
@@ -206,9 +220,9 @@ cfg_if! {
///
/// For more information, see
/// [the sendfile(2) man page.](https://leaf.dragonflybsd.org/cgi/web-man?command=sendfile&section=2)
- pub fn sendfile(
- in_fd: RawFd,
- out_sock: RawFd,
+ pub fn sendfile<F1: AsFd, F2: AsFd>(
+ in_fd: F1,
+ out_sock: F2,
offset: off_t,
count: Option<usize>,
headers: Option<&[&[u8]]>,
@@ -218,8 +232,8 @@ cfg_if! {
let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers));
let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr);
let return_code = unsafe {
- libc::sendfile(in_fd,
- out_sock,
+ libc::sendfile(in_fd.as_fd().as_raw_fd(),
+ out_sock.as_fd().as_raw_fd(),
offset,
count.unwrap_or(0),
hdtr_ptr as *mut libc::sf_hdtr,
@@ -252,9 +266,9 @@ cfg_if! {
///
/// For more information, see
/// [the sendfile(2) man page.](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man2/sendfile.2.html)
- pub fn sendfile(
- in_fd: RawFd,
- out_sock: RawFd,
+ pub fn sendfile<F1: AsFd, F2: AsFd>(
+ in_fd: F1,
+ out_sock: F2,
offset: off_t,
count: Option<off_t>,
headers: Option<&[&[u8]]>,
@@ -264,8 +278,8 @@ cfg_if! {
let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers));
let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr);
let return_code = unsafe {
- libc::sendfile(in_fd,
- out_sock,
+ libc::sendfile(in_fd.as_fd().as_raw_fd(),
+ out_sock.as_fd().as_raw_fd(),
offset,
&mut len as *mut off_t,
hdtr_ptr as *mut libc::sf_hdtr,
diff --git a/src/sys/statvfs.rs b/src/sys/statvfs.rs
index 8de369f4..c2c86624 100644
--- a/src/sys/statvfs.rs
+++ b/src/sys/statvfs.rs
@@ -3,7 +3,7 @@
//! See [the man pages](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatvfs.html)
//! for more details.
use std::mem;
-use std::os::unix::io::AsRawFd;
+use std::os::unix::io::{AsFd, AsRawFd};
use libc::{self, c_ulong};
@@ -146,11 +146,11 @@ pub fn statvfs<P: ?Sized + NixPath>(path: &P) -> Result<Statvfs> {
}
/// Return a `Statvfs` object with information about `fd`
-pub fn fstatvfs<T: AsRawFd>(fd: &T) -> Result<Statvfs> {
+pub fn fstatvfs<Fd: AsFd>(fd: Fd) -> Result<Statvfs> {
unsafe {
Errno::clear();
let mut stat = mem::MaybeUninit::<libc::statvfs>::uninit();
- Errno::result(libc::fstatvfs(fd.as_raw_fd(), stat.as_mut_ptr()))
+ Errno::result(libc::fstatvfs(fd.as_fd().as_raw_fd(), stat.as_mut_ptr()))
.map(|_| Statvfs(stat.assume_init()))
}
}
diff --git a/src/sys/timerfd.rs b/src/sys/timerfd.rs
index a35fc927..90a05a8c 100644
--- a/src/sys/timerfd.rs
+++ b/src/sys/timerfd.rs
@@ -33,24 +33,28 @@ pub use crate::sys::time::timer::{Expiration, TimerSetTimeFlags};
use crate::unistd::read;
use crate::{errno::Errno, Result};
use libc::c_int;
-use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
+use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd};
/// A timerfd instance. This is also a file descriptor, you can feed it to
-/// other interfaces consuming file descriptors, epoll for example.
+/// other interfaces taking file descriptors as arguments, [`epoll`] for example.
+///
+/// [`epoll`]: crate::sys::epoll
#[derive(Debug)]
pub struct TimerFd {
- fd: RawFd,
+ fd: OwnedFd,
}
-impl AsRawFd for TimerFd {
- fn as_raw_fd(&self) -> RawFd {
- self.fd
+impl AsFd for TimerFd {
+ fn as_fd(&self) -> BorrowedFd<'_> {
+ self.fd.as_fd()
}
}
impl FromRawFd for TimerFd {
unsafe fn from_raw_fd(fd: RawFd) -> Self {
- TimerFd { fd }
+ TimerFd {
+ fd: OwnedFd::from_raw_fd(fd),
+ }
}
}
@@ -97,7 +101,9 @@ impl TimerFd {
Errno::result(unsafe {
libc::timerfd_create(clockid as i32, flags.bits())
})
- .map(|fd| Self { fd })
+ .map(|fd| Self {
+ fd: unsafe { OwnedFd::from_raw_fd(fd) },
+ })
}
/// Sets a new alarm on the timer.
@@ -145,7 +151,7 @@ impl TimerFd {
let timerspec: TimerSpec = expiration.into();
Errno::result(unsafe {
libc::timerfd_settime(
- self.fd,
+ self.fd.as_fd().as_raw_fd(),
flags.bits(),
timerspec.as_ref(),
std::ptr::null_mut(),
@@ -159,7 +165,10 @@ impl TimerFd {
pub fn get(&self) -> Result<Option<Expiration>> {
let mut timerspec = TimerSpec::none();
Errno::result(unsafe {
- libc::timerfd_gettime(self.fd, timerspec.as_mut())
+ libc::timerfd_gettime(
+ self.fd.as_fd().as_raw_fd(),
+ timerspec.as_mut(),
+ )
})
.map(|_| {
if timerspec.as_ref().it_interval.tv_sec == 0
@@ -179,7 +188,7 @@ impl TimerFd {
pub fn unset(&self) -> Result<()> {
Errno::result(unsafe {
libc::timerfd_settime(
- self.fd,
+ self.fd.as_fd().as_raw_fd(),
TimerSetTimeFlags::empty().bits(),
TimerSpec::none().as_ref(),
std::ptr::null_mut(),
@@ -192,7 +201,7 @@ impl TimerFd {
///
/// Note: If the alarm is unset, then you will wait forever.
pub fn wait(&self) -> Result<()> {
- while let Err(e) = read(self.fd, &mut [0u8; 8]) {
+ while let Err(e) = read(self.fd.as_fd().as_raw_fd(), &mut [0u8; 8]) {
if e != Errno::EINTR {
return Err(e);
}
@@ -201,14 +210,3 @@ impl TimerFd {
Ok(())
}
}
-
-impl Drop for TimerFd {
- fn drop(&mut self) {
- if !std::thread::panicking() {
- let result = Errno::result(unsafe { libc::close(self.fd) });
- if let Err(Errno::EBADF) = result {
- panic!("close of TimerFd encountered EBADF");
- }
- }
- }
-}
diff --git a/src/sys/uio.rs b/src/sys/uio.rs
index 7248bd0c..ce0fb54d 100644
--- a/src/sys/uio.rs
+++ b/src/sys/uio.rs
@@ -4,12 +4,12 @@ use crate::errno::Errno;
use crate::Result;
use libc::{self, c_int, c_void, off_t, size_t};
use std::io::{IoSlice, IoSliceMut};
-use std::os::unix::io::RawFd;
+use std::os::unix::io::{AsFd, AsRawFd};
/// Low-level vectored write to a raw file descriptor
///
/// See also [writev(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/writev.html)
-pub fn writev(fd: RawFd, iov: &[IoSlice<'_>]) -> Result<usize> {
+pub fn writev<Fd: AsFd>(fd: Fd, iov: &[IoSlice<'_>]) -> Result<usize> {
// SAFETY: to quote the documentation for `IoSlice`:
//
// [IoSlice] is semantically a wrapper around a &[u8], but is
@@ -18,7 +18,7 @@ pub fn writev(fd: RawFd, iov: &[IoSlice<'_>]) -> Result<usize> {
//
// Because it is ABI compatible, a pointer cast here is valid
let res = unsafe {
- libc::writev(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int)
+ libc::writev(fd.as_fd().as_raw_fd(), iov.as_ptr() as *const libc::iovec, iov.len() as c_int)
};
Errno::result(res).map(|r| r as usize)
@@ -27,10 +27,10 @@ pub fn writev(fd: RawFd, iov: &[IoSlice<'_>]) -> Result<usize> {
/// Low-level vectored read from a raw file descriptor
///
/// See also [readv(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/readv.html)
-pub fn readv(fd: RawFd, iov: &mut [IoSliceMut<'_>]) -> Result<usize> {
+pub fn readv<Fd: AsFd>(fd: Fd, iov: &mut [IoSliceMut<'_>]) -> Result<usize> {
// SAFETY: same as in writev(), IoSliceMut is ABI-compatible with iovec
let res = unsafe {
- libc::readv(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int)
+ libc::readv(fd.as_fd().as_raw_fd(), iov.as_ptr() as *const libc::iovec, iov.len() as c_int)
};
Errno::result(res).map(|r| r as usize)
@@ -44,14 +44,14 @@ pub fn readv(fd: RawFd, iov: &mut [IoSliceMut<'_>]) -> Result<usize> {
/// See also: [`writev`](fn.writev.html) and [`pwrite`](fn.pwrite.html)
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn pwritev(fd: RawFd, iov: &[IoSlice<'_>], offset: off_t) -> Result<usize> {
+pub fn pwritev<Fd: AsFd>(fd: Fd, iov: &[IoSlice<'_>], offset: off_t) -> Result<usize> {
#[cfg(target_env = "uclibc")]
let offset = offset as libc::off64_t; // uclibc doesn't use off_t
// SAFETY: same as in writev()
let res = unsafe {
libc::pwritev(
- fd,
+ fd.as_fd().as_raw_fd(),
iov.as_ptr() as *const libc::iovec,
iov.len() as c_int,
offset,
@@ -70,8 +70,8 @@ pub fn pwritev(fd: RawFd, iov: &[IoSlice<'_>], offset: off_t) -> Result<usize> {
/// See also: [`readv`](fn.readv.html) and [`pread`](fn.pread.html)
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn preadv(
- fd: RawFd,
+pub fn preadv<Fd: AsFd>(
+ fd: Fd,
iov: &mut [IoSliceMut<'_>],
offset: off_t,
) -> Result<usize> {
@@ -81,7 +81,7 @@ pub fn preadv(
// SAFETY: same as in readv()
let res = unsafe {
libc::preadv(
- fd,
+ fd.as_fd().as_raw_fd(),
iov.as_ptr() as *const libc::iovec,
iov.len() as c_int,
offset,
@@ -95,10 +95,10 @@ pub fn preadv(
///
/// See also [pwrite(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html)
// TODO: move to unistd
-pub fn pwrite(fd: RawFd, buf: &[u8], offset: off_t) -> Result<usize> {
+pub fn pwrite<Fd: AsFd>(fd: Fd, buf: &[u8], offset: off_t) -> Result<usize> {
let res = unsafe {
libc::pwrite(
- fd,
+ fd.as_fd().as_raw_fd(),
buf.as_ptr() as *const c_void,
buf.len() as size_t,
offset,
@@ -112,10 +112,10 @@ pub fn pwrite(fd: RawFd, buf: &[u8], offset: off_t) -> Result<usize> {
///
/// See also [pread(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html)
// TODO: move to unistd
-pub fn pread(fd: RawFd, buf: &mut [u8], offset: off_t) -> Result<usize> {
+pub fn pread<Fd: AsFd>(fd: Fd, buf: &mut [u8], offset: off_t) -> Result<usize> {
let res = unsafe {
libc::pread(
- fd,
+ fd.as_fd().as_raw_fd(),
buf.as_mut_ptr() as *mut c_void,
buf.len() as size_t,
offset,
diff --git a/test/sys/test_uio.rs b/test/sys/test_uio.rs
index 0f4b8a65..fc09465f 100644
--- a/test/sys/test_uio.rs
+++ b/test/sys/test_uio.rs
@@ -4,7 +4,7 @@ use rand::distributions::Alphanumeric;
use rand::{thread_rng, Rng};
use std::fs::OpenOptions;
use std::io::IoSlice;
-use std::os::unix::io::AsRawFd;
+use std::os::unix::io::{FromRawFd, OwnedFd};
use std::{cmp, iter};
#[cfg(not(target_os = "redox"))]
@@ -40,12 +40,16 @@ fn test_writev() {
iovecs.push(IoSlice::new(b));
consumed += slice_len;
}
- let pipe_res = pipe();
- let (reader, writer) = pipe_res.expect("Couldn't create pipe");
+ let (reader, writer) = pipe().expect("Couldn't create pipe");
// FileDesc will close its filedesc (reader).
let mut read_buf: Vec<u8> = iter::repeat(0u8).take(128 * 16).collect();
+
+ // Temporary workaround to cope with the existing RawFd pipe(2), should be
+ // removed when pipe(2) becomes I/O-safe.
+ let writer = unsafe { OwnedFd::from_raw_fd(writer) };
+
// Blocking io, should write all data.
- let write_res = writev(writer, &iovecs);
+ let write_res = writev(&writer, &iovecs);
let written = write_res.expect("couldn't write");
// Check whether we written all data
assert_eq!(to_write.len(), written);
@@ -55,7 +59,6 @@ fn test_writev() {
assert_eq!(read, written);
// Check equality of written and read data
assert_eq!(&to_write, &read_buf);
- close(writer).expect("closed writer");
close(reader).expect("closed reader");
}
@@ -88,7 +91,12 @@ fn test_readv() {
let (reader, writer) = pipe().expect("couldn't create pipe");
// Blocking io, should write all data.
write(writer, &to_write).expect("write failed");
- let read = readv(reader, &mut iovecs[..]).expect("read failed");
+
+ // Temporary workaround to cope with the existing RawFd pipe(2), should be
+ // removed when pipe(2) becomes I/O-safe.
+ let reader = unsafe { OwnedFd::from_raw_fd(reader) };
+
+ let read = readv(&reader, &mut iovecs[..]).expect("read failed");
// Check whether we've read all data
assert_eq!(to_write.len(), read);
// Cccumulate data from iovecs
@@ -100,7 +108,6 @@ fn test_readv() {
assert_eq!(read_buf.len(), to_write.len());
// Check equality of written and read data
assert_eq!(&read_buf, &to_write);
- close(reader).expect("couldn't close reader");
close(writer).expect("couldn't close writer");
}
@@ -111,7 +118,7 @@ fn test_pwrite() {
let mut file = tempfile().unwrap();
let buf = [1u8; 8];
- assert_eq!(Ok(8), pwrite(file.as_raw_fd(), &buf, 8));
+ assert_eq!(Ok(8), pwrite(&file, &buf, 8));
let mut file_content = Vec::new();
file.read_to_end(&mut file_content).unwrap();
let mut expected = vec![0u8; 8];
@@ -137,7 +144,7 @@ fn test_pread() {
file.write_all(&file_content).unwrap();
let mut buf = [0u8; 16];
- assert_eq!(Ok(16), pread(file.as_raw_fd(), &mut buf, 16));
+ assert_eq!(Ok(16), pread(&file, &mut buf, 16));
let expected: Vec<_> = (16..32).collect();
assert_eq!(&buf[..], &expected[..]);
}
@@ -168,7 +175,7 @@ fn test_pwritev() {
.open(path)
.unwrap();
- let written = pwritev(file.as_raw_fd(), &iovecs, 100).ok().unwrap();
+ let written = pwritev(&file, &iovecs, 100).ok().unwrap();
assert_eq!(written, to_write.len());
// Read the data back and make sure it matches
@@ -206,7 +213,7 @@ fn test_preadv() {
.iter_mut()
.map(|buf| IoSliceMut::new(&mut buf[..]))
.collect();
- assert_eq!(Ok(100), preadv(file.as_raw_fd(), &mut iovecs, 100));
+ assert_eq!(Ok(100), preadv(&file, &mut iovecs, 100));
}
let all = buffers.concat();
diff --git a/test/test_sendfile.rs b/test/test_sendfile.rs
index f73a3b56..c6ac6e6f 100644
--- a/test/test_sendfile.rs
+++ b/test/test_sendfile.rs
@@ -1,5 +1,6 @@
use std::io::prelude::*;
-use std::os::unix::prelude::*;
+#[cfg(any(target_os = "android", target_os = "linux"))]
+use std::os::unix::io::{FromRawFd, OwnedFd};
use libc::off_t;
use nix::sys::sendfile::*;
@@ -23,7 +24,12 @@ fn test_sendfile_linux() {
let (rd, wr) = pipe().unwrap();
let mut offset: off_t = 5;
- let res = sendfile(wr, tmp.as_raw_fd(), Some(&mut offset), 2).unwrap();
+ // The construct of this `OwnedFd` is a temporary workaround, when `pipe(2)`
+ // becomes I/O-safe:
+ // pub fn pipe() -> std::result::Result<(OwnedFd, OwnedFd), Error>
+ // then it is no longer needed.
+ let wr = unsafe { OwnedFd::from_raw_fd(wr) };
+ let res = sendfile(&wr, &tmp, Some(&mut offset), 2).unwrap();
assert_eq!(2, res);
@@ -33,7 +39,6 @@ fn test_sendfile_linux() {
assert_eq!(7, offset);
close(rd).unwrap();
- close(wr).unwrap();
}
#[cfg(target_os = "linux")]
@@ -45,7 +50,12 @@ fn test_sendfile64_linux() {
let (rd, wr) = pipe().unwrap();
let mut offset: libc::off64_t = 5;
- let res = sendfile64(wr, tmp.as_raw_fd(), Some(&mut offset), 2).unwrap();
+ // The construct of this `OwnedFd` is a temporary workaround, when `pipe(2)`
+ // becomes I/O-safe:
+ // pub fn pipe() -> std::result::Result<(OwnedFd, OwnedFd), Error>
+ // then it is no longer needed.
+ let wr = unsafe { OwnedFd::from_raw_fd(wr) };
+ let res = sendfile64(&wr, &tmp, Some(&mut offset), 2).unwrap();
assert_eq!(2, res);
@@ -55,7 +65,6 @@ fn test_sendfile64_linux() {
assert_eq!(7, offset);
close(rd).unwrap();
- close(wr).unwrap();
}
#[cfg(target_os = "freebsd")]
@@ -83,8 +92,8 @@ fn test_sendfile_freebsd() {
// Call the test method
let (res, bytes_written) = sendfile(
- tmp.as_raw_fd(),
- wr.as_raw_fd(),
+ &tmp,
+ &wr,
body_offset as off_t,
None,
Some(headers.as_slice()),
@@ -134,8 +143,8 @@ fn test_sendfile_dragonfly() {
// Call the test method
let (res, bytes_written) = sendfile(
- tmp.as_raw_fd(),
- wr.as_raw_fd(),
+ &tmp,
+ &wr,
body_offset as off_t,
None,
Some(headers.as_slice()),
@@ -183,8 +192,8 @@ fn test_sendfile_darwin() {
// Call the test method
let (res, bytes_written) = sendfile(
- tmp.as_raw_fd(),
- wr.as_raw_fd(),
+ &tmp,
+ &wr,
body_offset as off_t,
None,
Some(headers.as_slice()),