< prev index next >

src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/CommandExecutor.java

Print this page
rev 1636 : 8151291: $EXEC yields "unknown command" on Cygwin
Reviewed-by: jlaskey, hanneswi, sdama

*** 62,71 **** --- 62,74 ---- private static final boolean IS_WINDOWS = AccessController.doPrivileged((PrivilegedAction<Boolean>)() -> { return System.getProperty("os.name").contains("Windows"); }); + // Cygwin drive alias prefix. + private static final String CYGDRIVE = "/cygdrive/"; + // User's home directory private static final String HOME_DIRECTORY = AccessController.doPrivileged((PrivilegedAction<String>)() -> { return System.getProperty("user.home"); });
*** 386,396 **** * @param cwd current working directory * @param fileName name of file or directory * @return resolved Path to file */ private static Path resolvePath(final String cwd, final String fileName) { ! return Paths.get(cwd).resolve(fileName).normalize(); } /** * builtIn - checks to see if the command is a builtin and performs * appropriate action. --- 389,399 ---- * @param cwd current working directory * @param fileName name of file or directory * @return resolved Path to file */ private static Path resolvePath(final String cwd, final String fileName) { ! return Paths.get(sanitizePath(cwd)).resolve(fileName).normalize(); } /** * builtIn - checks to see if the command is a builtin and performs * appropriate action.
*** 400,410 **** */ private boolean builtIn(final List<String> cmd, final String cwd) { switch (cmd.get(0)) { // Set current working directory. case "cd": ! // If zero args then use home dirrectory as cwd else use first arg. final String newCWD = cmd.size() < 2 ? HOME_DIRECTORY : cmd.get(1); // Normalize the cwd final Path cwdPath = resolvePath(cwd, newCWD); // Check if is a directory. --- 403,414 ---- */ private boolean builtIn(final List<String> cmd, final String cwd) { switch (cmd.get(0)) { // Set current working directory. case "cd": ! final boolean cygpath = IS_WINDOWS && cwd.startsWith(CYGDRIVE); ! // If zero args then use home directory as cwd else use first arg. final String newCWD = cmd.size() < 2 ? HOME_DIRECTORY : cmd.get(1); // Normalize the cwd final Path cwdPath = resolvePath(cwd, newCWD); // Check if is a directory.
*** 416,426 **** reportError("not.directory", file.toString()); return true; } // Set PWD environment variable to be picked up as cwd. ! environment.put("PWD", cwdPath.toString()); return true; // Set an environment variable. case "setenv": if (3 <= cmd.size()) { --- 420,436 ---- reportError("not.directory", file.toString()); return true; } // Set PWD environment variable to be picked up as cwd. ! // Make sure Cygwin paths look like Unix paths. ! String scwd = cwdPath.toString(); ! if (cygpath && scwd.length() >= 2 && ! Character.isLetter(scwd.charAt(0)) && scwd.charAt(1) == ':') { ! scwd = CYGDRIVE + Character.toLowerCase(scwd.charAt(0)) + "/" + scwd.substring(2); ! } ! environment.put("PWD", scwd); return true; // Set an environment variable. case "setenv": if (3 <= cmd.size()) {
*** 443,453 **** return false; } /** ! * preprocessCommand - scan the command for redirects * @param tokens command tokens * @param cwd current working directory * @param redirectInfo redirection information * @return tokens remaining for actual command */ --- 453,464 ---- return false; } /** ! * preprocessCommand - scan the command for redirects, and sanitize the ! * executable path * @param tokens command tokens * @param cwd current working directory * @param redirectInfo redirection information * @return tokens remaining for actual command */
*** 469,493 **** // Strip quotes and add to command. command.add(stripQuotes(token)); } return command; } /** * createProcessBuilder - create a ProcessBuilder for the command. * @param command command tokens * @param cwd current working directory * @param redirectInfo redirect information */ private void createProcessBuilder(final List<String> command, final String cwd, final RedirectInfo redirectInfo) { // Create new ProcessBuilder. final ProcessBuilder pb = new ProcessBuilder(command); // Set current working directory. ! pb.directory(new File(cwd)); // Map environment variables. final Map<String, String> processEnvironment = pb.environment(); processEnvironment.clear(); processEnvironment.putAll(environment); --- 480,533 ---- // Strip quotes and add to command. command.add(stripQuotes(token)); } + if (command.size() > 0) { + command.set(0, sanitizePath(command.get(0))); + } + return command; } /** + * Sanitize a path in case the underlying platform is Cygwin. In that case, + * convert from the {@code /cygdrive/x} drive specification to the usual + * Windows {@code X:} format. + * + * @param d a String representing a path + * @return a String representing the same path in a form that can be + * processed by the underlying platform + */ + private static String sanitizePath(final String d) { + if (!IS_WINDOWS || (IS_WINDOWS && !d.startsWith(CYGDRIVE))) { + return d; + } + final String pd = d.substring(CYGDRIVE.length()); + if (pd.length() >= 2 && pd.charAt(1) == '/') { + // drive letter plus / -> convert /cygdrive/x/... to X:/... + return pd.charAt(0) + ":" + pd.substring(1); + } else if (pd.length() == 1) { + // just drive letter -> convert /cygdrive/x to X: + return pd.charAt(0) + ":"; + } + // remaining case: /cygdrive/ -> can't convert + return d; + } + + /** * createProcessBuilder - create a ProcessBuilder for the command. * @param command command tokens * @param cwd current working directory * @param redirectInfo redirect information */ private void createProcessBuilder(final List<String> command, final String cwd, final RedirectInfo redirectInfo) { // Create new ProcessBuilder. final ProcessBuilder pb = new ProcessBuilder(command); // Set current working directory. ! pb.directory(new File(sanitizePath(cwd))); // Map environment variables. final Map<String, String> processEnvironment = pb.environment(); processEnvironment.clear(); processEnvironment.putAll(environment);
*** 521,531 **** } // Create ProcessBuilder with cwd and redirects set. createProcessBuilder(command, cwd, redirectInfo); ! // If piped the wait for the next command. if (isPiped) { return; } // Fetch first and last ProcessBuilder. --- 561,571 ---- } // Create ProcessBuilder with cwd and redirects set. createProcessBuilder(command, cwd, redirectInfo); ! // If piped, wait for the next command. if (isPiped) { return; } // Fetch first and last ProcessBuilder.
*** 763,773 **** command(command, false); } /** * process - process a command array of strings ! * @param script command script to be processed */ void process(final List<String> tokens) { // Prepare to accumulate command tokens. final List<String> command = new ArrayList<>(); --- 803,813 ---- command(command, false); } /** * process - process a command array of strings ! * @param tokens command script to be processed */ void process(final List<String> tokens) { // Prepare to accumulate command tokens. final List<String> command = new ArrayList<>();
< prev index next >