Skip to content
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

Deprecating the Process exit_status method in favor of exit_code. #8647

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

jwoertink
Copy link
Contributor

I originally ran in to some confusion when using exit_status and getting a 0 even though the program was raising an exception. It turned out that exit_code was the correct method here.

As per @RX14 comment: #8381 (comment) I have deprecated the exit_status method in favor of just using exit_code.

Fixes #8381

src/process/status.cr Outdated Show resolved Hide resolved
@refi64
Copy link
Contributor

refi64 commented Jan 4, 2020 via email

@jwoertink
Copy link
Contributor Author

@refi64 In the other thread there was a mention of possibly renaming it. I'm cool with that option too. I'll wait for some more feedback before I change anything though.

@RX14
Copy link
Contributor

RX14 commented Jan 5, 2020

I think it can be removed, it's easy enough to bitshift it back if required.

@refi64
Copy link
Contributor

refi64 commented Jan 5, 2020 via email

@straight-shoota
Copy link
Member

straight-shoota commented Jan 5, 2020

Simple question: How's this implemented in other languages? We don't need to reinvent such basic things, just look what others are doing and pick the best one.

@jwoertink
Copy link
Contributor Author

I'm down for any suggestions here. I think the main thing is that it's clear what one does versus another. It almost feels like these two method names are reversed. I tried looking at a few other languages, but trying to decipher low level process stuff is a little over my head.

@jan-zajic
Copy link
Contributor

In Go lang, ExitCode() returns the exit code of the exited process, or -1 if the process hasn't exited or was terminated by a signal.

In Rust, ExitStatus has method code, that Returns the exit code of the process, if any. On Unix, this will return None if the process was terminated by a signal;

In Nim, Process method peekExitCode Return -1 if the process is still running. Otherwise the process' exit code. On posix, if the process has exited because of a signal, 128 + signal number will be returned.

That +128 is similiar what all Unix shells do. for example in Bash documented here

You can find similar note in Java native sources (Solaris implementation):

/* The child exited because of a signal.
The best value to return is 0x80 + signal number,
because that is what all Unix shells do, and because
it allows callers to distinguish between process exit and
process death by signal.
Unfortunately, the historical behavior on Solaris is to return
the signal number, and we preserve this for compatibility. */

But since we have wrapping Process::Status class, we can easily deprecate exit_status method, as proposed, so +1 for that. Any other informations encoded in status can be easily accessed by other methods like exit_signal and normal_exit?. Is for discussion what to return from exit_code method if exited abnormally, but I think it is subject for another PR?

@jwoertink
Copy link
Contributor Author

Thanks for looking up that info @jan-zajic

@straight-shoota
Copy link
Member

We should probably follow Go and Rust in only returning an exit code if there is actually one and not tread a signal indicator as an exit code. This may be fine for more platform-specific implementations, but for a portable language it feels wrong when a child doesn't exit but the process status reports an exit code.

Go's implementation also provides access to system-specific information, such as extracting the singal number or whether the process was core dumped. The API is hidden in syscall.WaitStatus which can be accessed but isn't documented in the public API. I'm not sure about the reason for this as it appears that the same API works on all platforms (on windows it simply always return null status). So it should actually be fine to have this publicly documented.
Rust on the other hand provides more detailed information in a system-specific package.
That's probably the best solution. We are going to have a shard for system-specific implementations such as fork anyway, so it would fit there very well. This would also mean to remove most of the method in Process::Status (#exit_signal, #normal_exit?, #signal_exit?).

Is for discussion what to return from exit_code method if exited abnormally, but I think it is subject for another PR?

I'd prefer to combine deprecation of #exit_status and possible changes to #exit_code in one PR because they belong together and should produce a breaking change only once.

@oprypin
Copy link
Member

oprypin commented Apr 11, 2020

I think it's very clear that we shouldn't expose exit_status, I don't know any other language that does.
What does worry me, though, is that a process can exit with a signal but have exit_code == 0. I don't know any other language that does this either. Usually it causes the exit code to be -signal or 128 + signal.

So, just due to this, it's not 100% obvious that this is a good change, as it might direct people towards checking exit_code == 0, which is worse than exit_status == 0.

@oprypin
Copy link
Member

oprypin commented Apr 11, 2020

If I was making this decision on my own, I'd merge this PR immediately and then also make exit_code return -signal_code if signal_exit?

@refi64
Copy link
Contributor

refi64 commented Apr 11, 2020

I've had to rebuild exit status values before because a language doesn't expose it, it's a pretty painful experience and I don't really see any loss from having e.g. platform_exit_status.

@oprypin
Copy link
Member

oprypin commented Apr 12, 2020

Having explored the full variety of exit statuses and how poorly they are covered by the convenience methods, now I'm not so sure that we are ready to deprecate this. In addition to what @refi64 said.

@straight-shoota
Copy link
Member

issue: Status#exit_code calls #exit_status internally. We should expand that to @exit_status.to_i32!.
(I could not add this comment in the affected line directly because it's not part of the diff.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Exit status consistency issue
7 participants