Open bmitc opened 2 years ago
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.
Tagging subscribers to this area: @dotnet/interop-contrib See info in area-owners.md if you want to be subscribed.
Author: | bmitc |
---|---|
Assignees: | - |
Labels: | `area-System.Runtime.InteropServices`, `untriaged` |
Milestone: | - |
This should cancel the signal
The semantics of Cancel
depend on the signal and what use-case we want to enable.
SIGTSTP
was added on request of @alexrp (https://github.com/dotnet/runtime/issues/50527#issuecomment-812840192).
We didn't diverge much into his specific use-case when including it.
We should look at the use-case and see what is the meaningful behavior when Cancel
is true
/false
.
Looking at the code, I think they currently both do the same thing: prevent SIGTSTP
from stopping the app.
My understanding (and reason for bringing it up back then) is that the common use case for handling SIGTSTP
is to save any critical program state before it's suspended. I would expect a program to do that in the event handler, so no need to set Cancel = true
.
I can't really think of why one would want to completely block SIGTSTP
. Seeing as SIGSTOP
can't be blocked anyway, there's no way to 'opt out' of suspension altogether. In any case, I would expect Cancel
to do the intuitive thing: true
blocks the signal, false
lets it go through (so the program gets suspended).
I would expect Cancel to do the intuitive thing: true blocks the signal, false lets it go through (so the program gets suspended).
We can change it to do that, which is a breaking change, but probably the desired behavior.
When at its default value of Cancel = false
, the process will then be stopped. (by sending SIGSTOP
to it after the handler ran).
When set to Cancel = true
, the process will keep running.
@bmitc how does that sound to you?
I apologize for getting back to this so late. This is a side project that got pushed aside. Thank you @tmds and @alexrp for responding so quickly to this, and I'm again sorry for the delay.
My use case was using pure F# to implement the modified Kilo text editor described in Build Your Own Text Editor. Specifically, it was in implementing the section Turn off Ctrl-C
and Ctrl-Z
signals where I came across this issue. The tutorial uses the C library termios to accomplish disabling SIGINT
and SIGTSTP
. For reference (also in the above link):
By default,
Ctrl-C
sends aSIGINT
signal to the current process which causes it to terminate, andCtrl-Z
sends aSIGTSTP
signal to the current process which causes it to suspend. Let’s turn off the sending of both of these signals.
But to do this behavior in pure F#/.NET, I was needing the PosixSignal.SIGINT
and PosixSignal.SIGTSTP
signals actually canceled when doing context.Cancel <- true
. I think a terminal text editor is probably a legitimate use case for canceling these, although admittedly is probably a rare one.
However, I am not remotely close to an expert on terminal implementations, which is one reason why I was working through this tutorial, so it's possible I misunderstand something here.
Specifically, it was in implementing the section Turn off Ctrl-C and Ctrl-Z signals where I came across this issue. The tutorial uses the C library termios to accomplish disabling SIGINT and SIGTSTP. For reference (also in the above link):
Besides adding the PosixSignalRegistration
, you should also set Console.TreatControlCAsInput
to true
.
Then you'll be able to read the Ctrl-C and Ctrl-Z combinations.
KeyChar
will be the raw control value as mentioned in the article (Now Ctrl-C can be read as a 3 byte and Ctrl-Z can be read as a 26 byte.). ConsoleKey
will be set based on that.
Moving this to .NET 9 as the likely fix is a breaking change and we're pretty late into .NET 8 for breaking changes.
Sadly we didn't get to this in .NET 9 and it is likely still a breaking change, so moving to .NET 10.
Description
I am writing a console application in F# using .NET 7. I am wanting to intercept and prevent console exit signals, such as
PosixSignal.SIGTSTP
andPosixSignal.SIGINT
. These enums are defined here. To ignore them, I create and register a handler usingPosixSignalRegistration.Create
and then writetrue
to theCancel
property inside the handler. This should cancel the signal, to my understanding, as it does forPosixSignal.SIGINT
. However, that doesn't seem to be the case forPosixSignal.SIGTSTP
.Reproduction Steps
These steps were executed on Ubuntu 20 running in WSL2 on Windows 11.
Save the following code into an F# script named
posix.fsx
.Run the script with
dotnet fsi posix.fsx
Type any character except
'q'
. The key information will be printed out.Enter
Ctrl + C
and note that"Prevented Posix SIGINT"
is printed out to the screen but that the process is still running, which can be verified by entering in other characters (again, besides'q'
).Enter
Ctrl + Z
and note that:[3]+ Stopped dotnet fsi posix.fsx
is printed to the screen"Prevented Posix SIGTSTP"
is printed out afterwards, after the new prompt is shown.Enter
is entered. This behavior is a little inconsistent.Expected behavior
When
Ctrl + Z
is entered,"Prevented Posix SIGTSTP"
should be printed to the console without the program being stopped.Actual behavior
Regression?
Not sure.
Known Workarounds
None that I know of.
Configuration
The architecture is x64.
Other information
No response