Browse Source

Update getrandom impl based on ctru error codes

pull/10/head
Ian Chamberlain 3 years ago committed by Andrea Ciliberti
parent
commit
b01d256883
  1. 46
      src/lib.rs

46
src/lib.rs

@ -74,26 +74,38 @@ unsafe extern "C" fn getrandom(
mut buflen: libc::size_t, mut buflen: libc::size_t,
flags: libc::c_uint, flags: libc::c_uint,
) -> libc::ssize_t { ) -> libc::ssize_t {
// TODO: is this needed? Maybe just `buflen = buflen.min(libc::ssize_t::MAX)` ? // Based on https://man7.org/linux/man-pages/man2/getrandom.2.html
buflen = buflen.min(0x1FFFFFF); // 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);
if flags != 0 { let ret = ctru_sys::PS_GenerateRandomBytes(buf, buflen as libc::c_uint);
// no flags are supported on 3DS
*__errno() = libc::EINVAL;
return -1;
}
let ret = ctru_sys::PS_GenerateRandomBytes(buf, buflen as libc::c_uint) as libc::ssize_t; // avoid conflicting a real POSIX errno by using a value < 0
if ret < 0 { // should we define this in ctru-sys somewhere or something?
// this is kind of a hack, but at least gives some visibility to the const ECTRU: libc::c_int = -1;
// error code returned by PS_GenerateRandomBytes I guess? Another option
// might be to panic, which could use a payload of a specific error type if ctru_sys::R_SUCCEEDED(ret) {
// that the ctru panic handler could decode into 3DS-specific human-readable
// errors.
*__errno() = ret as libc::c_int;
-1
} else {
// safe because above ensures buflen < isize::MAX // safe because above ensures buflen < isize::MAX
buflen as libc::ssize_t 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
} }
} }

Loading…
Cancel
Save