2 * Copyright 2000-2012 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.execution.process;
18 import com.intellij.execution.ExecutionException;
19 import com.intellij.execution.configurations.GeneralCommandLine;
20 import com.intellij.execution.configurations.PtyCommandLine;
21 import com.intellij.openapi.application.Application;
22 import com.intellij.openapi.application.ApplicationManager;
23 import com.intellij.openapi.diagnostic.Logger;
24 import com.intellij.openapi.vfs.CharsetToolkit;
25 import com.intellij.openapi.vfs.encoding.EncodingManager;
26 import org.jetbrains.annotations.NotNull;
27 import org.jetbrains.annotations.Nullable;
29 import java.nio.charset.Charset;
30 import java.util.concurrent.Future;
32 public class OSProcessHandler extends BaseOSProcessHandler {
33 private static final Logger LOG = Logger.getInstance("#com.intellij.execution.process.OSProcessHandler");
34 private boolean myHasPty = false;
36 private boolean myDestroyRecursively = true;
38 public OSProcessHandler(@NotNull GeneralCommandLine commandLine) throws ExecutionException {
39 this(commandLine.createProcess(), commandLine.getCommandLineString(), CharsetToolkit.UTF8_CHARSET);
40 setHasPty(commandLine instanceof PtyCommandLine);
43 public OSProcessHandler(@NotNull final Process process) {
47 public OSProcessHandler(@NotNull final Process process, @Nullable final String commandLine) {
48 this(process, commandLine, EncodingManager.getInstance().getDefaultCharset());
51 public OSProcessHandler(@NotNull final Process process, @Nullable final String commandLine, @Nullable final Charset charset) {
52 super(process, commandLine, charset);
55 protected OSProcessHandler(@NotNull final OSProcessHandler base) {
56 this(base.myProcess, base.myCommandLine);
60 protected Future<?> executeOnPooledThread(Runnable task) {
61 final Application application = ApplicationManager.getApplication();
63 if (application != null) {
64 return application.executeOnPooledThread(task);
67 return super.executeOnPooledThread(task);
70 protected boolean shouldDestroyProcessRecursively() {
71 // Override this method if you want to kill process recursively (whole process try) by default
72 // such behaviour is better than default java one, which doesn't kill children processes
73 return myDestroyRecursively;
76 public void setShouldDestroyProcessRecursively(boolean destroyRecursively) {
77 myDestroyRecursively = destroyRecursively;
81 protected void doDestroyProcess() {
82 // Override this method if you want to customize default destroy behaviour, e.g.
83 // if you want use some soft-kill.
84 final Process process = getProcess();
85 if (shouldDestroyProcessRecursively() && processCanBeKilledByOS(process)) {
86 killProcessTree(process);
93 public static boolean processCanBeKilledByOS(Process process) {
94 return !(process instanceof SelfKiller);
98 * Kill the whole process tree.
100 * @param process Process
101 * @return True if process tree has been successfully killed.
103 protected boolean killProcessTree(@NotNull Process process) {
104 LOG.debug("killing process tree");
105 final boolean destroyed = OSProcessManager.getInstance().killProcessTree(process);
107 LOG.warn("Cannot kill process tree. Trying to destroy process using Java API. Cmdline:\n" + myCommandLine);
114 * In case of pty this process handler will use blocking read. The value should be set before
115 * startNotify invocation. It is set by default in case of using GeneralCommandLine based constructor.
117 * @param hasPty true if process is pty based
119 public void setHasPty(boolean hasPty) {
124 protected boolean useNonBlockingRead() {
126 // blocking read in case of pty based process
130 return super.useNonBlockingRead();