-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Exit status consistency issue #8381
Comments
You probably want to use |
@Blacksmocke16 There should not be a difference between |
|
I think we should remove or rename |
@RX14 Would a good option here be to deprecate |
yep |
For your enjoyment, First column is the status code in hexadecimal; *XX00: EXITED, EXITSTATUS=XX *01: SIGNALED, TERMSIG=1 ... ... *7E: SIGNALED, TERMSIG=126 *XX7F: STOPPED, STOPSIG=XX (note no wildcard on the last one) The striked out lines are invalid states but I'm posting what the macros happen to produce anyway. The program to produce this#include <sys/wait.h>
#include <stdio.h>
int main() {
const int exited = 1, signaled = 2, stopped = 4, continued = 8, coredump = 16;
int prev_kind = 0;
int prev_value = 0;
for (int n = 0; n < 0x100000; ++n) {
int kind = 0;
if (WIFEXITED(n))
kind |= exited;
if (WIFSIGNALED(n))
kind |= signaled;
if (WIFSTOPPED(n))
kind |= stopped;
if (WIFCONTINUED(n))
kind |= continued;
if (WCOREDUMP(n))
kind |= coredump;
if (kind != prev_kind) {
printf("\n");
}
printf("%4x", n);
int value = -1;
if (kind & exited)
printf(" exit %3d", value = WEXITSTATUS(n));
if (kind & signaled)
printf(" signal %3d", value = WTERMSIG(n));
if (kind & stopped)
printf(" stop %3d", value = WSTOPSIG(n));
if (kind & continued)
printf(" continued");
if (kind & coredump)
printf(" coredump");
printf(" ");
if (kind == prev_kind && value == prev_value + 1)
printf("\r");
else
printf("\n");
prev_kind = kind;
prev_value = value;
}
} So in terms of what the stdlib allows at the moment (or rather doesn't expose):
|
@oprypin wanted me to repost this idea from gitter, so there you go:
|
Having separate types seems way overkill to me. I'd rather keep it simple and don't implement every single POSIX feature. The vast majority of use cases only asking for |
I see the virtue in simplicity, however the solution needs to distinguish between a valid exit status and its absense altogether. The doc says that:
And afaiu it's user's job to remember to always check for normal_exit before exit_code, lest the result would silently be invalid. Moreover removing exit_status would make precise handling impossible. |
I'd like to keep it one type too. |
I've already described my preferred solution in #8647 (comment) If the process exited with a status code,
We can make the platform specific raw exit code available. Either as a special property or through a platform specific shard which could also include other advanced POSIX-specific features. |
There is also an option to do what bash does: https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html |
I would much prefer to do what Python does, as that doesn't cannibalize the number space of actual exit codes 128-255. So, |
On the one hand that makes sense, but on the other if what you need is to pass that code higher up, using it as an argument to your own |
I don't think passing signals is something you want to do |
That's what shell does:
|
Backwards-compatible! Based on crystal-lang#8381 (comment)
Backwards-compatible! Based on crystal-lang#8381 (comment)
Backwards-compatible! Based on crystal-lang#8381 (comment)
It turns out that `.exit_status` is not correct. We want `.exit_code`. See discussion here: crystal-lang/crystal#8381
Some of the inconsistencies regarding exist statuses were fixed with I think the only remaining issue is that |
It probably makes sense to expose the platform-specific value in an explicit and documented manner. It is already available through direct access on the instance variable (e.g. It seems like a good idea to name the method It's a bit tricky to decide what its return type should be, though. The native values are I think we have two options:
|
I'd go for 3. the return type is platform dependent. It's a platform specific method that returns a platform specific value after all. |
@ysbaddaden even if that makes the most sense, it goes directly against how all other platform-dependent APIs have been defined so far |
@ysbaddaden Isn't that option 2 without the explicit cast? (I suppose the return type restriction could be optional as well, but what would be the point of that?) Usually types should be identical across platforms in order to have a stable and portable API. The idea is that it should allow code that works on one platform work on any other platform as well. But this is hardly possible with the platform-specific exit status. You need platform-specific code to interpret it. On the other hand, option 1. seems like a relatively effortless way to coerce the same type on all platforms, which I figure should be fine? |
@straight-shoota yeah, 3. is 2. without the explicit cast so it's fully system dependent (even if we add another target someday). I'm not sure about 1. because it would cast u32 to i32 and then we can't compare with constants without casting back to u32, can we? |
My proposal was to cast from i32 to u32 because the range of valid/significant values is positive on Windows and Unix and can be greater than So direct comparison with constants should work trivially on Windows because On Unix systems you don't compare to constants directly anyway, you need to apply a bit mask. |
My Bad. I thought casting from u32 to i32 🤦 |
Not sure where that leaves us now with regards to the expected return type 🤔 I suppose |
I suppose it's fine. |
When you
raise
in a file, then check your exit status from the terminal, you'll see1
, but it seems if that raise comes from within aProcess
, then you don't get that status code:I expected running
crystal run.cr
would return a exit status code of1
but got0
.ref: https://gitter.im/crystal-lang/crystal?at=5db34583fb4dab784a05c80d
The text was updated successfully, but these errors were encountered: