Repository navigation
Ctrl+C doesn't work as expected with SSH Remoting #2321
Description
Activity
- addedWG-RemotingPSRP issues with any transport layerPSRP issues with any transport layer
on Sep 20, 2016 - modified the milestones: This milestone has been deleted, This milestone has been deleted
on Dec 19, 2016 PaulHigin commented
on Feb 1, 2017 ContributorAuthorMore actionsThis has been fixed as part of the work for issue #2827 for a Windows client. When creating the ssh.exe process we can use the CREATE_NEW_PROCESS_GROUP process creation flag which prevents the console Ctrl+C signal from propagating to that process. But there is no support for this in managed code used on Linux clients so it is not fixed there yet.
I'm hitting this problem.
Would be really useful to get fix for unix.Unhandled Exception: System.IO.IOException: Broken pipe at System.IO.UnixFileStream.CheckFileCall(Int64 result, Boolean ignoreNotSupported) at System.IO.UnixFileStream.WriteNative(Byte[] array, Int32 offset, Int32 count) at System.IO.UnixFileStream.FlushWriteBuffer() at System.IO.UnixFileStream.Flush(Boolean flushToDisk) at System.Management.Automation.Remoting.OutOfProcessTextWriter.WriteLine(String data) at System.Management.Automation.Remoting.Client.OutOfProcessClientCommandTransportManager.SendStopSignal() at System.Management.Automation.Internal.ClientPowerShellDataStructureHandler.SendStopPowerShellMessage() at System.Management.Automation.Runspaces.Internal.ClientRemotePowerShell.StopAsync() at System.Management.Automation.PowerShell.CoreStop(Boolean isSyncCall, AsyncCallback callback, Object state) at System.Management.Automation.PowerShell.BeginStop(AsyncCallback callback, Object state) at System.Management.Automation.RemotePipeline.Stop() at Microsoft.PowerShell.Executor.Cancel() at Microsoft.PowerShell.Executor.CancelCurrentExecutor() at Microsoft.PowerShell.ConsoleHost.HandleBreak() at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)But there is no support for this in managed code used on Linux clients so it is not fixed there yet
Is it a CoreCLR limitation? Should we start conversation with dotnet people?
It seems
sshcan set raw mode and sendCtrl-Cto remote host as character.
http://unix.stackexchange.com/questions/102061/ctrl-c-handling-in-ssh-sessionPaulHigin commented
on Feb 28, 2017 ContributorAuthorMore actionsThis is interesting. I can verify that interactive SSH sessions don't handle the Ctrl+C signal and appear to pass it to the remote session as expected.
But in any case I don't want ssh to handle Ctrl+C at all. Instead it should be handled only in the PowerShell client process but it appears to get passed to the ssh child process as well.
In Windows this was an easy fix by simply preventing Ctrl+C from being passed from the PowerShell process to the child ssh process. I am not sure what the mechanism is for Linux but it may be a similar issue.
Paul Higinbotham (@PaulHigin) Unix has the same behavior as Windows based on process groups
To move the process in a new process group, the process must make a callsetpgid(0,0)I believe that it can be easily and quickly be fixed in CoreCLR (add support for
CREATE_NEW_PROCESS_GROUPflag)I may be wrong, but it seems the above mentioned ssh RAW mode uses
setpgid(0,0)https://github.com/openssh/openssh-portable/blob/79e4829ec81dead1b30999e1626eca589319a47f/sshpty.c#L112
If so, we implicitly have "fix" :-) If you have the opportunity to check, look at PGID for ssd in raw modeps xao pid,ppid,pgid,sid,comm.PaulHigin commented
on Mar 2, 2017 ContributorAuthorMore actionsIlya (@iSazonov) This is great. Thanks very much for the information. I will look into this and check with the CoreCLR group about adding CREATE_NEW_PROCESS_GROUP support.
But I don't understand your comment about SSH RAW mode. RAW mode doesn't seem to be well documented and it is not clear if it can be used with subsystems. But even if it can it still passes the signal to the SSH process and I presume on to the SSHD remote session, and I want to prevent this.
I prefer the CoreCLR fix and you too - so that we can both forget about ssh raw mode even if it works :-)
PaulHigin commented
on Mar 16, 2017 ContributorAuthorMore actionssetpgid() doesn't allow the process group id to be set if the process has already started executing code. In addition there are restrictions to what process group id it can be set to (must be a process in the same session). I didn't see anywhere where you can create a process with a new group process id so I am not sure if this is possible. In any case I need to make a request to .Net to see if CREATE_NEW_PROCESS_GROUP can be supported. My guess is this can't be done in the beta 1 timeframe.
19 remaining items
Paul Higinbotham (@PaulHigin) it looks like this works now (with a weird error about the pipeline that doesn't show up locally). I still leave this to you to close, though, because it still looks like you're talking to CoreFX folks about this issue.
[jaiello-centos]: PS /home/jaiello> 1..100 | % { sleep 1; "Output $_" } Output 1 Output 2 Output 3 Output 4 The pipeline has been stopped. + CategoryInfo : OperationStopped: (:) [], PipelineStoppedException + FullyQualifiedErrorId : PipelineStoppedPaulHigin commented
on May 25, 2017 ContributorAuthorMore actionsIt currently only works on Windows clients. It is still broken on Linux clients.
Paul Higinbotham (@PaulHigin) Really? Like Linux SSH clients? Or Linux PowerShell clients? Both appear to work for me right now...
- addedIssue-BugIssue has been identified as a bug in the productIssue has been identified as a bug in the productand removedWaiting - DotNetCorewaiting on a fix/change in .NETwaiting on a fix/change in .NET
on Jun 1, 2017 PaulHigin commented
on Jun 1, 2017 ContributorAuthorMore actionsYes. On Linux/Mac OSes Ctrl+C is handled by the SSH child process and closes the process/connection. We want to prevent this and let PSRP (PowerShell remoting protocol) handle the Ctrl+C signal.
Okay, I see it now. Not sure why I couldn't get it before, but this looks like it's only for PSRP over SSH. Not generic Linux SSH clients. For posterity, the error I see right now is:
The background process reported an error with the following message: "The named pipe target process has ended.". + CategoryInfo : ResourceUnavailable: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : System.Management.Automation.Remoting.PSRemotingDataStructureExceptionPaul Higinbotham (@PaulHigin) sergei (@vors) If we put the remote pseudo-terminal in raw mode - is it resolve the problem?
ssh -t remotehost command args- put local terminal in raw mode. Then PowerShell put remote pseudo-terminal in raw mode with cfmakeraw - Is it possible?- modified the milestones: This milestone has been deleted, This milestone has been deleted
on Jun 7, 2017 PaulHigin commented
on Jun 19, 2017 ContributorAuthorMore actionsThis is now fixed for both Windows and Linux platforms.
In PowerShell Ctrl+C should stop a running command. But in an SSH interactive remote session Ctrl+C terminates the SSH process and closes the session. This behavior is the same for both Windows and Linux clients.
This is happening because both PowerShell and SSH processes are attached to the console and so they both get the SIGINT signal. PowerShell sends a PSRP stop signal over the channel as expected but the SSH process also handles the signal and terminates the process which closes the remote session.
Steps to reproduce
Expected behavior
Running command stops and remote session prompt is displayed.
Actual behavior
Session is ended with error:
Also the exception is unhandled causing PowerShell process to crash.
Environment data