-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add getrandom impl using ctru_sys bindings #8
Conversation
Make a PR to libc too. |
Yes, this is a standard Newlib function, and it's a linker fix for it since it's not normally available. |
At some point we should consider renaming the linker fix lib to something like |
src/lib.rs
Outdated
buflen: libc::size_t, | ||
_flags: libc::c_uint, | ||
) -> libc::ssize_t { | ||
let ret = ctru_sys::psInit(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to happen every time, or can we lazily initialize it with something like core::sync::Once
?
Also, do we need to call psExit
or not worry about it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question re: psExit
. The docs are pretty sparse on what these functions actually do, but I would assume that it is more correct to call it before the program ends. I'm not really sure how we could handle something like that in this crate... maybe this impl should only call PS_GenerateRandomBytes
and it's up to the user to initialize / exit PS itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, also – as far as I can tell there's no problem calling it more than once, but it could be done with Once
if we wanted to avoid the potential overhead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's OK with not calling psExit
then I'd go with the Once
route.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opted to remove psInit
entirely, as I think it makes more sense to treat Ps
the way e.g. Gfx
and Apt
are in ctru-rs
already (and I have a local changeset to do so). With the new implementation I pushed, failing to initialize the Ps
causes a runtime panic (from std
) if the user tries to e.g. construct a HashMap
, but everything works if they do initialize it.
Trying it out with a real application ( |
src/lib.rs
Outdated
mut buflen: libc::size_t, | ||
flags: libc::c_uint, | ||
) -> libc::ssize_t { | ||
// TODO: is this needed? Maybe just `buflen = buflen.min(libc::ssize_t::MAX)` ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This number chosen based on https://man7.org/linux/man-pages/man2/getrandom.2.html#NOTES
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is the GRND_RANDOM flag for using random
instead of urandom
(under linux). Maybe we could check those to change the maximum buffer length(for urandom
it's 33554431, while for random
it's 512), so it would more closely resemble the original.
GRND_NONBLOCK
instead looks like it can just be ignored, as it doesn't change how our code behaves.
We don't need to return errors when those flags are set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting... as it turns out, getrandom
, getentropy
, GRND_NONBLOCK
, and GRND_RANDOM
seem to only be defined in newlib for Cygwin, and not on 3DS (or any other platform).
So, I guess I will just add them to horizon/mod.rs
in libc
, and anyone using it will just have to live with the fact that GRND_NONBLOCK
doesn't work at all.
src/lib.rs
Outdated
let ret = ctru_sys::PS_GenerateRandomBytes(buf, buflen as libc::c_uint) as libc::ssize_t; | ||
if ret < 0 { | ||
// this is kind of a hack, but at least gives some visibility to the | ||
// error code returned by PS_GenerateRandomBytes I guess? Another option |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on this header file, these error codes aren't compatible:
https://github.com/devkitPro/libctru/blob/master/libctru/include/3ds/result.h
We would probably want to parse the 3ds result and return the appropriate error code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, std
implementation seems to just report them as "unexpected error code XYZ" if I set it in errno here. I have some local changes to sort of "parse" those error codes based on https://www.3dbrew.org/wiki/Error_codes but seeing that header, I wonder if we can just leverage ports of those macros instead. Let me see if I can put something in ctru-sys
for this...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks nice! 👍
Okay, I've updated all relevant PRs for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Will merge once rust3ds/ctru-rs#35 is finalized.
OH, having linker-fix depend on ctru-sys creates a dependency duplication error in cargo. @ian-h-chamberlain |
Ah yeah, I think I didn't notice because I had so many |
Fixed in rust3ds/ctru-rs@c59de27 @ian-h-chamberlain It is cool to have that |
That's true, I think technically we could remove it from
See how there are two different versions of |
Yes, absolutely, dependency duplicates aren't cool but |
Ref Meziu/rust-horizon#6
Add a
getrandom
call thatlibc
can link against. This will also require a change tolibc
to declare anextern "C" fn getrandom
and then finally updatestd
to utilize that call whentarget_os = "horizon"
.Two main questions:
ctru-sys
instead if we wanted, but putting it here feels like a "linker-fix" to me. It does require adding the dependency onctru-sys
, though.try_into().unwrap()
feels a bit heavy-handed, maybe if the conversion fails we should seterrno
or something? Doesctru-sys
have an API for something likeerrno
for us to set in case of non-zero return values from thePS_
syscall?@Meziu @AzureMarker