diff --git a/src/header/mod.rs b/src/header/mod.rs index 2de1178582651ac9457a4fd9cddbde4eb0ee287d..81934256d8024abf23c329213ed50fb154aee20a 100644 --- a/src/header/mod.rs +++ b/src/header/mod.rs @@ -50,6 +50,7 @@ pub mod _wctype; pub mod arch_aarch64_user; pub mod arch_x64_user; pub mod sys_procfs; +pub mod sys_random; pub mod sys_uio; pub mod sys_un; pub mod sys_utsname; diff --git a/src/header/sys_random/cbindgen.toml b/src/header/sys_random/cbindgen.toml new file mode 100644 index 0000000000000000000000000000000000000000..d83dd8b5eb817360438daf964619d9c19b7967be --- /dev/null +++ b/src/header/sys_random/cbindgen.toml @@ -0,0 +1,9 @@ +sys_includes = ["sys/types.h"] +include_guard = "_SYS_RANDOM_H" +language = "C" +style = "Tag" +no_includes = true +cpp_compat = true + +[enum] +prefix_with_name = true diff --git a/src/header/sys_random/mod.rs b/src/header/sys_random/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..bc90bfa65ca9f99a04ca719f6d66cd42698c3f60 --- /dev/null +++ b/src/header/sys_random/mod.rs @@ -0,0 +1,14 @@ +use core::slice; + +use crate::platform::{Pal, Sys, types::*}; + +pub const GRND_NONBLOCK: c_uint = 1; +pub const GRND_RANDOM: c_uint = 2; + +#[no_mangle] +unsafe extern "C" fn getrandom(buf: *mut c_void, buflen: size_t, flags: c_uint) -> ssize_t { + Sys::getrandom(slice::from_raw_parts_mut( + buf as *mut u8, + buflen as usize + ), flags) +} diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 19b908ffed6727f5a746cdb291c2871e68765245..3115b2805a75749dd642d7544664d3009289aec5 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -254,6 +254,10 @@ impl Pal for Sys { e(unsafe { syscall!(GETPPID) }) as pid_t } + fn getrandom(buf: &mut [u8], flags: c_uint) -> ssize_t { + e(unsafe { syscall!(GETRANDOM, buf.as_mut_ptr(), buf.len(), flags) }) as ssize_t + } + unsafe fn getrlimit(resource: c_int, rlim: *mut rlimit) -> c_int { e(syscall!(GETRLIMIT, resource, rlim)) as c_int } diff --git a/src/platform/pal/mod.rs b/src/platform/pal/mod.rs index 9900e378d36743fc63da293a0c6e1f485ba93d40..f7984dac6917d7aaf81ac76dc6aceda2460deed6 100644 --- a/src/platform/pal/mod.rs +++ b/src/platform/pal/mod.rs @@ -91,6 +91,8 @@ pub trait Pal { fn getppid() -> pid_t; + fn getrandom(buf: &mut [u8], flags: c_uint) -> ssize_t; + unsafe fn getrlimit(resource: c_int, rlim: *mut rlimit) -> c_int; fn gettid() -> pid_t; diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index b77cf63d1354421441d19c8fb2a6bb95bea5550a..58117dd3205a1c9c1bd012e2cbb109caa5ee4303 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -13,6 +13,7 @@ use crate::{ errno::{EINVAL, EIO, EPERM, ERANGE}, fcntl, sys_mman::MAP_ANON, + sys_random, sys_resource::{rlimit, RLIM_INFINITY}, sys_stat::stat, sys_statvfs::statvfs, @@ -555,6 +556,33 @@ impl Pal for Sys { e(syscall::getppid()) as pid_t } + fn getrandom(buf: &mut [u8], flags: c_uint) -> ssize_t { + //TODO: make this a system call? + + let path = if flags & sys_random::GRND_RANDOM != 0 { + //TODO: /dev/random equivalent + "rand:" + } else { + "rand:" + }; + + let mut open_flags = syscall::O_RDONLY | syscall::O_CLOEXEC; + if flags & sys_random::GRND_NONBLOCK != 0 { + open_flags |= syscall::O_NONBLOCK; + } + + let fd = e(syscall::open(path, open_flags)); + if fd == !0 { + return -1; + } + + let res = e(syscall::read(fd, buf)) as ssize_t; + + let _ = syscall::close(fd); + + res + } + unsafe fn getrlimit(resource: c_int, rlim: *mut rlimit) -> c_int { //TODO if !rlim.is_null() { diff --git a/src/platform/test/mod.rs b/src/platform/test/mod.rs index 01889bb3588b6f58ea662a474529eef9429a8e68..d5fb9e04787f93610ab630ff982fdc5e1b48f188 100644 --- a/src/platform/test/mod.rs +++ b/src/platform/test/mod.rs @@ -63,3 +63,22 @@ fn clock_gettime() { assert_ne!(timespec.tv_nsec, -1); } } + +//TDOO: everything else + +#[test] +fn getrandom() { + use crate::header::sys_random; + use crate::platform::types::ssize_t; + + let mut arrays = [[0; 32]; 32]; + for i in 1..arrays.len() { + assert_eq!(Sys::getrandom(&mut arrays[i], 0), arrays[i].len() as ssize_t); + + for j in 0..arrays.len() { + if i != j { + assert_ne!(&arrays[i], &arrays[j]); + } + } + } +}