Skip to content

Commit

Permalink
Initial std library support for NuttX
Browse files Browse the repository at this point in the history
Signed-off-by: Huang Qi <[email protected]>
  • Loading branch information
no1wudi committed Sep 24, 2024
1 parent bab810c commit c47920f
Show file tree
Hide file tree
Showing 20 changed files with 225 additions and 22 deletions.
2 changes: 1 addition & 1 deletion panic_unwind/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ cfg_if::cfg_if! {
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",
))] {
Expand Down
1 change: 1 addition & 0 deletions std/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
2 changes: 2 additions & 0 deletions std/src/os/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ pub mod macos;
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")]
Expand Down
92 changes: 92 additions & 0 deletions std/src/os/nuttx/fs.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
4 changes: 4 additions & 0 deletions std/src/os/nuttx/mod.rs
Original file line number Diff line number Diff line change
@@ -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;
33 changes: 33 additions & 0 deletions std/src/os/nuttx/raw.rs
Original file line number Diff line number Diff line change
@@ -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;
2 changes: 2 additions & 0 deletions std/src/os/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down
1 change: 1 addition & 0 deletions std/src/sys/pal/unix/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ impl DoubleEndedIterator for Args {
target_os = "nto",
target_os = "hurd",
target_os = "rtems",
target_os = "nuttx",
))]
mod imp {
use crate::ffi::c_char;
Expand Down
11 changes: 11 additions & 0 deletions std/src/sys/pal/unix/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "";
}
42 changes: 36 additions & 6 deletions std/src/sys/pal/unix/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,12 @@ impl FileDesc {
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(
Expand All @@ -110,14 +115,24 @@ impl FileDesc {
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> {
Expand Down Expand Up @@ -297,7 +312,12 @@ impl FileDesc {
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(
Expand All @@ -309,14 +329,24 @@ impl FileDesc {
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))]
Expand Down
19 changes: 15 additions & 4 deletions std/src/sys/pal/unix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand All @@ -501,7 +502,7 @@ impl FileAttr {
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)
}
Expand All @@ -513,6 +514,7 @@ impl FileAttr {
target_os = "vita",
target_os = "hurd",
target_os = "rtems",
target_os = "nuttx",
)))]
pub fn accessed(&self) -> io::Result<SystemTime> {
#[cfg(target_pointer_width = "32")]
Expand All @@ -535,7 +537,7 @@ impl FileAttr {
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)
}
Expand Down Expand Up @@ -866,6 +868,7 @@ impl Drop for Dir {
target_os = "horizon",
target_os = "vxworks",
target_os = "rtems",
target_os = "nuttx",
)))]
{
let fd = unsafe { libc::dirfd(self.0) };
Expand Down Expand Up @@ -1000,6 +1003,13 @@ impl DirEntry {
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",
Expand Down Expand Up @@ -1327,7 +1337,8 @@ impl File {
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),
Expand All @@ -1342,7 +1353,7 @@ impl File {
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.
Expand Down
3 changes: 2 additions & 1 deletion std/src/sys/pal/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ static ON_BROKEN_PIPE_FLAG_USED: crate::sync::atomic::AtomicBool =
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)
Expand Down Expand Up @@ -424,7 +425,7 @@ cfg_if::cfg_if! {
}
}

#[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;

Expand Down
6 changes: 3 additions & 3 deletions std/src/sys/pal/unix/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Loading

0 comments on commit c47920f

Please sign in to comment.