diff --git a/library/std/src/os/fd/mod.rs b/library/std/src/os/fd/mod.rs index 473d7ae3e2ae6..a2dfef990cfbf 100644 --- a/library/std/src/os/fd/mod.rs +++ b/library/std/src/os/fd/mod.rs @@ -13,13 +13,13 @@ mod raw; mod owned; // Implementations for `AsRawFd` etc. for network types. -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] mod net; // Implementation of stdio file descriptor constants. mod stdio; -#[cfg(test)] +#[cfg(all(test, not(target_os = "qurt")))] mod tests; // Export the types and traits for the public API. diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 8a39fe073bf95..2d27e416e2ccd 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -210,7 +210,7 @@ impl Drop for OwnedFd { // the latest POSIX wording: http://austingroupbugs.net/view.php?id=529 #[cfg(not(target_os = "hermit"))] { - #[cfg(unix)] + #[cfg(all(unix, not(target_os = "qurt")))] crate::sys::fs::debug_assert_fd_is_open(self.fd.as_inner()); let _ = libc::close(self.fd.as_inner()); @@ -344,7 +344,7 @@ impl From for fs::File { } #[stable(feature = "io_safety", since = "1.63.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl AsFd for crate::net::TcpStream { #[inline] fn as_fd(&self) -> BorrowedFd<'_> { @@ -353,7 +353,7 @@ impl AsFd for crate::net::TcpStream { } #[stable(feature = "io_safety", since = "1.63.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl From for OwnedFd { /// Takes ownership of a [`TcpStream`](crate::net::TcpStream)'s socket file descriptor. #[inline] @@ -363,7 +363,7 @@ impl From for OwnedFd { } #[stable(feature = "io_safety", since = "1.63.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl From for crate::net::TcpStream { #[inline] fn from(owned_fd: OwnedFd) -> Self { @@ -374,7 +374,7 @@ impl From for crate::net::TcpStream { } #[stable(feature = "io_safety", since = "1.63.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl AsFd for crate::net::TcpListener { #[inline] fn as_fd(&self) -> BorrowedFd<'_> { @@ -383,7 +383,7 @@ impl AsFd for crate::net::TcpListener { } #[stable(feature = "io_safety", since = "1.63.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl From for OwnedFd { /// Takes ownership of a [`TcpListener`](crate::net::TcpListener)'s socket file descriptor. #[inline] @@ -393,7 +393,7 @@ impl From for OwnedFd { } #[stable(feature = "io_safety", since = "1.63.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl From for crate::net::TcpListener { #[inline] fn from(owned_fd: OwnedFd) -> Self { @@ -404,7 +404,7 @@ impl From for crate::net::TcpListener { } #[stable(feature = "io_safety", since = "1.63.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl AsFd for crate::net::UdpSocket { #[inline] fn as_fd(&self) -> BorrowedFd<'_> { @@ -413,7 +413,7 @@ impl AsFd for crate::net::UdpSocket { } #[stable(feature = "io_safety", since = "1.63.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl From for OwnedFd { /// Takes ownership of a [`UdpSocket`](crate::net::UdpSocket)'s file descriptor. #[inline] @@ -423,7 +423,7 @@ impl From for OwnedFd { } #[stable(feature = "io_safety", since = "1.63.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl From for crate::net::UdpSocket { #[inline] fn from(owned_fd: OwnedFd) -> Self { @@ -532,7 +532,7 @@ impl<'a> AsFd for io::StderrLock<'a> { } #[stable(feature = "anonymous_pipe", since = "1.87.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl AsFd for io::PipeReader { fn as_fd(&self) -> BorrowedFd<'_> { self.0.as_fd() @@ -540,7 +540,7 @@ impl AsFd for io::PipeReader { } #[stable(feature = "anonymous_pipe", since = "1.87.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl From for OwnedFd { fn from(pipe: io::PipeReader) -> Self { pipe.0.into_inner() @@ -548,7 +548,7 @@ impl From for OwnedFd { } #[stable(feature = "anonymous_pipe", since = "1.87.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl AsFd for io::PipeWriter { fn as_fd(&self) -> BorrowedFd<'_> { self.0.as_fd() @@ -556,7 +556,7 @@ impl AsFd for io::PipeWriter { } #[stable(feature = "anonymous_pipe", since = "1.87.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl From for OwnedFd { fn from(pipe: io::PipeWriter) -> Self { pipe.0.into_inner() @@ -564,7 +564,7 @@ impl From for OwnedFd { } #[stable(feature = "anonymous_pipe", since = "1.87.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl From for io::PipeReader { fn from(owned_fd: OwnedFd) -> Self { Self(FromInner::from_inner(owned_fd)) @@ -572,7 +572,7 @@ impl From for io::PipeReader { } #[stable(feature = "anonymous_pipe", since = "1.87.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl From for io::PipeWriter { fn from(owned_fd: OwnedFd) -> Self { Self(FromInner::from_inner(owned_fd)) diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs index 39e374174646c..5e4ad948d12f5 100644 --- a/library/std/src/os/fd/raw.rs +++ b/library/std/src/os/fd/raw.rs @@ -193,7 +193,7 @@ impl IntoRawFd for fs::File { } #[stable(feature = "asraw_stdio", since = "1.21.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl AsRawFd for io::Stdin { #[inline] fn as_raw_fd(&self) -> RawFd { @@ -202,6 +202,7 @@ impl AsRawFd for io::Stdin { } #[stable(feature = "asraw_stdio", since = "1.21.0")] +#[cfg(not(target_os = "qurt"))] impl AsRawFd for io::Stdout { #[inline] fn as_raw_fd(&self) -> RawFd { @@ -210,6 +211,7 @@ impl AsRawFd for io::Stdout { } #[stable(feature = "asraw_stdio", since = "1.21.0")] +#[cfg(not(target_os = "qurt"))] impl AsRawFd for io::Stderr { #[inline] fn as_raw_fd(&self) -> RawFd { @@ -218,7 +220,7 @@ impl AsRawFd for io::Stderr { } #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] -#[cfg(not(target_os = "trusty"))] +#[cfg(not(any(target_os = "trusty", target_os = "qurt")))] impl<'a> AsRawFd for io::StdinLock<'a> { #[inline] fn as_raw_fd(&self) -> RawFd { @@ -227,6 +229,7 @@ impl<'a> AsRawFd for io::StdinLock<'a> { } #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] +#[cfg(not(target_os = "qurt"))] impl<'a> AsRawFd for io::StdoutLock<'a> { #[inline] fn as_raw_fd(&self) -> RawFd { @@ -235,6 +238,7 @@ impl<'a> AsRawFd for io::StdoutLock<'a> { } #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] +#[cfg(not(target_os = "qurt"))] impl<'a> AsRawFd for io::StderrLock<'a> { #[inline] fn as_raw_fd(&self) -> RawFd { diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 76374402be4b3..4b2f8940fed5c 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -165,6 +165,8 @@ pub mod nto; pub mod nuttx; #[cfg(target_os = "openbsd")] pub mod openbsd; +#[cfg(target_os = "qurt")] +pub mod qurt; #[cfg(target_os = "redox")] pub mod redox; #[cfg(target_os = "rtems")] diff --git a/library/std/src/os/qurt/ffi.rs b/library/std/src/os/qurt/ffi.rs new file mode 100644 index 0000000000000..9cca5f3619f3d --- /dev/null +++ b/library/std/src/os/qurt/ffi.rs @@ -0,0 +1,65 @@ +//! QuRT-specific extension to the primitives in the [`std::ffi`] module. +//! +//! [`std::ffi`]: crate::ffi + +#![stable(feature = "raw_ext", since = "1.1.0")] + +use crate::ffi::{OsStr, OsString}; +use crate::mem; +use crate::sealed::Sealed; +use crate::sys::os_str::Buf; +use crate::sys::{AsInner, FromInner, IntoInner}; + +/// QuRT-specific extensions to [`OsString`]. +/// +/// This trait is sealed: it cannot be implemented outside the standard library. +#[stable(feature = "raw_ext", since = "1.1.0")] +pub trait OsStringExt: Sealed { + /// Creates an [`OsString`] from a byte vector. + #[stable(feature = "raw_ext", since = "1.1.0")] + fn from_vec(vec: Vec) -> Self; + + /// Yields the underlying byte vector of this [`OsString`]. + #[stable(feature = "raw_ext", since = "1.1.0")] + fn into_vec(self) -> Vec; +} + +#[stable(feature = "raw_ext", since = "1.1.0")] +impl OsStringExt for OsString { + #[inline] + fn from_vec(vec: Vec) -> OsString { + FromInner::from_inner(Buf { inner: vec }) + } + + #[inline] + fn into_vec(self) -> Vec { + self.into_inner().inner + } +} + +/// QuRT-specific extensions to [`OsStr`]. +/// +/// This trait is sealed: it cannot be implemented outside the standard library. +#[stable(feature = "raw_ext", since = "1.1.0")] +pub trait OsStrExt: Sealed { + #[stable(feature = "raw_ext", since = "1.1.0")] + /// Creates an [`OsStr`] from a byte slice. + fn from_bytes(slice: &[u8]) -> &Self; + + /// Gets the underlying byte view of the [`OsStr`] slice. + #[stable(feature = "raw_ext", since = "1.1.0")] + fn as_bytes(&self) -> &[u8]; +} + +#[stable(feature = "raw_ext", since = "1.1.0")] +impl OsStrExt for OsStr { + #[inline] + fn from_bytes(slice: &[u8]) -> &OsStr { + unsafe { mem::transmute(slice) } + } + + #[inline] + fn as_bytes(&self) -> &[u8] { + &self.as_inner().inner + } +} diff --git a/library/std/src/os/qurt/fs.rs b/library/std/src/os/qurt/fs.rs new file mode 100644 index 0000000000000..d815077eaa14b --- /dev/null +++ b/library/std/src/os/qurt/fs.rs @@ -0,0 +1,140 @@ +//! QuRT-specific extensions to primitives in the [`std::fs`] module. +//! +//! [`std::fs`]: crate::fs +//! +//! Note: QuRT has a minimal stat structure without uid/gid/blksize/blocks/nsec fields. +//! The accessor methods for these fields return stub values (0). + +#![stable(feature = "metadata_ext", since = "1.1.0")] + +use crate::fs::Metadata; +#[allow(deprecated)] +use crate::os::qurt::raw; +use crate::sys::AsInner; + +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: crate::fs::Metadata +/// +/// Note: QuRT has a minimal stat structure. The following fields are not available +/// and return stub values: +/// - `st_uid`, `st_gid`: QuRT doesn't have user/group ownership (returns 0) +/// - `st_blksize`, `st_blocks`: QuRT doesn't track block information (returns 0) +/// - `st_atime_nsec`, `st_mtime_nsec`, `st_ctime_nsec`: QuRT only has second-level precision (returns 0) +#[stable(feature = "metadata_ext", since = "1.1.0")] +pub trait MetadataExt { + #[stable(feature = "metadata_ext", since = "1.1.0")] + #[deprecated( + since = "1.8.0", + note = "deprecated in favor of the accessor \ + methods of this trait" + )] + #[allow(deprecated)] + fn as_raw_stat(&self) -> &raw::stat; + + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_dev(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ino(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mode(&self) -> u32; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_nlink(&self) -> u64; + /// Returns 0 on QuRT (user ownership not supported). + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_uid(&self) -> u32; + /// Returns 0 on QuRT (group ownership not supported). + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_gid(&self) -> u32; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_rdev(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_size(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_atime(&self) -> i64; + /// Returns 0 on QuRT (nanosecond precision not supported). + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_atime_nsec(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mtime(&self) -> i64; + /// Returns 0 on QuRT (nanosecond precision not supported). + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mtime_nsec(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ctime(&self) -> i64; + /// Returns 0 on QuRT (nanosecond precision not supported). + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ctime_nsec(&self) -> i64; + /// Returns 0 on QuRT (block size not tracked). + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_blksize(&self) -> u64; + /// Returns 0 on QuRT (block count not tracked). + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_blocks(&self) -> u64; +} + +#[stable(feature = "metadata_ext", since = "1.1.0")] +impl MetadataExt for Metadata { + #[allow(deprecated)] + fn as_raw_stat(&self) -> &raw::stat { + // Note: This cast is technically incorrect since libc::stat and raw::stat + // have different layouts on QuRT, but this function is deprecated. + // Users should use the accessor methods instead. + unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) } + } + fn st_dev(&self) -> u64 { + self.as_inner().as_inner().st_dev as u64 + } + fn st_ino(&self) -> u64 { + self.as_inner().as_inner().st_ino as u64 + } + fn st_mode(&self) -> u32 { + self.as_inner().as_inner().st_mode as u32 + } + fn st_nlink(&self) -> u64 { + self.as_inner().as_inner().st_nlink as u64 + } + fn st_uid(&self) -> u32 { + // QuRT doesn't have user ownership + 0 + } + fn st_gid(&self) -> u32 { + // QuRT doesn't have group ownership + 0 + } + fn st_rdev(&self) -> u64 { + self.as_inner().as_inner().st_rdev as u64 + } + fn st_size(&self) -> u64 { + self.as_inner().as_inner().st_size as u64 + } + fn st_atime(&self) -> i64 { + self.as_inner().as_inner().st_atime as i64 + } + fn st_atime_nsec(&self) -> i64 { + // QuRT only has second-level precision + 0 + } + fn st_mtime(&self) -> i64 { + self.as_inner().as_inner().st_mtime as i64 + } + fn st_mtime_nsec(&self) -> i64 { + // QuRT only has second-level precision + 0 + } + fn st_ctime(&self) -> i64 { + self.as_inner().as_inner().st_ctime as i64 + } + fn st_ctime_nsec(&self) -> i64 { + // QuRT only has second-level precision + 0 + } + fn st_blksize(&self) -> u64 { + // QuRT doesn't track block size + 0 + } + fn st_blocks(&self) -> u64 { + // QuRT doesn't track block count + 0 + } +} diff --git a/library/std/src/os/qurt/io.rs b/library/std/src/os/qurt/io.rs new file mode 100644 index 0000000000000..119f4f0944b1b --- /dev/null +++ b/library/std/src/os/qurt/io.rs @@ -0,0 +1,8 @@ +//! QuRT-specific I/O functionality. +//! +//! QuRT supports Unix-like file descriptors through its POSIX compatibility layer. + +#![stable(feature = "raw_ext", since = "1.1.0")] + +#[stable(feature = "rust1", since = "1.0.0")] +pub use crate::os::fd::*; diff --git a/library/std/src/os/qurt/mod.rs b/library/std/src/os/qurt/mod.rs new file mode 100644 index 0000000000000..e006deac5f199 --- /dev/null +++ b/library/std/src/os/qurt/mod.rs @@ -0,0 +1,21 @@ +//! QuRT-specific definitions. + +#![stable(feature = "raw_ext", since = "1.1.0")] + +pub mod ffi; +pub mod fs; +pub mod io; +pub mod raw; + +/// A prelude for conveniently writing platform-specific code. +/// +/// Includes all extension traits, and some important type definitions. +#[stable(feature = "rust1", since = "1.0.0")] +pub mod prelude { + #[doc(no_inline)] + #[stable(feature = "rust1", since = "1.0.0")] + pub use super::ffi::{OsStrExt, OsStringExt}; + #[doc(no_inline)] + #[stable(feature = "rust1", since = "1.0.0")] + pub use super::fs::MetadataExt; +} diff --git a/library/std/src/os/qurt/raw.rs b/library/std/src/os/qurt/raw.rs new file mode 100644 index 0000000000000..5432e4e3825fa --- /dev/null +++ b/library/std/src/os/qurt/raw.rs @@ -0,0 +1,68 @@ +//! QuRT-specific raw type definitions. + +#![stable(feature = "raw_ext", since = "1.1.0")] + +use core::ffi::c_long; + +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type dev_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type ino_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type mode_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type nlink_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type uid_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type gid_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type off_t = i64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type blksize_t = i64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type blkcnt_t = i64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type time_t = i64; + +// Threading types for QuRT pthread support +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type pthread_t = libc::pthread_t; + +#[repr(C)] +#[derive(Clone)] +#[stable(feature = "raw_ext", since = "1.1.0")] +pub struct stat { + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_dev: dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ino: ino_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mode: mode_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_nlink: nlink_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_uid: uid_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_gid: gid_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_rdev: dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_size: off_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blksize: blksize_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blocks: blkcnt_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime_nsec: c_long, +} diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs index 219b340b92469..07eb436893023 100644 --- a/library/std/src/os/unix/fs.rs +++ b/library/std/src/os/unix/fs.rs @@ -7,11 +7,13 @@ #[allow(unused_imports)] use io::{Read, Write}; +#[allow(unused_imports)] use super::platform::fs::MetadataExt as _; // Used for `File::read` on intra-doc links use crate::ffi::OsStr; use crate::fs::{self, OpenOptions, Permissions}; use crate::io::BorrowedCursor; +#[cfg(not(target_os = "qurt"))] use crate::os::unix::io::{AsFd, AsRawFd}; use crate::path::Path; use crate::sealed::Sealed; @@ -1118,6 +1120,7 @@ impl DirBuilderExt for fs::DirBuilder { /// Ok(()) /// } /// ``` +#[cfg(not(target_os = "qurt"))] #[stable(feature = "unix_chown", since = "1.73.0")] pub fn chown>(dir: P, uid: Option, gid: Option) -> io::Result<()> { sys::fs::chown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX)) @@ -1138,6 +1141,7 @@ pub fn chown>(dir: P, uid: Option, gid: Option) -> io:: /// Ok(()) /// } /// ``` +#[cfg(not(target_os = "qurt"))] #[stable(feature = "unix_chown", since = "1.73.0")] pub fn fchown(fd: F, uid: Option, gid: Option) -> io::Result<()> { sys::fs::fchown(fd.as_fd().as_raw_fd(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX)) @@ -1158,6 +1162,7 @@ pub fn fchown(fd: F, uid: Option, gid: Option) -> io::Result< /// Ok(()) /// } /// ``` +#[cfg(not(target_os = "qurt"))] #[stable(feature = "unix_chown", since = "1.73.0")] pub fn lchown>(dir: P, uid: Option, gid: Option) -> io::Result<()> { sys::fs::lchown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX)) @@ -1184,6 +1189,7 @@ pub fn lchown>(dir: P, uid: Option, gid: Option) -> io: /// ``` #[stable(feature = "unix_chroot", since = "1.56.0")] #[cfg(not(target_os = "fuchsia"))] +#[cfg(not(target_os = "qurt"))] pub fn chroot>(dir: P) -> io::Result<()> { sys::fs::chroot(dir.as_ref()) } @@ -1220,6 +1226,7 @@ pub fn chroot>(dir: P) -> io::Result<()> { /// # } /// ``` #[unstable(feature = "unix_mkfifo", issue = "139324")] +#[cfg(not(target_os = "qurt"))] pub fn mkfifo>(path: P, permissions: Permissions) -> io::Result<()> { sys::fs::mkfifo(path.as_ref(), permissions.mode()) } diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs index 18b0f70c06877..3d7388e393812 100644 --- a/library/std/src/os/unix/io/mod.rs +++ b/library/std/src/os/unix/io/mod.rs @@ -217,7 +217,8 @@ fn replace_stdio_fd(this: BorrowedFd<'_>, other: OwnedFd) -> io::Result<()> { target_arch = "wasm32", target_os = "hermit", target_os = "trusty", - target_os = "motor" + target_os = "motor", + target_os = "qurt" )) => { cvt(unsafe {libc::dup2(other.as_raw_fd(), this.as_raw_fd())}).map(|_| ()) } diff --git a/library/std/src/os/unix/mod.rs b/library/std/src/os/unix/mod.rs index 78c957270c451..9d15c09bf1a0c 100644 --- a/library/std/src/os/unix/mod.rs +++ b/library/std/src/os/unix/mod.rs @@ -75,6 +75,8 @@ mod platform { pub use crate::os::nuttx::*; #[cfg(target_os = "openbsd")] pub use crate::os::openbsd::*; + #[cfg(target_os = "qurt")] + pub use crate::os::qurt::*; #[cfg(target_os = "redox")] pub use crate::os::redox::*; #[cfg(target_os = "rtems")] @@ -91,6 +93,7 @@ pub mod ffi; pub mod fs; pub mod io; pub mod net; +#[cfg(not(target_os = "qurt"))] pub mod process; pub mod raw; pub mod thread; @@ -115,9 +118,11 @@ pub mod prelude { #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] pub use super::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; + #[cfg(not(target_os = "qurt"))] #[doc(no_inline)] #[unstable(feature = "unix_send_signal", issue = "141975")] pub use super::process::ChildExt; + #[cfg(not(target_os = "qurt"))] #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] pub use super::process::{CommandExt, ExitStatusExt}; diff --git a/library/std/src/os/unix/net/mod.rs b/library/std/src/os/unix/net/mod.rs index a44b23a77d2d4..91feffa50f158 100644 --- a/library/std/src/os/unix/net/mod.rs +++ b/library/std/src/os/unix/net/mod.rs @@ -3,14 +3,18 @@ #![allow(irrefutable_let_patterns)] #![stable(feature = "unix_socket", since = "1.10.0")] +#[cfg(not(target_os = "qurt"))] mod addr; #[doc(cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin")))] #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))] mod ancillary; +#[cfg(not(target_os = "qurt"))] mod datagram; +#[cfg(not(target_os = "qurt"))] mod listener; +#[cfg(not(target_os = "qurt"))] mod stream; -#[cfg(all(test, not(target_os = "emscripten")))] +#[cfg(all(test, not(any(target_os = "emscripten", target_os = "qurt"))))] mod tests; #[cfg(any( target_os = "android", @@ -25,15 +29,19 @@ mod tests; ))] mod ucred; +#[cfg(not(target_os = "qurt"))] #[stable(feature = "unix_socket", since = "1.10.0")] pub use self::addr::*; #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))] #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub use self::ancillary::*; +#[cfg(not(target_os = "qurt"))] #[stable(feature = "unix_socket", since = "1.10.0")] pub use self::datagram::*; +#[cfg(not(target_os = "qurt"))] #[stable(feature = "unix_socket", since = "1.10.0")] pub use self::listener::*; +#[cfg(not(target_os = "qurt"))] #[stable(feature = "unix_socket", since = "1.10.0")] pub use self::stream::*; #[cfg(any( @@ -47,5 +55,5 @@ pub use self::stream::*; target_vendor = "apple", target_os = "cygwin", ))] -#[unstable(feature = "peer_credentials_unix_socket", issue = "42839")] +#[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")] pub use self::ucred::*; diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 6838bb422b0e0..64d22dd66917b 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -156,6 +156,7 @@ target_env = "sgx", target_os = "xous", target_os = "trusty", + target_os = "qurt", )) ))] mod tests; diff --git a/library/std/src/sys/args/mod.rs b/library/std/src/sys/args/mod.rs index 5424d40a15883..5971b9af01e54 100644 --- a/library/std/src/sys/args/mod.rs +++ b/library/std/src/sys/args/mod.rs @@ -3,7 +3,10 @@ #![forbid(unsafe_op_in_unsafe_fn)] #[cfg(any( - all(target_family = "unix", not(any(target_os = "espidf", target_os = "vita"))), + all( + target_family = "unix", + not(any(target_os = "espidf", target_os = "vita", target_os = "qurt")) + ), target_family = "windows", target_os = "hermit", target_os = "motor", @@ -15,7 +18,7 @@ mod common; cfg_select! { any( - all(target_family = "unix", not(any(target_os = "espidf", target_os = "vita"))), + all(target_family = "unix", not(any(target_os = "espidf", target_os = "vita", target_os = "qurt"))), target_os = "hermit", ) => { mod unix; diff --git a/library/std/src/sys/args/unsupported.rs b/library/std/src/sys/args/unsupported.rs index ecffc6d26414b..ba63d04731d00 100644 --- a/library/std/src/sys/args/unsupported.rs +++ b/library/std/src/sys/args/unsupported.rs @@ -3,6 +3,10 @@ use crate::fmt; pub struct Args {} +pub unsafe fn init(_argc: isize, _argv: *const *const u8) { + // No-op for unsupported platforms +} + pub fn args() -> Args { Args {} } diff --git a/library/std/src/sys/backtrace.rs b/library/std/src/sys/backtrace.rs index 858a95882b39f..634eca4f89fbb 100644 --- a/library/std/src/sys/backtrace.rs +++ b/library/std/src/sys/backtrace.rs @@ -197,12 +197,17 @@ pub fn output_filename( cwd: Option<&PathBuf>, ) -> fmt::Result { let file: Cow<'_, Path> = match bows { - #[cfg(unix)] + #[cfg(all(unix, not(target_os = "qurt")))] BytesOrWideString::Bytes(bytes) => { use crate::os::unix::prelude::*; Path::new(crate::ffi::OsStr::from_bytes(bytes)).into() } - #[cfg(not(unix))] + #[cfg(target_os = "qurt")] + BytesOrWideString::Bytes(bytes) => { + use crate::os::qurt::prelude::*; + Path::new(crate::ffi::OsStr::from_bytes(bytes)).into() + } + #[cfg(not(any(unix, target_os = "qurt")))] BytesOrWideString::Bytes(bytes) => { Path::new(crate::str::from_utf8(bytes).unwrap_or("")).into() } diff --git a/library/std/src/sys/env/unix.rs b/library/std/src/sys/env/unix.rs index 66805ce3fa71e..175a6cc11f3cc 100644 --- a/library/std/src/sys/env/unix.rs +++ b/library/std/src/sys/env/unix.rs @@ -5,6 +5,9 @@ use libc::c_char; pub use super::common::Env; use crate::ffi::{CStr, OsStr, OsString}; use crate::io; +#[cfg(target_os = "qurt")] +use crate::os::qurt::prelude::*; +#[cfg(not(target_os = "qurt"))] use crate::os::unix::prelude::*; use crate::sync::{PoisonError, RwLock}; use crate::sys::cvt; diff --git a/library/std/src/sys/fd/mod.rs b/library/std/src/sys/fd/mod.rs index 02d61a62f4e6b..746a839f5b1e8 100644 --- a/library/std/src/sys/fd/mod.rs +++ b/library/std/src/sys/fd/mod.rs @@ -3,7 +3,7 @@ #![forbid(unsafe_op_in_unsafe_fn)] cfg_select! { - any(target_family = "unix", target_os = "wasi") => { + any(target_family = "unix", target_os = "wasi", target_os = "qurt") => { mod unix; pub use unix::*; } diff --git a/library/std/src/sys/fd/unix.rs b/library/std/src/sys/fd/unix.rs index bb6c0ac9e18e6..a312c13663708 100644 --- a/library/std/src/sys/fd/unix.rs +++ b/library/std/src/sys/fd/unix.rs @@ -8,6 +8,7 @@ mod tests; target_os = "l4re", target_os = "android", target_os = "hurd", + target_os = "qurt", )))] use libc::off_t as off64_t; #[cfg(any( @@ -28,6 +29,8 @@ cfg_select! { // #[cfg(gnu_file_offset_bits64)]. use libc::pread64; } + // QuRT doesn't have pread/pwrite - handled separately below + target_os = "qurt" => {} _ => { use libc::pread as pread64; } @@ -94,6 +97,7 @@ const fn max_iov() -> usize { target_os = "openbsd", target_os = "horizon", target_os = "vita", + target_os = "qurt", target_vendor = "apple", target_os = "cygwin", )))] @@ -121,6 +125,7 @@ impl FileDesc { #[cfg(not(any( target_os = "espidf", target_os = "horizon", + target_os = "qurt", target_os = "vita", target_os = "nuttx" )))] @@ -138,6 +143,7 @@ impl FileDesc { #[cfg(any( target_os = "espidf", target_os = "horizon", + target_os = "qurt", target_os = "vita", target_os = "nuttx" ))] @@ -150,6 +156,7 @@ impl FileDesc { cfg!(not(any( target_os = "espidf", target_os = "horizon", + target_os = "qurt", target_os = "vita", target_os = "nuttx", target_os = "wasi", @@ -161,6 +168,7 @@ impl FileDesc { (&mut me).read_to_end(buf) } + #[cfg(not(target_os = "qurt"))] pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result { cvt(unsafe { pread64( @@ -173,6 +181,11 @@ impl FileDesc { .map(|n| n as usize) } + #[cfg(target_os = "qurt")] + pub fn read_at(&self, _buf: &mut [u8], _offset: u64) -> io::Result { + Err(io::const_error!(io::ErrorKind::Unsupported, "pread not supported on QuRT")) + } + pub fn read_buf(&self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> { // SAFETY: `cursor.as_mut()` starts with `cursor.capacity()` writable bytes let ret = cvt(unsafe { @@ -190,6 +203,7 @@ impl FileDesc { Ok(()) } + #[cfg(not(target_os = "qurt"))] pub fn read_buf_at(&self, mut cursor: BorrowedCursor<'_>, offset: u64) -> io::Result<()> { // SAFETY: `cursor.as_mut()` starts with `cursor.capacity()` writable bytes let ret = cvt(unsafe { @@ -208,6 +222,11 @@ impl FileDesc { Ok(()) } + #[cfg(target_os = "qurt")] + pub fn read_buf_at(&self, _cursor: BorrowedCursor<'_>, _offset: u64) -> io::Result<()> { + Err(io::const_error!(io::ErrorKind::Unsupported, "pread not supported on QuRT")) + } + #[cfg(any( target_os = "aix", target_os = "dragonfly", // DragonFly 1.5 @@ -355,6 +374,7 @@ impl FileDesc { #[cfg(not(any( target_os = "espidf", target_os = "horizon", + target_os = "qurt", target_os = "vita", target_os = "nuttx" )))] @@ -372,6 +392,7 @@ impl FileDesc { #[cfg(any( target_os = "espidf", target_os = "horizon", + target_os = "qurt", target_os = "vita", target_os = "nuttx" ))] @@ -384,12 +405,14 @@ impl FileDesc { cfg!(not(any( target_os = "espidf", target_os = "horizon", + target_os = "qurt", target_os = "vita", target_os = "nuttx", target_os = "wasi", ))) } + #[cfg(not(target_os = "qurt"))] pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result { #[cfg(not(any( all(target_os = "linux", not(target_env = "musl")), @@ -415,6 +438,11 @@ impl FileDesc { } } + #[cfg(target_os = "qurt")] + pub fn write_at(&self, _buf: &[u8], _offset: u64) -> io::Result { + Err(io::const_error!(io::ErrorKind::Unsupported, "pwrite not supported on QuRT")) + } + #[cfg(any( target_os = "aix", target_os = "dragonfly", // DragonFly 1.5 @@ -562,6 +590,10 @@ impl FileDesc { target_os = "vxworks", target_os = "nto", target_os = "wasi", + target_os = "espidf", + target_os = "horizon", + target_os = "vita", + target_os = "qurt", )))] pub fn set_cloexec(&self) -> io::Result<()> { unsafe { @@ -597,9 +629,14 @@ impl FileDesc { Ok(()) } } - #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))] + #[cfg(any( + target_os = "espidf", + target_os = "horizon", + target_os = "vita", + target_os = "qurt" + ))] pub fn set_cloexec(&self) -> io::Result<()> { - // FD_CLOEXEC is not supported in ESP-IDF, Horizon OS and Vita but there's no need to, + // FD_CLOEXEC is not supported in ESP-IDF, Horizon OS, Vita, and QuRT but there's no need to, // because none of them supports spawning processes. Ok(()) } diff --git a/library/std/src/sys/fs/mod.rs b/library/std/src/sys/fs/mod.rs index 0c297c5766b82..bb884d7f4bea7 100644 --- a/library/std/src/sys/fs/mod.rs +++ b/library/std/src/sys/fs/mod.rs @@ -6,14 +6,14 @@ use crate::path::{Path, PathBuf}; pub mod common; cfg_select! { - any(target_family = "unix", target_os = "wasi") => { + any(target_family = "unix", target_os = "wasi", target_os = "qurt") => { mod unix; use unix as imp; - #[cfg(not(target_os = "wasi"))] + #[cfg(not(any(target_os = "wasi", target_os = "qurt")))] pub use unix::{chown, fchown, lchown, mkfifo}; - #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] + #[cfg(not(any(target_os = "fuchsia", target_os = "wasi", target_os = "qurt")))] pub use unix::chroot; - #[cfg(not(target_os = "wasi"))] + #[cfg(not(any(target_os = "wasi", target_os = "qurt")))] pub(crate) use unix::debug_assert_fd_is_open; #[cfg(any(target_os = "linux", target_os = "android"))] pub(super) use unix::CachedFileMetadata; @@ -52,7 +52,12 @@ cfg_select! { } // FIXME: Replace this with platform-specific path conversion functions. -#[cfg(not(any(target_family = "unix", target_os = "windows", target_os = "wasi")))] +#[cfg(not(any( + target_family = "unix", + target_os = "windows", + target_os = "wasi", + target_os = "qurt" +)))] #[inline] pub fn with_native_path(path: &Path, f: &dyn Fn(&Path) -> io::Result) -> io::Result { f(path) @@ -124,11 +129,15 @@ pub fn set_permissions(path: &Path, perm: FilePermissions) -> io::Result<()> { pub fn set_permissions_nofollow(path: &Path, perm: crate::fs::Permissions) -> io::Result<()> { use crate::fs::OpenOptions; + #[cfg_attr( + any(target_os = "espidf", target_os = "horizon", target_os = "qurt"), + allow(unused_mut) + )] let mut options = OpenOptions::new(); - // ESP-IDF and Horizon do not support O_NOFOLLOW, so we skip setting it. + // ESP-IDF, Horizon, and QuRT do not support O_NOFOLLOW, so we skip setting it. // Their filesystems do not have symbolic links, so no special handling is required. - #[cfg(not(any(target_os = "espidf", target_os = "horizon")))] + #[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "qurt")))] { use crate::os::unix::fs::OpenOptionsExt; options.custom_flags(libc::O_NOFOLLOW); diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 7db474544f04a..09f3d94ea5a95 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -28,6 +28,7 @@ use libc::fstatat64; target_os = "fuchsia", target_os = "illumos", target_os = "nto", + target_os = "qurt", target_os = "redox", target_os = "solaris", target_os = "vita", @@ -45,6 +46,7 @@ use libc::readdir as readdir64; target_os = "l4re", target_os = "linux", target_os = "nto", + target_os = "qurt", target_os = "redox", target_os = "solaris", target_os = "vita", @@ -66,11 +68,18 @@ use libc::{ target_os = "l4re", target_os = "android", target_os = "hurd", + target_os = "qurt", )))] use libc::{ dirent as dirent64, fstat as fstat64, ftruncate as ftruncate64, lseek as lseek64, lstat as lstat64, off_t as off64_t, open as open64, stat as stat64, }; +// QuRT doesn't have lstat - use stat instead +#[cfg(target_os = "qurt")] +use libc::{ + dirent as dirent64, fstat as fstat64, ftruncate as ftruncate64, lseek as lseek64, + off_t as off64_t, open as open64, stat as stat64, stat as lstat64, +}; #[cfg(any( all(target_os = "linux", not(target_env = "musl")), target_os = "l4re", @@ -98,6 +107,7 @@ use crate::sys::weak::syscall; #[cfg(target_os = "android")] use crate::sys::weak::weak; use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner, cvt, cvt_r}; +#[cfg_attr(target_os = "qurt", allow(unused_imports))] use crate::{mem, ptr}; pub struct File(FileDesc); @@ -280,6 +290,7 @@ cfg_select! { target_os = "redox", target_os = "espidf", target_os = "horizon", + target_os = "qurt", target_os = "vita", target_os = "nto", target_os = "vxworks", @@ -410,6 +421,7 @@ fn get_path_from_fd(fd: c_int) -> Option { target_os = "illumos", target_os = "linux", target_os = "nto", + target_os = "qurt", target_os = "redox", target_os = "solaris", target_os = "vita", @@ -436,6 +448,7 @@ pub struct DirEntry { target_os = "illumos", target_os = "linux", target_os = "nto", + target_os = "qurt", target_os = "redox", target_os = "solaris", target_os = "vita", @@ -448,6 +461,7 @@ struct dirent64_min { target_os = "illumos", target_os = "aix", target_os = "nto", + target_os = "qurt", target_os = "vita", )))] d_type: u8, @@ -462,6 +476,7 @@ struct dirent64_min { target_os = "illumos", target_os = "linux", target_os = "nto", + target_os = "qurt", target_os = "redox", target_os = "solaris", target_os = "vita", @@ -619,6 +634,7 @@ impl FileAttr { target_os = "horizon", target_os = "vita", target_os = "hurd", + target_os = "qurt", target_os = "rtems", target_os = "nuttx", )))] @@ -636,6 +652,7 @@ impl FileAttr { #[cfg(any( target_os = "vxworks", target_os = "espidf", + target_os = "qurt", target_os = "vita", target_os = "rtems", ))] @@ -654,6 +671,7 @@ impl FileAttr { target_os = "horizon", target_os = "vita", target_os = "hurd", + target_os = "qurt", target_os = "rtems", target_os = "nuttx", )))] @@ -671,6 +689,7 @@ impl FileAttr { #[cfg(any( target_os = "vxworks", target_os = "espidf", + target_os = "qurt", target_os = "vita", target_os = "rtems" ))] @@ -844,6 +863,7 @@ impl Iterator for ReadDir { target_os = "illumos", target_os = "linux", target_os = "nto", + target_os = "qurt", target_os = "redox", target_os = "solaris", target_os = "vita", @@ -917,6 +937,7 @@ impl Iterator for ReadDir { target_os = "illumos", target_os = "aix", target_os = "nto", + target_os = "qurt", )))] d_type: (*entry_ptr).d_type as u8, }; @@ -942,6 +963,7 @@ impl Iterator for ReadDir { target_os = "illumos", target_os = "linux", target_os = "nto", + target_os = "qurt", target_os = "redox", target_os = "solaris", target_os = "vita", @@ -987,6 +1009,7 @@ impl Iterator for ReadDir { /// So we check file flags instead which live on the file descriptor and not the underlying file. /// The downside is that it costs an extra syscall, so we only do it for debug. #[inline] +#[cfg_attr(target_os = "qurt", allow(dead_code))] pub(crate) fn debug_assert_fd_is_open(fd: RawFd) { use crate::sys::io::errno; @@ -1005,6 +1028,7 @@ impl Drop for DirStream { miri, target_os = "redox", target_os = "nto", + target_os = "qurt", target_os = "vita", target_os = "hurd", target_os = "espidf", @@ -1093,6 +1117,7 @@ impl DirEntry { target_os = "vxworks", target_os = "aix", target_os = "nto", + target_os = "qurt", target_os = "vita", ))] pub fn file_type(&self) -> io::Result { @@ -1106,6 +1131,7 @@ impl DirEntry { target_os = "vxworks", target_os = "aix", target_os = "nto", + target_os = "qurt", target_os = "vita", )))] pub fn file_type(&self) -> io::Result { @@ -1136,6 +1162,7 @@ impl DirEntry { target_os = "l4re", target_os = "linux", target_os = "nto", + target_os = "qurt", target_os = "redox", target_os = "rtems", target_os = "solaris", @@ -1195,6 +1222,7 @@ impl DirEntry { target_os = "redox", target_os = "aix", target_os = "nto", + target_os = "qurt", target_os = "vita", target_os = "hurd", target_os = "wasi", @@ -1212,6 +1240,7 @@ impl DirEntry { target_os = "redox", target_os = "aix", target_os = "nto", + target_os = "qurt", target_os = "vita", target_os = "hurd", target_os = "wasi", @@ -1378,6 +1407,7 @@ impl File { Ok(FileAttr::from_stat64(stat)) } + #[cfg(not(target_os = "qurt"))] pub fn fsync(&self) -> io::Result<()> { cvt_r(|| unsafe { os_fsync(self.as_raw_fd()) })?; return Ok(()); @@ -1392,6 +1422,12 @@ impl File { } } + #[cfg(target_os = "qurt")] + pub fn fsync(&self) -> io::Result<()> { + Err(io::const_error!(io::ErrorKind::Unsupported, "fsync not supported on QuRT")) + } + + #[cfg(not(target_os = "qurt"))] pub fn datasync(&self) -> io::Result<()> { cvt_r(|| unsafe { os_datasync(self.as_raw_fd()) })?; return Ok(()); @@ -1431,6 +1467,11 @@ impl File { } } + #[cfg(target_os = "qurt")] + pub fn datasync(&self) -> io::Result<()> { + Err(io::const_error!(io::ErrorKind::Unsupported, "datasync not supported on QuRT")) + } + #[cfg(any( target_os = "freebsd", target_os = "fuchsia", @@ -1774,16 +1815,22 @@ impl File { self.0.duplicate().map(File) } + #[cfg(not(target_os = "qurt"))] pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> { cvt_r(|| unsafe { libc::fchmod(self.as_raw_fd(), perm.mode) })?; Ok(()) } + #[cfg(target_os = "qurt")] + pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> { + Err(io::const_error!(io::ErrorKind::Unsupported, "fchmod not supported on QuRT")) + } + pub fn set_times(&self, times: FileTimes) -> io::Result<()> { cfg_select! { - any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx") => { + any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx", target_os = "qurt") => { // Redox doesn't appear to support `UTIME_OMIT`. - // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore + // ESP-IDF, HorizonOS, and QuRT do not support `futimens` at all and the behavior for those OS is therefore // the same as for Redox. let _ = times; Err(io::const_error!( @@ -1850,6 +1897,7 @@ impl File { target_os = "espidf", target_os = "horizon", target_os = "nuttx", + target_os = "qurt", )))] fn file_time_to_timespec(time: Option) -> io::Result { match time { @@ -2081,14 +2129,21 @@ pub fn rename(old: &CStr, new: &CStr) -> io::Result<()> { cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) }).map(|_| ()) } +#[cfg(not(target_os = "qurt"))] pub fn set_perm(p: &CStr, perm: FilePermissions) -> io::Result<()> { cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) }).map(|_| ()) } +#[cfg(target_os = "qurt")] +pub fn set_perm(_p: &CStr, _perm: FilePermissions) -> io::Result<()> { + Err(io::const_error!(io::ErrorKind::Unsupported, "chmod not supported on QuRT")) +} + pub fn rmdir(p: &CStr) -> io::Result<()> { cvt(unsafe { libc::rmdir(p.as_ptr()) }).map(|_| ()) } +#[cfg(not(target_os = "qurt"))] pub fn readlink(c_path: &CStr) -> io::Result { let p = c_path.as_ptr(); @@ -2115,12 +2170,28 @@ pub fn readlink(c_path: &CStr) -> io::Result { } } +#[cfg(target_os = "qurt")] +pub fn readlink(_c_path: &CStr) -> io::Result { + Err(io::const_error!(io::ErrorKind::Unsupported, "readlink not supported on QuRT")) +} + +#[cfg(not(target_os = "qurt"))] pub fn symlink(original: &CStr, link: &CStr) -> io::Result<()> { cvt(unsafe { libc::symlink(original.as_ptr(), link.as_ptr()) }).map(|_| ()) } +#[cfg(target_os = "qurt")] +pub fn symlink(_original: &CStr, _link: &CStr) -> io::Result<()> { + Err(io::const_error!(io::ErrorKind::Unsupported, "symlink not supported on QuRT")) +} + pub fn link(original: &CStr, link: &CStr) -> io::Result<()> { cfg_select! { + target_os = "qurt" => { + // QuRT doesn't support hard links + let _ = (original, link); + return Err(io::const_error!(io::ErrorKind::Unsupported, "link not supported on QuRT")); + } any( // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. // POSIX leaves it implementation-defined whether `link` follows @@ -2182,6 +2253,7 @@ pub fn lstat(p: &CStr) -> io::Result { Ok(FileAttr::from_stat64(stat)) } +#[cfg(not(target_os = "qurt"))] pub fn canonicalize(path: &CStr) -> io::Result { let r = unsafe { libc::realpath(path.as_ptr(), ptr::null_mut()) }; if r.is_null() { @@ -2194,6 +2266,11 @@ pub fn canonicalize(path: &CStr) -> io::Result { }))) } +#[cfg(target_os = "qurt")] +pub fn canonicalize(_path: &CStr) -> io::Result { + Err(io::const_error!(io::ErrorKind::Unsupported, "realpath not supported on QuRT")) +} + fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)> { use crate::fs::File; use crate::sys::fs::common::NOT_FILE_ERROR; @@ -2208,7 +2285,7 @@ fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)> fn set_times_impl(p: &CStr, times: FileTimes, follow_symlinks: bool) -> io::Result<()> { cfg_select! { - any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx", target_os = "vita", target_os = "rtems") => { + any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx", target_os = "vita", target_os = "rtems", target_os = "qurt") => { let _ = (p, times, follow_symlinks); Err(io::const_error!( io::ErrorKind::Unsupported, @@ -2446,7 +2523,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { Ok(bytes_copied as u64) } -#[cfg(not(target_os = "wasi"))] +#[cfg(not(any(target_os = "wasi", target_os = "qurt")))] pub fn chown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { run_path_with_cstr(path, &|path| { cvt(unsafe { libc::chown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) }) @@ -2454,13 +2531,13 @@ pub fn chown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { }) } -#[cfg(not(target_os = "wasi"))] +#[cfg(not(any(target_os = "wasi", target_os = "qurt")))] pub fn fchown(fd: c_int, uid: u32, gid: u32) -> io::Result<()> { cvt(unsafe { libc::fchown(fd, uid as libc::uid_t, gid as libc::gid_t) })?; Ok(()) } -#[cfg(not(any(target_os = "vxworks", target_os = "wasi")))] +#[cfg(not(any(target_os = "vxworks", target_os = "wasi", target_os = "qurt")))] pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { run_path_with_cstr(path, &|path| { cvt(unsafe { libc::lchown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) }) @@ -2469,23 +2546,26 @@ pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { } #[cfg(target_os = "vxworks")] -pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { - let (_, _, _) = (path, uid, gid); - Err(io::const_error!(io::ErrorKind::Unsupported, "lchown not supported by vxworks")) +pub fn lchown(_path: &Path, _uid: u32, _gid: u32) -> io::Result<()> { + Err(io::const_error!(io::ErrorKind::Unsupported, "lchown not supported")) } -#[cfg(not(any(target_os = "fuchsia", target_os = "vxworks", target_os = "wasi")))] +#[cfg(not(any( + target_os = "fuchsia", + target_os = "vxworks", + target_os = "wasi", + target_os = "qurt" +)))] pub fn chroot(dir: &Path) -> io::Result<()> { run_path_with_cstr(dir, &|dir| cvt(unsafe { libc::chroot(dir.as_ptr()) }).map(|_| ())) } #[cfg(target_os = "vxworks")] -pub fn chroot(dir: &Path) -> io::Result<()> { - let _ = dir; - Err(io::const_error!(io::ErrorKind::Unsupported, "chroot not supported by vxworks")) +pub fn chroot(_dir: &Path) -> io::Result<()> { + Err(io::const_error!(io::ErrorKind::Unsupported, "chroot not supported")) } -#[cfg(not(target_os = "wasi"))] +#[cfg(not(any(target_os = "wasi", target_os = "qurt")))] pub fn mkfifo(path: &Path, mode: u32) -> io::Result<()> { run_path_with_cstr(path, &|path| { cvt(unsafe { libc::mkfifo(path.as_ptr(), mode.try_into().unwrap()) }).map(|_| ()) @@ -2494,11 +2574,12 @@ pub fn mkfifo(path: &Path, mode: u32) -> io::Result<()> { pub use remove_dir_impl::remove_dir_all; -// Fallback for REDOX, ESP-ID, Horizon, Vita, Vxworks and Miri +// Fallback for REDOX, ESP-ID, Horizon, QuRT, Vita, Vxworks and Miri #[cfg(any( target_os = "redox", target_os = "espidf", target_os = "horizon", + target_os = "qurt", target_os = "vita", target_os = "nto", target_os = "vxworks", @@ -2513,6 +2594,7 @@ mod remove_dir_impl { target_os = "redox", target_os = "espidf", target_os = "horizon", + target_os = "qurt", target_os = "vita", target_os = "nto", target_os = "vxworks", diff --git a/library/std/src/sys/io/mod.rs b/library/std/src/sys/io/mod.rs index b3587ab63696a..527f393ca193d 100644 --- a/library/std/src/sys/io/mod.rs +++ b/library/std/src/sys/io/mod.rs @@ -4,7 +4,13 @@ mod error; mod io_slice { cfg_select! { - any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3", target_os = "trusty", target_os = "wasi") => { + any( + all(target_family = "unix", not(target_os = "qurt")), + target_os = "hermit", + target_os = "solid_asp3", + target_os = "trusty", + target_os = "wasi" + ) => { mod iovec; pub use iovec::*; } @@ -25,7 +31,7 @@ mod io_slice { mod is_terminal { cfg_select! { - any(target_family = "unix", target_os = "wasi") => { + any(all(target_family = "unix", not(target_os = "qurt")), target_os = "wasi") => { mod isatty; pub use isatty::*; } diff --git a/library/std/src/sys/net/connection/mod.rs b/library/std/src/sys/net/connection/mod.rs index 2f064914a8317..f24315d04bdfc 100644 --- a/library/std/src/sys/net/connection/mod.rs +++ b/library/std/src/sys/net/connection/mod.rs @@ -1,6 +1,6 @@ cfg_select! { any( - all(target_family = "unix", not(target_os = "l4re")), + all(target_family = "unix", not(target_os = "l4re"), not(target_os = "qurt")), target_os = "windows", target_os = "hermit", all(target_os = "wasi", any(target_env = "p2", target_env = "p3")), diff --git a/library/std/src/sys/net/connection/unsupported.rs b/library/std/src/sys/net/connection/unsupported.rs index fb18e8dec557c..38941ebbb5f43 100644 --- a/library/std/src/sys/net/connection/unsupported.rs +++ b/library/std/src/sys/net/connection/unsupported.rs @@ -1,7 +1,7 @@ use crate::fmt; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, ToSocketAddrs}; -use crate::sys::unsupported; +use crate::sys::unsupported::unsupported; use crate::time::Duration; pub struct TcpStream(!); diff --git a/library/std/src/sys/net/hostname/mod.rs b/library/std/src/sys/net/hostname/mod.rs index 65fcd6bfb00d7..1c6efae7c90a8 100644 --- a/library/std/src/sys/net/hostname/mod.rs +++ b/library/std/src/sys/net/hostname/mod.rs @@ -1,5 +1,5 @@ cfg_select! { - all(target_family = "unix", not(target_os = "espidf")) => { + all(target_family = "unix", not(any(target_os = "espidf", target_os = "qurt"))) => { mod unix; pub use unix::hostname; } diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 0fbf37fda7fbf..8bad72c6deed7 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -61,6 +61,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { #[cfg(all(target_os = "linux", target_env = "gnu"))] use libc::open64 as open; + #[cfg(not(target_os = "qurt"))] if opened_devnull != -1 { if libc::dup(opened_devnull) != -1 { return; @@ -87,6 +88,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { target_os = "horizon", target_os = "vita", target_os = "rtems", + target_os = "qurt", // The poll on Darwin doesn't set POLLNVAL for closed fds. target_vendor = "apple", )))] @@ -133,6 +135,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { target_os = "l4re", target_os = "horizon", target_os = "vita", + target_os = "qurt", )))] { use crate::sys::io::errno; @@ -210,6 +213,7 @@ static ON_BROKEN_PIPE_USED: crate::sync::atomic::Atomic = target_os = "vxworks", target_os = "vita", target_os = "nuttx", + target_os = "qurt", )))] pub(crate) fn on_broken_pipe_used() -> bool { ON_BROKEN_PIPE_USED.load(crate::sync::atomic::Ordering::Relaxed) @@ -369,7 +373,13 @@ cfg_select! { _ => {} } -#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] +#[cfg(any( + target_os = "espidf", + target_os = "horizon", + target_os = "vita", + target_os = "nuttx", + target_os = "qurt" +))] pub mod unsupported { use crate::io; diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index b8280a8f29a02..c4aceb6dec987 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -8,6 +8,9 @@ mod tests; use libc::{c_char, c_int, c_void}; use crate::ffi::{CStr, OsStr, OsString}; +#[cfg(target_os = "qurt")] +use crate::os::qurt::prelude::*; +#[cfg(not(target_os = "qurt"))] use crate::os::unix::prelude::*; use crate::path::{self, PathBuf}; use crate::sys::cvt; @@ -48,12 +51,12 @@ pub fn getcwd() -> io::Result { } } -#[cfg(target_os = "espidf")] +#[cfg(any(target_os = "espidf", target_os = "qurt"))] pub fn chdir(_p: &path::Path) -> io::Result<()> { super::unsupported::unsupported() } -#[cfg(not(target_os = "espidf"))] +#[cfg(not(any(target_os = "espidf", target_os = "qurt")))] pub fn chdir(p: &path::Path) -> io::Result<()> { let result = run_path_with_cstr(p, &|p| unsafe { Ok(libc::chdir(p.as_ptr())) })?; if result == 0 { Ok(()) } else { Err(io::Error::last_os_error()) } @@ -373,7 +376,7 @@ pub fn current_exe() -> io::Result { path.canonicalize() } -#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))] +#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "qurt"))] pub fn current_exe() -> io::Result { super::unsupported::unsupported() } @@ -492,6 +495,7 @@ pub fn home_dir() -> Option { target_os = "horizon", target_os = "vita", target_os = "nuttx", + target_os = "qurt", all(target_vendor = "apple", not(target_os = "macos")), ))] unsafe fn fallback() -> Option { @@ -506,6 +510,7 @@ pub fn home_dir() -> Option { target_os = "horizon", target_os = "vita", target_os = "nuttx", + target_os = "qurt", all(target_vendor = "apple", not(target_os = "macos")), )))] unsafe fn fallback() -> Option { @@ -542,6 +547,7 @@ pub fn getpid() -> u32 { unsafe { libc::getpid() as u32 } } +#[cfg(not(target_os = "qurt"))] pub fn getppid() -> u32 { unsafe { libc::getppid() as u32 } } diff --git a/library/std/src/sys/pipe/mod.rs b/library/std/src/sys/pipe/mod.rs index 85228963b4adf..a995fc159f5ab 100644 --- a/library/std/src/sys/pipe/mod.rs +++ b/library/std/src/sys/pipe/mod.rs @@ -1,6 +1,11 @@ #![forbid(unsafe_op_in_unsafe_fn)] cfg_select! { + // QuRT uses unsupported pipes since it doesn't support process spawning + target_os = "qurt" => { + mod unsupported; + pub use unsupported::{Pipe, pipe}; + } unix => { mod unix; pub use unix::{Pipe, pipe}; diff --git a/library/std/src/sys/process/mod.rs b/library/std/src/sys/process/mod.rs index 121d3bc9d5c3c..cb24f189500e6 100644 --- a/library/std/src/sys/process/mod.rs +++ b/library/std/src/sys/process/mod.rs @@ -1,5 +1,5 @@ cfg_select! { - target_family = "unix" => { + all(target_family = "unix", not(target_os = "qurt")) => { mod unix; use unix as imp; } @@ -39,7 +39,8 @@ pub use imp::{ target_os = "espidf", target_os = "horizon", target_os = "vita", - target_os = "nuttx" + target_os = "nuttx", + target_os = "qurt" )) ), target_os = "windows", @@ -77,7 +78,8 @@ pub fn output(cmd: &mut Command) -> crate::io::Result<(ExitStatus, Vec, Vec< target_os = "espidf", target_os = "horizon", target_os = "vita", - target_os = "nuttx" + target_os = "nuttx", + target_os = "qurt" )) ), target_os = "windows", diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index 82ff94fb1e030..03bdc7df34552 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -405,7 +405,8 @@ impl Command { *sys::env::environ() = envp.as_ptr(); } - libc::execvp(self.get_program_cstr().as_ptr(), self.get_argv().as_ptr()); + // Cast to *const *const to match libc 0.2 signature; libc 1.0 uses *const *mut + libc::execvp(self.get_program_cstr().as_ptr(), self.get_argv().as_ptr() as *const *const _); Err(io::Error::last_os_error()) } diff --git a/library/std/src/sys/process/unsupported.rs b/library/std/src/sys/process/unsupported.rs index 455c38e55b7ba..704cead481ad3 100644 --- a/library/std/src/sys/process/unsupported.rs +++ b/library/std/src/sys/process/unsupported.rs @@ -5,7 +5,7 @@ use crate::num::NonZero; use crate::path::Path; use crate::process::StdioPipes; use crate::sys::fs::File; -use crate::sys::unsupported; +use crate::sys::unsupported::unsupported; use crate::{fmt, io}; //////////////////////////////////////////////////////////////////////////////// diff --git a/library/std/src/sys/random/mod.rs b/library/std/src/sys/random/mod.rs index 91f72d0738790..a57845126ce67 100644 --- a/library/std/src/sys/random/mod.rs +++ b/library/std/src/sys/random/mod.rs @@ -106,6 +106,7 @@ cfg_select! { all(target_family = "wasm", target_os = "unknown"), target_os = "xous", target_os = "vexos", + target_os = "qurt", ) => { // FIXME: finally remove std support for wasm32-unknown-unknown // FIXME: add random data generation to xous @@ -122,6 +123,7 @@ cfg_select! { all(target_os = "wasi", not(target_env = "p1")), target_os = "xous", target_os = "vexos", + target_os = "qurt", )))] pub fn hashmap_random_keys() -> (u64, u64) { let mut buf = [0; 16]; diff --git a/library/std/src/sys/stdio/mod.rs b/library/std/src/sys/stdio/mod.rs index 86d0f3fe49cb3..ae9b78eaae8b4 100644 --- a/library/std/src/sys/stdio/mod.rs +++ b/library/std/src/sys/stdio/mod.rs @@ -1,7 +1,11 @@ #![forbid(unsafe_op_in_unsafe_fn)] cfg_select! { - any(target_family = "unix", target_os = "hermit", target_os = "wasi") => { + any( + all(target_family = "unix", not(target_os = "qurt")), + target_os = "hermit", + target_os = "wasi" + ) => { mod unix; pub use unix::*; } diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs index 22f9bfef5a383..676e428424646 100644 --- a/library/std/src/sys/thread/unix.rs +++ b/library/std/src/sys/thread/unix.rs @@ -420,7 +420,7 @@ pub fn set_name(name: &CStr) { target_os = "freebsd", target_os = "dragonfly", target_os = "nuttx", - target_os = "cygwin" + target_os = "cygwin", ))] pub fn set_name(name: &CStr) { unsafe { @@ -519,6 +519,11 @@ pub fn set_name(name: &CStr) { debug_assert_eq!(res, libc::OK); } +#[cfg(target_os = "qurt")] +pub fn set_name(_name: &CStr) { + // QuRT doesn't support pthread_setname_np +} + #[cfg(not(target_os = "espidf"))] pub fn sleep(dur: Duration) { cfg_select! { diff --git a/library/sysroot/src/lib.rs b/library/sysroot/src/lib.rs index 71ceb580a40c3..8dcc1a554e12c 100644 --- a/library/sysroot/src/lib.rs +++ b/library/sysroot/src/lib.rs @@ -1 +1,2 @@ +#![cfg_attr(target_os = "qurt", feature(restricted_std))] // This is intentionally empty since this crate is only used to depend on other library crates. diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index d554807bbde70..ed1c87a44c8fb 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -26,6 +26,7 @@ #![feature(panic_can_unwind)] #![feature(test)] #![feature(thread_spawn_hook)] +#![feature(restricted_std)] #![allow(internal_features)] #![warn(rustdoc::unescaped_backticks)] #![warn(unreachable_pub)] diff --git a/library/test/src/test_result.rs b/library/test/src/test_result.rs index 4cb43fc45fd6c..77dc52f62604d 100644 --- a/library/test/src/test_result.rs +++ b/library/test/src/test_result.rs @@ -1,5 +1,5 @@ use std::any::Any; -#[cfg(unix)] +#[cfg(all(unix, not(target_os = "qurt")))] use std::os::unix::process::ExitStatusExt; use std::process::ExitStatus; @@ -114,7 +114,7 @@ pub(crate) fn get_result_from_exit_code( Some(TR_OK) => TestResult::TrOk, #[cfg(windows)] Some(STATUS_FAIL_FAST_EXCEPTION) => TestResult::TrFailed, - #[cfg(unix)] + #[cfg(all(unix, not(target_os = "qurt")))] None => match status.signal() { Some(libc::SIGABRT) => TestResult::TrFailed, Some(signal) => { @@ -125,7 +125,7 @@ pub(crate) fn get_result_from_exit_code( // Upon an abort, Fuchsia returns the status code ZX_TASK_RETCODE_EXCEPTION_KILL. #[cfg(target_os = "fuchsia")] Some(ZX_TASK_RETCODE_EXCEPTION_KILL) => TestResult::TrFailed, - #[cfg(not(unix))] + #[cfg(any(not(unix), target_os = "qurt"))] None => TestResult::TrFailedMsg(format!("unknown return code")), #[cfg(any(windows, unix))] Some(code) => TestResult::TrFailedMsg(format!("got unexpected return code {code}")), diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index e3fa826c45af3..a20d1fb9e4bdf 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -299,6 +299,7 @@ impl Cargo { && !target.contains("cygwin") && !target.contains("aix") && !target.contains("xous") + && !target.contains("qurt") { self.rustflags.arg("-Clink-args=-Wl,-z,origin"); Some(format!("-Wl,-rpath,$ORIGIN/../{libdir}"))