From 4e808f87ccb706d339c9ea10c3c9a9c9fd7fc6cb Mon Sep 17 00:00:00 2001
From: Meziu <meziu210@icloud.com>
Date: Tue, 19 Oct 2021 17:59:59 +0200
Subject: [PATCH 1/9] Horizon OS STD support
Co-authored-by: Ian Chamberlain <ian.h.chamberlain@gmail.com>
Co-authored-by: Mark Drobnak <mark.drobnak@gmail.com>
---
library/core/src/ffi/mod.rs | 3 +-
library/std/build.rs | 1 +
library/std/src/os/horizon/fs.rs | 95 +++++++++++++++++++
library/std/src/os/horizon/mod.rs | 6 ++
library/std/src/os/horizon/raw.rs | 70 ++++++++++++++
library/std/src/os/mod.rs | 2 +
library/std/src/os/unix/mod.rs | 2 +
library/std/src/os/unix/process.rs | 30 +++---
library/std/src/sys/unix/alloc.rs | 3 +-
library/std/src/sys/unix/env.rs | 11 +++
library/std/src/sys/unix/fd.rs | 41 ++++----
library/std/src/sys/unix/fs.rs | 22 +++--
.../std/src/sys/unix/locks/pthread_condvar.rs | 11 ++-
library/std/src/sys/unix/mod.rs | 6 +-
library/std/src/sys/unix/os.rs | 8 +-
library/std/src/sys/unix/process/mod.rs | 3 +-
.../sys/unix/process/process_unsupported.rs | 13 +--
library/std/src/sys/unix/rand.rs | 16 +++-
library/std/src/sys/unix/thread_parker.rs | 2 +-
library/std/src/sys/unix/time.rs | 5 +-
library/std/src/sys_common/net.rs | 5 +
21 files changed, 288 insertions(+), 67 deletions(-)
create mode 100644 library/std/src/os/horizon/fs.rs
create mode 100644 library/std/src/os/horizon/mod.rs
create mode 100644 library/std/src/os/horizon/raw.rs
diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs
index a38b8fb739aec..93cdf121fbe0f 100644
--- a/library/core/src/ffi/mod.rs
+++ b/library/core/src/ffi/mod.rs
@@ -143,7 +143,8 @@ mod c_char_definition {
target_arch = "powerpc"
)
),
- all(target_os = "fuchsia", target_arch = "aarch64")
+ all(target_os = "fuchsia", target_arch = "aarch64"),
+ target_os = "horizon"
))] {
pub type c_char = u8;
pub type NonZero_c_char = crate::num::NonZeroU8;
diff --git a/library/std/build.rs b/library/std/build.rs
index 43168e77296ab..bffbe802fd01e 100644
--- a/library/std/build.rs
+++ b/library/std/build.rs
@@ -29,6 +29,7 @@ fn main() {
|| target.contains("asmjs")
|| target.contains("espidf")
|| target.contains("solid")
+ || target.contains("nintendo-3ds")
{
// These platforms don't have any special requirements.
} else {
diff --git a/library/std/src/os/horizon/fs.rs b/library/std/src/os/horizon/fs.rs
new file mode 100644
index 0000000000000..a5a06764a4dd8
--- /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_atime as i64
+ }
+ fn st_atime_nsec(&self) -> i64 {
+ 0
+ }
+ fn st_mtime(&self) -> i64 {
+ self.as_inner().as_inner().st_mtime as i64
+ }
+ fn st_mtime_nsec(&self) -> i64 {
+ 0
+ }
+ fn st_ctime(&self) -> i64 {
+ self.as_inner().as_inner().st_ctime as i64
+ }
+ fn st_ctime_nsec(&self) -> i64 {
+ 0
+ }
+ 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 0000000000000..326d0ae9cb96d
--- /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 0000000000000..929fa7db1f964
--- /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 029f131c40be0..a1df72a8a0480 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 7b8ca79eeb846..cef546487f327 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 9dca9b4a4a3f6..64fd6497463a8 100644
--- a/library/std/src/os/unix/process.rs
+++ b/library/std/src/os/unix/process.rs
@@ -24,8 +24,9 @@ pub trait CommandExt: Sealed {
#[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,
+ #[cfg(not(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon")))]
+ id: u32,
+ #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon"))] id: u16,
) -> &mut process::Command;
/// Similar to `uid`, but sets the group ID of the child process. This has
@@ -33,8 +34,9 @@ pub trait CommandExt: Sealed {
#[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,
+ #[cfg(not(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon")))]
+ id: u32,
+ #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon"))] id: u16,
) -> &mut process::Command;
/// Sets the supplementary group IDs for the calling process. Translates to
@@ -42,8 +44,9 @@ pub trait CommandExt: Sealed {
#[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],
+ #[cfg(not(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon")))] groups: &[u32],
+ #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon"))]
+ groups: &[u16],
) -> &mut process::Command;
/// Schedules a closure to be run just before the `exec` function is
@@ -160,8 +163,9 @@ pub trait CommandExt: Sealed {
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,
+ #[cfg(not(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon")))]
+ id: u32,
+ #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon"))] id: u16,
) -> &mut process::Command {
self.as_inner_mut().uid(id);
self
@@ -169,8 +173,9 @@ impl CommandExt for process::Command {
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,
+ #[cfg(not(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon")))]
+ id: u32,
+ #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon"))] id: u16,
) -> &mut process::Command {
self.as_inner_mut().gid(id);
self
@@ -178,8 +183,9 @@ impl CommandExt for process::Command {
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],
+ #[cfg(not(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon")))] groups: &[u32],
+ #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon"))]
+ groups: &[u16],
) -> &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 7c3d9573940ae..9d6567c9fb471 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/env.rs b/library/std/src/sys/unix/env.rs
index 60551aeb3e73e..4d8391656a4dd 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 40a6458580250..137ca3a763368 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 5d0fb07900326..4dda3c3f8133d 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! {
@@ -424,7 +429,7 @@ impl FileAttr {
Ok(SystemTime::new(self.stat.st_atime as i64, self.stat.st_atime_nsec as i64))
}
- #[cfg(any(target_os = "vxworks", target_os = "espidf"))]
+ #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon"))]
pub fn accessed(&self) -> io::Result<SystemTime> {
Ok(SystemTime::new(self.stat.st_atime as i64, 0))
}
@@ -707,7 +712,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 +1257,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 +1555,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 61c28d696bcaa..b4e480be80e9e 100644
--- a/library/std/src/sys/unix/locks/pthread_condvar.rs
+++ b/library/std/src/sys/unix/locks/pthread_condvar.rs
@@ -16,7 +16,11 @@ const TIMESPEC_MAX: libc::timespec =
libc::timespec { tv_sec: <libc::time_t>::MAX, tv_nsec: 1_000_000_000 - 1 };
fn saturating_cast_to_time_t(value: u64) -> libc::time_t {
- if value > <libc::time_t>::MAX as u64 { <libc::time_t>::MAX } else { value as libc::time_t }
+ if value > <libc::time_t>::MAX as u64 {
+ <libc::time_t>::MAX
+ } else {
+ value as libc::time_t
+ }
}
impl LazyInit for Condvar {
@@ -47,7 +51,7 @@ 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")]
+ #[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 +63,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;
diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs
index ddec60961f0ca..000eaff6a022a 100644
--- a/library/std/src/sys/unix/mod.rs
+++ b/library/std/src/sys/unix/mod.rs
@@ -43,10 +43,10 @@ pub mod thread_local_key;
pub mod thread_parker;
pub mod time;
-#[cfg(target_os = "espidf")]
+#[cfg(any(target_os = "espidf", target_os = "horizon"))]
pub fn init(argc: isize, argv: *const *const u8) {}
-#[cfg(not(target_os = "espidf"))]
+#[cfg(not(any(target_os = "espidf", target_os = "horizon")))]
// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
pub unsafe fn init(argc: isize, argv: *const *const u8) {
@@ -344,7 +344,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 92bea9346d8f8..7252ad321844b 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 0165ece849ee5..3701510f3a428 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 5db57ee9e9e18..72f9f3f9ca74c 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 ea6df7247137c..56d01074c20ed 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_parker.rs b/library/std/src/sys/unix/thread_parker.rs
index 30ed2ec7f5442..76278ae30f1af 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 f99c453a3a85b..d114af49d26c7 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 05425f4a3622c..7498e61d3d001 100644
--- a/library/std/src/sys_common/net.rs
+++ b/library/std/src/sys_common/net.rs
@@ -399,7 +399,12 @@ impl TcpListener {
cvt(unsafe { c::bind(sock.as_raw(), addrp, len as _) })?;
// Start listening
+ #[cfg(not(target_os = "horizon"))]
cvt(unsafe { c::listen(sock.as_raw(), 128) })?;
+ // 40 is the maximum for Horizon OS
+ #[cfg(target_os = "horizon")]
+ cvt(unsafe { c::listen(sock.as_raw(), 40) })?;
+
Ok(TcpListener { inner: sock })
}
From be8b88f2b6929a09e0f147cd1fa027298f19cc5b Mon Sep 17 00:00:00 2001
From: AzureMarker <mark.drobnak@gmail.com>
Date: Wed, 29 Dec 2021 17:53:55 -0500
Subject: [PATCH 2/9] Lower listen backlog to fix accept crashes
See https://github.com/Meziu/rust-horizon/pull/1
---
library/std/src/sys_common/net.rs | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs
index 7498e61d3d001..f5730a2cea52b 100644
--- a/library/std/src/sys_common/net.rs
+++ b/library/std/src/sys_common/net.rs
@@ -398,13 +398,20 @@ impl TcpListener {
let (addrp, len) = addr.into_inner();
cvt(unsafe { c::bind(sock.as_raw(), addrp, len as _) })?;
- // Start listening
- #[cfg(not(target_os = "horizon"))]
- cvt(unsafe { c::listen(sock.as_raw(), 128) })?;
- // 40 is the maximum for Horizon OS
- #[cfg(target_os = "horizon")]
- cvt(unsafe { c::listen(sock.as_raw(), 40) })?;
+ 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(), backlog) })?;
Ok(TcpListener { inner: sock })
}
From 06eae300347447545f5d0e8e94c673da69a1d7fd Mon Sep 17 00:00:00 2001
From: AzureMarker <mark.drobnak@gmail.com>
Date: Thu, 3 Feb 2022 19:29:20 -0800
Subject: [PATCH 3/9] Use the right wait_timeout implementation
Our condvar doesn't support setting attributes, like
pthread_condattr_setclock, which the current wait_timeout expects to
have configured.
Switch to a different implementation, following espidf.
---
library/std/src/sys/unix/locks/pthread_condvar.rs | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/library/std/src/sys/unix/locks/pthread_condvar.rs b/library/std/src/sys/unix/locks/pthread_condvar.rs
index b4e480be80e9e..78f10f0534c03 100644
--- a/library/std/src/sys/unix/locks/pthread_condvar.rs
+++ b/library/std/src/sys/unix/locks/pthread_condvar.rs
@@ -16,11 +16,7 @@ const TIMESPEC_MAX: libc::timespec =
libc::timespec { tv_sec: <libc::time_t>::MAX, tv_nsec: 1_000_000_000 - 1 };
fn saturating_cast_to_time_t(value: u64) -> libc::time_t {
- if value > <libc::time_t>::MAX as u64 {
- <libc::time_t>::MAX
- } else {
- value as libc::time_t
- }
+ if value > <libc::time_t>::MAX as u64 { <libc::time_t>::MAX } else { value as libc::time_t }
}
impl LazyInit for Condvar {
@@ -51,6 +47,8 @@ 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
+ //
+ // 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());
@@ -105,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;
@@ -137,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;
From 19f68a272912beaa68cb6c172e16ee6f21e96bf8 Mon Sep 17 00:00:00 2001
From: Ian Chamberlain <ian.h.chamberlain@gmail.com>
Date: Wed, 9 Feb 2022 23:54:38 -0500
Subject: [PATCH 4/9] Enable argv support for horizon OS
See https://github.com/Meziu/rust-horizon/pull/9
---
library/std/src/sys/unix/args.rs | 3 ++-
library/std/src/sys/unix/mod.rs | 8 +++++---
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/library/std/src/sys/unix/args.rs b/library/std/src/sys/unix/args.rs
index ee5e3983ac26a..79964e2b2385f 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/mod.rs b/library/std/src/sys/unix/mod.rs
index 000eaff6a022a..34a023b02c4fe 100644
--- a/library/std/src/sys/unix/mod.rs
+++ b/library/std/src/sys/unix/mod.rs
@@ -43,10 +43,10 @@ pub mod thread_local_key;
pub mod thread_parker;
pub mod time;
-#[cfg(any(target_os = "espidf", target_os = "horizon"))]
+#[cfg(target_os = "espidf")]
pub fn init(argc: isize, argv: *const *const u8) {}
-#[cfg(not(any(target_os = "espidf", target_os = "horizon")))]
+#[cfg(not(target_os = "espidf"))]
// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
pub unsafe fn init(argc: isize, argv: *const *const u8) {
@@ -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);
}
}
From a49d14f08914390f24fa0ba6401b5f1de91939fc Mon Sep 17 00:00:00 2001
From: Ian Chamberlain <ian.h.chamberlain@gmail.com>
Date: Mon, 14 Feb 2022 20:55:01 -0500
Subject: [PATCH 5/9] Update libc::stat field names
See https://github.com/Meziu/rust-horizon/pull/14
---
library/std/src/os/horizon/fs.rs | 12 ++++++------
library/std/src/sys/unix/fs.rs | 7 ++++++-
2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/library/std/src/os/horizon/fs.rs b/library/std/src/os/horizon/fs.rs
index a5a06764a4dd8..1325522105dc8 100644
--- a/library/std/src/os/horizon/fs.rs
+++ b/library/std/src/os/horizon/fs.rs
@@ -69,22 +69,22 @@ impl MetadataExt for Metadata {
self.as_inner().as_inner().st_size as u64
}
fn st_atime(&self) -> i64 {
- self.as_inner().as_inner().st_atime as i64
+ self.as_inner().as_inner().st_atim.tv_sec
}
fn st_atime_nsec(&self) -> i64 {
- 0
+ self.as_inner().as_inner().st_atim.tv_nsec as i64
}
fn st_mtime(&self) -> i64 {
- self.as_inner().as_inner().st_mtime as i64
+ self.as_inner().as_inner().st_mtim.tv_sec
}
fn st_mtime_nsec(&self) -> i64 {
- 0
+ self.as_inner().as_inner().st_mtim.tv_nsec as i64
}
fn st_ctime(&self) -> i64 {
- self.as_inner().as_inner().st_ctime as i64
+ self.as_inner().as_inner().st_ctim.tv_sec
}
fn st_ctime_nsec(&self) -> i64 {
- 0
+ 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
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index 4dda3c3f8133d..8b0bbd6a55c6b 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -429,11 +429,16 @@ impl FileAttr {
Ok(SystemTime::new(self.stat.st_atime as i64, self.stat.st_atime_nsec as i64))
}
- #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon"))]
+ #[cfg(any(target_os = "vxworks", target_os = "espidf"))]
pub fn accessed(&self) -> io::Result<SystemTime> {
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",
From 82e8cd4834fa5d5b9ca7de216d07d89f9c7addc2 Mon Sep 17 00:00:00 2001
From: Ian Chamberlain <ian.h.chamberlain@gmail.com>
Date: Wed, 16 Mar 2022 23:26:22 -0400
Subject: [PATCH 6/9] Add platform-support page for armv6k-nintendo-3ds
Co-authored-by: Mark Drobnak <mark.drobnak@gmail.com>
---
src/doc/rustc/src/SUMMARY.md | 1 +
src/doc/rustc/src/platform-support.md | 2 +-
.../platform-support/armv6k-nintendo-3ds.md | 130 ++++++++++++++++++
3 files changed, 132 insertions(+), 1 deletion(-)
create mode 100644 src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index e464564c12078..87dc513853968 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -17,6 +17,7 @@
- [Template for Target-specific Documentation](platform-support/TEMPLATE.md)
- [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md)
- [\*-apple-watchos\*](platform-support/apple-watchos.md)
+ - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md)
- [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md)
- [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md)
- [\*-kmc-solid_\*](platform-support/kmc-solid.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index ec93bdd3fd37f..eb985803266e7 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -226,7 +226,7 @@ target | std | host | notes
`armv5te-unknown-linux-uclibceabi` | ? | | ARMv5TE Linux with uClibc
`armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD
`armv6-unknown-netbsd-eabihf` | ? | |
-`armv6k-nintendo-3ds` | * | | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain)
+[`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain)
`armv7-apple-ios` | ✓ | | ARMv7 iOS, Cortex-a8
[`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | ARMv7 Linux with uClibc, softfloat
[`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | ARMv7 Linux with uClibc, hardfloat
diff --git a/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md b/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md
new file mode 100644
index 0000000000000..215290e389843
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md
@@ -0,0 +1,130 @@
+# `armv6k-nintendo-3ds`
+
+**Tier: 3**
+
+The Nintendo 3DS platform, which has an ARMv6K processor, and its associated
+operating system (`horizon`).
+
+Rust support for this target is not affiliated with Nintendo, and is not derived
+from nor used with any official Nintendo SDK.
+
+## Target maintainers
+
+- [@Meziu](https://github.com/Meziu)
+- [@AzureMarker](https://github.com/AzureMarker)
+- [@ian-h-chamberlain](https://github.com/ian-h-chamberlain)
+
+## Requirements
+
+This target is cross-compiled. Dynamic linking is not supported.
+
+`#![no_std]` crates can be built using `build-std` to build `core` and optionally
+`alloc`, and either `panic_abort` or `panic_unwind`.
+
+`std` is partially supported, but mostly works. Some APIs are unimplemented
+and will simply return an error, such as `std::process`. An allocator is provided
+by default.
+
+In order to support some APIs, binaries must be linked against `libc` written
+for the target, using a linker for the target. These are provided by the
+devkitARM toolchain. See
+[Cross-compilation toolchains and C code](#cross-compilation-toolchains-and-c-code)
+for more details.
+
+Additionally, some helper crates provide implementations of some `libc` functions
+use by `std` that may otherwise be missing. These, or an alternate implementation
+of the relevant functions, are required to use `std`:
+
+- [`pthread-3ds`](https://github.com/Meziu/pthread-3ds) provides pthread APIs for `std::thread`.
+- [`linker-fix-3ds`](https://github.com/Meziu/rust-linker-fix-3ds) fulfills some other missing libc APIs.
+
+Binaries built for this target should be compatible with all variants of the
+3DS (and 2DS) hardware and firmware, but testing is limited and some versions may
+not work correctly.
+
+This target generates binaries in the ELF format.
+
+## Building the target
+
+You can build Rust with support for the target by adding it to the `target`
+list in `config.toml` and providing paths to the devkitARM toolchain.
+
+```toml
+[build]
+build-stage = 1
+target = ["armv6k-nintendo-3ds"]
+
+[target.armv6k-nintendo-3ds]
+cc = "/opt/devkitpro/devkitARM/bin/arm-none-eabi-gcc"
+cxx = "/opt/devkitpro/devkitARM/bin/arm-none-eabi-g++"
+ar = "/opt/devkitpro/devkitARM/bin/arm-none-eabi-ar"
+ranlib = "/opt/devkitpro/devkitARM/bin/arm-none-eabi-ranlib"
+linker = "/opt/devkitpro/devkitARM/bin/arm-none-eabi-gcc"
+```
+
+Also, to build `compiler_builtins` for the target, export these flags before
+building the Rust toolchain:
+
+```sh
+export CFLAGS_armv6k_nintendo_3ds="-mfloat-abi=hard -mtune=mpcore -mtp=soft -march=armv6k"
+```
+
+## Building Rust programs
+
+Rust does not yet ship pre-compiled artifacts for this target.
+
+The recommended way to build binaries is by using the
+[cargo-3ds](https://github.com/Meziu/cargo-3ds) tool, which uses `build-std`
+and provides commands that work like the usual `cargo run`, `cargo build`, etc.
+
+You can also build Rust with the target enabled (see
+[Building the target](#building-the-target) above).
+
+As mentioned in [Requirements](#requirements), programs that use `std` must link
+against both the devkitARM toolchain and libraries providing the `libc` APIs used
+in `std`. There is a general-purpose utility crate for working with nonstandard
+APIs provided by the OS: [`ctru-rs`](https://github.com/Meziu/ctru-rs).
+Add it to Cargo.toml to use it in your program:
+
+```toml
+[dependencies]
+ctru-rs = { git = "https://github.com/Meziu/ctru-rs.git" }
+```
+
+Using this library's `init()` function ensures the symbols needed to link
+against `std` are present (as mentioned in [Requirements](#requirements)
+above), as well as providing a runtime suitable for `std`:
+
+```rust,ignore (requires-3rd-party-library)
+fn main() {
+ ctru::init();
+}
+```
+
+## Testing
+
+Binaries built for this target can be run in an emulator (most commonly
+[Citra](https://citra-emu.org/)), or sent to a device through
+the use of a tool like devkitARM's `3dslink`. They may also simply be copied
+to an SD card to be inserted in the device.
+
+The `cargo-3ds` tool mentioned in [Building Rust programs](#building-rust-programs)
+supports the use of `3dslink` with `cargo 3ds run`. The default Rust test runner
+is not supported, but
+[custom test frameworks](https://doc.rust-lang.org/beta/unstable-book/language-features/custom-test-frameworks.html)
+can be used with `cargo 3ds test` to run unit tests on a device.
+
+The Rust test suite for `library/std` is not yet supported.
+
+## Cross-compilation toolchains and C code
+
+C code can be built for this target using the
+[devkitARM toolchain](https://devkitpro.org/wiki/Getting_Started).
+This toolchain provides `arm-none-eabi-gcc` as the linker used to link Rust
+programs as well.
+
+The toolchain also provides a `libc` implementation, which is required by `std`
+for many of its APIs, and a helper library `libctru` which is used by several
+of the helper crates listed in [Requirements](#requirements).
+This toolchain does not, however, include all of the APIs expected by `std`,
+and the remaining APIs are implemented by `pthread-3ds` and `linker-fix-3ds`.
From bc63d5a26a65752fb105957d3235cc9c8cb0767f Mon Sep 17 00:00:00 2001
From: Ian Chamberlain <ian.h.chamberlain@gmail.com>
Date: Wed, 23 Mar 2022 21:00:38 -0400
Subject: [PATCH 7/9] Enable thread_local_dtor on horizon OS
Always use fallback thread_local destructor, since __cxa_thread_atexit_impl
is never defined on the target.
See https://github.com/AzureMarker/rust-horizon/pull/2
---
library/std/src/sys/unix/thread_local_dtor.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/library/std/src/sys/unix/thread_local_dtor.rs b/library/std/src/sys/unix/thread_local_dtor.rs
index c3f410353b915..6e8be2a91de00 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);
From 5d5039e1b80862b4561a5199d57053f1ef027035 Mon Sep 17 00:00:00 2001
From: Mark Drobnak <mark.drobnak@gmail.com>
Date: Sat, 21 May 2022 17:11:48 -0700
Subject: [PATCH 8/9] Disable `has_thread_local` due to weird issues in some
programs
For example, in the following issue the `thread_info` thread-local is
not correctly initialized in debug builds:
https://github.com/Meziu/ctru-rs/issues/60
---
compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs b/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs
index ffcd1a3f4df75..67df73fa93591 100644
--- a/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs
+++ b/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs
@@ -37,7 +37,8 @@ pub fn target() -> Target {
pre_link_args,
exe_suffix: ".elf".into(),
no_default_libraries: false,
- has_thread_local: true,
+ // There are some issues in debug builds with this enabled in certain programs.
+ has_thread_local: false,
..Default::default()
},
}
From c814f842e46de25c95e08551a29f06ede1880a47 Mon Sep 17 00:00:00 2001
From: Mark Drobnak <mark.drobnak@gmail.com>
Date: Tue, 7 Jun 2022 19:57:15 -0700
Subject: [PATCH 9/9] Use a private type definition to reduce cfg noise
I checked with t-libs to make sure this is OK to do on stable functions:
https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Replacing.20std.20function.20arg.20type.20with.20private.20type.20def.3F
---
library/std/src/os/unix/process.rs | 52 +++++++++---------------------
1 file changed, 16 insertions(+), 36 deletions(-)
diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs
index 64fd6497463a8..df33976098fb4 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,32 +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", target_os = "horizon")))]
- id: u32,
- #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon"))] 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", target_os = "horizon")))]
- id: u32,
- #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon"))] 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", target_os = "horizon")))] groups: &[u32],
- #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon"))]
- 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.
@@ -161,32 +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", target_os = "horizon")))]
- id: u32,
- #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon"))] 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", target_os = "horizon")))]
- id: u32,
- #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon"))] 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", target_os = "horizon")))] groups: &[u32],
- #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "horizon"))]
- groups: &[u16],
- ) -> &mut process::Command {
+ fn groups(&mut self, groups: &[GroupId]) -> &mut process::Command {
self.as_inner_mut().groups(groups);
self
}