diff --git a/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java b/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java index e79694719284..658e4b3a7601 100644 --- a/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java +++ b/platform/platform-api/src/com/intellij/execution/process/OSProcessHandler.java @@ -71,7 +71,7 @@ public class OSProcessHandler extends BaseOSProcessHandler { // Override this method if you want to customize default destroy behaviour, e.g. // if you want use some soft-kill. final Process process = getProcess(); - if (shouldDestroyProcessRecursively()) { + if (shouldDestroyProcessRecursively() && processCanBeKilledByOS(process)) { killProcessTree(process); } else { @@ -79,6 +79,10 @@ public class OSProcessHandler extends BaseOSProcessHandler { } } + public static boolean processCanBeKilledByOS(Process process) { + return !(process instanceof OSProcessManager.SelfKiller); + } + /** * Kill the whole process tree. * diff --git a/platform/platform-api/src/com/intellij/execution/process/OSProcessManager.java b/platform/platform-api/src/com/intellij/execution/process/OSProcessManager.java index 50609042b642..f2c5d9f3915c 100644 --- a/platform/platform-api/src/com/intellij/execution/process/OSProcessManager.java +++ b/platform/platform-api/src/com/intellij/execution/process/OSProcessManager.java @@ -33,4 +33,9 @@ public abstract class OSProcessManager { @Nullable public abstract List getCommandLinesOfRunningProcesses(); + + /** + * Marker interface that represents a process that kills itself, for example a remote process, that can't be killed by the local OS + */ + public interface SelfKiller {} } diff --git a/platform/platform-impl/src/com/intellij/execution/process/KillableColoredProcessHandler.java b/platform/platform-impl/src/com/intellij/execution/process/KillableColoredProcessHandler.java index 356ff1729e1c..756723c4508b 100644 --- a/platform/platform-impl/src/com/intellij/execution/process/KillableColoredProcessHandler.java +++ b/platform/platform-impl/src/com/intellij/execution/process/KillableColoredProcessHandler.java @@ -23,11 +23,11 @@ import java.nio.charset.Charset; /** * @author Roman.Chernyatchik - * - * This process handler supports ANSI coloring and soft-kill feature. Soft kill works only on Unix. - * At first "stop" button send SIGINT signal to process, if it still hangs user can termintate it recursively with SIGKILL signal. - * - * P.S: probably OSProcessHandler is better place for this feature but it can affect other run configurations and should be tested + *

+ * This process handler supports ANSI coloring and soft-kill feature. Soft kill works only on Unix. + * At first "stop" button send SIGINT signal to process, if it still hangs user can termintate it recursively with SIGKILL signal. + *

+ * P.S: probably OSProcessHandler is better place for this feature but it can affect other run configurations and should be tested */ public class KillableColoredProcessHandler extends ColoredProcessHandler implements KillableProcess { public KillableColoredProcessHandler(final Process process, final String commandLine, @NotNull final Charset charset) { @@ -38,25 +38,40 @@ public class KillableColoredProcessHandler extends ColoredProcessHandler impleme super(process, commandLine); } - @Override - public boolean canKillProcess() { + /** + * This method shouldn't be overriden, see shouldKillProcessSoftly + * @return + */ + private boolean canKillProcessSoftly() { // soft-kill works on Unix systems - return SystemInfo.isUnix; + return SystemInfo.isUnix && processCanBeKilledByOS(getProcess()); } @Override protected void doDestroyProcess() { - if (!canKillProcess()) { + if (canKillProcessSoftly() && shouldKillProcessSoftly()) { + // Unix: [soft-kill] at first send INT signal: + final Process process = getProcess(); + UnixProcessManager.sendSigIntToProcessTree(process); + } + else { // if soft kill isn't supported - use default implementation super.doDestroyProcess(); - return; + // else IDE will suggest 'terminate dialog' } + } - // Unix: [soft-kill] at first send INT signal: - final Process process = getProcess(); - UnixProcessManager.sendSigIntToProcessTree(process); + /** + * This method should be overriden by children if the process shouldn't be killed softly (e.g. by kill -2) + * @return + */ + protected boolean shouldKillProcessSoftly() { + return true; + } - // else IDE will suggest 'terminate dialog' + @Override + public boolean canKillProcess() { + return processCanBeKilledByOS(getProcess()); } @Override diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSshProcess.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSshProcess.java index 9b0415c122e3..85b4c0bac93f 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSshProcess.java +++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSshProcess.java @@ -1,9 +1,11 @@ package com.intellij.remotesdk; +import com.intellij.execution.process.OSProcessManager; + /** * @author traff */ -abstract public class RemoteSshProcess extends Process { +abstract public class RemoteSshProcess extends Process implements OSProcessManager.SelfKiller { /** * Makes host:localPort server which is available on local side available on remote side as localhost:remotePort. */