-
Notifications
You must be signed in to change notification settings - Fork 32
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
libast: provide rand_r fallback #806
Comments
I took a cursory look at this. The most portable fix here is to replace
If thread safety is what's desired, then it needs to be completely implemented from scratch because there is no way to do thread-safe pseudo-random numbers in POSIX. If compatibility with the existing behavior is what's desired, then An additional oddity with the code is that |
If we decide to do a more thorough reimplementation, this is worth reading: |
Thanks for looking into this. A few points: Thread-safety is irrelevant because this project does not use threads, and never will. Parallelism is implemented by forking or spawning processes.
It's an ancient design decision that (For real randomness, the dev branch, i.e. future 93u+m/1.1, has added |
Oh, OK. That makes sense. I've coded up a proof-of-concept replacing |
Using In the meantime I've been working on a After that I would like to see a PR with your |
As of the referenced commit, the rand_r(3) function is used for $RANDOM instead of rand(3). This is necessary to keep repeatable seeded $RANDOM sequences working in the shell -- particularly in combination with virtual subshells, which require us to save and restore the intermediate seed value. Only rand_r will allow us to access and control that seed value so we can save it. However, POSIX removed rand_r in the 2024 edition, so we cannot count on operating systems continuing to provide it forever. src/lib/libast/features/{lib,sys}: - Add lib test for rand_r, checking if it exists in OS libraries. Defines _lib_rand_r as 1 if found. - Add extern test for rand_r, checking if the extern declaration is found in the system headers and emitting one if not. This is needed because some operating systems (e.g., NetBSD) keep deprecated functions in their libraries for ABI compatibility purposes while hiding or removing their header declarations. src/cmd/ksh93/sh/{init,subshell}.c: - Add rand_r fallback implementation (nicked from FreeBSD libc) if !_lib_rand_r (i.e., rand_r is not found in system libraries). - Since this is a static function (no need for extern here as it's only used in init.c), use a #define to rename it to _ksh_rand_r to avoid a conflict with the extern declaration. - Eliminate pointless srand(3) calls. It seeds rand(3) sequences; it's irrelevant to rand_r(3) because we give it a pointer to our own seed variable! All we need to do is assign to that. - Eliminate an init-time loop that calls rand(3) to check whether it returns large values. This is not inefficient, and now invalid in case we provide our own rand_r whose range may differ from the OS's rand. Determine this at compile time instead, using the RAND_MAX macro (which we redefine when providing our own rand_r). Resolves: #806
ksh depends on the operating system's rand_r function for reproducible seeded
$RANDOM
sequences. But rand_r has been removed from the 2024 version of the POSIX standard, so we cannot rely on systems continuing to provide it. We should add a fallback implementation to libast for use on systems that don't come with it.The text was updated successfully, but these errors were encountered: