diff options
| author | bors <bors@rust-lang.org> | 2022-06-15 14:21:28 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-06-15 14:21:28 +0000 |
| commit | c3605f8c8020dbbe8f0d1961c7b33c4c4b78ad0d (patch) | |
| tree | 9c69ec553ce9679b117c2fdf6cbdbe66512b7fc8 /library/std/src | |
| parent | a4cec9742b7e05c33c84cd75002cd56762f7e33b (diff) | |
| parent | c814f842e46de25c95e08551a29f06ede1880a47 (diff) | |
| download | rust-c3605f8c8020dbbe8f0d1961c7b33c4c4b78ad0d.tar.gz rust-c3605f8c8020dbbe8f0d1961c7b33c4c4b78ad0d.zip | |
Auto merge of #95897 - AzureMarker:feature/horizon-std, r=nagisa
STD support for the Nintendo 3DS Rustc already supports compiling for the Nintendo 3DS using the `armv6k-nintendo-3ds` target (Tier 3). Until now though, only `core` and `alloc` were supported. This PR adds standard library support for the Nintendo 3DS. A notable exclusion is `std::thread` support, which will come in a follow-up PR as it requires more complicated changes. This has been a joint effort by `@Meziu,` `@ian-h-chamberlain,` myself, and prior work by `@rust3ds` members. ### Background The Nintendo 3DS (Horizon OS) is a mostly-UNIX looking system, with the caveat that it does not come with a full libc implementation out of the box. On the homebrew side (I'm not under NDA), the libc interface is partially implemented by the [devkitPro](https://devkitpro.org/wiki/devkitPro_pacman) toolchain and a user library like [`libctru`](https://github.com/devkitPro/libctru). This is important because there are [some possible legal barriers](https://github.com/rust-lang/rust/pull/88529#issuecomment-919938396) to linking directly to a library that uses the underlying platform APIs, since they might be considered a trade secret or under NDA. To get around this, the standard library impl for the 3DS does not directly depend on any platform-level APIs. Instead, it expects standard libc functions to be linked in. The implementation of these libc functions is left to the user. Some functions are provided by the devkitPro toolchain, but in our testing, we used the following to fill in the other functions: - [`libctru`] - provides more basic APIs, such as `nanosleep`. Linked in by way of [`ctru-sys`](https://github.com/Meziu/ctru-rs/tree/master/ctru-sys). - [`pthread-3ds`](https://github.com/Meziu/pthread-3ds) - provides pthread APIs for `std::thread`. Implemented using [`libctru`]. - [`linker-fix-3ds`](https://github.com/Meziu/rust-linker-fix-3ds) - fulfills some other missing libc APIs. Implemented using [`libctru`]. For more details, see the `src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md` file added in this PR. ### Notes We've already upstreamed changes to the [`libc`] crate to support this PR, as well as the upcoming threading PR. These changes have all been released as of 0.2.121, so we bump the crate version in this PR. Edit: After some rebases, the version bump has already been merged so it doesn't appear in this PR. A lot of the changes in this PR are straightforward, and follow in the footsteps of the ESP-IDF target: https://github.com/rust-lang/rust/pull/87666. The 3DS does not support user space process spawning, so these APIs are unimplemented (similar to ESP-IDF). [`libctru`]: https://github.com/devkitPro/libctru [`libc`]: https://github.com/rust-lang/libc
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/os/horizon/fs.rs | 95 | ||||
| -rw-r--r-- | library/std/src/os/horizon/mod.rs | 6 | ||||
| -rw-r--r-- | library/std/src/os/horizon/raw.rs | 70 | ||||
| -rw-r--r-- | library/std/src/os/mod.rs | 2 | ||||
| -rw-r--r-- | library/std/src/os/unix/mod.rs | 2 | ||||
| -rw-r--r-- | library/std/src/os/unix/process.rs | 46 | ||||
| -rw-r--r-- | library/std/src/sys/unix/alloc.rs | 3 | ||||
| -rw-r--r-- | library/std/src/sys/unix/args.rs | 3 | ||||
| -rw-r--r-- | library/std/src/sys/unix/env.rs | 11 | ||||
| -rw-r--r-- | library/std/src/sys/unix/fd.rs | 41 | ||||
| -rw-r--r-- | library/std/src/sys/unix/fs.rs | 25 | ||||
| -rw-r--r-- | library/std/src/sys/unix/locks/pthread_condvar.rs | 13 | ||||
| -rw-r--r-- | library/std/src/sys/unix/mod.rs | 6 | ||||
| -rw-r--r-- | library/std/src/sys/unix/os.rs | 8 | ||||
| -rw-r--r-- | library/std/src/sys/unix/process/mod.rs | 3 | ||||
| -rw-r--r-- | library/std/src/sys/unix/process/process_unsupported.rs | 13 | ||||
| -rw-r--r-- | library/std/src/sys/unix/rand.rs | 16 | ||||
| -rw-r--r-- | library/std/src/sys/unix/thread_local_dtor.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/unix/thread_parker.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/unix/time.rs | 5 | ||||
| -rw-r--r-- | library/std/src/sys_common/net.rs | 14 |
21 files changed, 300 insertions, 86 deletions
diff --git a/library/std/src/os/horizon/fs.rs b/library/std/src/os/horizon/fs.rs new file mode 100644 index 00000000000..1325522105d --- /dev/null +++ b/library/std/src/os/horizon/fs.rs @@ -0,0 +1,95 @@ +#![stable(feature = "metadata_ext", since = "1.1.0")] + +use crate::fs::Metadata; +use crate::sys_common::AsInner; + +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: crate::fs::Metadata +#[stable(feature = "metadata_ext", since = "1.1.0")] +pub trait MetadataExt { + #[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; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_uid(&self) -> u32; + #[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; + #[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; + #[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; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ctime_nsec(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_blksize(&self) -> u64; + #[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 { + 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 { + self.as_inner().as_inner().st_uid as u32 + } + fn st_gid(&self) -> u32 { + self.as_inner().as_inner().st_gid as u32 + } + 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_atim.tv_sec + } + fn st_atime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_atim.tv_nsec as i64 + } + fn st_mtime(&self) -> i64 { + self.as_inner().as_inner().st_mtim.tv_sec + } + fn st_mtime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_mtim.tv_nsec as i64 + } + fn st_ctime(&self) -> i64 { + self.as_inner().as_inner().st_ctim.tv_sec + } + fn st_ctime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_ctim.tv_nsec as i64 + } + fn st_blksize(&self) -> u64 { + self.as_inner().as_inner().st_blksize as u64 + } + fn st_blocks(&self) -> u64 { + self.as_inner().as_inner().st_blocks as u64 + } +} diff --git a/library/std/src/os/horizon/mod.rs b/library/std/src/os/horizon/mod.rs new file mode 100644 index 00000000000..326d0ae9cb9 --- /dev/null +++ b/library/std/src/os/horizon/mod.rs @@ -0,0 +1,6 @@ +//! Definitions for Horizon OS + +#![stable(feature = "raw_ext", since = "1.1.0")] + +pub mod fs; +pub(crate) mod raw; diff --git a/library/std/src/os/horizon/raw.rs b/library/std/src/os/horizon/raw.rs new file mode 100644 index 00000000000..929fa7db1f9 --- /dev/null +++ b/library/std/src/os/horizon/raw.rs @@ -0,0 +1,70 @@ +//! Horizon OS raw type definitions + +#![stable(feature = "raw_ext", since = "1.1.0")] +#![deprecated( + since = "1.8.0", + note = "these type aliases are no longer supported by \ + the standard library, the `libc` crate on \ + crates.io should be used instead for the correct \ + definitions" +)] +#![allow(deprecated)] + +use crate::os::raw::c_long; +use crate::os::unix::raw::{gid_t, uid_t}; + +#[stable(feature = "pthread_t", since = "1.8.0")] +pub type pthread_t = libc::pthread_t; + +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type blkcnt_t = libc::blkcnt_t; + +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type blksize_t = libc::blksize_t; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type dev_t = libc::dev_t; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type ino_t = libc::ino_t; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type mode_t = libc::mode_t; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type nlink_t = libc::nlink_t; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type off_t = libc::off_t; + +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type time_t = libc::time_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_atime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime: time_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_spare4: [c_long; 2usize], +} diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 029f131c40b..a1df72a8a04 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -123,6 +123,8 @@ pub mod freebsd; pub mod fuchsia; #[cfg(target_os = "haiku")] pub mod haiku; +#[cfg(target_os = "horizon")] +pub mod horizon; #[cfg(target_os = "illumos")] pub mod illumos; #[cfg(target_os = "ios")] diff --git a/library/std/src/os/unix/mod.rs b/library/std/src/os/unix/mod.rs index 7b8ca79eeb8..cef546487f3 100644 --- a/library/std/src/os/unix/mod.rs +++ b/library/std/src/os/unix/mod.rs @@ -51,6 +51,8 @@ mod platform { pub use crate::os::fuchsia::*; #[cfg(target_os = "haiku")] pub use crate::os::haiku::*; + #[cfg(target_os = "horizon")] + pub use crate::os::horizon::*; #[cfg(target_os = "illumos")] pub use crate::os::illumos::*; #[cfg(target_os = "ios")] diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 3e989c85db9..5065530e8d4 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -12,6 +12,16 @@ use crate::sealed::Sealed; use crate::sys; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; +#[cfg(not(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon")))] +type UserId = u32; +#[cfg(not(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon")))] +type GroupId = u32; + +#[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon"))] +type UserId = u16; +#[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon"))] +type GroupId = u16; + /// Unix-specific extensions to the [`process::Command`] builder. /// /// This trait is sealed: it cannot be implemented outside the standard library. @@ -22,29 +32,17 @@ pub trait CommandExt: Sealed { /// `setuid` call in the child process. Failure in the `setuid` /// call will cause the spawn to fail. #[stable(feature = "rust1", since = "1.0.0")] - fn uid( - &mut self, - #[cfg(not(any(target_os = "vxworks", target_os = "espidf")))] id: u32, - #[cfg(any(target_os = "vxworks", target_os = "espidf"))] id: u16, - ) -> &mut process::Command; + fn uid(&mut self, id: UserId) -> &mut process::Command; /// Similar to `uid`, but sets the group ID of the child process. This has /// the same semantics as the `uid` field. #[stable(feature = "rust1", since = "1.0.0")] - fn gid( - &mut self, - #[cfg(not(any(target_os = "vxworks", target_os = "espidf")))] id: u32, - #[cfg(any(target_os = "vxworks", target_os = "espidf"))] id: u16, - ) -> &mut process::Command; + fn gid(&mut self, id: GroupId) -> &mut process::Command; /// Sets the supplementary group IDs for the calling process. Translates to /// a `setgroups` call in the child process. #[unstable(feature = "setgroups", issue = "90747")] - fn groups( - &mut self, - #[cfg(not(any(target_os = "vxworks", target_os = "espidf")))] groups: &[u32], - #[cfg(any(target_os = "vxworks", target_os = "espidf"))] groups: &[u16], - ) -> &mut process::Command; + fn groups(&mut self, groups: &[GroupId]) -> &mut process::Command; /// Schedules a closure to be run just before the `exec` function is /// invoked. @@ -158,29 +156,17 @@ pub trait CommandExt: Sealed { #[stable(feature = "rust1", since = "1.0.0")] impl CommandExt for process::Command { - fn uid( - &mut self, - #[cfg(not(any(target_os = "vxworks", target_os = "espidf")))] id: u32, - #[cfg(any(target_os = "vxworks", target_os = "espidf"))] id: u16, - ) -> &mut process::Command { + fn uid(&mut self, id: UserId) -> &mut process::Command { self.as_inner_mut().uid(id); self } - fn gid( - &mut self, - #[cfg(not(any(target_os = "vxworks", target_os = "espidf")))] id: u32, - #[cfg(any(target_os = "vxworks", target_os = "espidf"))] id: u16, - ) -> &mut process::Command { + fn gid(&mut self, id: GroupId) -> &mut process::Command { self.as_inner_mut().gid(id); self } - fn groups( - &mut self, - #[cfg(not(any(target_os = "vxworks", target_os = "espidf")))] groups: &[u32], - #[cfg(any(target_os = "vxworks", target_os = "espidf"))] groups: &[u16], - ) -> &mut process::Command { + fn groups(&mut self, groups: &[GroupId]) -> &mut process::Command { self.as_inner_mut().groups(groups); self } diff --git a/library/std/src/sys/unix/alloc.rs b/library/std/src/sys/unix/alloc.rs index 7c3d9573940..9d6567c9fb4 100644 --- a/library/std/src/sys/unix/alloc.rs +++ b/library/std/src/sys/unix/alloc.rs @@ -58,7 +58,8 @@ cfg_if::cfg_if! { target_os = "illumos", target_os = "redox", target_os = "solaris", - target_os = "espidf" + target_os = "espidf", + target_os = "horizon" ))] { #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { diff --git a/library/std/src/sys/unix/args.rs b/library/std/src/sys/unix/args.rs index ee5e3983ac2..79964e2b238 100644 --- a/library/std/src/sys/unix/args.rs +++ b/library/std/src/sys/unix/args.rs @@ -68,7 +68,8 @@ impl DoubleEndedIterator for Args { target_os = "l4re", target_os = "fuchsia", target_os = "redox", - target_os = "vxworks" + target_os = "vxworks", + target_os = "horizon" ))] mod imp { use super::Args; diff --git a/library/std/src/sys/unix/env.rs b/library/std/src/sys/unix/env.rs index 60551aeb3e7..4d8391656a4 100644 --- a/library/std/src/sys/unix/env.rs +++ b/library/std/src/sys/unix/env.rs @@ -119,6 +119,17 @@ pub mod os { pub const EXE_EXTENSION: &str = ""; } +#[cfg(target_os = "horizon")] +pub mod os { + pub const FAMILY: &str = "unix"; + pub const OS: &str = "horizon"; + pub const DLL_PREFIX: &str = "lib"; + pub const DLL_SUFFIX: &str = ".so"; + pub const DLL_EXTENSION: &str = "so"; + pub const EXE_SUFFIX: &str = ".elf"; + pub const EXE_EXTENSION: &str = "elf"; +} + #[cfg(all(target_os = "emscripten", target_arch = "asmjs"))] pub mod os { pub const FAMILY: &str = "unix"; diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs index 40a64585802..137ca3a7633 100644 --- a/library/std/src/sys/unix/fd.rs +++ b/library/std/src/sys/unix/fd.rs @@ -9,8 +9,6 @@ use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, Owned use crate::sys::cvt; use crate::sys_common::{AsInner, FromInner, IntoInner}; -use libc::{c_int, c_void}; - #[cfg(any( target_os = "android", target_os = "linux", @@ -38,7 +36,7 @@ pub struct FileDesc(OwnedFd); // 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; +const READ_LIMIT: usize = libc::c_int::MAX as usize - 1; #[cfg(not(target_os = "macos"))] const READ_LIMIT: usize = libc::ssize_t::MAX as usize; @@ -69,6 +67,7 @@ const fn max_iov() -> usize { target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "horizon" )))] const fn max_iov() -> usize { 16 // The minimum value required by POSIX. @@ -79,33 +78,33 @@ impl FileDesc { let ret = cvt(unsafe { libc::read( self.as_raw_fd(), - buf.as_mut_ptr() as *mut c_void, + buf.as_mut_ptr() as *mut libc::c_void, cmp::min(buf.len(), READ_LIMIT), ) })?; Ok(ret as usize) } - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "horizon")))] pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { let ret = cvt(unsafe { libc::readv( self.as_raw_fd(), bufs.as_ptr() as *const libc::iovec, - cmp::min(bufs.len(), max_iov()) as c_int, + cmp::min(bufs.len(), max_iov()) as libc::c_int, ) })?; Ok(ret as usize) } - #[cfg(target_os = "espidf")] + #[cfg(any(target_os = "espidf", target_os = "horizon"))] pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { return crate::io::default_read_vectored(|b| self.read(b), bufs); } #[inline] pub fn is_read_vectored(&self) -> bool { - cfg!(not(target_os = "espidf")) + cfg!(not(any(target_os = "espidf", target_os = "horizon"))) } pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> { @@ -122,7 +121,7 @@ impl FileDesc { unsafe { cvt(pread64( self.as_raw_fd(), - buf.as_mut_ptr() as *mut c_void, + buf.as_mut_ptr() as *mut libc::c_void, cmp::min(buf.len(), READ_LIMIT), offset as off64_t, )) @@ -134,7 +133,7 @@ impl FileDesc { let ret = cvt(unsafe { libc::read( self.as_raw_fd(), - buf.unfilled_mut().as_mut_ptr() as *mut c_void, + buf.unfilled_mut().as_mut_ptr() as *mut libc::c_void, cmp::min(buf.remaining(), READ_LIMIT), ) })?; @@ -151,33 +150,33 @@ impl FileDesc { let ret = cvt(unsafe { libc::write( self.as_raw_fd(), - buf.as_ptr() as *const c_void, + buf.as_ptr() as *const libc::c_void, cmp::min(buf.len(), READ_LIMIT), ) })?; Ok(ret as usize) } - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "horizon")))] pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { let ret = cvt(unsafe { libc::writev( self.as_raw_fd(), bufs.as_ptr() as *const libc::iovec, - cmp::min(bufs.len(), max_iov()) as c_int, + cmp::min(bufs.len(), max_iov()) as libc::c_int, ) })?; Ok(ret as usize) } - #[cfg(target_os = "espidf")] + #[cfg(any(target_os = "espidf", target_os = "horizon"))] pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { return crate::io::default_write_vectored(|b| self.write(b), bufs); } #[inline] pub fn is_write_vectored(&self) -> bool { - cfg!(not(target_os = "espidf")) + cfg!(not(any(target_os = "espidf", target_os = "horizon"))) } pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> { @@ -189,7 +188,7 @@ impl FileDesc { unsafe { cvt(pwrite64( self.as_raw_fd(), - buf.as_ptr() as *const c_void, + buf.as_ptr() as *const libc::c_void, cmp::min(buf.len(), READ_LIMIT), offset as off64_t, )) @@ -221,7 +220,7 @@ impl FileDesc { } } #[cfg(any( - all(target_env = "newlib", not(target_os = "espidf")), + all(target_env = "newlib", not(any(target_os = "espidf", target_os = "horizon"))), target_os = "solaris", target_os = "illumos", target_os = "emscripten", @@ -242,17 +241,17 @@ impl FileDesc { Ok(()) } } - #[cfg(target_os = "espidf")] + #[cfg(any(target_os = "espidf", target_os = "horizon"))] pub fn set_cloexec(&self) -> io::Result<()> { - // FD_CLOEXEC is not supported in ESP-IDF but there's no need to, - // because ESP-IDF does not support spawning processes either. + // FD_CLOEXEC is not supported in ESP-IDF and Horizon OS but there's no need to, + // because neither supports spawning processes. Ok(()) } #[cfg(target_os = "linux")] pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { unsafe { - let v = nonblocking as c_int; + let v = nonblocking as libc::c_int; cvt(libc::ioctl(self.as_raw_fd(), libc::FIONBIO, &v))?; Ok(()) } diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 5d0fb079003..8b0bbd6a55c 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -395,7 +395,7 @@ impl FileAttr { #[cfg(not(target_os = "netbsd"))] impl FileAttr { - #[cfg(all(not(target_os = "vxworks"), not(target_os = "espidf")))] + #[cfg(not(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon")))] pub fn modified(&self) -> io::Result<SystemTime> { #[cfg(target_pointer_width = "32")] cfg_has_statx! { @@ -412,7 +412,12 @@ impl FileAttr { Ok(SystemTime::new(self.stat.st_mtime as i64, 0)) } - #[cfg(all(not(target_os = "vxworks"), not(target_os = "espidf")))] + #[cfg(target_os = "horizon")] + pub fn modified(&self) -> io::Result<SystemTime> { + Ok(SystemTime::from(self.stat.st_mtim)) + } + + #[cfg(not(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon")))] pub fn accessed(&self) -> io::Result<SystemTime> { #[cfg(target_pointer_width = "32")] cfg_has_statx! { @@ -429,6 +434,11 @@ impl FileAttr { Ok(SystemTime::new(self.stat.st_atime as i64, 0)) } + #[cfg(target_os = "horizon")] + pub fn accessed(&self) -> io::Result<SystemTime> { + Ok(SystemTime::from(self.stat.st_atim)) + } + #[cfg(any( target_os = "freebsd", target_os = "openbsd", @@ -707,7 +717,8 @@ impl DirEntry { target_os = "fuchsia", target_os = "redox", target_os = "vxworks", - target_os = "espidf" + target_os = "espidf", + target_os = "horizon" ))] pub fn ino(&self) -> u64 { self.entry.d_ino as u64 @@ -1251,7 +1262,7 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> { let original = cstr(original)?; let link = cstr(link)?; cfg_if::cfg_if! { - if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf"))] { + if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf", target_os = "horizon"))] { // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. POSIX leaves // it implementation-defined whether `link` follows symlinks, so rely on the // `symlink_hard_link` test in library/std/src/fs/tests.rs to check the behavior. @@ -1549,14 +1560,14 @@ pub fn chroot(dir: &Path) -> io::Result<()> { pub use remove_dir_impl::remove_dir_all; -// Fallback for REDOX and ESP-IDF (and Miri) -#[cfg(any(target_os = "redox", target_os = "espidf", miri))] +// Fallback for REDOX, ESP-ID, Horizon, and Miri +#[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon", miri))] mod remove_dir_impl { pub use crate::sys_common::fs::remove_dir_all; } // Modern implementation using openat(), unlinkat() and fdopendir() -#[cfg(not(any(target_os = "redox", target_os = "espidf", miri)))] +#[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon", miri)))] mod remove_dir_impl { use super::{cstr, lstat, Dir, DirEntry, InnerReadDir, ReadDir}; use crate::ffi::CStr; diff --git a/library/std/src/sys/unix/locks/pthread_condvar.rs b/library/std/src/sys/unix/locks/pthread_condvar.rs index 61c28d696bc..78f10f0534c 100644 --- a/library/std/src/sys/unix/locks/pthread_condvar.rs +++ b/library/std/src/sys/unix/locks/pthread_condvar.rs @@ -47,7 +47,9 @@ impl Condvar { // So on that platform, init() should always be called // Moreover, that platform does not have pthread_condattr_setclock support, // hence that initialization should be skipped as well - #[cfg(target_os = "espidf")] + // + // Similar story for the 3DS (horizon). + #[cfg(any(target_os = "espidf", target_os = "horizon"))] unsafe fn init(&mut self) { let r = libc::pthread_cond_init(self.inner.get(), crate::ptr::null()); assert_eq!(r, 0); @@ -59,7 +61,8 @@ impl Condvar { target_os = "l4re", target_os = "android", target_os = "redox", - target_os = "espidf" + target_os = "espidf", + target_os = "horizon" )))] unsafe fn init(&mut self) { use crate::mem::MaybeUninit; @@ -100,7 +103,8 @@ impl Condvar { target_os = "macos", target_os = "ios", target_os = "android", - target_os = "espidf" + target_os = "espidf", + target_os = "horizon" )))] pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { use crate::mem; @@ -132,7 +136,8 @@ impl Condvar { target_os = "macos", target_os = "ios", target_os = "android", - target_os = "espidf" + target_os = "espidf", + target_os = "horizon" ))] pub unsafe fn wait_timeout(&self, mutex: &Mutex, mut dur: Duration) -> bool { use crate::ptr; diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index ddec60961f0..34a023b02c4 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -88,6 +88,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) { target_os = "ios", target_os = "redox", target_os = "l4re", + target_os = "horizon", )))] 'poll: { use crate::sys::os::errno; @@ -131,6 +132,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) { target_os = "fuchsia", target_os = "vxworks", target_os = "l4re", + target_os = "horizon", )))] { use crate::sys::os::errno; @@ -149,7 +151,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) { } unsafe fn reset_sigpipe() { - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia")))] + #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "horizon")))] rtassert!(signal(libc::SIGPIPE, libc::SIG_IGN) != libc::SIG_ERR); } } @@ -344,7 +346,7 @@ cfg_if::cfg_if! { } } -#[cfg(target_os = "espidf")] +#[cfg(any(target_os = "espidf", target_os = "horizon"))] mod unsupported { use crate::io; diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs index 92bea9346d8..7252ad32184 100644 --- a/library/std/src/sys/unix/os.rs +++ b/library/std/src/sys/unix/os.rs @@ -446,7 +446,7 @@ pub fn current_exe() -> io::Result<PathBuf> { path.canonicalize() } -#[cfg(target_os = "espidf")] +#[cfg(any(target_os = "espidf", target_os = "horizon"))] pub fn current_exe() -> io::Result<PathBuf> { super::unsupported::unsupported() } @@ -601,7 +601,8 @@ pub fn home_dir() -> Option<PathBuf> { target_os = "emscripten", target_os = "redox", target_os = "vxworks", - target_os = "espidf" + target_os = "espidf", + target_os = "horizon" ))] unsafe fn fallback() -> Option<OsString> { None @@ -612,7 +613,8 @@ pub fn home_dir() -> Option<PathBuf> { target_os = "emscripten", target_os = "redox", target_os = "vxworks", - target_os = "espidf" + target_os = "espidf", + target_os = "horizon" )))] unsafe fn fallback() -> Option<OsString> { let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) { diff --git a/library/std/src/sys/unix/process/mod.rs b/library/std/src/sys/unix/process/mod.rs index 0165ece849e..3701510f3a4 100644 --- a/library/std/src/sys/unix/process/mod.rs +++ b/library/std/src/sys/unix/process/mod.rs @@ -3,6 +3,7 @@ pub use self::process_inner::{ExitStatus, ExitStatusError, Process}; pub use crate::ffi::OsString as EnvKey; pub use crate::sys_common::process::CommandEnvs; +#[cfg_attr(any(target_os = "espidf", target_os = "horizon"), allow(unused))] mod process_common; cfg_if::cfg_if! { @@ -13,7 +14,7 @@ cfg_if::cfg_if! { } else if #[cfg(target_os = "vxworks")] { #[path = "process_vxworks.rs"] mod process_inner; - } else if #[cfg(target_os = "espidf")] { + } else if #[cfg(any(target_os = "espidf", target_os = "horizon"))] { #[path = "process_unsupported.rs"] mod process_inner; } else { diff --git a/library/std/src/sys/unix/process/process_unsupported.rs b/library/std/src/sys/unix/process/process_unsupported.rs index 5db57ee9e9e..72f9f3f9ca7 100644 --- a/library/std/src/sys/unix/process/process_unsupported.rs +++ b/library/std/src/sys/unix/process/process_unsupported.rs @@ -1,10 +1,6 @@ use crate::fmt; use crate::io; -use crate::io::ErrorKind; use crate::num::NonZeroI32; -use crate::sys; -use crate::sys::cvt; -use crate::sys::pipe::AnonPipe; use crate::sys::process::process_common::*; use crate::sys::unix::unsupported::*; use core::ffi::NonZero_c_int; @@ -18,13 +14,13 @@ use libc::{c_int, pid_t}; impl Command { pub fn spawn( &mut self, - default: Stdio, - needs_stdin: bool, + _default: Stdio, + _needs_stdin: bool, ) -> io::Result<(Process, StdioPipes)> { unsupported() } - pub fn exec(&mut self, default: Stdio) -> io::Error { + pub fn exec(&mut self, _default: Stdio) -> io::Error { unsupported_err() } } @@ -34,7 +30,7 @@ impl Command { //////////////////////////////////////////////////////////////////////////////// pub struct Process { - handle: pid_t, + _handle: pid_t, } impl Process { @@ -59,6 +55,7 @@ impl Process { pub struct ExitStatus(c_int); impl ExitStatus { + #[cfg_attr(target_os = "horizon", allow(unused))] pub fn success(&self) -> bool { self.code() == Some(0) } diff --git a/library/std/src/sys/unix/rand.rs b/library/std/src/sys/unix/rand.rs index ea6df724713..56d01074c20 100644 --- a/library/std/src/sys/unix/rand.rs +++ b/library/std/src/sys/unix/rand.rs @@ -59,17 +59,27 @@ mod imp { unsafe { getrandom(buf.as_mut_ptr().cast(), buf.len(), libc::GRND_NONBLOCK) } } - #[cfg(target_os = "espidf")] + #[cfg(any(target_os = "espidf", target_os = "horizon"))] fn getrandom(buf: &mut [u8]) -> libc::ssize_t { unsafe { libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) } } - #[cfg(not(any(target_os = "linux", target_os = "android", target_os = "espidf")))] + #[cfg(not(any( + target_os = "linux", + target_os = "android", + target_os = "espidf", + target_os = "horizon" + )))] fn getrandom_fill_bytes(_buf: &mut [u8]) -> bool { false } - #[cfg(any(target_os = "linux", target_os = "android", target_os = "espidf"))] + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "espidf", + target_os = "horizon" + ))] fn getrandom_fill_bytes(v: &mut [u8]) -> bool { use crate::sync::atomic::{AtomicBool, Ordering}; use crate::sys::os::errno; diff --git a/library/std/src/sys/unix/thread_local_dtor.rs b/library/std/src/sys/unix/thread_local_dtor.rs index c3f410353b9..6e8be2a91de 100644 --- a/library/std/src/sys/unix/thread_local_dtor.rs +++ b/library/std/src/sys/unix/thread_local_dtor.rs @@ -93,7 +93,7 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { } } -#[cfg(target_os = "vxworks")] +#[cfg(any(target_os = "vxworks", target_os = "horizon"))] pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { use crate::sys_common::thread_local_dtor::register_dtor_fallback; register_dtor_fallback(t, dtor); diff --git a/library/std/src/sys/unix/thread_parker.rs b/library/std/src/sys/unix/thread_parker.rs index 30ed2ec7f54..76278ae30f1 100644 --- a/library/std/src/sys/unix/thread_parker.rs +++ b/library/std/src/sys/unix/thread_parker.rs @@ -115,7 +115,7 @@ impl Parker { target_os = "redox" ))] { addr_of_mut!((*parker).cvar).write(UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER)); - } else if #[cfg(target_os = "espidf")] { + } else if #[cfg(any(target_os = "espidf", target_os = "horizon"))] { let r = libc::pthread_cond_init(addr_of_mut!((*parker).cvar).cast(), crate::ptr::null()); assert_eq!(r, 0); } else { diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs index f99c453a3a8..d114af49d26 100644 --- a/library/std/src/sys/unix/time.rs +++ b/library/std/src/sys/unix/time.rs @@ -18,6 +18,7 @@ pub(in crate::sys::unix) struct Timespec { } impl SystemTime { + #[cfg_attr(target_os = "horizon", allow(unused))] pub fn new(tv_sec: i64, tv_nsec: i64) -> SystemTime { SystemTime { t: Timespec::new(tv_sec, tv_nsec) } } @@ -303,9 +304,9 @@ mod inner { } } - #[cfg(not(any(target_os = "dragonfly", target_os = "espidf")))] + #[cfg(not(any(target_os = "dragonfly", target_os = "espidf", target_os = "horizon")))] pub type clock_t = libc::c_int; - #[cfg(any(target_os = "dragonfly", target_os = "espidf"))] + #[cfg(any(target_os = "dragonfly", target_os = "espidf", target_os = "horizon"))] pub type clock_t = libc::c_ulong; impl Timespec { diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs index 05425f4a362..f5730a2cea5 100644 --- a/library/std/src/sys_common/net.rs +++ b/library/std/src/sys_common/net.rs @@ -398,8 +398,20 @@ impl TcpListener { let (addrp, len) = addr.into_inner(); cvt(unsafe { c::bind(sock.as_raw(), addrp, len as _) })?; + cfg_if::cfg_if! { + if #[cfg(target_os = "horizon")] { + // The 3DS doesn't support a big connection backlog. Sometimes + // it allows up to about 37, but other times it doesn't even + // accept 32. There may be a global limitation causing this. + let backlog = 20; + } else { + // The default for all other platforms + let backlog = 128; + } + } + // Start listening - cvt(unsafe { c::listen(sock.as_raw(), 128) })?; + cvt(unsafe { c::listen(sock.as_raw(), backlog) })?; Ok(TcpListener { inner: sock }) } |
