Detegr / rust-ctrlc

Easy Ctrl-C handler for Rust projects
https://crates.io/crates/ctrlc
Other
599 stars 79 forks source link

Switch back stream to its initial flags ? #86

Closed NotSqrt closed 2 years ago

NotSqrt commented 2 years ago

Hello !

I've encountered a situation where a rust binary (volta.sh to name it) uses ctrlc which changes the stream to non-blocking here : https://github.com/Detegr/rust-ctrlc/blob/4c23810b1b4b43f5c5f69c33513e2452feccca54/src/platform/unix/mod.rs#L91 And then later, my python program calling the rust binary faces the exception BlockingIOError: [Errno 11] write could not complete without blocking when trying to write large amounts of text to its own stderr. It seems strange that it is the same fd, but I've confirmed that F_GETFL indicates that the O_NONBLOCK bit of the python stream has been set with the call fcntl.fcntl(stream, fcntl.F_GETFL) & os.O_NONBLOCK

Does that make sense to call fcntl again and restore the original flags when binaries using ctrlc exit normally ?

Detegr commented 2 years ago

I don't know what volta.sh does internally, but it does not make sense to me that flags for a fd that is created with pipe2 could have anything to do with the Python process' stderr. Can you provide a smaller example to narrow down the variables? Maybe some simple Rust program with ctrlc and some interface to Python, which is then called from Python?

NotSqrt commented 2 years ago

I've managed to reproduce the issue, and by simplifying it, I got to a point where Rust and ctrlc were no longer involved...

I was misdirected by strace, because the only call using F_SETFL was inside ctrlc, but it seems instead that it is directly inside the node binary that something strange happens.

2 successive calls F_GETFL (one from node, one from python) give different flags without any calls using F_SETFD

 > ~/.volta/tools/image/node/10.24.1/bin/node(v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*)+0xb9) [0x792319]
 > unexpected_backtracing_error [0x2cceceedbf1d]
[pid 69819] fcntl(2, F_GETFL)           = 0x1 (flags O_WRONLY)
--
 > ~/.pyenv/versions/3.10.1/bin/python3.10(_start+0x25) [0x64e45]
[pid 69814] fcntl(2, F_GETFL)           = 0x801 (flags O_WRONLY|O_NONBLOCK)

This bug was present in node 10.24.1, but is no longer present in node 14.18.3, so.. problem solved..