I'm using the ctrlc crate to catch Ctrl-C in my program but it doesn't work when it's started by cargo run, which defeats the purpose because I don't need to handle Ctrl-C in the release version, only during development.
Would it be possible for cargo run to also use the ctrlc crate and forward the termination signal to the child process?
On unix-like systems, cargo run replaces itself with the child process using the execve()-family, so there is nothing to forward, the signal is delivered straight to your target process. It shouldâ„¢ just work unless SIGINT is masked for some reason. What OS are you on?
Windows 8.1
I don't personally know how to "forward signals" on Windows, but an implementation would be most welcome!
Cargo uses job objects when running any child processes, so when cargo exits all child processes are automatically and forcefully terminated. In order to be able to have your program respond to console control events when using cargo run, cargo would have to stop using job objects to forcefully terminate everything when it exits.
I've seen enough people run into this roadblock that maybe we should reconsider why we're using job objects and try to solve the original problem some other way.
I believe the original issue was that when cargo received CTRL_C_EVENT it would not propagate automatically to child processes of cargo. An alternate way of solving this issue would be to abandon job objects and instead handle CTRL_C_EVENT during which we explicitly generate a CTRL_C_EVENT for every single child process, which means cargo has to keep track of all its current child processes. It would certainly be more complicated, but it would allow child processes to decide how to respond to CTRL_C_EVENT instead of just being forcefully terminated.
I'm using hyper, futures and ctrlc. Every time I interrupt the process, the application sometimes failed to go through all the codes which ought to be executed before the process exits. But if I cargo build and then start with the built binary, those codes are always executed. Is that related to this issue?
The Ctrl-C handler won't get triggered with cargo run, but it will when you run the exe manually.
@Boscop That's weird. I ran cargo run in Powershell in VS Code the Ctrl-C handler was actually triggered, and was always triggered, except it doesn't finish its works sometimes.
Using cargo 0.22.0 (3423351a5 2017-10-06).
My above change, #6004 fixes this for cmd.exe shells, but it's still a problem for PowerShell (maybe I'll try to poke at that at some point?) and likely MSYS shells.
@zachlute Thanks! So with your fix, a handler registered with the ctrlc crate should also be called when the exe being terminated was spawned by cargo run, correct? (Which didn't work before on Windows.)
Yes, though there's also a caveat. This fixes it for raw cargo.exe runs, but my understanding is that when run through rustup it's probably still an issue because I'll have to make the same fix in rustup. Now that this has landed, I'll try to poke at that once it hits nightly and see what's up.
@zachlute I usually run it through cargo watch -x run, will that work with ctrlc?
@zachlute what is the state of this, can this be closed now?
My understanding of the status quo here is that this problem is, as mentioned above, fixed for cmd.exe shells (and likely PowerShells?), but not for MSYS shells, because as @alexcrichton mentions in #6004, those don't send Ctrl+C events and just get killed with TerminateProcess.
So uh...I think my answer is 'yes, this is fixed for most people'.
Ok I will close this for not, we can reopen if someone is having problems.