diff options
Diffstat (limited to 'library/std/src/sys/pal/unix')
| -rw-r--r-- | library/std/src/sys/pal/unix/args.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/fs.rs | 29 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/futex.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/io.rs | 87 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/kernel_copy/tests.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/l4re.rs | 564 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/linux/pidfd/tests.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/mod.rs | 27 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/net.rs | 651 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/os.rs | 22 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/process/process_unix.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/process/zircon.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/stack_overflow.rs | 36 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/stdio.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/sync/mutex.rs | 6 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/thread.rs | 27 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/thread_parking.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/weak.rs | 2 |
18 files changed, 99 insertions, 1378 deletions
diff --git a/library/std/src/sys/pal/unix/args.rs b/library/std/src/sys/pal/unix/args.rs index 8438a61e90f..1c87a79803c 100644 --- a/library/std/src/sys/pal/unix/args.rs +++ b/library/std/src/sys/pal/unix/args.rs @@ -147,7 +147,7 @@ mod imp { /// This allows `std::env::args` to work even in a `cdylib`, as it does on macOS and Windows. #[cfg(all(target_os = "linux", target_env = "gnu"))] #[used] - #[link_section = ".init_array.00099"] + #[unsafe(link_section = ".init_array.00099")] static ARGV_INIT_ARRAY: extern "C" fn( crate::os::raw::c_int, *const *const u8, @@ -204,7 +204,7 @@ mod imp { } pub fn argc_argv() -> (isize, *const *const c_char) { - extern "C" { + unsafe extern "C" { // These functions are in crt_externs.h. fn _NSGetArgc() -> *mut c_int; fn _NSGetArgv() -> *mut *mut *mut c_char; diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 6c41781fe85..3df460e38b7 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -9,9 +9,12 @@ use libc::c_char; #[cfg(any( all(target_os = "linux", not(target_env = "musl")), target_os = "android", + target_os = "fuchsia", target_os = "hurd" ))] use libc::dirfd; +#[cfg(target_os = "fuchsia")] +use libc::fstatat as fstatat64; #[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "hurd"))] use libc::fstatat64; #[cfg(any( @@ -565,8 +568,7 @@ impl FileAttr { Err(io::const_error!( io::ErrorKind::Unsupported, - "creation time is not available on this platform \ - currently", + "creation time is not available on this platform currently", )) } @@ -848,7 +850,6 @@ impl Drop for Dir { target_os = "vita", target_os = "hurd", target_os = "espidf", - target_os = "fuchsia", target_os = "horizon", target_os = "vxworks", target_os = "rtems", @@ -880,6 +881,7 @@ impl DirEntry { any( all(target_os = "linux", not(target_env = "musl")), target_os = "android", + target_os = "fuchsia", target_os = "hurd" ), not(miri) // no dirfd on Miri @@ -908,6 +910,7 @@ impl DirEntry { not(any( all(target_os = "linux", not(target_env = "musl")), target_os = "android", + target_os = "fuchsia", target_os = "hurd", )), miri @@ -1211,6 +1214,7 @@ impl File { } #[cfg(any( target_os = "freebsd", + target_os = "fuchsia", target_os = "linux", target_os = "android", target_os = "netbsd", @@ -1223,6 +1227,7 @@ impl File { } #[cfg(not(any( target_os = "android", + target_os = "fuchsia", target_os = "freebsd", target_os = "linux", target_os = "netbsd", @@ -1238,6 +1243,7 @@ impl File { #[cfg(any( target_os = "freebsd", + target_os = "fuchsia", target_os = "linux", target_os = "netbsd", target_vendor = "apple", @@ -1249,6 +1255,7 @@ impl File { #[cfg(not(any( target_os = "freebsd", + target_os = "fuchsia", target_os = "linux", target_os = "netbsd", target_vendor = "apple", @@ -1259,6 +1266,7 @@ impl File { #[cfg(any( target_os = "freebsd", + target_os = "fuchsia", target_os = "linux", target_os = "netbsd", target_vendor = "apple", @@ -1270,6 +1278,7 @@ impl File { #[cfg(not(any( target_os = "freebsd", + target_os = "fuchsia", target_os = "linux", target_os = "netbsd", target_vendor = "apple", @@ -1280,6 +1289,7 @@ impl File { #[cfg(any( target_os = "freebsd", + target_os = "fuchsia", target_os = "linux", target_os = "netbsd", target_vendor = "apple", @@ -1297,6 +1307,7 @@ impl File { #[cfg(not(any( target_os = "freebsd", + target_os = "fuchsia", target_os = "linux", target_os = "netbsd", target_vendor = "apple", @@ -1307,6 +1318,7 @@ impl File { #[cfg(any( target_os = "freebsd", + target_os = "fuchsia", target_os = "linux", target_os = "netbsd", target_vendor = "apple", @@ -1324,6 +1336,7 @@ impl File { #[cfg(not(any( target_os = "freebsd", + target_os = "fuchsia", target_os = "linux", target_os = "netbsd", target_vendor = "apple", @@ -1334,6 +1347,7 @@ impl File { #[cfg(any( target_os = "freebsd", + target_os = "fuchsia", target_os = "linux", target_os = "netbsd", target_vendor = "apple", @@ -1345,6 +1359,7 @@ impl File { #[cfg(not(any( target_os = "freebsd", + target_os = "fuchsia", target_os = "linux", target_os = "netbsd", target_vendor = "apple", @@ -1422,6 +1437,10 @@ impl File { Ok(n as u64) } + pub fn tell(&self) -> io::Result<u64> { + self.seek(SeekFrom::Current(0)) + } + pub fn duplicate(&self) -> io::Result<File> { self.0.duplicate().map(File) } @@ -1443,11 +1462,11 @@ impl File { Some(time) if let Some(ts) = time.t.to_timespec() => Ok(ts), Some(time) if time > crate::sys::time::UNIX_EPOCH => Err(io::const_error!( io::ErrorKind::InvalidInput, - "timestamp is too large to set as a file time" + "timestamp is too large to set as a file time", )), Some(_) => Err(io::const_error!( io::ErrorKind::InvalidInput, - "timestamp is too small to set as a file time" + "timestamp is too small to set as a file time", )), None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }), }; diff --git a/library/std/src/sys/pal/unix/futex.rs b/library/std/src/sys/pal/unix/futex.rs index 0fc765dc87a..d4551dd6a38 100644 --- a/library/std/src/sys/pal/unix/futex.rs +++ b/library/std/src/sys/pal/unix/futex.rs @@ -219,7 +219,7 @@ pub fn futex_wake_all(futex: &AtomicU32) { } #[cfg(target_os = "emscripten")] -extern "C" { +unsafe extern "C" { fn emscripten_futex_wake(addr: *const AtomicU32, count: libc::c_int) -> libc::c_int; fn emscripten_futex_wait( addr: *const AtomicU32, @@ -267,7 +267,7 @@ pub mod zircon { pub const ZX_ERR_BAD_STATE: zx_status_t = -20; pub const ZX_ERR_TIMED_OUT: zx_status_t = -21; - extern "C" { + unsafe extern "C" { pub fn zx_clock_get_monotonic() -> zx_time_t; pub fn zx_futex_wait( value_ptr: *const zx_futex_t, diff --git a/library/std/src/sys/pal/unix/io.rs b/library/std/src/sys/pal/unix/io.rs deleted file mode 100644 index 0d5a152dc0d..00000000000 --- a/library/std/src/sys/pal/unix/io.rs +++ /dev/null @@ -1,87 +0,0 @@ -use libc::{c_void, iovec}; - -use crate::marker::PhantomData; -use crate::os::fd::{AsFd, AsRawFd}; -use crate::slice; - -#[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 const fn as_slice(&self) -> &'a [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 const fn into_slice(self) -> &'a mut [u8] { - unsafe { slice::from_raw_parts_mut(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 fn is_terminal(fd: &impl AsFd) -> bool { - let fd = fd.as_fd(); - unsafe { libc::isatty(fd.as_raw_fd()) != 0 } -} diff --git a/library/std/src/sys/pal/unix/kernel_copy/tests.rs b/library/std/src/sys/pal/unix/kernel_copy/tests.rs index 1350d743ff6..54d8f8ed2ed 100644 --- a/library/std/src/sys/pal/unix/kernel_copy/tests.rs +++ b/library/std/src/sys/pal/unix/kernel_copy/tests.rs @@ -2,7 +2,7 @@ use crate::fs::OpenOptions; use crate::io; use crate::io::{BufRead, Read, Result, Seek, SeekFrom, Write}; use crate::os::unix::io::AsRawFd; -use crate::sys_common::io::test::tmpdir; +use crate::test_helpers::tmpdir; #[test] fn copy_specialization() -> Result<()> { diff --git a/library/std/src/sys/pal/unix/l4re.rs b/library/std/src/sys/pal/unix/l4re.rs deleted file mode 100644 index 37dd370c514..00000000000 --- a/library/std/src/sys/pal/unix/l4re.rs +++ /dev/null @@ -1,564 +0,0 @@ -macro_rules! unimpl { - () => { - return Err(io::const_error!( - io::ErrorKind::Unsupported, - "No networking available on L4Re.", - )); - }; -} - -pub mod net { - #![allow(warnings)] - use crate::fmt; - use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; - use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr}; - use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; - use crate::sys::fd::FileDesc; - use crate::sys_common::{AsInner, FromInner, IntoInner}; - use crate::time::Duration; - - #[allow(unused_extern_crates)] - pub extern crate libc as netc; - - pub struct Socket(FileDesc); - impl Socket { - pub fn new(_: &SocketAddr, _: libc::c_int) -> io::Result<Socket> { - unimpl!(); - } - - pub fn new_raw(_: libc::c_int, _: libc::c_int) -> io::Result<Socket> { - unimpl!(); - } - - pub fn new_pair(_: libc::c_int, _: libc::c_int) -> io::Result<(Socket, Socket)> { - unimpl!(); - } - - pub fn connect_timeout(&self, _: &SocketAddr, _: Duration) -> io::Result<()> { - unimpl!(); - } - - pub fn accept( - &self, - _: *mut libc::sockaddr, - _: *mut libc::socklen_t, - ) -> io::Result<Socket> { - unimpl!(); - } - - pub fn duplicate(&self) -> io::Result<Socket> { - unimpl!(); - } - - pub fn read(&self, _: &mut [u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn read_buf(&self, _: BorrowedCursor<'_>) -> io::Result<()> { - unimpl!(); - } - - pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - unimpl!(); - } - - pub fn is_read_vectored(&self) -> bool { - false - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - unimpl!(); - } - - pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - unimpl!(); - } - - pub fn write(&self, _: &[u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> { - unimpl!(); - } - - pub fn is_write_vectored(&self) -> bool { - false - } - - pub fn set_timeout(&self, _: Option<Duration>, _: libc::c_int) -> io::Result<()> { - unimpl!(); - } - - pub fn timeout(&self, _: libc::c_int) -> io::Result<Option<Duration>> { - unimpl!(); - } - - pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { - unimpl!(); - } - - pub fn set_linger(&self, _: Option<Duration>) -> io::Result<()> { - unimpl!(); - } - - pub fn linger(&self) -> io::Result<Option<Duration>> { - unimpl!(); - } - - pub fn set_nodelay(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn nodelay(&self) -> io::Result<bool> { - unimpl!(); - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - unimpl!(); - } - - // This is used by sys_common code to abstract over Windows and Unix. - pub fn as_raw(&self) -> RawFd { - self.as_raw_fd() - } - } - - impl AsInner<FileDesc> for Socket { - #[inline] - fn as_inner(&self) -> &FileDesc { - &self.0 - } - } - - impl FromInner<FileDesc> for Socket { - fn from_inner(file_desc: FileDesc) -> Socket { - Socket(file_desc) - } - } - - impl IntoInner<FileDesc> for Socket { - fn into_inner(self) -> FileDesc { - self.0 - } - } - - impl AsFd for Socket { - fn as_fd(&self) -> BorrowedFd<'_> { - self.0.as_fd() - } - } - - impl AsRawFd for Socket { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() - } - } - - impl IntoRawFd for Socket { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw_fd() - } - } - - impl FromRawFd for Socket { - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - Self(FromRawFd::from_raw_fd(raw_fd)) - } - } - - pub struct TcpStream { - inner: Socket, - } - - impl TcpStream { - pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> { - unimpl!(); - } - - pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> { - unimpl!(); - } - - #[inline] - pub fn socket(&self) -> &Socket { - &self.inner - } - - pub fn into_socket(self) -> Socket { - self.inner - } - - pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { - unimpl!(); - } - - pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { - unimpl!(); - } - - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - unimpl!(); - } - - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - unimpl!(); - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn read(&self, _: &mut [u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn read_buf(&self, _: BorrowedCursor<'_>) -> io::Result<()> { - unimpl!(); - } - - pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - unimpl!(); - } - - pub fn is_read_vectored(&self) -> bool { - false - } - - pub fn write(&self, _: &[u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> { - unimpl!(); - } - - pub fn is_write_vectored(&self) -> bool { - false - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - unimpl!(); - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - unimpl!(); - } - - pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { - unimpl!(); - } - - pub fn duplicate(&self) -> io::Result<TcpStream> { - unimpl!(); - } - - pub fn set_linger(&self, _: Option<Duration>) -> io::Result<()> { - unimpl!(); - } - - pub fn linger(&self) -> io::Result<Option<Duration>> { - unimpl!(); - } - - pub fn set_nodelay(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn nodelay(&self) -> io::Result<bool> { - unimpl!(); - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn ttl(&self) -> io::Result<u32> { - unimpl!(); - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - unimpl!(); - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - } - - impl FromInner<Socket> for TcpStream { - fn from_inner(socket: Socket) -> TcpStream { - TcpStream { inner: socket } - } - } - - impl fmt::Debug for TcpStream { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "No networking support available on L4Re") - } - } - - pub struct TcpListener { - inner: Socket, - } - - impl TcpListener { - pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> { - unimpl!(); - } - - #[inline] - pub fn socket(&self) -> &Socket { - &self.inner - } - - pub fn into_socket(self) -> Socket { - self.inner - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - unimpl!(); - } - - pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { - unimpl!(); - } - - pub fn duplicate(&self) -> io::Result<TcpListener> { - unimpl!(); - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn ttl(&self) -> io::Result<u32> { - unimpl!(); - } - - pub fn set_only_v6(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn only_v6(&self) -> io::Result<bool> { - unimpl!(); - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - unimpl!(); - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - } - - impl FromInner<Socket> for TcpListener { - fn from_inner(socket: Socket) -> TcpListener { - TcpListener { inner: socket } - } - } - - impl fmt::Debug for TcpListener { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "No networking support available on L4Re.") - } - } - - pub struct UdpSocket { - inner: Socket, - } - - impl UdpSocket { - pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> { - unimpl!(); - } - - #[inline] - pub fn socket(&self) -> &Socket { - &self.inner - } - - pub fn into_socket(self) -> Socket { - self.inner - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - unimpl!(); - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - unimpl!(); - } - - pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - unimpl!(); - } - - pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - unimpl!(); - } - - pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> { - unimpl!(); - } - - pub fn duplicate(&self) -> io::Result<UdpSocket> { - unimpl!(); - } - - pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { - unimpl!(); - } - - pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { - unimpl!(); - } - - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - unimpl!(); - } - - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - unimpl!(); - } - - pub fn set_broadcast(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn broadcast(&self) -> io::Result<bool> { - unimpl!(); - } - - pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn multicast_loop_v4(&self) -> io::Result<bool> { - unimpl!(); - } - - pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn multicast_ttl_v4(&self) -> io::Result<u32> { - unimpl!(); - } - - pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn multicast_loop_v6(&self) -> io::Result<bool> { - unimpl!(); - } - - pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - unimpl!(); - } - - pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - unimpl!(); - } - - pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn ttl(&self) -> io::Result<u32> { - unimpl!(); - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - unimpl!(); - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn send(&self, _: &[u8]) -> io::Result<usize> { - unimpl!(); - } - - pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> { - unimpl!(); - } - } - - impl FromInner<Socket> for UdpSocket { - fn from_inner(socket: Socket) -> UdpSocket { - UdpSocket { inner: socket } - } - } - - impl fmt::Debug for UdpSocket { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "No networking support on L4Re available.") - } - } - - pub struct LookupHost { - original: *mut libc::addrinfo, - cur: *mut libc::addrinfo, - } - - impl Iterator for LookupHost { - type Item = SocketAddr; - fn next(&mut self) -> Option<SocketAddr> { - None - } - } - - impl LookupHost { - pub fn port(&self) -> u16 { - 0 // unimplemented - } - } - - unsafe impl Sync for LookupHost {} - unsafe impl Send for LookupHost {} - - impl TryFrom<&str> for LookupHost { - type Error = io::Error; - - fn try_from(_v: &str) -> io::Result<LookupHost> { - unimpl!(); - } - } - - impl<'a> TryFrom<(&'a str, u16)> for LookupHost { - type Error = io::Error; - - fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> { - unimpl!(); - } - } -} diff --git a/library/std/src/sys/pal/unix/linux/pidfd/tests.rs b/library/std/src/sys/pal/unix/linux/pidfd/tests.rs index fb928c76fbd..17b06bea912 100644 --- a/library/std/src/sys/pal/unix/linux/pidfd/tests.rs +++ b/library/std/src/sys/pal/unix/linux/pidfd/tests.rs @@ -45,8 +45,8 @@ fn test_command_pidfd() { .expect_err("pidfd should not have been created"); // exercise the fork/exec path since the earlier attempts may have used pidfd_spawnp() - let mut child = - unsafe { Command::new("false").pre_exec(|| Ok(())) }.create_pidfd(true).spawn().unwrap(); + let mut cmd = Command::new("false"); + let mut child = unsafe { cmd.pre_exec(|| Ok(())) }.create_pidfd(true).spawn().unwrap(); assert!(child.id() > 0 && child.id() < -1i32 as u32); diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 3cc1cae8d00..c0b56d8d2b2 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -11,17 +11,10 @@ pub mod env; pub mod fd; pub mod fs; pub mod futex; -pub mod io; #[cfg(any(target_os = "linux", target_os = "android"))] pub mod kernel_copy; -#[cfg(target_os = "l4re")] -mod l4re; #[cfg(target_os = "linux")] pub mod linux; -#[cfg(not(target_os = "l4re"))] -pub mod net; -#[cfg(target_os = "l4re")] -pub use self::l4re::net; pub mod os; pub mod pipe; pub mod process; @@ -380,24 +373,24 @@ cfg_if::cfg_if! { cfg(target_feature = "crt-static"))] #[link(name = "dl", cfg(not(target_feature = "crt-static")))] #[link(name = "log", cfg(not(target_feature = "crt-static")))] - extern "C" {} + unsafe extern "C" {} } else if #[cfg(target_os = "freebsd")] { #[link(name = "execinfo")] #[link(name = "pthread")] - extern "C" {} + unsafe extern "C" {} } else if #[cfg(target_os = "netbsd")] { #[link(name = "pthread")] #[link(name = "rt")] - extern "C" {} + unsafe extern "C" {} } else if #[cfg(any(target_os = "dragonfly", target_os = "openbsd"))] { #[link(name = "pthread")] - extern "C" {} + unsafe extern "C" {} } else if #[cfg(target_os = "solaris")] { #[link(name = "socket")] #[link(name = "posix4")] #[link(name = "pthread")] #[link(name = "resolv")] - extern "C" {} + unsafe extern "C" {} } else if #[cfg(target_os = "illumos")] { #[link(name = "socket")] #[link(name = "posix4")] @@ -406,24 +399,24 @@ cfg_if::cfg_if! { #[link(name = "nsl")] // Use libumem for the (malloc-compatible) allocator #[link(name = "umem")] - extern "C" {} + unsafe extern "C" {} } else if #[cfg(target_vendor = "apple")] { // Link to `libSystem.dylib`. // // Don't get confused by the presence of `System.framework`, // it is a deprecated wrapper over the dynamic library. #[link(name = "System")] - extern "C" {} + unsafe extern "C" {} } else if #[cfg(target_os = "fuchsia")] { #[link(name = "zircon")] #[link(name = "fdio")] - extern "C" {} + unsafe extern "C" {} } else if #[cfg(all(target_os = "linux", target_env = "uclibc"))] { #[link(name = "dl")] - extern "C" {} + unsafe extern "C" {} } else if #[cfg(target_os = "vita")] { #[link(name = "pthread", kind = "static", modifiers = "-bundle")] - extern "C" {} + unsafe extern "C" {} } } diff --git a/library/std/src/sys/pal/unix/net.rs b/library/std/src/sys/pal/unix/net.rs deleted file mode 100644 index d73b9fd5eb8..00000000000 --- a/library/std/src/sys/pal/unix/net.rs +++ /dev/null @@ -1,651 +0,0 @@ -use libc::{MSG_PEEK, c_int, c_void, size_t, sockaddr, socklen_t}; - -use crate::ffi::CStr; -use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut}; -use crate::net::{Shutdown, SocketAddr}; -use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; -use crate::sys::fd::FileDesc; -use crate::sys::pal::unix::IsMinusOne; -use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr}; -use crate::sys_common::{AsInner, FromInner, IntoInner}; -use crate::time::{Duration, Instant}; -use crate::{cmp, mem}; - -cfg_if::cfg_if! { - if #[cfg(target_vendor = "apple")] { - use libc::SO_LINGER_SEC as SO_LINGER; - } else { - use libc::SO_LINGER; - } -} - -pub use crate::sys::{cvt, cvt_r}; - -#[allow(unused_extern_crates)] -pub extern crate libc as netc; - -pub type wrlen_t = size_t; - -pub struct Socket(FileDesc); - -pub fn init() {} - -pub fn cvt_gai(err: c_int) -> io::Result<()> { - if err == 0 { - return Ok(()); - } - - // We may need to trigger a glibc workaround. See on_resolver_failure() for details. - on_resolver_failure(); - - #[cfg(not(any(target_os = "espidf", target_os = "nuttx")))] - if err == libc::EAI_SYSTEM { - return Err(io::Error::last_os_error()); - } - - #[cfg(not(any(target_os = "espidf", target_os = "nuttx")))] - let detail = unsafe { - // We can't always expect a UTF-8 environment. When we don't get that luxury, - // it's better to give a low-quality error message than none at all. - CStr::from_ptr(libc::gai_strerror(err)).to_string_lossy() - }; - - #[cfg(any(target_os = "espidf", target_os = "nuttx"))] - let detail = ""; - - Err(io::Error::new( - io::ErrorKind::Uncategorized, - &format!("failed to lookup address information: {detail}")[..], - )) -} - -impl Socket { - pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> { - let fam = match *addr { - SocketAddr::V4(..) => libc::AF_INET, - SocketAddr::V6(..) => libc::AF_INET6, - }; - Socket::new_raw(fam, ty) - } - - pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> { - unsafe { - cfg_if::cfg_if! { - if #[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "hurd", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd", - target_os = "nto", - target_os = "solaris", - ))] { - // On platforms that support it we pass the SOCK_CLOEXEC - // flag to atomically create the socket and set it as - // CLOEXEC. On Linux this was added in 2.6.27. - let fd = cvt(libc::socket(fam, ty | libc::SOCK_CLOEXEC, 0))?; - let socket = Socket(FileDesc::from_raw_fd(fd)); - - // DragonFlyBSD, FreeBSD and NetBSD use `SO_NOSIGPIPE` as a `setsockopt` - // flag to disable `SIGPIPE` emission on socket. - #[cfg(any(target_os = "freebsd", target_os = "netbsd", target_os = "dragonfly"))] - setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)?; - - Ok(socket) - } else { - let fd = cvt(libc::socket(fam, ty, 0))?; - let fd = FileDesc::from_raw_fd(fd); - fd.set_cloexec()?; - let socket = Socket(fd); - - // macOS and iOS use `SO_NOSIGPIPE` as a `setsockopt` - // flag to disable `SIGPIPE` emission on socket. - #[cfg(target_vendor = "apple")] - setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)?; - - Ok(socket) - } - } - } - } - - #[cfg(not(target_os = "vxworks"))] - pub fn new_pair(fam: c_int, ty: c_int) -> io::Result<(Socket, Socket)> { - unsafe { - let mut fds = [0, 0]; - - cfg_if::cfg_if! { - if #[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "linux", - target_os = "hurd", - target_os = "netbsd", - target_os = "openbsd", - target_os = "nto", - ))] { - // Like above, set cloexec atomically - cvt(libc::socketpair(fam, ty | libc::SOCK_CLOEXEC, 0, fds.as_mut_ptr()))?; - Ok((Socket(FileDesc::from_raw_fd(fds[0])), Socket(FileDesc::from_raw_fd(fds[1])))) - } else { - cvt(libc::socketpair(fam, ty, 0, fds.as_mut_ptr()))?; - let a = FileDesc::from_raw_fd(fds[0]); - let b = FileDesc::from_raw_fd(fds[1]); - a.set_cloexec()?; - b.set_cloexec()?; - Ok((Socket(a), Socket(b))) - } - } - } - } - - #[cfg(target_os = "vxworks")] - pub fn new_pair(_fam: c_int, _ty: c_int) -> io::Result<(Socket, Socket)> { - unimplemented!() - } - - pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> { - let (addr, len) = addr.into_inner(); - loop { - let result = unsafe { libc::connect(self.as_raw_fd(), addr.as_ptr(), len) }; - if result.is_minus_one() { - let err = crate::sys::os::errno(); - match err { - libc::EINTR => continue, - libc::EISCONN => return Ok(()), - _ => return Err(io::Error::from_raw_os_error(err)), - } - } - return Ok(()); - } - } - - pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> { - self.set_nonblocking(true)?; - let r = unsafe { - let (addr, len) = addr.into_inner(); - cvt(libc::connect(self.as_raw_fd(), addr.as_ptr(), len)) - }; - self.set_nonblocking(false)?; - - match r { - Ok(_) => return Ok(()), - // there's no ErrorKind for EINPROGRESS :( - Err(ref e) if e.raw_os_error() == Some(libc::EINPROGRESS) => {} - Err(e) => return Err(e), - } - - let mut pollfd = libc::pollfd { fd: self.as_raw_fd(), events: libc::POLLOUT, revents: 0 }; - - if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 { - return Err(io::Error::ZERO_TIMEOUT); - } - - let start = Instant::now(); - - loop { - let elapsed = start.elapsed(); - if elapsed >= timeout { - return Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")); - } - - let timeout = timeout - elapsed; - let mut timeout = timeout - .as_secs() - .saturating_mul(1_000) - .saturating_add(timeout.subsec_nanos() as u64 / 1_000_000); - if timeout == 0 { - timeout = 1; - } - - let timeout = cmp::min(timeout, c_int::MAX as u64) as c_int; - - match unsafe { libc::poll(&mut pollfd, 1, timeout) } { - -1 => { - let err = io::Error::last_os_error(); - if !err.is_interrupted() { - return Err(err); - } - } - 0 => {} - _ => { - if cfg!(target_os = "vxworks") { - // VxWorks poll does not return POLLHUP or POLLERR in revents. Check if the - // connection actually succeeded and return ok only when the socket is - // ready and no errors were found. - if let Some(e) = self.take_error()? { - return Err(e); - } - } else { - // linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look - // for POLLHUP or POLLERR rather than read readiness - if pollfd.revents & (libc::POLLHUP | libc::POLLERR) != 0 { - let e = self.take_error()?.unwrap_or_else(|| { - io::const_error!( - io::ErrorKind::Uncategorized, - "no error set after POLLHUP", - ) - }); - return Err(e); - } - } - - return Ok(()); - } - } - } - } - - pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t) -> io::Result<Socket> { - // Unfortunately the only known way right now to accept a socket and - // atomically set the CLOEXEC flag is to use the `accept4` syscall on - // platforms that support it. On Linux, this was added in 2.6.28, - // glibc 2.10 and musl 0.9.5. - cfg_if::cfg_if! { - if #[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "linux", - target_os = "hurd", - target_os = "netbsd", - target_os = "openbsd", - ))] { - unsafe { - let fd = cvt_r(|| libc::accept4(self.as_raw_fd(), storage, len, libc::SOCK_CLOEXEC))?; - Ok(Socket(FileDesc::from_raw_fd(fd))) - } - } else { - unsafe { - let fd = cvt_r(|| libc::accept(self.as_raw_fd(), storage, len))?; - let fd = FileDesc::from_raw_fd(fd); - fd.set_cloexec()?; - Ok(Socket(fd)) - } - } - } - } - - pub fn duplicate(&self) -> io::Result<Socket> { - self.0.duplicate().map(Socket) - } - - fn recv_with_flags(&self, mut buf: BorrowedCursor<'_>, flags: c_int) -> io::Result<()> { - let ret = cvt(unsafe { - libc::recv( - self.as_raw_fd(), - buf.as_mut().as_mut_ptr() as *mut c_void, - buf.capacity(), - flags, - ) - })?; - unsafe { - buf.advance_unchecked(ret as usize); - } - Ok(()) - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - let mut buf = BorrowedBuf::from(buf); - self.recv_with_flags(buf.unfilled(), 0)?; - Ok(buf.len()) - } - - pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { - let mut buf = BorrowedBuf::from(buf); - self.recv_with_flags(buf.unfilled(), MSG_PEEK)?; - Ok(buf.len()) - } - - pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> { - self.recv_with_flags(buf, 0) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - self.0.read_vectored(bufs) - } - - #[inline] - pub fn is_read_vectored(&self) -> bool { - self.0.is_read_vectored() - } - - fn recv_from_with_flags( - &self, - buf: &mut [u8], - flags: c_int, - ) -> io::Result<(usize, SocketAddr)> { - let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() }; - let mut addrlen = mem::size_of_val(&storage) as libc::socklen_t; - - let n = cvt(unsafe { - libc::recvfrom( - self.as_raw_fd(), - buf.as_mut_ptr() as *mut c_void, - buf.len(), - flags, - (&raw mut storage) as *mut _, - &mut addrlen, - ) - })?; - Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?)) - } - - pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.recv_from_with_flags(buf, 0) - } - - #[cfg(any(target_os = "android", target_os = "linux"))] - pub fn recv_msg(&self, msg: &mut libc::msghdr) -> io::Result<usize> { - let n = cvt(unsafe { libc::recvmsg(self.as_raw_fd(), msg, libc::MSG_CMSG_CLOEXEC) })?; - Ok(n as usize) - } - - pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - self.recv_from_with_flags(buf, MSG_PEEK) - } - - pub fn write(&self, buf: &[u8]) -> io::Result<usize> { - self.0.write(buf) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - self.0.write_vectored(bufs) - } - - #[inline] - pub fn is_write_vectored(&self) -> bool { - self.0.is_write_vectored() - } - - #[cfg(any(target_os = "android", target_os = "linux"))] - pub fn send_msg(&self, msg: &mut libc::msghdr) -> io::Result<usize> { - let n = cvt(unsafe { libc::sendmsg(self.as_raw_fd(), msg, 0) })?; - Ok(n as usize) - } - - pub fn set_timeout(&self, dur: Option<Duration>, kind: libc::c_int) -> io::Result<()> { - let timeout = match dur { - Some(dur) => { - if dur.as_secs() == 0 && dur.subsec_nanos() == 0 { - return Err(io::Error::ZERO_TIMEOUT); - } - - let secs = if dur.as_secs() > libc::time_t::MAX as u64 { - libc::time_t::MAX - } else { - dur.as_secs() as libc::time_t - }; - let mut timeout = libc::timeval { - tv_sec: secs, - tv_usec: dur.subsec_micros() as libc::suseconds_t, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => libc::timeval { tv_sec: 0, tv_usec: 0 }, - }; - setsockopt(self, libc::SOL_SOCKET, kind, timeout) - } - - pub fn timeout(&self, kind: libc::c_int) -> io::Result<Option<Duration>> { - let raw: libc::timeval = getsockopt(self, libc::SOL_SOCKET, kind)?; - if raw.tv_sec == 0 && raw.tv_usec == 0 { - Ok(None) - } else { - let sec = raw.tv_sec as u64; - let nsec = (raw.tv_usec as u32) * 1000; - Ok(Some(Duration::new(sec, nsec))) - } - } - - pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { - let how = match how { - Shutdown::Write => libc::SHUT_WR, - Shutdown::Read => libc::SHUT_RD, - Shutdown::Both => libc::SHUT_RDWR, - }; - cvt(unsafe { libc::shutdown(self.as_raw_fd(), how) })?; - Ok(()) - } - - pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> { - let linger = libc::linger { - l_onoff: linger.is_some() as libc::c_int, - l_linger: linger.unwrap_or_default().as_secs() as libc::c_int, - }; - - setsockopt(self, libc::SOL_SOCKET, SO_LINGER, linger) - } - - pub fn linger(&self) -> io::Result<Option<Duration>> { - let val: libc::linger = getsockopt(self, libc::SOL_SOCKET, SO_LINGER)?; - - Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64))) - } - - pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { - setsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY, nodelay as c_int) - } - - pub fn nodelay(&self) -> io::Result<bool> { - let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY)?; - Ok(raw != 0) - } - - #[cfg(any(target_os = "android", target_os = "linux",))] - pub fn set_quickack(&self, quickack: bool) -> io::Result<()> { - setsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK, quickack as c_int) - } - - #[cfg(any(target_os = "android", target_os = "linux",))] - pub fn quickack(&self) -> io::Result<bool> { - let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK)?; - Ok(raw != 0) - } - - // bionic libc makes no use of this flag - #[cfg(target_os = "linux")] - pub fn set_deferaccept(&self, accept: u32) -> io::Result<()> { - setsockopt(self, libc::IPPROTO_TCP, libc::TCP_DEFER_ACCEPT, accept as c_int) - } - - #[cfg(target_os = "linux")] - pub fn deferaccept(&self) -> io::Result<u32> { - let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_DEFER_ACCEPT)?; - Ok(raw as u32) - } - - #[cfg(any(target_os = "freebsd", target_os = "netbsd"))] - pub fn set_acceptfilter(&self, name: &CStr) -> io::Result<()> { - if !name.to_bytes().is_empty() { - const AF_NAME_MAX: usize = 16; - let mut buf = [0; AF_NAME_MAX]; - for (src, dst) in name.to_bytes().iter().zip(&mut buf[..AF_NAME_MAX - 1]) { - *dst = *src as libc::c_char; - } - let mut arg: libc::accept_filter_arg = unsafe { mem::zeroed() }; - arg.af_name = buf; - setsockopt(self, libc::SOL_SOCKET, libc::SO_ACCEPTFILTER, &mut arg) - } else { - setsockopt( - self, - libc::SOL_SOCKET, - libc::SO_ACCEPTFILTER, - core::ptr::null_mut() as *mut c_void, - ) - } - } - - #[cfg(any(target_os = "freebsd", target_os = "netbsd"))] - pub fn acceptfilter(&self) -> io::Result<&CStr> { - let arg: libc::accept_filter_arg = - getsockopt(self, libc::SOL_SOCKET, libc::SO_ACCEPTFILTER)?; - let s: &[u8] = - unsafe { core::slice::from_raw_parts(arg.af_name.as_ptr() as *const u8, 16) }; - let name = CStr::from_bytes_with_nul(s).unwrap(); - Ok(name) - } - - #[cfg(any(target_os = "android", target_os = "linux",))] - pub fn set_passcred(&self, passcred: bool) -> io::Result<()> { - setsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED, passcred as libc::c_int) - } - - #[cfg(any(target_os = "android", target_os = "linux",))] - pub fn passcred(&self) -> io::Result<bool> { - let passcred: libc::c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED)?; - Ok(passcred != 0) - } - - #[cfg(target_os = "netbsd")] - pub fn set_local_creds(&self, local_creds: bool) -> io::Result<()> { - setsockopt(self, 0 as libc::c_int, libc::LOCAL_CREDS, local_creds as libc::c_int) - } - - #[cfg(target_os = "netbsd")] - pub fn local_creds(&self) -> io::Result<bool> { - let local_creds: libc::c_int = getsockopt(self, 0 as libc::c_int, libc::LOCAL_CREDS)?; - Ok(local_creds != 0) - } - - #[cfg(target_os = "freebsd")] - pub fn set_local_creds_persistent(&self, local_creds_persistent: bool) -> io::Result<()> { - setsockopt( - self, - libc::AF_LOCAL, - libc::LOCAL_CREDS_PERSISTENT, - local_creds_persistent as libc::c_int, - ) - } - - #[cfg(target_os = "freebsd")] - pub fn local_creds_persistent(&self) -> io::Result<bool> { - let local_creds_persistent: libc::c_int = - getsockopt(self, libc::AF_LOCAL, libc::LOCAL_CREDS_PERSISTENT)?; - Ok(local_creds_persistent != 0) - } - - #[cfg(not(any(target_os = "solaris", target_os = "illumos", target_os = "vita")))] - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - let mut nonblocking = nonblocking as libc::c_int; - cvt(unsafe { libc::ioctl(self.as_raw_fd(), libc::FIONBIO, &mut nonblocking) }).map(drop) - } - - #[cfg(target_os = "vita")] - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - let option = nonblocking as libc::c_int; - setsockopt(self, libc::SOL_SOCKET, libc::SO_NONBLOCK, option) - } - - #[cfg(any(target_os = "solaris", target_os = "illumos"))] - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - // FIONBIO is inadequate for sockets on illumos/Solaris, so use the - // fcntl(F_[GS]ETFL)-based method provided by FileDesc instead. - self.0.set_nonblocking(nonblocking) - } - - #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))] - pub fn set_mark(&self, mark: u32) -> io::Result<()> { - #[cfg(target_os = "linux")] - let option = libc::SO_MARK; - #[cfg(target_os = "freebsd")] - let option = libc::SO_USER_COOKIE; - #[cfg(target_os = "openbsd")] - let option = libc::SO_RTABLE; - setsockopt(self, libc::SOL_SOCKET, option, mark as libc::c_int) - } - - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?; - if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } - } - - // This is used by sys_common code to abstract over Windows and Unix. - pub fn as_raw(&self) -> RawFd { - self.as_raw_fd() - } -} - -impl AsInner<FileDesc> for Socket { - #[inline] - fn as_inner(&self) -> &FileDesc { - &self.0 - } -} - -impl IntoInner<FileDesc> for Socket { - fn into_inner(self) -> FileDesc { - self.0 - } -} - -impl FromInner<FileDesc> for Socket { - fn from_inner(file_desc: FileDesc) -> Self { - Self(file_desc) - } -} - -impl AsFd for Socket { - fn as_fd(&self) -> BorrowedFd<'_> { - self.0.as_fd() - } -} - -impl AsRawFd for Socket { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() - } -} - -impl IntoRawFd for Socket { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw_fd() - } -} - -impl FromRawFd for Socket { - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - Self(FromRawFd::from_raw_fd(raw_fd)) - } -} - -// In versions of glibc prior to 2.26, there's a bug where the DNS resolver -// will cache the contents of /etc/resolv.conf, so changes to that file on disk -// can be ignored by a long-running program. That can break DNS lookups on e.g. -// laptops where the network comes and goes. See -// https://sourceware.org/bugzilla/show_bug.cgi?id=984. Note however that some -// distros including Debian have patched glibc to fix this for a long time. -// -// A workaround for this bug is to call the res_init libc function, to clear -// the cached configs. Unfortunately, while we believe glibc's implementation -// of res_init is thread-safe, we know that other implementations are not -// (https://github.com/rust-lang/rust/issues/43592). Code here in std could -// try to synchronize its res_init calls with a Mutex, but that wouldn't -// protect programs that call into libc in other ways. So instead of calling -// res_init unconditionally, we call it only when we detect we're linking -// against glibc version < 2.26. (That is, when we both know its needed and -// believe it's thread-safe). -#[cfg(all(target_os = "linux", target_env = "gnu"))] -fn on_resolver_failure() { - use crate::sys; - - // If the version fails to parse, we treat it the same as "not glibc". - if let Some(version) = sys::os::glibc_version() { - if version < (2, 26) { - unsafe { libc::res_init() }; - } - } -} - -#[cfg(not(all(target_os = "linux", target_env = "gnu")))] -fn on_resolver_failure() {} diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index b83772e34c1..78404b4afa7 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -30,7 +30,7 @@ cfg_if::cfg_if! { } } -extern "C" { +unsafe extern "C" { #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))] #[cfg_attr( any( @@ -82,7 +82,7 @@ pub fn errno() -> i32 { #[cfg(target_os = "rtems")] pub fn errno() -> i32 { - extern "C" { + unsafe extern "C" { #[thread_local] static _tls_errno: c_int; } @@ -92,7 +92,7 @@ pub fn errno() -> i32 { #[cfg(target_os = "dragonfly")] pub fn errno() -> i32 { - extern "C" { + unsafe extern "C" { #[thread_local] static errno: c_int; } @@ -103,7 +103,7 @@ pub fn errno() -> i32 { #[cfg(target_os = "dragonfly")] #[allow(dead_code)] pub fn set_errno(e: i32) { - extern "C" { + unsafe extern "C" { #[thread_local] static mut errno: c_int; } @@ -115,7 +115,7 @@ pub fn set_errno(e: i32) { /// Gets a detailed string description for the given error number. pub fn error_string(errno: i32) -> String { - extern "C" { + unsafe extern "C" { #[cfg_attr( all( any(target_os = "linux", target_os = "hurd", target_env = "newlib"), @@ -260,7 +260,7 @@ pub fn current_exe() -> io::Result<PathBuf> { let exe_path = env::args().next().ok_or(io::const_error!( ErrorKind::NotFound, - "an executable path was not found because no arguments were provided through argv" + "an executable path was not found because no arguments were provided through argv", ))?; let path = PathBuf::from(exe_path); if path.is_absolute() { @@ -382,9 +382,7 @@ pub fn current_exe() -> io::Result<PathBuf> { cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _, &mut argv_len, ptr::null_mut(), 0))?; argv.set_len(argv_len as usize); if argv[0].is_null() { - return Err( - io::const_error!(io::ErrorKind::Uncategorized, "no current exe available",), - ); + return Err(io::const_error!(io::ErrorKind::Uncategorized, "no current exe available")); } let argv0 = CStr::from_ptr(argv[0]).to_bytes(); if argv0[0] == b'.' || argv0.iter().any(|b| *b == b'/') { @@ -526,7 +524,7 @@ pub fn current_exe() -> io::Result<PathBuf> { let exe_path = env::args().next().ok_or(io::const_error!( ErrorKind::Uncategorized, - "an executable path was not found because no arguments were provided through argv" + "an executable path was not found because no arguments were provided through argv", ))?; let path = PathBuf::from(exe_path); @@ -610,7 +608,7 @@ pub unsafe fn environ() -> *mut *const *const c_char { // Use the `environ` static which is part of POSIX. #[cfg(not(target_vendor = "apple"))] pub unsafe fn environ() -> *mut *const *const c_char { - extern "C" { + unsafe extern "C" { static mut environ: *const *const c_char; } &raw mut environ @@ -847,7 +845,7 @@ pub fn getppid() -> u32 { #[cfg(all(target_os = "linux", target_env = "gnu"))] pub fn glibc_version() -> Option<(usize, usize)> { - extern "C" { + unsafe extern "C" { fn gnu_get_libc_version() -> *const libc::c_char; } let version_cstr = unsafe { CStr::from_ptr(gnu_get_libc_version()) }; diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index 2bff192a5bd..aa7406dd548 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -228,7 +228,7 @@ impl Command { let envp = self.capture_env(); if self.saw_nul() { - return io::const_error!(ErrorKind::InvalidInput, "nul byte found in provided data",); + return io::const_error!(ErrorKind::InvalidInput, "nul byte found in provided data"); } match self.setup_io(default, true) { @@ -1228,7 +1228,7 @@ mod linux_child_ext { .as_ref() // SAFETY: The os type is a transparent wrapper, therefore we can transmute references .map(|fd| unsafe { mem::transmute::<&imp::PidFd, &os::PidFd>(fd) }) - .ok_or_else(|| io::Error::new(ErrorKind::Uncategorized, "No pidfd was created.")) + .ok_or_else(|| io::const_error!(ErrorKind::Uncategorized, "No pidfd was created.")) } fn into_pidfd(mut self) -> Result<os::PidFd, Self> { diff --git a/library/std/src/sys/pal/unix/process/zircon.rs b/library/std/src/sys/pal/unix/process/zircon.rs index 4035e2370a3..7932bd26d76 100644 --- a/library/std/src/sys/pal/unix/process/zircon.rs +++ b/library/std/src/sys/pal/unix/process/zircon.rs @@ -75,7 +75,7 @@ pub struct zx_info_process_t { pub reserved1: u32, } -extern "C" { +unsafe extern "C" { pub fn zx_job_default() -> zx_handle_t; pub fn zx_task_kill(handle: zx_handle_t) -> zx_status_t; @@ -115,7 +115,7 @@ pub struct fdio_spawn_action_t { pub reserved1: u64, } -extern "C" { +unsafe extern "C" { pub fn fdio_spawn_etc( job: zx_handle_t, flags: u32, diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs index db5c6bd3a1c..43ece63457f 100644 --- a/library/std/src/sys/pal/unix/stack_overflow.rs +++ b/library/std/src/sys/pal/unix/stack_overflow.rs @@ -319,21 +319,27 @@ mod imp { ))] unsafe fn get_stack_start() -> Option<*mut libc::c_void> { let mut ret = None; - let mut attr: libc::pthread_attr_t = crate::mem::zeroed(); + let mut attr: mem::MaybeUninit<libc::pthread_attr_t> = mem::MaybeUninit::uninit(); + if !cfg!(target_os = "freebsd") { + attr = mem::MaybeUninit::zeroed(); + } #[cfg(target_os = "freebsd")] - assert_eq!(libc::pthread_attr_init(&mut attr), 0); + assert_eq!(libc::pthread_attr_init(attr.as_mut_ptr()), 0); #[cfg(target_os = "freebsd")] - let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr); + let e = libc::pthread_attr_get_np(libc::pthread_self(), attr.as_mut_ptr()); #[cfg(not(target_os = "freebsd"))] - let e = libc::pthread_getattr_np(libc::pthread_self(), &mut attr); + let e = libc::pthread_getattr_np(libc::pthread_self(), attr.as_mut_ptr()); if e == 0 { let mut stackaddr = crate::ptr::null_mut(); let mut stacksize = 0; - assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, &mut stacksize), 0); + assert_eq!( + libc::pthread_attr_getstack(attr.as_ptr(), &mut stackaddr, &mut stacksize), + 0 + ); ret = Some(stackaddr); } if e == 0 || cfg!(target_os = "freebsd") { - assert_eq!(libc::pthread_attr_destroy(&mut attr), 0); + assert_eq!(libc::pthread_attr_destroy(attr.as_mut_ptr()), 0); } ret } @@ -509,16 +515,20 @@ mod imp { // FIXME: I am probably not unsafe. unsafe fn current_guard() -> Option<Range<usize>> { let mut ret = None; - let mut attr: libc::pthread_attr_t = crate::mem::zeroed(); + + let mut attr: mem::MaybeUninit<libc::pthread_attr_t> = mem::MaybeUninit::uninit(); + if !cfg!(target_os = "freebsd") { + attr = mem::MaybeUninit::zeroed(); + } #[cfg(target_os = "freebsd")] - assert_eq!(libc::pthread_attr_init(&mut attr), 0); + assert_eq!(libc::pthread_attr_init(attr.as_mut_ptr()), 0); #[cfg(target_os = "freebsd")] - let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr); + let e = libc::pthread_attr_get_np(libc::pthread_self(), attr.as_mut_ptr()); #[cfg(not(target_os = "freebsd"))] - let e = libc::pthread_getattr_np(libc::pthread_self(), &mut attr); + let e = libc::pthread_getattr_np(libc::pthread_self(), attr.as_mut_ptr()); if e == 0 { let mut guardsize = 0; - assert_eq!(libc::pthread_attr_getguardsize(&attr, &mut guardsize), 0); + assert_eq!(libc::pthread_attr_getguardsize(attr.as_ptr(), &mut guardsize), 0); if guardsize == 0 { if cfg!(all(target_os = "linux", target_env = "musl")) { // musl versions before 1.1.19 always reported guard @@ -531,7 +541,7 @@ mod imp { } let mut stackptr = crate::ptr::null_mut::<libc::c_void>(); let mut size = 0; - assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackptr, &mut size), 0); + assert_eq!(libc::pthread_attr_getstack(attr.as_ptr(), &mut stackptr, &mut size), 0); let stackaddr = stackptr.addr(); ret = if cfg!(any(target_os = "freebsd", target_os = "netbsd", target_os = "hurd")) { @@ -552,7 +562,7 @@ mod imp { }; } if e == 0 || cfg!(target_os = "freebsd") { - assert_eq!(libc::pthread_attr_destroy(&mut attr), 0); + assert_eq!(libc::pthread_attr_destroy(attr.as_mut_ptr()), 0); } ret } diff --git a/library/std/src/sys/pal/unix/stdio.rs b/library/std/src/sys/pal/unix/stdio.rs index 97e75f1b5b6..8c2f61a40de 100644 --- a/library/std/src/sys/pal/unix/stdio.rs +++ b/library/std/src/sys/pal/unix/stdio.rs @@ -92,7 +92,7 @@ pub fn is_ebadf(err: &io::Error) -> bool { err.raw_os_error() == Some(libc::EBADF as i32) } -pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE; +pub const STDIN_BUF_SIZE: usize = crate::sys::io::DEFAULT_BUF_SIZE; pub fn panic_output() -> Option<impl io::Write> { Some(Stderr::new()) diff --git a/library/std/src/sys/pal/unix/sync/mutex.rs b/library/std/src/sys/pal/unix/sync/mutex.rs index 8ff6c3d3d15..557e70af94b 100644 --- a/library/std/src/sys/pal/unix/sync/mutex.rs +++ b/library/std/src/sys/pal/unix/sync/mutex.rs @@ -111,9 +111,9 @@ impl Drop for Mutex { // `PTHREAD_MUTEX_INITIALIZER`, which is valid at all locations. Thus, // this call always destroys a valid mutex. let r = unsafe { libc::pthread_mutex_destroy(self.raw()) }; - if cfg!(target_os = "dragonfly") { - // On DragonFly pthread_mutex_destroy() returns EINVAL if called on a - // mutex that was just initialized with libc::PTHREAD_MUTEX_INITIALIZER. + if cfg!(any(target_os = "aix", target_os = "dragonfly")) { + // On AIX and DragonFly pthread_mutex_destroy() returns EINVAL if called + // on a mutex that was just initialized with libc::PTHREAD_MUTEX_INITIALIZER. // Once it is used (locked/unlocked) or pthread_mutex_init() is called, // this behaviour no longer occurs. debug_assert!(r == 0 || r == libc::EINVAL); diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 356669980c7..37d5e01790a 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -23,7 +23,7 @@ mod zircon { type zx_status_t = i32; pub const ZX_PROP_NAME: u32 = 3; - extern "C" { + unsafe extern "C" { pub fn zx_object_set_property( handle: zx_handle_t, property: u32, @@ -49,24 +49,27 @@ impl Thread { pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> { let p = Box::into_raw(Box::new(p)); let mut native: libc::pthread_t = mem::zeroed(); - let mut attr: libc::pthread_attr_t = mem::zeroed(); - assert_eq!(libc::pthread_attr_init(&mut attr), 0); + let mut attr: mem::MaybeUninit<libc::pthread_attr_t> = mem::MaybeUninit::uninit(); + assert_eq!(libc::pthread_attr_init(attr.as_mut_ptr()), 0); #[cfg(target_os = "espidf")] if stack > 0 { // Only set the stack if a non-zero value is passed // 0 is used as an indication that the default stack size configured in the ESP-IDF menuconfig system should be used assert_eq!( - libc::pthread_attr_setstacksize(&mut attr, cmp::max(stack, min_stack_size(&attr))), + libc::pthread_attr_setstacksize( + attr.as_mut_ptr(), + cmp::max(stack, min_stack_size(&attr)) + ), 0 ); } #[cfg(not(target_os = "espidf"))] { - let stack_size = cmp::max(stack, min_stack_size(&attr)); + let stack_size = cmp::max(stack, min_stack_size(attr.as_ptr())); - match libc::pthread_attr_setstacksize(&mut attr, stack_size) { + match libc::pthread_attr_setstacksize(attr.as_mut_ptr(), stack_size) { 0 => {} n => { assert_eq!(n, libc::EINVAL); @@ -77,16 +80,16 @@ impl Thread { let page_size = os::page_size(); let stack_size = (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1); - assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0); + assert_eq!(libc::pthread_attr_setstacksize(attr.as_mut_ptr(), stack_size), 0); } }; } - let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _); + let ret = libc::pthread_create(&mut native, attr.as_ptr(), thread_start, p as *mut _); // Note: if the thread creation fails and this assert fails, then p will // be leaked. However, an alternative design could cause double-free // which is clearly worse. - assert_eq!(libc::pthread_attr_destroy(&mut attr), 0); + assert_eq!(libc::pthread_attr_destroy(attr.as_mut_ptr()), 0); return if ret != 0 { // The thread failed to start and as a result p was not consumed. Therefore, it is @@ -144,7 +147,7 @@ impl Thread { const TASK_COMM_LEN: usize = 16; let name = truncate_cstr::<{ TASK_COMM_LEN }>(name); } else { - // FreeBSD, DragonFly, FreeBSD and NuttX do not enforce length limits. + // FreeBSD, DragonFly BSD and NuttX do not enforce length limits. } }; // Available since glibc 2.12, musl 1.1.16, and uClibc 1.0.20 for Linux, @@ -230,7 +233,7 @@ impl Thread { #[cfg(target_os = "vxworks")] pub fn set_name(name: &CStr) { // FIXME(libc): adding real STATUS, ERROR type eventually. - extern "C" { + unsafe extern "C" { fn taskNameSet(task_id: libc::TASK_ID, task_name: *mut libc::c_char) -> libc::c_int; } @@ -506,7 +509,7 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> { } else if #[cfg(target_os = "vxworks")] { // Note: there is also `vxCpuConfiguredGet`, closer to _SC_NPROCESSORS_CONF // expectations than the actual cores availability. - extern "C" { + unsafe extern "C" { fn vxCpuEnabledGet() -> libc::cpuset_t; } diff --git a/library/std/src/sys/pal/unix/thread_parking.rs b/library/std/src/sys/pal/unix/thread_parking.rs index 72dd2031479..bef8b4fb363 100644 --- a/library/std/src/sys/pal/unix/thread_parking.rs +++ b/library/std/src/sys/pal/unix/thread_parking.rs @@ -8,7 +8,7 @@ use crate::ffi::{c_int, c_void}; use crate::ptr; use crate::time::Duration; -extern "C" { +unsafe extern "C" { fn ___lwp_park60( clock_id: clockid_t, flags: c_int, diff --git a/library/std/src/sys/pal/unix/weak.rs b/library/std/src/sys/pal/unix/weak.rs index 35762f5a53b..5a37598f438 100644 --- a/library/std/src/sys/pal/unix/weak.rs +++ b/library/std/src/sys/pal/unix/weak.rs @@ -31,7 +31,7 @@ use crate::{mem, ptr}; pub(crate) macro weak { (fn $name:ident($($t:ty),*) -> $ret:ty) => ( let ref $name: ExternWeak<unsafe extern "C" fn($($t),*) -> $ret> = { - extern "C" { + unsafe extern "C" { #[linkage = "extern_weak"] static $name: Option<unsafe extern "C" fn($($t),*) -> $ret>; } |
