Skip to content

Commit

Permalink
Auto merge of #2714 - AzureMarker:horizon-getrandom-and-fixes, r=Amanieu
Browse files Browse the repository at this point in the history
Horizon (Nintendo 3DS) getrandom function and fixes

This PR adds `getrandom`, conforming to the [Linux spec](https://man7.org/linux/man-pages/man2/getrandom.2.html), to the `horizon` OS (Nintendo 3DS).

The 3DS doesn't have a full libc implementation, and its randomness API is pretty complicated: rust-random/getrandom#248. For this reason (see the linked PR for more details), the randomness implementation is abstracted by using the Linux `getrandom` interface.

This PR also fixes some types on the horizon platform. See the commits and diff.

cc: `@ian-h-chamberlain` `@Meziu`
  • Loading branch information
bors committed Mar 14, 2022
2 parents 55cc85f + f25ae98 commit 1a31128
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 33 deletions.
11 changes: 6 additions & 5 deletions src/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,20 @@ pub type uintptr_t = usize;
pub type ssize_t = isize;

pub type pid_t = i32;
pub type in_addr_t = u32;
pub type in_port_t = u16;
pub type sighandler_t = ::size_t;
pub type cc_t = ::c_uchar;

cfg_if! {
if #[cfg(target_os = "espidf")] {
if #[cfg(any(target_os = "espidf", target_os = "horizon"))] {
pub type uid_t = ::c_ushort;
pub type gid_t = ::c_ushort;
} else {
pub type uid_t = u32;
pub type gid_t = u32;
}
}
pub type in_addr_t = u32;
pub type in_port_t = u16;
pub type sighandler_t = ::size_t;
pub type cc_t = ::c_uchar;

#[cfg_attr(feature = "extra_traits", derive(Debug))]
pub enum DIR {}
Expand Down
2 changes: 2 additions & 0 deletions src/unix/newlib/aarch64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,5 @@ pub const MSG_DONTROUTE: ::c_int = 0;
pub const MSG_WAITALL: ::c_int = 0;
pub const MSG_MORE: ::c_int = 0;
pub const MSG_NOSIGNAL: ::c_int = 0;

pub use crate::unix::newlib::generic::{sigset_t, stat};
2 changes: 2 additions & 0 deletions src/unix/newlib/arm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,5 @@ pub const MSG_DONTROUTE: ::c_int = 0;
pub const MSG_WAITALL: ::c_int = 0;
pub const MSG_MORE: ::c_int = 0;
pub const MSG_NOSIGNAL: ::c_int = 0;

pub use crate::unix::newlib::generic::{sigset_t, stat};
2 changes: 2 additions & 0 deletions src/unix/newlib/espidf/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,5 @@ extern "C" {
#[link_name = "lwip_recvmsg"]
pub fn recvmsg(s: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t;
}

pub use crate::unix::newlib::generic::{sigset_t, stat};
27 changes: 27 additions & 0 deletions src/unix/newlib/generic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//! Common types used by most newlib platforms

s! {
pub struct sigset_t {
__val: [::c_ulong; 16],
}

pub struct stat {
pub st_dev: ::dev_t,
pub st_ino: ::ino_t,
pub st_mode: ::mode_t,
pub st_nlink: ::nlink_t,
pub st_uid: ::uid_t,
pub st_gid: ::gid_t,
pub st_rdev: ::dev_t,
pub st_size: ::off_t,
pub st_atime: ::time_t,
pub st_spare1: ::c_long,
pub st_mtime: ::time_t,
pub st_spare2: ::c_long,
pub st_ctime: ::time_t,
pub st_spare3: ::c_long,
pub st_blksize: ::blksize_t,
pub st_blocks: ::blkcnt_t,
pub st_spare4: [::c_long; 2usize],
}
}
29 changes: 26 additions & 3 deletions src/unix/newlib/horizon/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ pub type c_ulong = u32;

pub type wchar_t = ::c_uint;

pub type in_port_t = ::c_ushort;
pub type u_register_t = ::c_uint;
pub type u_char = ::c_uchar;
pub type u_short = ::c_ushort;
Expand All @@ -19,8 +18,8 @@ pub type clock_t = c_ulong;
pub type daddr_t = c_long;
pub type caddr_t = *mut c_char;
pub type sbintime_t = ::c_longlong;
pub type sigset_t = ::c_ulong;

// External implementations are needed to use networking and threading.
s! {
pub struct sockaddr {
pub sa_family: ::sa_family_t,
Expand All @@ -34,8 +33,9 @@ s! {

pub struct sockaddr_in {
pub sin_family: ::sa_family_t,
pub sin_port: in_port_t,
pub sin_port: ::in_port_t,
pub sin_addr: ::in_addr,
pub sin_zero: [::c_uchar; 8],
}

pub struct sockaddr_in6 {
Expand All @@ -55,6 +55,23 @@ s! {
pub struct sched_param {
pub sched_priority: ::c_int,
}

pub struct stat {
pub st_dev: ::dev_t,
pub st_ino: ::ino_t,
pub st_mode: ::mode_t,
pub st_nlink: ::nlink_t,
pub st_uid: ::uid_t,
pub st_gid: ::gid_t,
pub st_rdev: ::dev_t,
pub st_size: ::off_t,
pub st_atim: ::timespec,
pub st_mtim: ::timespec,
pub st_ctim: ::timespec,
pub st_blksize: ::blksize_t,
pub st_blocks: ::blkcnt_t,
pub st_spare4: [::c_long; 2usize],
}
}

pub const SIGEV_NONE: ::c_int = 1;
Expand Down Expand Up @@ -155,6 +172,10 @@ pub const RTLD_DEFAULT: *mut ::c_void = 0 as *mut ::c_void;
pub const SCHED_FIFO: ::c_int = 1;
pub const SCHED_RR: ::c_int = 2;

// For getrandom()
pub const GRND_NONBLOCK: ::c_uint = 0x1;
pub const GRND_RANDOM: ::c_uint = 0x2;

// Horizon OS works doesn't or can't hold any of this information
safe_f! {
pub {const} fn WIFSTOPPED(_status: ::c_int) -> bool {
Expand Down Expand Up @@ -232,5 +253,7 @@ extern "C" {

pub fn pthread_getprocessorid_np() -> ::c_int;

pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t;

pub fn gethostid() -> ::c_long;
}
35 changes: 10 additions & 25 deletions src/unix/newlib/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,26 +139,6 @@ s! {
pub tm_isdst: ::c_int,
}

pub struct stat {
pub st_dev: ::dev_t,
pub st_ino: ::ino_t,
pub st_mode: ::mode_t,
pub st_nlink: ::nlink_t,
pub st_uid: ::uid_t,
pub st_gid: ::gid_t,
pub st_rdev: dev_t,
pub st_size: off_t,
pub st_atime: time_t,
pub st_spare1: ::c_long,
pub st_mtime: time_t,
pub st_spare2: ::c_long,
pub st_ctime: time_t,
pub st_spare3: ::c_long,
pub st_blksize: blksize_t,
pub st_blocks: blkcnt_t,
pub st_spare4: [::c_long; 2usize],
}

pub struct statvfs {
pub f_bsize: ::c_ulong,
pub f_frsize: ::c_ulong,
Expand All @@ -173,10 +153,6 @@ s! {
pub f_namemax: ::c_ulong,
}

pub struct sigset_t {
__val: [::c_ulong; 16],
}

pub struct sigaction {
pub sa_handler: extern fn(arg1: ::c_int),
pub sa_mask: sigset_t,
Expand Down Expand Up @@ -293,7 +269,14 @@ pub const __PTHREAD_RWLOCK_INT_FLAGS_SHARED: usize = 1;
pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0;
pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1;
pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2;
pub const FD_SETSIZE: usize = 1024;

cfg_if! {
if #[cfg(target_os = "horizon")] {
pub const FD_SETSIZE: usize = 64;
} else {
pub const FD_SETSIZE: usize = 1024;
}
}
// intentionally not public, only used for fd_set
const ULONG_SIZE: usize = 32;

Expand Down Expand Up @@ -739,6 +722,8 @@ extern "C" {
pub fn uname(buf: *mut ::utsname) -> ::c_int;
}

mod generic;

cfg_if! {
if #[cfg(target_os = "espidf")] {
mod espidf;
Expand Down
2 changes: 2 additions & 0 deletions src/unix/newlib/powerpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ pub type wchar_t = ::c_int;
pub type c_long = i32;
pub type c_ulong = u32;

pub use crate::unix::newlib::generic::{sigset_t, stat};

// the newlib shipped with devkitPPC does not support the following components:
// - sockaddr
// - AF_INET6
Expand Down

0 comments on commit 1a31128

Please sign in to comment.