Skip to content

Commit

Permalink
Rollup merge of rust-lang#130595 - no1wudi:master, r=ibraheemdev
Browse files Browse the repository at this point in the history
Initial std library support for NuttX

This PR add the initial libstd support for NuttX platform (Tier 3), currently it depends on rust-lang/libc#3909 which provide the essential libc definitions.
  • Loading branch information
matthiaskrgr authored Sep 25, 2024
2 parents 508b433 + 24f622c commit 5b72787
Show file tree
Hide file tree
Showing 20 changed files with 225 additions and 22 deletions.
2 changes: 1 addition & 1 deletion library/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 library/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 library/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 library/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 library/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 library/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 library/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 library/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 library/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 library/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 library/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 library/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 @@ -425,7 +426,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 library/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 5b72787

Please sign in to comment.