-
Notifications
You must be signed in to change notification settings - Fork 20
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 interrupt
function to std::process::Child
#97
Comments
I'll note that Windows does not have a direct equivalent to this. Therefore it may need to be a Unix extension. |
the windows equivalent would probably be something like |
For sure, it can be done but it isn't exactly equivalent. As you say, the So this is rather more complex than the Unix case and a somewhat more niche feature. |
If we're doing a unix-specific thing then I think a general signal-sending thing would be better than specifically |
I agree: since this needs to be a UNIX extension anyway, let's support sending signals. That said, signal numbers are not portable, so we'll need to define signal constants for the common subset that works on every UNIX platform. |
#[non_exhaustive]
enum Signal {
Term,
Kill,
Interrupt,
// a bunch more...
PlatformSpecific(u32)
} |
PlatformSpecific is great for input, but causes problems for output: if we add a new variant, matching PlatformSpecific can fail. I would suggest an accessor function instead. |
We already have places in I somewhat feel that any new API here should follow suit (rather than something type-safe/high-level like an enum or wrapper), otherwise it will feel weird and unfortunate for these existing APIs not to use it. That is, IMO the drawback of inconsistency (specifically, inconsistency in a way that makes the existing APIs feel bad) is not worth the benefit of using something higher level for this. (I guess I could be convinced that input vs output makes a big difference here, though). (This is relevant to #88 as well, which is using |
"weird and unfortunate" suggests that the precedent is bad and perhaps shouldn't be followed? Plus we can offer conversion methods between a higher-level enum and the i32 values. |
I think it is non-ideal to use a I can't see a better implementation than: enum Signal {
Term,
Kill,
Interrupt,
// ...
Custom(u32)
}
impl From<Signal> for i32 {
fn from(signal: Signal) -> Self {
match signal {
Signal::Term => 15,
Signal::Kill => 9,
Signal::Interrupt => 2,
// ...
Signal::Custom(x) => x as i32,
}
}
}
fn signal(sig: Signal) {
raw_signal(i32::from(sig))
}
fn raw_signal(sig: i32) {
// ...
} The unfortunate thing is, the more we push for the largest amount of compatibility we quickly regress back to an implementation which is near identical to |
If we have a high level representation for signals, then yes, it would feel unfortunate that we don't use it consistently. I don't think that is enough to justify having one, though. |
IOW, if we do add a higher level signal type, I think we should be prepared to deprecate the existing functions which work with signals and replace them with versions that use it. I'm not a particular fan of that, but I don't think these are so widely used that there would be much churn. |
It's worth noting that |
We discussed this in the libs meeting and think this would be good to add. Some notes on the specific design points:
|
So if I want to send a SIGINT, how do I do that? This sounds like I pretty much have to also depend on libc to learn the signal numbers for the current target? Hard-coding a number certainly shouldn't be encouraged. |
Proposal
Problem statement
With running a binary it is common their will be artefacts which should be removed on ending execution (e.g. a unix socket). When developing such a binary, integration tests will need to run the binary and then clean-up afterwards.
At the moment it is not clear how to do this, this should be a convenient and clear.
Motivation, use-cases
At the moment you might do this like:
Yet if you are in the rarer circumstance where you don't trust the running application and/or need to short-circuit it, it is significantly easier to do:
I would forward that really
SIGINT
should be the more common use case thanSIGKILL
so it is odd that we have a convenience method forSIGKILL
but notSIGINT
.Solution sketches
The simple solution would be to add an
interrupt
function tostd::process::Child
that behaves simiarlly to thekill
function except sends theSIGINT
signal.Notably in the above example it is not guaranteed that the program will exit, especially if it captures the signal then hangs, this may lead to code where you want to interrupt the process then after a given timeout kill the process:
This case may warrant a
interrupt_timeout
function, such that this code could look like:Links and related work
I've already made a partial PR on this: rust-lang/rust#101387
What happens now?
This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.
The text was updated successfully, but these errors were encountered: