From eb93725b1fb84d50d70ba57ce48e6fadfd983a7f Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Tue, 29 Jan 2013 17:20:38 +0400 Subject: [PATCH] added setenv method from "c" lib --- .../PathEnvironmentVariableUtil.java | 116 +++++------------- .../execution/process/UnixProcessManager.java | 19 ++- 2 files changed, 51 insertions(+), 84 deletions(-) diff --git a/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java b/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java index 4bde01e7c2a9..d4d05fa21498 100644 --- a/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java +++ b/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java @@ -1,44 +1,37 @@ package com.intellij.execution.configurations; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.process.CapturingProcessHandler; -import com.intellij.execution.process.ProcessOutput; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; +import com.intellij.execution.process.UnixProcessManager; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.util.EnvironmentUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; +import java.lang.reflect.Field; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; /** * @author Sergey Simonchik */ public class PathEnvironmentVariableUtil { - private static final Logger LOG = Logger.getInstance(PathEnvironmentVariableUtil.class); public static final String PATH_ENV_VAR_NAME = "PATH"; - private static final int BLOCK_TIMEOUT_MILLIS = 50; - private static volatile String ourFixedMacPathEnvVarValue; + private static final String ourFixedMacPathEnvVarValue; + static { - asyncCalcFixedMacPathEnvVarValue(); + ourFixedMacPathEnvVarValue = calcFixedMacPathEnvVarValue(); } - private PathEnvironmentVariableUtil() {} + private PathEnvironmentVariableUtil() { + } /** - * Tries to return a real value for PATH environment variable by parsing the result of - * {@code /usr/libexec/path_helper -s} command execution. + * Tries to return a real value for PATH environment variable. * Workaround for http://youtrack.jetbrains.com/issue/IDEA-99154 */ @Nullable @@ -46,78 +39,17 @@ public class PathEnvironmentVariableUtil { return ourFixedMacPathEnvVarValue; } - @Nullable - private static String getOriginalPathEnvVarValue() { - Map envVars = EnvironmentUtil.getEnvironmentProperties(); - return envVars.get(PATH_ENV_VAR_NAME); - } - - private static void asyncCalcFixedMacPathEnvVarValue() { + private static String calcFixedMacPathEnvVarValue() { if (SystemInfo.isMac) { - final String originalValue = getOriginalPathEnvVarValue(); - final Semaphore semaphore = new Semaphore(0, true); - ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { - @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod") - @Override - public void run() { - try { - ourFixedMacPathEnvVarValue = findFixedPathEnvVarValue(originalValue); - } - finally { - semaphore.release(); - } - } - }); - try { - semaphore.tryAcquire(BLOCK_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); - } - catch (InterruptedException e) { - LOG.info("Unexpected thread interruption", e); - } - } - } - - @Nullable - private static String findFixedPathEnvVarValue(@Nullable String originalValue) { - File executable = new File("/usr/libexec/path_helper"); - if (executable.isFile() && executable.canExecute()) { - GeneralCommandLine commandLine = new GeneralCommandLine(); - try { - commandLine.setExePath(executable.getAbsolutePath()); - commandLine.addParameter("-s"); - List stdout = executeAndGetStdout(commandLine); - final String prefix = "PATH=\""; - final String suffix = "\"; export PATH;"; - for (String line : stdout) { - if (line.startsWith(prefix) && line.endsWith(suffix)) { - String value = line.substring(prefix.length(), line.length() - suffix.length()); - return mergePaths(ContainerUtil.newArrayList(originalValue, value)); - } - } - } catch (Exception e) { - LOG.info("Can't execute '" + commandLine.getCommandLineString() + "'", e); - } + Map originalEnvVars = EnvironmentUtil.getEnvironmentProperties(); + final String originalPath = originalEnvVars.get(PATH_ENV_VAR_NAME); + Map envVars = UnixProcessManager.getOrLoadConsoleEnvironment(); + String consolePath = envVars.get(PATH_ENV_VAR_NAME); + return mergePaths(ContainerUtil.newArrayList(originalPath, consolePath)); } return null; } - @NotNull - public static List executeAndGetStdout(@NotNull GeneralCommandLine commandLine) throws ExecutionException { - final Process process = commandLine.createProcess(); - CapturingProcessHandler processHandler = new CapturingProcessHandler(process, CharsetToolkit.UTF8_CHARSET); - ProcessOutput output = processHandler.runProcess(2000); - int exitCode = output.getExitCode(); - if (exitCode != 0) { - throw new ExecutionException("Exit code of '" + commandLine.getCommandLineString() - + "' is " + exitCode); - } - if (!output.getStderr().isEmpty()) { - throw new ExecutionException("Stderr of '" + commandLine.getCommandLineString() - + "': " + output.getStderr()); - } - return output.getStdoutLines(); - } - @Nullable private static String mergePaths(@NotNull List pathStrings) { LinkedHashSet paths = ContainerUtil.newLinkedHashSet(); @@ -135,4 +67,24 @@ public class PathEnvironmentVariableUtil { return StringUtil.join(paths, File.pathSeparator); } + public static void setPathEnvVarAtProcessLevel() { + if (ourFixedMacPathEnvVarValue != null) { + UnixProcessManager.setEnv(PATH_ENV_VAR_NAME, ourFixedMacPathEnvVarValue, true); + } + } + + public static void setPathEnvVarInSystemEnv() { + try { + Map unmodifiable = System.getenv(); + Class cu = unmodifiable.getClass(); + Field m = cu.getDeclaredField("m"); + m.setAccessible(true); + Map map = (Map)m.get(unmodifiable); + if (ourFixedMacPathEnvVarValue != null) { + map.put(PATH_ENV_VAR_NAME, ourFixedMacPathEnvVarValue); + } + } + catch (Exception ignore) { + } + } } diff --git a/platform/util/src/com/intellij/execution/process/UnixProcessManager.java b/platform/util/src/com/intellij/execution/process/UnixProcessManager.java index fa1281c40902..56b6d8e6180b 100644 --- a/platform/util/src/com/intellij/execution/process/UnixProcessManager.java +++ b/platform/util/src/com/intellij/execution/process/UnixProcessManager.java @@ -88,6 +88,21 @@ public class UnixProcessManager { C_LIB.kill(pid, signal); } + + /** + * Adds or changes an environment variable. + * @param name string that contains the name of the environment variable to be added or changed + * @param value the value of the environment variable + * @param overwrite change the existing entry. If {@code name} has already been defined and exists in the environment variable table, + * its value will be updated with {@code value}. If {@code name} was previously undefined, it will be appended to the table. + */ + public static void setEnv(@NotNull String name, @NotNull String value, boolean overwrite) { + if (C_LIB != null) { + checkCLib(); + C_LIB.setenv(name, value, overwrite ? 1 : 0); + } + } + private static void checkCLib() { if (C_LIB == null) { throw new IllegalStateException("System is not unix(couldn't load c library)"); @@ -290,10 +305,10 @@ public class UnixProcessManager { } - public interface CLib extends Library { + private interface CLib extends Library { int getpid(); - int kill(int pid, int signal); + int setenv(String name, String value, int overwrite); } public static class ProcessInfo {