summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Gohman <dev@sunfishcode.online>2021-11-20 07:19:14 -0800
committerDan Gohman <dev@sunfishcode.online>2021-12-02 13:03:32 -0800
commit81f8d8cbdc369acd2f981e5a089369ccbd200e10 (patch)
tree9abc1206296c7cbca5b203374793263877d0a37f
parentc0f446e2e9bcb8469e64623284a8a0a0b87e6ce8 (diff)
downloadrust-81f8d8cbdc369acd2f981e5a089369ccbd200e10.tar.gz
Port library/std/src/sys/unix/fd.rs to rustix.
-rw-r--r--library/std/src/sys/unix/fd.rs173
-rw-r--r--library/std/src/sys/unix/io.rs77
2 files changed, 39 insertions, 211 deletions
diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs
index ea688571a98..47f77e30373 100644
--- a/library/std/src/sys/unix/fd.rs
+++ b/library/std/src/sys/unix/fd.rs
@@ -3,89 +3,34 @@
#[cfg(test)]
mod tests;
-use crate::cmp;
use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read};
use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
-use crate::sys::cvt;
use crate::sys_common::{AsInner, FromInner, IntoInner};
-use libc::{c_int, c_void};
+use rustix::fs::FdFlags;
+#[cfg(not(target_os = "linux"))]
+use rustix::fs::OFlags;
#[derive(Debug)]
pub struct FileDesc(OwnedFd);
-// The maximum read limit on most POSIX-like systems is `SSIZE_MAX`,
-// with the man page quoting that if the count of bytes to read is
-// greater than `SSIZE_MAX` the result is "unspecified".
-//
-// On macOS, however, apparently the 64-bit libc is either buggy or
-// intentionally showing odd behavior by rejecting any read with a size
-// larger than or equal to INT_MAX. To handle both of these the read
-// size is capped on both platforms.
-#[cfg(target_os = "macos")]
-const READ_LIMIT: usize = c_int::MAX as usize - 1;
-#[cfg(not(target_os = "macos"))]
-const READ_LIMIT: usize = libc::ssize_t::MAX as usize;
-
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
-const fn max_iov() -> usize {
- libc::IOV_MAX as usize
-}
-
-#[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))]
-const fn max_iov() -> usize {
- libc::UIO_MAXIOV as usize
-}
-
-#[cfg(not(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-)))]
-const fn max_iov() -> usize {
- 16 // The minimum value required by POSIX.
-}
-
impl FileDesc {
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
- let ret = cvt(unsafe {
- libc::read(
- self.as_raw_fd(),
- buf.as_mut_ptr() as *mut c_void,
- cmp::min(buf.len(), READ_LIMIT),
- )
- })?;
- Ok(ret as usize)
+ let ret = rustix::io::read(self, buf)?;
+ Ok(ret)
}
#[cfg(not(target_os = "espidf"))]
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
- let ret = cvt(unsafe {
- libc::readv(
- self.as_raw_fd(),
- bufs.as_ptr() as *const libc::iovec,
- cmp::min(bufs.len(), max_iov()) as c_int,
- )
- })?;
- Ok(ret as usize)
+ let ret = rustix::io::readv(self, unsafe { crate::mem::transmute(bufs) })?;
+ Ok(ret)
}
#[cfg(target_os = "espidf")]
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
- return crate::io::default_read_vectored(|b| self.read(b), bufs);
+ return crate::io::default_read_vectored(|b| self.read(b), unsafe {
+ crate::mem::transmute(bufs)
+ });
}
#[inline]
@@ -99,48 +44,26 @@ impl FileDesc {
}
pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
- #[cfg(not(any(target_os = "linux", target_os = "android")))]
- use libc::pread as pread64;
- #[cfg(any(target_os = "linux", target_os = "android"))]
- use libc::pread64;
-
- unsafe {
- cvt(pread64(
- self.as_raw_fd(),
- buf.as_mut_ptr() as *mut c_void,
- cmp::min(buf.len(), READ_LIMIT),
- offset as i64,
- ))
- .map(|n| n as usize)
- }
+ let ret = rustix::io::pread(self, buf, offset)?;
+ Ok(ret)
}
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
- let ret = cvt(unsafe {
- libc::write(
- self.as_raw_fd(),
- buf.as_ptr() as *const c_void,
- cmp::min(buf.len(), READ_LIMIT),
- )
- })?;
- Ok(ret as usize)
+ let ret = rustix::io::write(self, buf)?;
+ Ok(ret)
}
#[cfg(not(target_os = "espidf"))]
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
- let ret = cvt(unsafe {
- libc::writev(
- self.as_raw_fd(),
- bufs.as_ptr() as *const libc::iovec,
- cmp::min(bufs.len(), max_iov()) as c_int,
- )
- })?;
- Ok(ret as usize)
+ let ret = rustix::io::writev(self, unsafe { crate::mem::transmute(bufs) })?;
+ Ok(ret)
}
#[cfg(target_os = "espidf")]
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
- return crate::io::default_write_vectored(|b| self.write(b), bufs);
+ return crate::io::default_write_vectored(|b| self.write(b), unsafe {
+ crate::mem::transmute(bufs)
+ });
}
#[inline]
@@ -149,25 +72,13 @@ impl FileDesc {
}
pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
- #[cfg(not(any(target_os = "linux", target_os = "android")))]
- use libc::pwrite as pwrite64;
- #[cfg(any(target_os = "linux", target_os = "android"))]
- use libc::pwrite64;
-
- unsafe {
- cvt(pwrite64(
- self.as_raw_fd(),
- buf.as_ptr() as *const c_void,
- cmp::min(buf.len(), READ_LIMIT),
- offset as i64,
- ))
- .map(|n| n as usize)
- }
+ let ret = rustix::io::pwrite(self, buf, offset)?;
+ Ok(ret)
}
#[cfg(target_os = "linux")]
pub fn get_cloexec(&self) -> io::Result<bool> {
- unsafe { Ok((cvt(libc::fcntl(self.as_raw_fd(), libc::F_GETFD))? & libc::FD_CLOEXEC) != 0) }
+ Ok(rustix::fs::fcntl_getfd(self)?.contains(FdFlags::CLOEXEC))
}
#[cfg(not(any(
@@ -183,10 +94,8 @@ impl FileDesc {
target_os = "vxworks"
)))]
pub fn set_cloexec(&self) -> io::Result<()> {
- unsafe {
- cvt(libc::ioctl(self.as_raw_fd(), libc::FIOCLEX))?;
- Ok(())
- }
+ rustix::io::ioctl_fioclex(self)?;
+ Ok(())
}
#[cfg(any(
all(target_env = "newlib", not(target_os = "espidf")),
@@ -201,14 +110,12 @@ impl FileDesc {
target_os = "vxworks"
))]
pub fn set_cloexec(&self) -> io::Result<()> {
- unsafe {
- let previous = cvt(libc::fcntl(self.as_raw_fd(), libc::F_GETFD))?;
- let new = previous | libc::FD_CLOEXEC;
- if new != previous {
- cvt(libc::fcntl(self.as_raw_fd(), libc::F_SETFD, new))?;
- }
- Ok(())
+ let previous = rustix::fs::fcntl_getfd(self)?;
+ let new = previous | FdFlags::CLOEXEC;
+ if new != previous {
+ rustix::fs::fcntl_setfd(self, new)?;
}
+ Ok(())
}
#[cfg(target_os = "espidf")]
pub fn set_cloexec(&self) -> io::Result<()> {
@@ -219,24 +126,21 @@ impl FileDesc {
#[cfg(target_os = "linux")]
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
- unsafe {
- let v = nonblocking as c_int;
- cvt(libc::ioctl(self.as_raw_fd(), libc::FIONBIO, &v))?;
- Ok(())
- }
+ rustix::io::ioctl_fionbio(self, nonblocking)?;
+ Ok(())
}
#[cfg(not(target_os = "linux"))]
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
unsafe {
- let previous = cvt(libc::fcntl(self.as_raw_fd(), libc::F_GETFL))?;
+ let previous = rustix::fs::fcntl_getfl(self)?;
let new = if nonblocking {
- previous | libc::O_NONBLOCK
+ previous | OFlags::NONBLOCK;
} else {
- previous & !libc::O_NONBLOCK
+ previous & !OFlags::NONBLOCK;
};
if new != previous {
- cvt(libc::fcntl(self.as_raw_fd(), libc::F_SETFL, new))?;
+ rustix::fcntl_setfl(self, new)?;
}
Ok(())
}
@@ -247,17 +151,16 @@ impl FileDesc {
// CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This
// is a POSIX flag that was added to Linux in 2.6.24.
#[cfg(not(target_os = "espidf"))]
- let cmd = libc::F_DUPFD_CLOEXEC;
+ let fd = rustix::fs::fcntl_dupfd_cloexec(self, 0)?;
// For ESP-IDF, F_DUPFD is used instead, because the CLOEXEC semantics
// will never be supported, as this is a bare metal framework with
// no capabilities for multi-process execution. While F_DUPFD is also
// not supported yet, it might be (currently it returns ENOSYS).
#[cfg(target_os = "espidf")]
- let cmd = libc::F_DUPFD;
+ let fd = rustix::fs::fcntl_dupfd(self, 0)?;
- let fd = cvt(unsafe { libc::fcntl(self.as_raw_fd(), cmd, 0) })?;
- Ok(unsafe { FileDesc::from_raw_fd(fd) })
+ Ok(FileDesc::from_inner(fd))
}
}
diff --git a/library/std/src/sys/unix/io.rs b/library/std/src/sys/unix/io.rs
index deb5ee76bd0..c31cafcf4f4 100644
--- a/library/std/src/sys/unix/io.rs
+++ b/library/std/src/sys/unix/io.rs
@@ -1,76 +1 @@
-use crate::marker::PhantomData;
-use crate::slice;
-
-use libc::{c_void, iovec};
-
-#[derive(Copy, Clone)]
-#[repr(transparent)]
-pub struct IoSlice<'a> {
- vec: iovec,
- _p: PhantomData<&'a [u8]>,
-}
-
-impl<'a> IoSlice<'a> {
- #[inline]
- pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
- IoSlice {
- vec: iovec { iov_base: buf.as_ptr() as *mut u8 as *mut c_void, iov_len: buf.len() },
- _p: PhantomData,
- }
- }
-
- #[inline]
- pub fn advance(&mut self, n: usize) {
- if self.vec.iov_len < n {
- panic!("advancing IoSlice beyond its length");
- }
-
- unsafe {
- self.vec.iov_len -= n;
- self.vec.iov_base = self.vec.iov_base.add(n);
- }
- }
-
- #[inline]
- pub fn as_slice(&self) -> &[u8] {
- unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
- }
-}
-
-#[repr(transparent)]
-pub struct IoSliceMut<'a> {
- vec: iovec,
- _p: PhantomData<&'a mut [u8]>,
-}
-
-impl<'a> IoSliceMut<'a> {
- #[inline]
- pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
- IoSliceMut {
- vec: iovec { iov_base: buf.as_mut_ptr() as *mut c_void, iov_len: buf.len() },
- _p: PhantomData,
- }
- }
-
- #[inline]
- pub fn advance(&mut self, n: usize) {
- if self.vec.iov_len < n {
- panic!("advancing IoSliceMut beyond its length");
- }
-
- unsafe {
- self.vec.iov_len -= n;
- self.vec.iov_base = self.vec.iov_base.add(n);
- }
- }
-
- #[inline]
- pub fn as_slice(&self) -> &[u8] {
- unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
- }
-
- #[inline]
- pub fn as_mut_slice(&mut self) -> &mut [u8] {
- unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
- }
-}
+pub use rustix::io::{IoSlice, IoSliceMut};