diff --git a/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs b/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs index 8d9035f241b..fc168eca14b 100644 --- a/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs +++ b/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs @@ -588,6 +588,16 @@ internal static int NonWindowsGetProcessParentPid(int pid) return IsMacOS ? Unix.NativeMethods.GetPPid(pid) : Unix.GetProcFSParentPid(pid); } + internal static bool NonWindowsKillProcess(int pid) + { + return Unix.NativeMethods.KillProcess(pid); + } + + internal static int NonWindowsWaitPid(int pid, bool nohang) + { + return Unix.NativeMethods.WaitPid(pid, nohang); + } + internal static class Windows { /// The native methods class. @@ -1063,6 +1073,13 @@ internal static class NativeMethods [DllImport(psLib, CharSet = CharSet.Ansi)] internal static extern uint GetCurrentThreadId(); + [DllImport(psLib)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool KillProcess(int pid); + + [DllImport(psLib)] + internal static extern int WaitPid(int pid, bool nohang); + // This is a struct tm from . [StructLayout(LayoutKind.Sequential)] internal unsafe struct UnixTm diff --git a/src/System.Management.Automation/System.Management.Automation.csproj b/src/System.Management.Automation/System.Management.Automation.csproj index 3f317b802a3..9f293b76697 100644 --- a/src/System.Management.Automation/System.Management.Automation.csproj +++ b/src/System.Management.Automation/System.Management.Automation.csproj @@ -28,7 +28,7 @@ - + diff --git a/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs b/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs index a16e7820bd1..04ce777964e 100644 --- a/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs +++ b/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs @@ -2227,6 +2227,11 @@ internal int StartSSHProcess( return StartSSHProcessImpl(startInfo, out stdInWriterVar, out stdOutReaderVar, out stdErrReaderVar); } + internal void KillSSHProcess(int pid) + { + KillSSHProcessImpl(pid); + } + #endregion #region SSH Process Creation @@ -2265,6 +2270,16 @@ private static int StartSSHProcessImpl( return pid; } + private static void KillSSHProcessImpl(int pid) + { + // killing a zombie might or might not return ESRCH, so we ignore kill's return value + Platform.NonWindowsKillProcess(pid); + + // block while waiting for process to die + // shouldn't take long after SIGKILL + Platform.NonWindowsWaitPid(pid, false); + } + #region UNIX Create Process // @@ -2570,6 +2585,17 @@ private static int StartSSHProcessImpl( return sshProcess.Id; } + private static void KillSSHProcessImpl(int pid) + { + using (var sshProcess = System.Diagnostics.Process.GetProcessById(pid)) + { + if ((sshProcess != null) && (sshProcess.Handle != IntPtr.Zero) && !sshProcess.HasExited) + { + sshProcess.Kill(); + } + } + } + // Process creation flags private const int CREATE_NEW_PROCESS_GROUP = 0x00000200; private const int CREATE_SUSPENDED = 0x00000004; diff --git a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs index ff206938879..2d92e520167 100644 --- a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs +++ b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs @@ -1735,13 +1735,7 @@ private void CloseConnection() { try { - using (var sshProcess = System.Diagnostics.Process.GetProcessById(sshProcessId)) - { - if ((sshProcess != null) && (sshProcess.Handle != IntPtr.Zero) && !sshProcess.HasExited) - { - sshProcess.Kill(); - } - } + _connectionInfo.KillSSHProcess(sshProcessId); } catch (ArgumentException) { } catch (InvalidOperationException) { }