diff options
| author | bors <bors@rust-lang.org> | 2020-07-23 08:56:45 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-07-23 08:56:45 +0000 |
| commit | 2bbfa02b1b15974d5772b520aa027bf79f8c248e (patch) | |
| tree | e7e74cc74874cf154f4b5c5ea97cf04c132c982d /src/libstd | |
| parent | fcac11993ca055bbdc7683a2f6ed7b88a838fb0f (diff) | |
| parent | 8f02f2c1abd6c3fbd3053da5bb6759a4698a949e (diff) | |
| download | rust-2bbfa02b1b15974d5772b520aa027bf79f8c248e.tar.gz rust-2bbfa02b1b15974d5772b520aa027bf79f8c248e.zip | |
Auto merge of #74667 - Manishearth:rollup-s6k59sw, r=Manishearth
Rollup of 8 pull requests Successful merges: - #74141 (libstd/libcore: fix various typos) - #74490 (add a Backtrace::disabled function) - #74548 (one more Path::with_extension example, to demonstrate behavior) - #74587 (Prefer constant over function) - #74606 (Remove Linux workarounds for missing CLOEXEC support) - #74637 (Make str point to primitive page) - #74654 (require type defaults to be after const generic parameters) - #74659 (Improve codegen for unchecked float casts on wasm) Failed merges: r? @ghost
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/backtrace.rs | 6 | ||||
| -rw-r--r-- | src/libstd/f32.rs | 2 | ||||
| -rw-r--r-- | src/libstd/f64.rs | 2 | ||||
| -rw-r--r-- | src/libstd/os/linux/fs.rs | 2 | ||||
| -rw-r--r-- | src/libstd/os/redox/fs.rs | 2 | ||||
| -rw-r--r-- | src/libstd/path.rs | 3 | ||||
| -rw-r--r-- | src/libstd/sys/sgx/fd.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/unix/ext/fs.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sys/unix/fd.rs | 81 | ||||
| -rw-r--r-- | src/libstd/sys/unix/fs.rs | 51 | ||||
| -rw-r--r-- | src/libstd/sys/unix/net.rs | 103 | ||||
| -rw-r--r-- | src/libstd/sys/unix/os.rs | 1 | ||||
| -rw-r--r-- | src/libstd/sys/unix/pipe.rs | 61 | ||||
| -rw-r--r-- | src/libstd/sys/unix/weak.rs | 5 | ||||
| -rw-r--r-- | src/libstd/sys/vxworks/fd.rs | 20 | ||||
| -rw-r--r-- | src/libstd/sys/vxworks/time.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/wasi/fs.rs | 8 |
17 files changed, 121 insertions, 234 deletions
diff --git a/src/libstd/backtrace.rs b/src/libstd/backtrace.rs index e65775c1ced..09f83ea5fca 100644 --- a/src/libstd/backtrace.rs +++ b/src/libstd/backtrace.rs @@ -291,6 +291,12 @@ impl Backtrace { Backtrace::create(Backtrace::force_capture as usize) } + /// Forcibly captures a disabled backtrace, regardless of environment + /// variable configuration. + pub const fn disabled() -> Backtrace { + Backtrace { inner: Inner::Disabled } + } + // Capture a backtrace which start just before the function addressed by // `ip` fn create(ip: usize) -> Backtrace { diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index b392d6e7226..c905bcf5e3d 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -1500,7 +1500,7 @@ mod tests { assert_approx_eq!(f32::from_bits(0x44a72000), 1337.0); assert_approx_eq!(f32::from_bits(0xc1640000), -14.25); - // Check that NaNs roundtrip their bits regardless of signalingness + // Check that NaNs roundtrip their bits regardless of signaling-ness // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits let masked_nan1 = f32::NAN.to_bits() ^ 0x002A_AAAA; let masked_nan2 = f32::NAN.to_bits() ^ 0x0055_5555; diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index 72268d2cc2f..f09fc8d790b 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -1523,7 +1523,7 @@ mod tests { assert_approx_eq!(f64::from_bits(0x4094e40000000000), 1337.0); assert_approx_eq!(f64::from_bits(0xc02c800000000000), -14.25); - // Check that NaNs roundtrip their bits regardless of signalingness + // Check that NaNs roundtrip their bits regardless of signaling-ness // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits let masked_nan1 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA; let masked_nan2 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555; diff --git a/src/libstd/os/linux/fs.rs b/src/libstd/os/linux/fs.rs index d22b44a0666..657737394ab 100644 --- a/src/libstd/os/linux/fs.rs +++ b/src/libstd/os/linux/fs.rs @@ -285,7 +285,7 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_ctime_nsec(&self) -> i64; - /// Returns the "preferred" blocksize for efficient filesystem I/O. + /// Returns the "preferred" block size for efficient filesystem I/O. /// /// # Examples /// diff --git a/src/libstd/os/redox/fs.rs b/src/libstd/os/redox/fs.rs index 6c87df534bd..61b5bff3805 100644 --- a/src/libstd/os/redox/fs.rs +++ b/src/libstd/os/redox/fs.rs @@ -289,7 +289,7 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_ctime_nsec(&self) -> i64; - /// Returns the "preferred" blocksize for efficient filesystem I/O. + /// Returns the "preferred" block size for efficient filesystem I/O. /// /// # Examples /// diff --git a/src/libstd/path.rs b/src/libstd/path.rs index f14a9ff72f6..392c815ef28 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -2244,6 +2244,9 @@ impl Path { /// /// let path = Path::new("foo.rs"); /// assert_eq!(path.with_extension("txt"), PathBuf::from("foo.txt")); + /// + /// let path = Path::new("foo.tar.gz"); + /// assert_eq!(path.with_extension(""), PathBuf::from("foo.tar")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn with_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf { diff --git a/src/libstd/sys/sgx/fd.rs b/src/libstd/sys/sgx/fd.rs index 90158030c7f..e5dc5b5adaa 100644 --- a/src/libstd/sys/sgx/fd.rs +++ b/src/libstd/sys/sgx/fd.rs @@ -19,7 +19,7 @@ impl FileDesc { self.fd } - /// Extracts the actual filedescriptor without closing it. + /// Extracts the actual file descriptor without closing it. pub fn into_raw(self) -> Fd { let fd = self.fd; mem::forget(self); diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index 2b2bbc6e9d6..f174a59b49a 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -624,7 +624,7 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn ctime_nsec(&self) -> i64; - /// Returns the blocksize for filesystem I/O. + /// Returns the block size for filesystem I/O. /// /// # Examples /// @@ -635,7 +635,7 @@ pub trait MetadataExt { /// /// fn main() -> io::Result<()> { /// let meta = fs::metadata("some_file")?; - /// let blocksize = meta.blksize(); + /// let block_size = meta.blksize(); /// Ok(()) /// } /// ``` diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index c481ca8961f..84c4d662161 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -3,28 +3,28 @@ use crate::cmp; use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read}; use crate::mem; -use crate::sync::atomic::{AtomicBool, Ordering}; use crate::sys::cvt; use crate::sys_common::AsInner; -use libc::{c_int, c_void, ssize_t}; +use libc::{c_int, c_void}; #[derive(Debug)] pub struct FileDesc { fd: c_int, } -fn max_len() -> usize { - // 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. - if cfg!(target_os = "macos") { <c_int>::MAX as usize - 1 } else { <ssize_t>::MAX as usize } -} +// 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; impl FileDesc { pub fn new(fd: c_int) -> FileDesc { @@ -44,7 +44,7 @@ impl FileDesc { pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { let ret = cvt(unsafe { - libc::read(self.fd, buf.as_mut_ptr() as *mut c_void, cmp::min(buf.len(), max_len())) + libc::read(self.fd, buf.as_mut_ptr() as *mut c_void, cmp::min(buf.len(), READ_LIMIT)) })?; Ok(ret as usize) } @@ -92,7 +92,7 @@ impl FileDesc { cvt_pread64( self.fd, buf.as_mut_ptr() as *mut c_void, - cmp::min(buf.len(), max_len()), + cmp::min(buf.len(), READ_LIMIT), offset as i64, ) .map(|n| n as usize) @@ -101,7 +101,7 @@ impl FileDesc { pub fn write(&self, buf: &[u8]) -> io::Result<usize> { let ret = cvt(unsafe { - libc::write(self.fd, buf.as_ptr() as *const c_void, cmp::min(buf.len(), max_len())) + libc::write(self.fd, buf.as_ptr() as *const c_void, cmp::min(buf.len(), READ_LIMIT)) })?; Ok(ret as usize) } @@ -144,7 +144,7 @@ impl FileDesc { cvt_pwrite64( self.fd, buf.as_ptr() as *const c_void, - cmp::min(buf.len(), max_len()), + cmp::min(buf.len(), READ_LIMIT), offset as i64, ) .map(|n| n as usize) @@ -223,50 +223,9 @@ impl FileDesc { pub fn duplicate(&self) -> io::Result<FileDesc> { // We want to atomically duplicate this file descriptor and set the // CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This - // flag, however, isn't supported on older Linux kernels (earlier than - // 2.6.24). - // - // To detect this and ensure that CLOEXEC is still set, we - // follow a strategy similar to musl [1] where if passing - // F_DUPFD_CLOEXEC causes `fcntl` to return EINVAL it means it's not - // supported (the third parameter, 0, is always valid), so we stop - // trying that. - // - // Also note that Android doesn't have F_DUPFD_CLOEXEC, but get it to - // resolve so we at least compile this. - // - // [1]: http://comments.gmane.org/gmane.linux.lib.musl.general/2963 - #[cfg(any(target_os = "android", target_os = "haiku"))] - use libc::F_DUPFD as F_DUPFD_CLOEXEC; - #[cfg(not(any(target_os = "android", target_os = "haiku")))] - use libc::F_DUPFD_CLOEXEC; - - let make_filedesc = |fd| { - let fd = FileDesc::new(fd); - fd.set_cloexec()?; - Ok(fd) - }; - static TRY_CLOEXEC: AtomicBool = AtomicBool::new(!cfg!(target_os = "android")); - let fd = self.raw(); - if TRY_CLOEXEC.load(Ordering::Relaxed) { - match cvt(unsafe { libc::fcntl(fd, F_DUPFD_CLOEXEC, 0) }) { - // We *still* call the `set_cloexec` method as apparently some - // linux kernel at some point stopped setting CLOEXEC even - // though it reported doing so on F_DUPFD_CLOEXEC. - Ok(fd) => { - return Ok(if cfg!(target_os = "linux") { - make_filedesc(fd)? - } else { - FileDesc::new(fd) - }); - } - Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => { - TRY_CLOEXEC.store(false, Ordering::Relaxed); - } - Err(e) => return Err(e), - } - } - cvt(unsafe { libc::fcntl(fd, libc::F_DUPFD, 0) }).and_then(make_filedesc) + // is a POSIX flag that was added to Linux in 2.6.24. + let fd = cvt(unsafe { libc::fcntl(self.raw(), libc::F_DUPFD_CLOEXEC, 0) })?; + Ok(FileDesc::new(fd)) } } diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 29cdbf05354..acb18e6d064 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -708,56 +708,7 @@ impl File { // However, since this is a variadic function, C integer promotion rules mean that on // the ABI level, this still gets passed as `c_int` (aka `u32` on Unix platforms). let fd = cvt_r(|| unsafe { open64(path.as_ptr(), flags, opts.mode as c_int) })?; - let fd = FileDesc::new(fd); - - // Currently the standard library supports Linux 2.6.18 which did not - // have the O_CLOEXEC flag (passed above). If we're running on an older - // Linux kernel then the flag is just ignored by the OS. After we open - // the first file, we check whether it has CLOEXEC set. If it doesn't, - // we will explicitly ask for a CLOEXEC fd for every further file we - // open, if it does, we will skip that step. - // - // The CLOEXEC flag, however, is supported on versions of macOS/BSD/etc - // that we support, so we only do this on Linux currently. - #[cfg(target_os = "linux")] - fn ensure_cloexec(fd: &FileDesc) -> io::Result<()> { - use crate::sync::atomic::{AtomicUsize, Ordering}; - - const OPEN_CLOEXEC_UNKNOWN: usize = 0; - const OPEN_CLOEXEC_SUPPORTED: usize = 1; - const OPEN_CLOEXEC_NOTSUPPORTED: usize = 2; - static OPEN_CLOEXEC: AtomicUsize = AtomicUsize::new(OPEN_CLOEXEC_UNKNOWN); - - let need_to_set; - match OPEN_CLOEXEC.load(Ordering::Relaxed) { - OPEN_CLOEXEC_UNKNOWN => { - need_to_set = !fd.get_cloexec()?; - OPEN_CLOEXEC.store( - if need_to_set { - OPEN_CLOEXEC_NOTSUPPORTED - } else { - OPEN_CLOEXEC_SUPPORTED - }, - Ordering::Relaxed, - ); - } - OPEN_CLOEXEC_SUPPORTED => need_to_set = false, - OPEN_CLOEXEC_NOTSUPPORTED => need_to_set = true, - _ => unreachable!(), - } - if need_to_set { - fd.set_cloexec()?; - } - Ok(()) - } - - #[cfg(not(target_os = "linux"))] - fn ensure_cloexec(_: &FileDesc) -> io::Result<()> { - Ok(()) - } - - ensure_cloexec(&fd)?; - Ok(File(fd)) + Ok(File(FileDesc::new(fd))) } pub fn file_attr(&self) -> io::Result<FileAttr> { diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs index 3717c660b57..011325fddc5 100644 --- a/src/libstd/sys/unix/net.rs +++ b/src/libstd/sys/unix/net.rs @@ -54,31 +54,26 @@ impl Socket { pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> { unsafe { - // On linux we first attempt to pass the SOCK_CLOEXEC flag to - // atomically create the socket and set it as CLOEXEC. Support for - // this option, however, was added in 2.6.27, and we still support - // 2.6.18 as a kernel, so if the returned error is EINVAL we - // fallthrough to the fallback. - #[cfg(target_os = "linux")] - { - match cvt(libc::socket(fam, ty | libc::SOCK_CLOEXEC, 0)) { - Ok(fd) => return Ok(Socket(FileDesc::new(fd))), - Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {} - Err(e) => return Err(e), - } - } - - let fd = cvt(libc::socket(fam, ty, 0))?; - let fd = FileDesc::new(fd); - fd.set_cloexec()?; - let socket = Socket(fd); + cfg_if::cfg_if! { + if #[cfg(target_os = "linux")] { + // On Linux we pass the SOCK_CLOEXEC flag to atomically create + // the socket and set it as CLOEXEC, added in 2.6.27. + let fd = cvt(libc::socket(fam, ty | libc::SOCK_CLOEXEC, 0))?; + Ok(Socket(FileDesc::new(fd))) + } else { + let fd = cvt(libc::socket(fam, ty, 0))?; + let fd = FileDesc::new(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)?; + // 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) + Ok(socket) + } + } } } @@ -86,24 +81,20 @@ impl Socket { unsafe { let mut fds = [0, 0]; - // Like above, see if we can set cloexec atomically - #[cfg(target_os = "linux")] - { - match cvt(libc::socketpair(fam, ty | libc::SOCK_CLOEXEC, 0, fds.as_mut_ptr())) { - Ok(_) => { - return Ok((Socket(FileDesc::new(fds[0])), Socket(FileDesc::new(fds[1])))); - } - Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {} - Err(e) => return Err(e), + cfg_if::cfg_if! { + if #[cfg(target_os = "linux")] { + // Like above, set cloexec atomically + cvt(libc::socketpair(fam, ty | libc::SOCK_CLOEXEC, 0, fds.as_mut_ptr()))?; + Ok((Socket(FileDesc::new(fds[0])), Socket(FileDesc::new(fds[1])))) + } else { + cvt(libc::socketpair(fam, ty, 0, fds.as_mut_ptr()))?; + let a = FileDesc::new(fds[0]); + let b = FileDesc::new(fds[1]); + a.set_cloexec()?; + b.set_cloexec()?; + Ok((Socket(a), Socket(b))) } } - - cvt(libc::socketpair(fam, ty, 0, fds.as_mut_ptr()))?; - let a = FileDesc::new(fds[0]); - let b = FileDesc::new(fds[1]); - a.set_cloexec()?; - b.set_cloexec()?; - Ok((Socket(a), Socket(b))) } } @@ -177,30 +168,20 @@ impl Socket { 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 - // Linux. This was added in 2.6.28, however, and because we support - // 2.6.18 we must detect this support dynamically. - #[cfg(target_os = "linux")] - { - syscall! { - fn accept4( - fd: c_int, - addr: *mut sockaddr, - addr_len: *mut socklen_t, - flags: c_int - ) -> c_int - } - let res = cvt_r(|| unsafe { accept4(self.0.raw(), storage, len, libc::SOCK_CLOEXEC) }); - match res { - Ok(fd) => return Ok(Socket(FileDesc::new(fd))), - Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {} - Err(e) => return Err(e), + // Linux. This was added in 2.6.28, glibc 2.10 and musl 0.9.5. + cfg_if::cfg_if! { + if #[cfg(target_os = "linux")] { + let fd = cvt_r(|| unsafe { + libc::accept4(self.0.raw(), storage, len, libc::SOCK_CLOEXEC) + })?; + Ok(Socket(FileDesc::new(fd))) + } else { + let fd = cvt_r(|| unsafe { libc::accept(self.0.raw(), storage, len) })?; + let fd = FileDesc::new(fd); + fd.set_cloexec()?; + Ok(Socket(fd)) } } - - let fd = cvt_r(|| unsafe { libc::accept(self.0.raw(), storage, len) })?; - let fd = FileDesc::new(fd); - fd.set_cloexec()?; - Ok(Socket(fd)) } pub fn duplicate(&self) -> io::Result<Socket> { diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index a9cd5094997..2fcb5b9c4e6 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -71,6 +71,7 @@ pub fn errno() -> i32 { /// Sets the platform-specific value of errno #[cfg(all(not(target_os = "linux"), not(target_os = "dragonfly")))] // needed for readdir and syscall! +#[allow(dead_code)] // but not all target cfgs actually end up using it pub fn set_errno(e: i32) { unsafe { *errno_location() = e as c_int } } diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index f2a2eabef91..7ae37bdda70 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -1,11 +1,8 @@ use crate::io::{self, IoSlice, IoSliceMut}; use crate::mem; -use crate::sync::atomic::{AtomicBool, Ordering}; use crate::sys::fd::FileDesc; use crate::sys::{cvt, cvt_r}; -use libc::c_int; - //////////////////////////////////////////////////////////////////////////////// // Anonymous pipes //////////////////////////////////////////////////////////////////////////////// @@ -13,46 +10,32 @@ use libc::c_int; pub struct AnonPipe(FileDesc); pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { - syscall! { fn pipe2(fds: *mut c_int, flags: c_int) -> c_int } - static INVALID: AtomicBool = AtomicBool::new(false); - let mut fds = [0; 2]; - // Unfortunately the only known way right now to create atomically set the - // CLOEXEC flag is to use the `pipe2` syscall on Linux. This was added in - // 2.6.27, however, and because we support 2.6.18 we must detect this - // support dynamically. - if cfg!(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox" - )) && !INVALID.load(Ordering::SeqCst) - { - // Note that despite calling a glibc function here we may still - // get ENOSYS. Glibc has `pipe2` since 2.9 and doesn't try to - // emulate on older kernels, so if you happen to be running on - // an older kernel you may see `pipe2` as a symbol but still not - // see the syscall. - match cvt(unsafe { pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC) }) { - Ok(_) => { - return Ok((AnonPipe(FileDesc::new(fds[0])), AnonPipe(FileDesc::new(fds[1])))); - } - Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => { - INVALID.store(true, Ordering::SeqCst); - } - Err(e) => return Err(e), + // The only known way right now to create atomically set the CLOEXEC flag is + // to use the `pipe2` syscall. This was added to Linux in 2.6.27, glibc 2.9 + // and musl 0.9.3, and some other targets also have it. + cfg_if::cfg_if! { + if #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox" + ))] { + cvt(unsafe { libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC) })?; + Ok((AnonPipe(FileDesc::new(fds[0])), AnonPipe(FileDesc::new(fds[1])))) + } else { + cvt(unsafe { libc::pipe(fds.as_mut_ptr()) })?; + + let fd0 = FileDesc::new(fds[0]); + let fd1 = FileDesc::new(fds[1]); + fd0.set_cloexec()?; + fd1.set_cloexec()?; + Ok((AnonPipe(fd0), AnonPipe(fd1))) } } - cvt(unsafe { libc::pipe(fds.as_mut_ptr()) })?; - - let fd0 = FileDesc::new(fds[0]); - let fd1 = FileDesc::new(fds[1]); - fd0.set_cloexec()?; - fd1.set_cloexec()?; - Ok((AnonPipe(fd0), AnonPipe(fd1))) } impl AnonPipe { diff --git a/src/libstd/sys/unix/weak.rs b/src/libstd/sys/unix/weak.rs index 08cbe596174..f4b33a00f7c 100644 --- a/src/libstd/sys/unix/weak.rs +++ b/src/libstd/sys/unix/weak.rs @@ -16,6 +16,11 @@ //! symbol, but that caused Debian to detect an unnecessarily strict versioned //! dependency on libc6 (#23628). +// There are a variety of `#[cfg]`s controlling which targets are involved in +// each instance of `weak!` and `syscall!`. Rather than trying to unify all of +// that, we'll just allow that some unix targets don't use this module at all. +#![allow(dead_code, unused_macros)] + use crate::ffi::CStr; use crate::marker; use crate::mem; diff --git a/src/libstd/sys/vxworks/fd.rs b/src/libstd/sys/vxworks/fd.rs index 7fa86f0db04..ea186846929 100644 --- a/src/libstd/sys/vxworks/fd.rs +++ b/src/libstd/sys/vxworks/fd.rs @@ -13,12 +13,10 @@ pub struct FileDesc { fd: c_int, } -fn max_len() -> usize { - // 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". - <ssize_t>::MAX as usize -} +// 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". +const READ_LIMIT: usize = ssize_t::MAX as usize; impl FileDesc { pub fn new(fd: c_int) -> FileDesc { @@ -29,7 +27,7 @@ impl FileDesc { self.fd } - /// Extracts the actual filedescriptor without closing it. + /// Extracts the actual file descriptor without closing it. pub fn into_raw(self) -> c_int { let fd = self.fd; mem::forget(self); @@ -38,7 +36,7 @@ impl FileDesc { pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { let ret = cvt(unsafe { - libc::read(self.fd, buf.as_mut_ptr() as *mut c_void, cmp::min(buf.len(), max_len())) + libc::read(self.fd, buf.as_mut_ptr() as *mut c_void, cmp::min(buf.len(), READ_LIMIT)) })?; Ok(ret as usize) } @@ -79,7 +77,7 @@ impl FileDesc { cvt_pread( self.fd, buf.as_mut_ptr() as *mut c_void, - cmp::min(buf.len(), max_len()), + cmp::min(buf.len(), READ_LIMIT), offset as i64, ) .map(|n| n as usize) @@ -88,7 +86,7 @@ impl FileDesc { pub fn write(&self, buf: &[u8]) -> io::Result<usize> { let ret = cvt(unsafe { - libc::write(self.fd, buf.as_ptr() as *const c_void, cmp::min(buf.len(), max_len())) + libc::write(self.fd, buf.as_ptr() as *const c_void, cmp::min(buf.len(), READ_LIMIT)) })?; Ok(ret as usize) } @@ -124,7 +122,7 @@ impl FileDesc { cvt_pwrite( self.fd, buf.as_ptr() as *const c_void, - cmp::min(buf.len(), max_len()), + cmp::min(buf.len(), READ_LIMIT), offset as i64, ) .map(|n| n as usize) diff --git a/src/libstd/sys/vxworks/time.rs b/src/libstd/sys/vxworks/time.rs index 8365c9ee9c9..8f46f4d284f 100644 --- a/src/libstd/sys/vxworks/time.rs +++ b/src/libstd/sys/vxworks/time.rs @@ -1,6 +1,6 @@ use crate::cmp::Ordering; use crate::time::Duration; -use ::core::hash::{Hash, Hasher}; +use core::hash::{Hash, Hasher}; pub use self::inner::{Instant, SystemTime, UNIX_EPOCH}; use crate::convert::TryInto; diff --git a/src/libstd/sys/wasi/fs.rs b/src/libstd/sys/wasi/fs.rs index 793daea43c2..2eed9e436a9 100644 --- a/src/libstd/sys/wasi/fs.rs +++ b/src/libstd/sys/wasi/fs.rs @@ -597,14 +597,14 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result<File> { /// /// WASI has no fundamental capability to do this. All syscalls and operations /// are relative to already-open file descriptors. The C library, however, -/// manages a map of preopened file descriptors to their path, and then the C +/// manages a map of pre-opened file descriptors to their path, and then the C /// library provides an API to look at this. In other words, when you want to /// open a path `p`, you have to find a previously opened file descriptor in a /// global table and then see if `p` is relative to that file descriptor. /// /// This function, if successful, will return two items: /// -/// * The first is a `ManuallyDrop<WasiFd>`. This represents a preopened file +/// * The first is a `ManuallyDrop<WasiFd>`. This represents a pre-opened file /// descriptor which we don't have ownership of, but we can use. You shouldn't /// actually drop the `fd`. /// @@ -619,7 +619,7 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result<File> { /// appropriate rights for performing `rights` actions. /// /// Note that this can fail if `p` doesn't look like it can be opened relative -/// to any preopened file descriptor. +/// to any pre-opened file descriptor. fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> { let p = CString::new(p.as_os_str().as_bytes())?; unsafe { @@ -627,7 +627,7 @@ fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> { let fd = __wasilibc_find_relpath(p.as_ptr(), &mut ret); if fd == -1 { let msg = format!( - "failed to find a preopened file descriptor \ + "failed to find a pre-opened file descriptor \ through which {:?} could be opened", p ); |
