Initial std library support for NuttX

Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
This commit is contained in:
Huang Qi 2024-09-19 16:00:56 +08:00
parent f5cd2c5888
commit 24f622cf80
20 changed files with 225 additions and 22 deletions

View File

@ -48,7 +48,7 @@
target_os = "psp",
target_os = "xous",
target_os = "solid_asp3",
all(target_family = "unix", not(any(target_os = "espidf", target_os = "rtems"))),
all(target_family = "unix", not(any(target_os = "espidf", target_os = "rtems", target_os = "nuttx"))),
all(target_vendor = "fortanix", target_env = "sgx"),
target_family = "wasm",
))] {

View File

@ -54,6 +54,7 @@ fn main() {
|| target_os == "teeos"
|| target_os == "zkvm"
|| target_os == "rtems"
|| target_os == "nuttx"
// See src/bootstrap/src/core/build_steps/synthetic_targets.rs
|| env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()

View File

@ -139,6 +139,8 @@ pub mod windows {}
pub mod netbsd;
#[cfg(target_os = "nto")]
pub mod nto;
#[cfg(target_os = "nuttx")]
pub mod nuttx;
#[cfg(target_os = "openbsd")]
pub mod openbsd;
#[cfg(target_os = "redox")]

View File

@ -0,0 +1,92 @@
#![stable(feature = "metadata_ext", since = "1.1.0")]
use crate::fs::Metadata;
use crate::sys_common::AsInner;
#[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_ext", since = "1.1.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 as i64
}
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 as i64
}
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 as i64
}
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
}
}

View File

@ -0,0 +1,4 @@
#![stable(feature = "raw_ext", since = "1.1.0")]
#![forbid(unsafe_op_in_unsafe_fn)]
pub mod fs;
pub(crate) mod raw;

View File

@ -0,0 +1,33 @@
//! rtems 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)]
#[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;

View File

@ -69,6 +69,8 @@ mod platform {
pub use crate::os::netbsd::*;
#[cfg(target_os = "nto")]
pub use crate::os::nto::*;
#[cfg(target_os = "nuttx")]
pub use crate::os::nuttx::*;
#[cfg(target_os = "openbsd")]
pub use crate::os::openbsd::*;
#[cfg(target_os = "redox")]

View File

@ -113,6 +113,7 @@ fn next_back(&mut self) -> Option<OsString> {
target_os = "nto",
target_os = "hurd",
target_os = "rtems",
target_os = "nuttx",
))]
mod imp {
use crate::ffi::c_char;

View File

@ -283,3 +283,14 @@ pub mod os {
pub const EXE_SUFFIX: &str = "";
pub const EXE_EXTENSION: &str = "";
}
#[cfg(target_os = "nuttx")]
pub mod os {
pub const FAMILY: &str = "unix";
pub const OS: &str = "nuttx";
pub const DLL_PREFIX: &str = "lib";
pub const DLL_SUFFIX: &str = ".so";
pub const DLL_EXTENSION: &str = "so";
pub const EXE_SUFFIX: &str = "";
pub const EXE_EXTENSION: &str = "";
}

View File

@ -98,7 +98,12 @@ pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
Ok(ret as usize)
}
#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))]
#[cfg(not(any(
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nuttx"
)))]
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
let ret = cvt(unsafe {
libc::readv(
@ -110,14 +115,24 @@ pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
Ok(ret as usize)
}
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))]
#[cfg(any(
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nuttx"
))]
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
io::default_read_vectored(|b| self.read(b), bufs)
}
#[inline]
pub fn is_read_vectored(&self) -> bool {
cfg!(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))
cfg!(not(any(
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nuttx"
)))
}
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
@ -297,7 +312,12 @@ pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
Ok(ret as usize)
}
#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))]
#[cfg(not(any(
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nuttx"
)))]
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
let ret = cvt(unsafe {
libc::writev(
@ -309,14 +329,24 @@ pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
Ok(ret as usize)
}
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))]
#[cfg(any(
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nuttx"
))]
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
io::default_write_vectored(|b| self.write(b), bufs)
}
#[inline]
pub fn is_write_vectored(&self) -> bool {
cfg!(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))
cfg!(not(any(
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nuttx"
)))
}
#[cfg_attr(target_os = "vxworks", allow(unused_unsafe))]

View File

@ -479,6 +479,7 @@ impl FileAttr {
target_os = "vita",
target_os = "hurd",
target_os = "rtems",
target_os = "nuttx",
)))]
pub fn modified(&self) -> io::Result<SystemTime> {
#[cfg(target_pointer_width = "32")]
@ -501,7 +502,7 @@ pub fn modified(&self) -> io::Result<SystemTime> {
SystemTime::new(self.stat.st_mtime as i64, 0)
}
#[cfg(any(target_os = "horizon", target_os = "hurd"))]
#[cfg(any(target_os = "horizon", target_os = "hurd", target_os = "nuttx"))]
pub fn modified(&self) -> io::Result<SystemTime> {
SystemTime::new(self.stat.st_mtim.tv_sec as i64, self.stat.st_mtim.tv_nsec as i64)
}
@ -513,6 +514,7 @@ pub fn modified(&self) -> io::Result<SystemTime> {
target_os = "vita",
target_os = "hurd",
target_os = "rtems",
target_os = "nuttx",
)))]
pub fn accessed(&self) -> io::Result<SystemTime> {
#[cfg(target_pointer_width = "32")]
@ -535,7 +537,7 @@ pub fn accessed(&self) -> io::Result<SystemTime> {
SystemTime::new(self.stat.st_atime as i64, 0)
}
#[cfg(any(target_os = "horizon", target_os = "hurd"))]
#[cfg(any(target_os = "horizon", target_os = "hurd", target_os = "nuttx"))]
pub fn accessed(&self) -> io::Result<SystemTime> {
SystemTime::new(self.stat.st_atim.tv_sec as i64, self.stat.st_atim.tv_nsec as i64)
}
@ -866,6 +868,7 @@ fn drop(&mut self) {
target_os = "horizon",
target_os = "vxworks",
target_os = "rtems",
target_os = "nuttx",
)))]
{
let fd = unsafe { libc::dirfd(self.0) };
@ -1000,6 +1003,13 @@ pub fn ino(&self) -> u64 {
self.entry.d_fileno as u64
}
#[cfg(target_os = "nuttx")]
pub fn ino(&self) -> u64 {
// Leave this 0 for now, as NuttX does not provide an inode number
// in its directory entries.
0
}
#[cfg(any(
target_os = "netbsd",
target_os = "openbsd",
@ -1327,7 +1337,8 @@ pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
target_os = "redox",
target_os = "espidf",
target_os = "horizon",
target_os = "vxworks"
target_os = "vxworks",
target_os = "nuttx",
)))]
let to_timespec = |time: Option<SystemTime>| match time {
Some(time) if let Some(ts) = time.t.to_timespec() => Ok(ts),
@ -1342,7 +1353,7 @@ pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }),
};
cfg_if::cfg_if! {
if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "vxworks"))] {
if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "vxworks", target_os = "nuttx"))] {
// 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
// the same as for Redox.

View File

@ -222,6 +222,7 @@ mod sigpipe {
target_os = "horizon",
target_os = "vxworks",
target_os = "vita",
target_os = "nuttx",
)))]
pub(crate) fn on_broken_pipe_flag_used() -> bool {
ON_BROKEN_PIPE_FLAG_USED.load(crate::sync::atomic::Ordering::Relaxed)
@ -424,7 +425,7 @@ pub fn abort_internal() -> ! {
}
}
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))]
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))]
mod unsupported {
use crate::io;

View File

@ -38,19 +38,19 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
// We may need to trigger a glibc workaround. See on_resolver_failure() for details.
on_resolver_failure();
#[cfg(not(target_os = "espidf"))]
#[cfg(not(any(target_os = "espidf", target_os = "nuttx")))]
if err == libc::EAI_SYSTEM {
return Err(io::Error::last_os_error());
}
#[cfg(not(target_os = "espidf"))]
#[cfg(not(any(target_os = "espidf", target_os = "nuttx")))]
let detail = unsafe {
// We can't always expect a UTF-8 environment. When we don't get that luxury,
// it's better to give a low-quality error message than none at all.
CStr::from_ptr(libc::gai_strerror(err)).to_string_lossy()
};
#[cfg(target_os = "espidf")]
#[cfg(any(target_os = "espidf", target_os = "nuttx"))]
let detail = "";
Err(io::Error::new(

View File

@ -48,6 +48,7 @@
target_os = "openbsd",
target_os = "android",
target_os = "redox",
target_os = "nuttx",
target_env = "newlib"
),
link_name = "__errno"
@ -399,6 +400,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
target_os = "linux",
target_os = "hurd",
target_os = "android",
target_os = "nuttx",
target_os = "emscripten"
))]
pub fn current_exe() -> io::Result<PathBuf> {
@ -717,6 +719,7 @@ pub fn home_dir() -> Option<PathBuf> {
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nuttx",
all(target_vendor = "apple", not(target_os = "macos")),
))]
unsafe fn fallback() -> Option<OsString> {
@ -730,6 +733,7 @@ unsafe fn fallback() -> Option<OsString> {
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nuttx",
all(target_vendor = "apple", not(target_os = "macos")),
)))]
unsafe fn fallback() -> Option<OsString> {

View File

@ -2,10 +2,10 @@
pub use self::process_inner::{ExitStatus, ExitStatusError, Process};
pub use crate::ffi::OsString as EnvKey;
#[cfg_attr(any(target_os = "espidf", target_os = "horizon"), allow(unused))]
#[cfg_attr(any(target_os = "espidf", target_os = "horizon", target_os = "nuttx"), allow(unused))]
mod process_common;
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))]
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))]
mod process_unsupported;
cfg_if::cfg_if! {
@ -16,7 +16,7 @@
} else if #[cfg(target_os = "vxworks")] {
#[path = "process_vxworks.rs"]
mod process_inner;
} else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))] {
} else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] {
mod process_inner {
pub use super::process_unsupported::*;
}

View File

@ -140,7 +140,12 @@ pub fn set_name(name: &CStr) {
}
}
#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))]
#[cfg(any(
target_os = "freebsd",
target_os = "dragonfly",
target_os = "openbsd",
target_os = "nuttx"
))]
pub fn set_name(name: &CStr) {
unsafe {
libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr());
@ -747,12 +752,15 @@ unsafe fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
}
// No point in looking up __pthread_get_minstack() on non-glibc platforms.
#[cfg(all(not(all(target_os = "linux", target_env = "gnu")), not(target_os = "netbsd")))]
#[cfg(all(
not(all(target_os = "linux", target_env = "gnu")),
not(any(target_os = "netbsd", target_os = "nuttx"))
))]
unsafe fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
libc::PTHREAD_STACK_MIN
}
#[cfg(target_os = "netbsd")]
#[cfg(any(target_os = "netbsd", target_os = "nuttx"))]
unsafe fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
static STACK: crate::sync::OnceLock<usize> = crate::sync::OnceLock::new();

View File

@ -31,7 +31,7 @@ fn rust_eh_personality() {
target_os = "psp",
target_os = "xous",
target_os = "solid_asp3",
all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re"), not(target_os = "rtems")),
all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re"), not(target_os = "rtems"), not(target_os = "nuttx")),
all(target_vendor = "fortanix", target_env = "sgx"),
))] {
mod gcc;

View File

@ -42,6 +42,7 @@
target_os = "hurd",
target_os = "l4re",
target_os = "nto",
target_os = "nuttx",
))] {
mod unix_legacy;
pub use unix_legacy::fill_bytes;

View File

@ -21,6 +21,7 @@
target_os = "haiku",
target_os = "l4re",
target_os = "nto",
target_os = "nuttx",
target_vendor = "apple",
))] {
use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP;

View File

@ -23,6 +23,7 @@
target_os = "none",
target_os = "espidf",
target_os = "rtems",
target_os = "nuttx",
))] {
// These "unix" family members do not have unwinder.
} else if #[cfg(any(