Skip to content

Commit

Permalink
Merge pull request #8 from ian-h-chamberlain/getrandom
Browse files Browse the repository at this point in the history
  • Loading branch information
Meziu authored Feb 1, 2022
2 parents a2c7bb1 + 754afa8 commit f6c3cde
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ license = "MIT/Apache 2.0"
edition = "2018"

[dependencies]
ctru-sys = { git = "https://github.com/Meziu/ctru-rs.git" }
libc = "0.2.116"
42 changes: 42 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,45 @@ unsafe extern "C" fn clock_gettime(

retval
}

#[no_mangle]
unsafe extern "C" fn getrandom(
buf: *mut libc::c_void,
mut buflen: libc::size_t,
flags: libc::c_uint,
) -> libc::ssize_t {
// Based on https://man7.org/linux/man-pages/man2/getrandom.2.html
// Technically we only have one source (no true /dev/random), but the
// behavior should be more expected this way.
let maxlen = if flags & libc::GRND_RANDOM != 0 {
512
} else {
0x1FFFFFF
};
buflen = buflen.min(maxlen);

let ret = ctru_sys::PS_GenerateRandomBytes(buf, buflen as libc::c_uint);

// avoid conflicting a real POSIX errno by using a value < 0
// should we define this in ctru-sys somewhere or something?
const ECTRU: libc::c_int = -1;

if ctru_sys::R_SUCCEEDED(ret) {
// safe because above ensures buflen < isize::MAX
buflen as libc::ssize_t
} else {
// best-effort attempt at translating return codes
*__errno() = match ctru_sys::R_SUMMARY(ret) as libc::c_uint {
ctru_sys::RS_WOULDBLOCK => libc::EAGAIN,
ctru_sys::RS_INVALIDARG | ctru_sys::RS_WRONGARG => {
match ctru_sys::R_DESCRIPTION(ret) as libc::c_uint {
// most likely user error, forgot to initialize PS module
ctru_sys::RD_INVALID_HANDLE => ECTRU,
_ => libc::EINVAL,
}
}
_ => ECTRU,
};
-1
}
}

0 comments on commit f6c3cde

Please sign in to comment.