From: <cr...@us...> - 2009-02-15 05:39:36
|
Revision: 5026 http://jnode.svn.sourceforge.net/jnode/?rev=5026&view=rev Author: crawley Date: 2009-02-15 05:39:30 +0000 (Sun, 15 Feb 2009) Log Message: ----------- Changes to core infrastructure to allow 'procletization' of the System properties and environment. System.getenv() et al are wired up, but System.getProperties() et al are not. Also implemented in shell, the proclet-mode invoker and the Bjorne interpreter (via the 'export' built-in). Modified Paths: -------------- trunk/core/src/core/org/jnode/vm/IOContext.java trunk/core/src/core/org/jnode/vm/VmIOContext.java trunk/core/src/core/org/jnode/vm/VmSystem.java trunk/core/src/openjdk/svm/java/lang/ProcessEnvironment.java trunk/shell/src/shell/org/jnode/shell/AsyncCommandInvoker.java trunk/shell/src/shell/org/jnode/shell/CommandInvoker.java trunk/shell/src/shell/org/jnode/shell/CommandRunner.java trunk/shell/src/shell/org/jnode/shell/CommandShell.java trunk/shell/src/shell/org/jnode/shell/DefaultCommandInvoker.java trunk/shell/src/shell/org/jnode/shell/DefaultInterpreter.java trunk/shell/src/shell/org/jnode/shell/RedirectingInterpreter.java trunk/shell/src/shell/org/jnode/shell/ShellManager.java trunk/shell/src/shell/org/jnode/shell/ShellUtils.java trunk/shell/src/shell/org/jnode/shell/ThreadCommandInvoker.java trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneControlException.java trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneInterpreter.java trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneParser.java trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneToken.java trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneTokenizer.java trunk/shell/src/shell/org/jnode/shell/bjorne/ExitBuiltin.java trunk/shell/src/shell/org/jnode/shell/bjorne/VariableSlot.java trunk/shell/src/shell/org/jnode/shell/command/PrintEnvCommand.java trunk/shell/src/shell/org/jnode/shell/def/DefaultShellManager.java trunk/shell/src/shell/org/jnode/shell/isolate/IsolateCommandInvoker.java trunk/shell/src/shell/org/jnode/shell/proclet/ProcletCommandInvoker.java trunk/shell/src/shell/org/jnode/shell/proclet/ProcletContext.java trunk/shell/src/shell/org/jnode/shell/proclet/ProcletIOContext.java Added Paths: ----------- trunk/shell/src/shell/org/jnode/shell/SimpleCommandInvoker.java trunk/shell/src/shell/org/jnode/shell/bjorne/ExportBuiltin.java Modified: trunk/core/src/core/org/jnode/vm/IOContext.java =================================================================== --- trunk/core/src/core/org/jnode/vm/IOContext.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/core/src/core/org/jnode/vm/IOContext.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -22,57 +22,24 @@ import java.io.InputStream; import java.io.PrintStream; +import java.util.Map; +import java.util.Properties; /** - * This interface provides the hooks for implementing special semantics for System.in, System.out - * and System.err. Specifically, it is used to implement 'proclet' mode where the stream objects - * are proxies for context specific streams. + * This interface provides the hooks for implementing special semantics for + * System.in, System.out and System.err. Specifically, it is used to implement + * 'proclet' mode where the stream objects are proxies for context specific + * streams. It also supports 'proclet' mode contextualization of the System + * properties ({@link System#getProperties()}) and environment ({@link System#getenv()}). * * @author Levente S\u00e1ntha * @author cr...@jn... */ public interface IOContext { + + // FIXME ... the name of this interface is misleading. /** - * This hook is used to set the 'global' version of System.in; e.g. the one used - * when there is no active proclet context. - * - * @param in the new global System.in - */ - void setGlobalInStream(InputStream in); - - /** - * This hook is used to get the 'global' version of System.in. - */ - InputStream getGlobalInStream(); - - /** - * This hook is used to set the 'global' version of System.out; e.g. the one used - * when there is no active proclet context. - * - * @param out the new global System.out - */ - void setGlobalOutStream(PrintStream out); - - /** - * This hook is used to get the 'global' version of System.out. - */ - PrintStream getGlobalOutStream(); - - /** - * This hook is used to set the 'global' version of System.err; e.g. the one used - * when there is no active proclet context. - * - * @param err the new global System.err - */ - void setGlobalErrStream(PrintStream err); - - /** - * This hook is used to get the 'global' version of System.err. - */ - PrintStream getGlobalErrStream(); - - /** * This hook is used when "setting" System.in; i.e. via System.setIn(in). * * @param in the application supplied value for System.in @@ -107,8 +74,31 @@ * This hook is used to get the 'real' stream underlying System.err in the current context. */ PrintStream getRealSystemErr(); + + /** + * The hook is used to get the current context's 'system properties' + */ + Properties getProperties(); + + /** + * The hook is used to set the current context's 'system properties' + */ + void setProperties(Properties props); + + /** + * The hook is used to get the current context's environment; e.g. containing exported + * shell variables. + */ + Map<String, String> getEnv(); + + /** + * The hook is used to get the current context's environment. + */ + void setEnv(Map<String, String> env); void enterContext(); void exitContext(); + + } Modified: trunk/core/src/core/org/jnode/vm/VmIOContext.java =================================================================== --- trunk/core/src/core/org/jnode/vm/VmIOContext.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/core/src/core/org/jnode/vm/VmIOContext.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -22,40 +22,29 @@ import java.io.InputStream; import java.io.PrintStream; +import java.util.Map; +import java.util.Properties; /** + * This is the implementation of the IOContext API that is be used when + * 'proclet' mode is not enabled. It also provides static methods for + * getting and setting the 'global' versions of the Stream state, and + * the System properties and environment. (The 'global' state is used + * in 'proclet' mode when the current thread is not part of a 'proclet'.) + * * @author Levente S\u00e1ntha * @author cr...@jn... */ public class VmIOContext implements IOContext { + // FIXME ... restrict visibility (if possible) and add Java security + // access controls. + private static InputStream globalInStream; private static PrintStream globalOutStream; private static PrintStream globalErrStream; + private static Properties globalSysProps; + private static Map<String, String> globalEnv; - public void setGlobalInStream(InputStream in) { - globalInStream = in; - } - - public void setGlobalOutStream(PrintStream out) { - globalOutStream = out; - } - - public PrintStream getGlobalOutStream() { - return globalOutStream; - } - - public void setGlobalErrStream(PrintStream err) { - globalErrStream = err; - } - - public PrintStream getGlobalErrStream() { - return globalErrStream; - } - - public InputStream getGlobalInStream() { - return globalInStream; - } - public void setSystemIn(InputStream in) { globalInStream = in; VmSystem.setStaticField(System.class, "in", in); @@ -90,4 +79,100 @@ public PrintStream getRealSystemOut() { return System.out; } + + public Map<String, String> getEnv() { + return globalEnv; + } + + public Properties getProperties() { + return globalSysProps; + } + + public void setEnv(Map<String, String> env) { + globalEnv = env; + } + + public void setProperties(Properties props) { + globalSysProps = props; + } + + /** + * Set the 'global' view of {@link System#in}. + * @param in the new input stream. + */ + public static void setGlobalInStream(InputStream in) { + globalInStream = in; + } + + /** + * Set the 'global' view of {@link System#out}. + * @param in the new output stream. + */ + public static void setGlobalOutStream(PrintStream out) { + globalOutStream = out; + } + + /** + * Get the 'global' view of {@link System#out}. + * @return the 'global' output stream. + */ + public static PrintStream getGlobalOutStream() { + return globalOutStream; + } + + /** + * Set the 'global' view of {@link System#err}. + * @param in the new error stream. + */ + public static void setGlobalErrStream(PrintStream err) { + globalErrStream = err; + } + + /** + * Get the 'global' view of {@link System#err}. + * @return the 'global' error stream. + */ + public static PrintStream getGlobalErrStream() { + return globalErrStream; + } + + /** + * Get the 'global' view of {@link System#in}. + * @return the 'global' input stream. + */ + public static InputStream getGlobalInStream() { + return globalInStream; + } + + /** + * Set the 'global' view of the environment returned by {@link System#getenv()}. + * @param env the new 'global' environment. + */ + public static void setGlobalEnv(Map<String, String> env) { + globalEnv = env; + } + + /** + * Set the 'global' view of the Properties returned by {@link System#getProperties()}. + * @param env the new 'global' properties. + */ + public static void setGlobalProperties(Properties props) { + globalSysProps = props; + } + + /** + * Get the 'global' view of the environment returned by {@link System#getenv()}. + * @return the current 'global' environment. + */ + public static Map<String, String> getGlobalEnv() { + return globalEnv; + } + + /** + * Get the 'global' view of the Properties returned by {@link System#getProperties()}. + * @return the current 'global' Properties. + */ + public static Properties getGlobalProperties() { + return globalSysProps; + } } Modified: trunk/core/src/core/org/jnode/vm/VmSystem.java =================================================================== --- trunk/core/src/core/org/jnode/vm/VmSystem.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/core/src/core/org/jnode/vm/VmSystem.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -171,11 +171,11 @@ final ConsoleAppender infoApp = new ConsoleAppender(new PatternLayout(LAYOUT)); root.addAppender(infoApp); - initOpenJDKSpeciffics(); + initOpenJDKSpecifics(); } } - private static void initOpenJDKSpeciffics() { + private static void initOpenJDKSpecifics() { //todo this will be moved to java.lang.System during openjdk integration sun.misc.SharedSecrets.setJavaLangAccess(new sun.misc.JavaLangAccess() { public sun.reflect.ConstantPool getConstantPool(Class klass) { @@ -199,6 +199,9 @@ throw new UnsupportedOperationException(); } }); + + // Trigger initialization of the global environment variables. + System.getenv(); } static boolean isInitialized() { @@ -221,14 +224,13 @@ if (bootOut == null) { bootOut = sout; bootOutStream = new PrintStream(bootOut, true); - IOContext ioContext = getIOContext(); - ioContext.setGlobalOutStream(bootOutStream); - ioContext.setGlobalErrStream(bootOutStream); + VmIOContext.setGlobalOutStream(bootOutStream); + VmIOContext.setGlobalErrStream(bootOutStream); return bootOutStream; } else if (VmIsolate.isRoot()) { return bootOutStream; } else { - return VmIsolate.currentIsolate().getIOContext().getGlobalOutStream(); + return VmIOContext.getGlobalOutStream(); } } @@ -1125,7 +1127,7 @@ * @return the global 'err' stream. */ public static PrintStream getGlobalErrStream() { - return getIOContext().getGlobalErrStream(); + return VmIOContext.getGlobalErrStream(); } /** @@ -1134,7 +1136,7 @@ * @return the global 'in' stream. */ public static InputStream getGlobalInStream() { - return getIOContext().getGlobalInStream(); + return VmIOContext.getGlobalInStream(); } /** @@ -1143,7 +1145,7 @@ * @return the global 'out' stream. */ public static PrintStream getGlobalOutStream() { - return getIOContext().getGlobalOutStream(); + return VmIOContext.getGlobalOutStream(); } /** Modified: trunk/core/src/openjdk/svm/java/lang/ProcessEnvironment.java =================================================================== --- trunk/core/src/openjdk/svm/java/lang/ProcessEnvironment.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/core/src/openjdk/svm/java/lang/ProcessEnvironment.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -57,9 +57,16 @@ import java.io.*; import java.util.*; +import org.jnode.vm.VmIOContext; +import org.jnode.vm.VmSystem; + final class ProcessEnvironment { + // FIXME ... this class needs some work for JNode, Redo / remove the + // code that populates the map from the 'C environment' and maybe even + // get rid of StringEnvironment and replace it with a simple HashMap. + private static final HashMap<Variable,Value> theEnvironment; private static final Map<String,String> theUnmodifiableEnvironment; static final int MIN_NAME_LENGTH = 0; @@ -78,16 +85,18 @@ theUnmodifiableEnvironment = Collections.unmodifiableMap (new StringEnvironment(theEnvironment)); + + VmIOContext.setGlobalEnv(theUnmodifiableEnvironment); } /* Only for use by System.getenv(String) */ static String getenv(String name) { - return theUnmodifiableEnvironment.get(name); + return VmSystem.getIOContext().getEnv().get(name); } /* Only for use by System.getenv() */ static Map<String,String> getenv() { - return theUnmodifiableEnvironment; + return VmSystem.getIOContext().getEnv(); } /* Only for use by ProcessBuilder.environment() */ Modified: trunk/shell/src/shell/org/jnode/shell/AsyncCommandInvoker.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/AsyncCommandInvoker.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/AsyncCommandInvoker.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -27,6 +27,8 @@ import java.lang.reflect.Modifier; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.Map; +import java.util.Properties; import org.jnode.driver.input.KeyboardEvent; import org.jnode.driver.input.KeyboardListener; @@ -46,7 +48,7 @@ * @author Martin Husted Hartvig (ha...@jn...) * @author cr...@jn... */ -public abstract class AsyncCommandInvoker implements CommandInvoker, +public abstract class AsyncCommandInvoker implements SimpleCommandInvoker, KeyboardListener { CommandShell commandShell; @@ -92,9 +94,15 @@ CommandRunner cr = setup(cmdLine, cmdInfo); return forkIt(cmdLine, cmdInfo, cr); } - - private CommandRunner setup(CommandLine cmdLine, CommandInfo cmdInfo) + + protected CommandRunner setup(CommandLine cmdLine, CommandInfo cmdInfo) throws ShellException { + return setup(cmdLine, cmdInfo, null, null); + } + + protected CommandRunner setup(CommandLine cmdLine, CommandInfo cmdInfo, + Properties sysProps, Map<String, String> env) + throws ShellException { Method method; CommandRunner cr = null; @@ -112,7 +120,7 @@ throw new ShellInvocationException("Problem while creating command instance", ex); } if (command != null) { - cr = new CommandRunner(this, cmdInfo, cmdLine, resolvedIOs); + cr = new CommandRunner(this, cmdInfo, cmdLine, resolvedIOs, sysProps, env); } else { try { method = cmdInfo.getCommandClass().getMethod(MAIN_METHOD, MAIN_ARG_TYPES); @@ -132,7 +140,7 @@ method.setAccessible(true); cr = new CommandRunner( this, cmdInfo, cmdInfo.getCommandClass(), method, - new Object[] {cmdLine.getArguments()}, resolvedIOs); + new Object[] {cmdLine.getArguments()}, resolvedIOs, sysProps, env); } catch (NoSuchMethodException e) { // continue; } @@ -147,7 +155,7 @@ return cr; } - private int runIt(CommandLine cmdLine, CommandInfo cmdInfo, CommandRunner cr) + protected int runIt(CommandLine cmdLine, CommandInfo cmdInfo, CommandRunner cr) throws ShellInvocationException { try { if (cmdInfo.isInternal()) { @@ -178,7 +186,7 @@ } } - private CommandThread forkIt(CommandLine cmdLine, CommandInfo cmdInfo, + protected CommandThread forkIt(CommandLine cmdLine, CommandInfo cmdInfo, CommandRunner cr) throws ShellInvocationException { if (cmdInfo.isInternal()) { throw new ShellFailureException("unexpected internal command"); Modified: trunk/shell/src/shell/org/jnode/shell/CommandInvoker.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/CommandInvoker.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/CommandInvoker.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -20,36 +20,35 @@ package org.jnode.shell; -/* - * User: Sam Reid Date: Dec 20, 2003 Time: 1:18:31 AM Copyright (c) Dec 20, 2003 - * by Sam Reid - */ +import java.util.Map; +import java.util.Properties; /** - * This is the common API for the various mechanisms for running 'commands'. - * - * @author Sam Reid + * This 'advanced' invoker API adds methods for invoking commands with + * different system properties or environment variables to the parent. + * * @author cr...@jn... */ -public interface CommandInvoker { +public interface CommandInvoker extends SimpleCommandInvoker { - public interface Factory { - CommandInvoker create(CommandShell shell); - - String getName(); - } - /** * Run a command synchronously, passing back the resulting return code. * * @param commandLine this provides the command name (alias), the command * arguments and (where relevant) the command's i/o stream context. * @param cmdInfo a CommandInfo descriptor for the command to be run. + * @param sysProps a Properties object containing the command's system + * properties. If this parameter is {@code null}, a copy of the + * system properties for the calling context should be used. + * @param env a Map object containing the command's environment variables. + * If this parameter is {@code null}, the environment variables for + * the calling context should be used. * @return an integer return code, with zero indicating command success, * non-zero indicating command failure. * @throws ShellException if there was some problem launching the command. */ - int invoke(CommandLine commandLine, CommandInfo cmdInfo) + int invoke(CommandLine commandLine, CommandInfo cmdInfo, + Properties sysProps, Map<String, String> env) throws ShellException; /** @@ -59,22 +58,19 @@ * @param commandLine this provides the command name (alias), the command * arguments and (where relevant) the command's i/o stream context. * @param cmdInfo a CommandInfo descriptor for the command to be run. + * @param sysProps a Properties object containing the command's system + * properties. If this parameter is {@code null}, a copy of the + * system properties for the calling context should be used. + * @param env a Map object containing the command's environment variables. + * If this parameter is {@code null}, the environment variables for + * the calling context should be used. * @return the thread for the command. Calling * {@link java.lang.Thread#start()} will cause the command to * execute. * @throws ShellException if there was some problem launching the command. */ - CommandThread invokeAsynchronous(CommandLine commandLine, CommandInfo cmdInfo) + CommandThread invokeAsynchronous(CommandLine commandLine, CommandInfo cmdInfo, + Properties sysProps, Map<String, String> env) throws ShellException; - /** - * Get the invoker's name. - * - * @return the name. - */ - String getName(); - - boolean isDebugEnabled(); - - void setDebugEnabled(boolean enabled); } Modified: trunk/shell/src/shell/org/jnode/shell/CommandRunner.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/CommandRunner.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/CommandRunner.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -29,6 +29,8 @@ import java.lang.reflect.Modifier; import java.security.AccessController; import java.security.PrivilegedActionException; +import java.util.Map; +import java.util.Properties; import org.jnode.shell.help.HelpException; import org.jnode.shell.help.HelpFactory; @@ -45,7 +47,7 @@ */ public class CommandRunner implements Runnable { - private final CommandInvoker invoker; + private final SimpleCommandInvoker invoker; private final CommandIO[] ios; final Class<?> targetClass; final Method method; @@ -53,12 +55,14 @@ final CommandInfo cmdInfo; final CommandLine commandLine; final PrintWriter shellErr; + final Properties sysProps; + final Map<String, String> env; private int rc; - public CommandRunner(CommandInvoker invoker, + public CommandRunner(SimpleCommandInvoker invoker, CommandInfo cmdInfo, Class<?> targetClass, Method method, Object[] args, - CommandIO[] ios) { + CommandIO[] ios, Properties sysProps, Map<String, String> env) { this.invoker = invoker; this.targetClass = targetClass; this.method = method; @@ -67,10 +71,13 @@ this.args = args; this.ios = ios; this.shellErr = ios[Command.SHELL_ERR].getPrintWriter(); + this.env = env; + this.sysProps = sysProps; } - public CommandRunner(CommandInvoker invoker, - CommandInfo cmdInfo, CommandLine commandLine, CommandIO[] ios) { + public CommandRunner(SimpleCommandInvoker invoker, + CommandInfo cmdInfo, CommandLine commandLine, CommandIO[] ios, + Properties sysProps, Map<String, String> env) { this.invoker = invoker; this.targetClass = null; this.method = null; @@ -79,6 +86,8 @@ this.commandLine = commandLine; this.ios = ios; this.shellErr = ios[Command.SHELL_ERR].getPrintWriter(); + this.env = env; + this.sysProps = sysProps; } public void run() { @@ -199,4 +208,11 @@ return commandLine != null ? commandLine.getCommandName() : null; } + public Properties getSysProps() { + return sysProps; + } + + public Map<String, String> getEnv() { + return env; + } } Modified: trunk/shell/src/shell/org/jnode/shell/CommandShell.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/CommandShell.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/CommandShell.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -38,6 +38,8 @@ import java.text.DateFormat; import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.Properties; import java.util.StringTokenizer; import javax.naming.NameNotFoundException; @@ -151,7 +153,7 @@ */ private String lastInputLine = ""; - private CommandInvoker invoker; + private SimpleCommandInvoker invoker; private String invokerName; private CommandInterpreter interpreter; @@ -573,11 +575,19 @@ * command is run using the CommandShell's current invoker. * * @param cmdLine the CommandLine object. + * @param env + * @param sysProps * @return the command's return code * @throws ShellException */ - public int invoke(CommandLine cmdLine, CommandInfo cmdInfo) throws ShellException { - return this.invoker.invoke(cmdLine, cmdInfo); + public int invoke(CommandLine cmdLine, CommandInfo cmdInfo, + Properties sysProps, Map<String, String> env) + throws ShellException { + if (this.invoker instanceof CommandInvoker) { + return ((CommandInvoker) this.invoker).invoke(cmdLine, cmdInfo, sysProps, env); + } else { + return this.invoker.invoke(cmdLine, cmdInfo); + } } /** @@ -843,7 +853,7 @@ } } - public CommandInvoker getDefaultCommandInvoker() { + public SimpleCommandInvoker getDefaultCommandInvoker() { return ShellUtils.createInvoker("default", this); } Modified: trunk/shell/src/shell/org/jnode/shell/DefaultCommandInvoker.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/DefaultCommandInvoker.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/DefaultCommandInvoker.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -49,7 +49,7 @@ * @author Sam Reid * @author cr...@jn... */ -public class DefaultCommandInvoker implements CommandInvoker { +public class DefaultCommandInvoker implements SimpleCommandInvoker { private final PrintWriter err; private final CommandShell shell; @@ -58,7 +58,7 @@ private static final Class<?>[] MAIN_ARG_TYPES = new Class[] {String[].class}; public static final Factory FACTORY = new Factory() { - public CommandInvoker create(CommandShell shell) { + public SimpleCommandInvoker create(CommandShell shell) { return new DefaultCommandInvoker(shell); } Modified: trunk/shell/src/shell/org/jnode/shell/DefaultInterpreter.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/DefaultInterpreter.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/DefaultInterpreter.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -102,7 +102,7 @@ shell.addCommandToHistory(line); try { CommandInfo cmdInfo = cmd.parseCommandLine(shell); - return shell.invoke(cmd, cmdInfo); + return shell.invoke(cmd, cmdInfo, null, null); } catch (CommandSyntaxException ex) { throw new ShellException("Command arguments don't match syntax", ex); } Modified: trunk/shell/src/shell/org/jnode/shell/RedirectingInterpreter.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/RedirectingInterpreter.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/RedirectingInterpreter.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -249,7 +249,7 @@ desc.commandLine.setStreams(new CommandIO[] {in, out, err, CommandLine.DEFAULT_STDERR}); try { CommandInfo cmdInfo = desc.commandLine.parseCommandLine(shell); - return shell.invoke(desc.commandLine, cmdInfo); + return shell.invoke(desc.commandLine, cmdInfo, null, null); } catch (CommandSyntaxException ex) { throw new ShellException( "Command arguments don't match syntax", ex); Modified: trunk/shell/src/shell/org/jnode/shell/ShellManager.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/ShellManager.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/ShellManager.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -48,15 +48,15 @@ */ public void registerShell(Shell currentShell); - public void registerInvokerFactory(CommandInvoker.Factory factory); + public void registerInvokerFactory(SimpleCommandInvoker.Factory factory); public void registerInterpreterFactory(CommandInterpreter.Factory factory); - public void unregisterInvokerFactory(CommandInvoker.Factory factory); + public void unregisterInvokerFactory(SimpleCommandInvoker.Factory factory); public void unregisterInterpreterFactory(CommandInterpreter.Factory factory); - public CommandInvoker createInvoker(String name, CommandShell shell) + public SimpleCommandInvoker createInvoker(String name, CommandShell shell) throws IllegalArgumentException; public CommandInterpreter createInterpreter(String name) Modified: trunk/shell/src/shell/org/jnode/shell/ShellUtils.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/ShellUtils.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/ShellUtils.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -92,7 +92,7 @@ return getShellManager().getCurrentShell().getSyntaxManager(); } - public static void registerCommandInvoker(CommandInvoker.Factory factory) + public static void registerCommandInvoker(SimpleCommandInvoker.Factory factory) throws NameNotFoundException { getShellManager().registerInvokerFactory(factory); } @@ -102,7 +102,7 @@ getShellManager().registerInterpreterFactory(factory); } - public static CommandInvoker createInvoker(String name, CommandShell shell) + public static SimpleCommandInvoker createInvoker(String name, CommandShell shell) throws IllegalArgumentException { try { return getShellManager().createInvoker(name, shell); Added: trunk/shell/src/shell/org/jnode/shell/SimpleCommandInvoker.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/SimpleCommandInvoker.java (rev 0) +++ trunk/shell/src/shell/org/jnode/shell/SimpleCommandInvoker.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -0,0 +1,80 @@ +/* + * $Id: CommandInvoker.java 4977 2009-02-02 09:09:41Z lsantha $ + * + * Copyright (C) 2003-2009 JNode.org + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; If not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.jnode.shell; + +/* + * User: Sam Reid Date: Dec 20, 2003 Time: 1:18:31 AM Copyright (c) Dec 20, 2003 + * by Sam Reid + */ + +/** + * This is the common API for the various mechanisms for running 'commands'. + * + * @author Sam Reid + * @author cr...@jn... + */ +public interface SimpleCommandInvoker { + + public interface Factory { + SimpleCommandInvoker create(CommandShell shell); + + String getName(); + } + + /** + * Run a command synchronously, passing back the resulting return code. + * + * @param commandLine this provides the command name (alias), the command + * arguments and (where relevant) the command's i/o stream context. + * @param cmdInfo a CommandInfo descriptor for the command to be run. + * @return an integer return code, with zero indicating command success, + * non-zero indicating command failure. + * @throws ShellException if there was some problem launching the command. + */ + int invoke(CommandLine commandLine, CommandInfo cmdInfo) + throws ShellException; + + /** + * Create a thread for running a command asynchronously. This can be used + * for running and for assembling command pipelines. + * + * @param commandLine this provides the command name (alias), the command + * arguments and (where relevant) the command's i/o stream context. + * @param cmdInfo a CommandInfo descriptor for the command to be run. + * @return the thread for the command. Calling + * {@link java.lang.Thread#start()} will cause the command to + * execute. + * @throws ShellException if there was some problem launching the command. + */ + CommandThread invokeAsynchronous(CommandLine commandLine, CommandInfo cmdInfo) + throws ShellException; + + /** + * Get the invoker's name. + * + * @return the name. + */ + String getName(); + + boolean isDebugEnabled(); + + void setDebugEnabled(boolean enabled); +} Modified: trunk/shell/src/shell/org/jnode/shell/ThreadCommandInvoker.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/ThreadCommandInvoker.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/ThreadCommandInvoker.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -40,7 +40,7 @@ public class ThreadCommandInvoker extends AsyncCommandInvoker { public static final Factory FACTORY = new Factory() { - public CommandInvoker create(CommandShell shell) { + public SimpleCommandInvoker create(CommandShell shell) { return new ThreadCommandInvoker(shell); } Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneContext.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -257,7 +257,7 @@ value.length(); // Check that the value is non-null. VariableSlot var = variables.get(name); if (var == null) { - variables.put(name, new VariableSlot(value, false)); + variables.put(name, new VariableSlot(name, value, false)); } else { var.value = value; } @@ -291,7 +291,7 @@ VariableSlot var = variables.get(name); if (var == null) { if (exported) { - variables.put(name, new VariableSlot("", exported)); + variables.put(name, new VariableSlot(name, "", exported)); } } else { var.exported = exported; @@ -901,10 +901,21 @@ } resolvePrintStream(streams[Command.STD_ERR]).println(sb); } - lastReturnCode = interpreter.executeCommand(command, this, streams); + Map<String, String> env = buildEnvFromExports(); + lastReturnCode = interpreter.executeCommand(command, this, streams, null, env); return lastReturnCode; } + private Map<String, String> buildEnvFromExports() { + HashMap<String, String> map = new HashMap<String, String>(variables.size()); + for (VariableSlot var : variables.values()) { + if (var.exported) { + map.put(var.name, var.value); + } + } + return map; + } + PrintStream resolvePrintStream(CommandIO commandIOIF) { return interpreter.resolvePrintStream(commandIOIF); } Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneControlException.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneControlException.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneControlException.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -22,6 +22,12 @@ import org.jnode.shell.ShellException; +/** + * This exception is used to implement constructs that exit scopes + * in the bjorne interpreter. It should never be thrown by an application. + * + * @author cr...@jn... + */ class BjorneControlException extends ShellException { private static final long serialVersionUID = 1L; Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneInterpreter.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneInterpreter.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneInterpreter.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -41,6 +41,8 @@ import java.io.Reader; import java.io.StringWriter; import java.util.HashMap; +import java.util.Map; +import java.util.Properties; import org.jnode.driver.console.CompletionInfo; import org.jnode.shell.CommandInfo; @@ -140,10 +142,12 @@ BUILTINS.put("break", new BreakBuiltin()); BUILTINS.put("continue", new ContinueBuiltin()); BUILTINS.put("exit", new ExitBuiltin()); + BUILTINS.put("export", new ExportBuiltin()); BUILTINS.put("return", new ReturnBuiltin()); BUILTINS.put("set", new SetBuiltin()); BUILTINS.put("shift", new ShiftBuiltin()); BUILTINS.put(".", new SourceBuiltin()); + BUILTINS.put("source", new SourceBuiltin()); BUILTINS.put(":", new ColonBuiltin()); } @@ -325,7 +329,8 @@ } } - int executeCommand(CommandLine cmdLine, BjorneContext context, CommandIO[] streams) + int executeCommand(CommandLine cmdLine, BjorneContext context, CommandIO[] streams, + Properties sysProps, Map<String, String> env) throws ShellException { BjorneBuiltin builtin = BUILTINS.get(cmdLine.getCommandName()); if (builtin != null) { @@ -336,7 +341,7 @@ cmdLine.setStreams(streams); try { CommandInfo cmdInfo = cmdLine.parseCommandLine(shell); - return shell.invoke(cmdLine, cmdInfo); + return shell.invoke(cmdLine, cmdInfo, sysProps, env); } catch (CommandSyntaxException ex) { throw new ShellException("Command arguments don't match syntax", ex); } Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneParser.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneParser.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneParser.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -427,17 +427,17 @@ case TOK_LESSGREAT: case TOK_CLOBBER: arg = tokens.next(); - tt = arg.getTokenType(); - if (tt != TOK_WORD) { - syntaxError("expected a filename after " + token, tt); + int tt2 = arg.getTokenType(); + if (tt2 != TOK_WORD) { + syntaxError("expected a filename after " + token, tt2); } break; case TOK_DLESS: case TOK_DLESSDASH: arg = tokens.next(); - tt = arg.getTokenType(); - if (arg.getTokenType() != TOK_WORD) { - syntaxError("expected a here-end marker " + token, tt); + int tt3 = arg.getTokenType(); + if (tt3 != TOK_WORD) { + syntaxError("expected a here-end marker " + token, tt3); } // TODO ... need to grab the HERE document ... break; Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneToken.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneToken.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneToken.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -169,6 +169,9 @@ public static boolean isName(String str) { int len = str.length(); + if (len == 0) { + return false; + } for (int i = 0; i < len; i++) { char ch = str.charAt(i); switch (ch) { Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneTokenizer.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneTokenizer.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/bjorne/BjorneTokenizer.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -492,8 +492,7 @@ case RULE_7b_CONTEXT: int pos = token.getText().indexOf('='); if (pos <= 0 - || !BjorneToken.isName(token.getText() - .substring(0, pos - 1))) { + || !BjorneToken.isName(token.getText().substring(0, pos))) { return token; } return remakeToken(TOK_ASSIGNMENT, token); Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/ExitBuiltin.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/bjorne/ExitBuiltin.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/bjorne/ExitBuiltin.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -25,6 +25,12 @@ import org.jnode.shell.CommandLine; import org.jnode.shell.ShellException; +/** + * This class implements the 'exit' built-in. This is done by throwing a + * BjorneControlException with code 'BRANCH_EXIT'. + * + * @author cr...@jn... + */ final class ExitBuiltin extends BjorneBuiltin { @SuppressWarnings("deprecation") public int invoke(CommandLine command, BjorneInterpreter interpreter, Added: trunk/shell/src/shell/org/jnode/shell/bjorne/ExportBuiltin.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/bjorne/ExportBuiltin.java (rev 0) +++ trunk/shell/src/shell/org/jnode/shell/bjorne/ExportBuiltin.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -0,0 +1,61 @@ +/* + * $Id$ + * + * Copyright (C) 2003-2009 JNode.org + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; If not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.jnode.shell.bjorne; + +import java.util.Iterator; + +import org.jnode.shell.CommandLine; +import org.jnode.shell.ShellException; + +/** + * This class implements the 'export' built-in. + * + * @author cr...@jn... + */ +final class ExportBuiltin extends BjorneBuiltin { + @SuppressWarnings("deprecation") + public int invoke(CommandLine command, BjorneInterpreter interpreter, + BjorneContext context) throws ShellException { + Iterator<String> args = command.iterator(); + if (!args.hasNext()) { + throw new BjorneControlException(BjorneInterpreter.BRANCH_EXIT, + context.getParent().getLastReturnCode()); + } + while (args.hasNext()) { + String arg = args.next(); + int pos = arg.indexOf('='); + if (pos == -1) { + context.getParent().setExported(arg, true); + } else if (pos == 0) { + error("export: " + arg + ": not a valid identifier", context); + } else { + String name = arg.substring(0, pos); + String value = arg.substring(pos + 1); + if (!BjorneToken.isName(name)) { + error("export: " + name + ": not a valid identifier", context); + } + context.getParent().setVariable(name, value); + context.getParent().setExported(name, true); + } + } + return 0; + } +} Modified: trunk/shell/src/shell/org/jnode/shell/bjorne/VariableSlot.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/bjorne/VariableSlot.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/bjorne/VariableSlot.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -23,19 +23,24 @@ class VariableSlot { public String value; - + public final String name; public boolean exported; - public VariableSlot(String value, boolean exported) { + public VariableSlot(String name, String value, boolean exported) { + if (name == null) { + throw new ShellFailureException("null name"); + } if (value == null) { throw new ShellFailureException("null value"); } this.value = value; this.exported = exported; + this.name = name; } public VariableSlot(VariableSlot other) { this.value = other.value; this.exported = other.exported; + this.name = other.name; } } Modified: trunk/shell/src/shell/org/jnode/shell/command/PrintEnvCommand.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/command/PrintEnvCommand.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/command/PrintEnvCommand.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -50,7 +50,8 @@ * Execute this command */ public void execute() throws Exception { - final Map<String, String> env = (Map<String, String>) AccessController.doPrivileged(new GetEnvAction()); + final Map<String, String> env = + (Map<String, String>) AccessController.doPrivileged(new GetEnvAction()); final TreeMap<String, String> sortedEnv = new TreeMap<String, String>(env); final PrintWriter out = getOutput().getPrintWriter(); for (Map.Entry<String, String> entry : sortedEnv.entrySet()) { Modified: trunk/shell/src/shell/org/jnode/shell/def/DefaultShellManager.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/def/DefaultShellManager.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/def/DefaultShellManager.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -23,7 +23,7 @@ import java.util.HashMap; import org.jnode.shell.CommandInterpreter; -import org.jnode.shell.CommandInvoker; +import org.jnode.shell.SimpleCommandInvoker; import org.jnode.shell.CommandShell; import org.jnode.shell.Shell; import org.jnode.shell.ShellManager; @@ -40,8 +40,8 @@ private final InheritableThreadLocal<Shell> currentShell = new InheritableThreadLocal<Shell>(); - private final HashMap<String, CommandInvoker.Factory> invokerFactories = - new HashMap<String, CommandInvoker.Factory>(); + private final HashMap<String, SimpleCommandInvoker.Factory> invokerFactories = + new HashMap<String, SimpleCommandInvoker.Factory>(); private final HashMap<String, CommandInterpreter.Factory> interpreterFactories = new HashMap<String, CommandInterpreter.Factory>(); @@ -70,8 +70,8 @@ return factory.create(); } - public CommandInvoker createInvoker(String name, CommandShell shell) throws IllegalArgumentException { - CommandInvoker.Factory factory = invokerFactories.get(name); + public SimpleCommandInvoker createInvoker(String name, CommandShell shell) throws IllegalArgumentException { + SimpleCommandInvoker.Factory factory = invokerFactories.get(name); if (factory == null) { throw new IllegalArgumentException("Unknown invoker '" + name + "'"); } @@ -82,7 +82,7 @@ interpreterFactories.put(factory.getName(), factory); } - public void registerInvokerFactory(CommandInvoker.Factory factory) { + public void registerInvokerFactory(SimpleCommandInvoker.Factory factory) { invokerFactories.put(factory.getName(), factory); } @@ -90,7 +90,7 @@ interpreterFactories.put(factory.getName(), null); } - public void unregisterInvokerFactory(CommandInvoker.Factory factory) { + public void unregisterInvokerFactory(SimpleCommandInvoker.Factory factory) { invokerFactories.put(factory.getName(), null); } } Modified: trunk/shell/src/shell/org/jnode/shell/isolate/IsolateCommandInvoker.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/isolate/IsolateCommandInvoker.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/isolate/IsolateCommandInvoker.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -23,7 +23,7 @@ import java.io.IOException; import org.jnode.shell.AsyncCommandInvoker; -import org.jnode.shell.CommandInvoker; +import org.jnode.shell.SimpleCommandInvoker; import org.jnode.shell.CommandRunner; import org.jnode.shell.CommandShell; import org.jnode.shell.CommandThread; @@ -37,7 +37,7 @@ public class IsolateCommandInvoker extends AsyncCommandInvoker { public static final Factory FACTORY = new Factory() { - public CommandInvoker create(CommandShell shell) { + public SimpleCommandInvoker create(CommandShell shell) { return new IsolateCommandInvoker(shell); } Modified: trunk/shell/src/shell/org/jnode/shell/proclet/ProcletCommandInvoker.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/proclet/ProcletCommandInvoker.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/proclet/ProcletCommandInvoker.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -20,25 +20,34 @@ package org.jnode.shell.proclet; +import java.util.Map; +import java.util.Properties; + import org.jnode.shell.AsyncCommandInvoker; import org.jnode.shell.Command; +import org.jnode.shell.CommandInfo; import org.jnode.shell.CommandInvoker; +import org.jnode.shell.CommandLine; import org.jnode.shell.CommandRunner; import org.jnode.shell.CommandShell; +import org.jnode.shell.CommandThread; import org.jnode.shell.CommandThreadImpl; +import org.jnode.shell.ShellException; +import org.jnode.shell.SimpleCommandInvoker; import org.jnode.shell.io.CommandIO; import org.jnode.vm.VmSystem; /** * This command invoker runs commands in their own proclet, giving each one its - * own stdin,out,err etcetera. + * own standard input / output / error stream, system properties and environment + * variables. * * @author cr...@jn... */ -public class ProcletCommandInvoker extends AsyncCommandInvoker { +public class ProcletCommandInvoker extends AsyncCommandInvoker implements CommandInvoker { public static final Factory FACTORY = new Factory() { - public CommandInvoker create(CommandShell shell) { + public SimpleCommandInvoker create(CommandShell shell) { return new ProcletCommandInvoker(shell); } @@ -58,9 +67,23 @@ return "proclet"; } + public int invoke(CommandLine cmdLine, CommandInfo cmdInfo, + Properties sysProps, Map<String, String> env) + throws ShellException { + CommandRunner cr = setup(cmdLine, cmdInfo, sysProps, env); + return runIt(cmdLine, cmdInfo, cr); + } + + public CommandThread invokeAsynchronous(CommandLine cmdLine, CommandInfo cmdInfo, + Properties sysProps, Map<String, String> env) + throws ShellException { + CommandRunner cr = setup(cmdLine, cmdInfo, sysProps, env); + return forkIt(cmdLine, cmdInfo, cr); + } + protected CommandThreadImpl createThread(CommandRunner cr) { CommandIO[] ios = cr.getIos(); - return ProcletContext.createProclet(cr, null, null, + return ProcletContext.createProclet(cr, cr.getSysProps(), cr.getEnv(), new Object[] { ios[Command.STD_IN].getInputStream(), ios[Command.STD_OUT].getPrintStream(), Modified: trunk/shell/src/shell/org/jnode/shell/proclet/ProcletContext.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/proclet/ProcletContext.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/proclet/ProcletContext.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -20,10 +20,10 @@ package org.jnode.shell.proclet; +import gnu.java.security.action.GetPropertiesAction; + import java.io.Closeable; import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -32,6 +32,7 @@ import org.jnode.util.ProxyStream; import org.jnode.util.ProxyStreamException; import org.jnode.vm.VmExit; +import org.jnode.vm.VmIOContext; import org.jnode.vm.VmSystem; import org.jnode.vm.isolate.VmIsolate; @@ -62,20 +63,6 @@ Map<String, String> environment, Object[] streams) throws ProcletException { super(parent, nextProcletName()); ProcletContext parentContext = getParentContext(parent); - if (properties == null) { - if (parentContext != null) { - properties = parentContext.properties; - } - if (properties == null) { - properties = AccessController.doPrivileged( - new PrivilegedAction<Properties>() { - public Properties run() { - return System.getProperties(); - } - }); - } - properties = (Properties) properties.clone(); - } if (streams == null) { try { streams = new Object[] { @@ -85,12 +72,20 @@ throw new ProcletException("Broken streams", ex); } } + if (properties == null) { + if (parentContext != null) { + properties = parentContext.properties; + } else { + // FIXME ... temporary + properties = AccessController.doPrivileged(new GetPropertiesAction()); + } + properties = (Properties) properties.clone(); + } if (environment == null) { if (parentContext != null) { - environment = new HashMap<String, String>( - parentContext.environment); + environment = parentContext.environment; } else { - environment = new HashMap<String, String>(); + environment = VmIOContext.getGlobalEnv(); } } this.environment = environment; @@ -128,6 +123,10 @@ public synchronized void setProperties(Properties properties) { this.properties = properties; } + + public synchronized void setEnvironment(Map<String, String> environment) { + this.environment = environment; + } /** * Get the ProcletContext for the current thread. @@ -303,5 +302,4 @@ return getClass().getName() + "[name=" + getName() + ",maxpri=" + getMaxPriority() + ",pid=" + getPid() + ']'; } - } Modified: trunk/shell/src/shell/org/jnode/shell/proclet/ProcletIOContext.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/proclet/ProcletIOContext.java 2009-02-14 20:29:54 UTC (rev 5025) +++ trunk/shell/src/shell/org/jnode/shell/proclet/ProcletIOContext.java 2009-02-15 05:39:30 UTC (rev 5026) @@ -22,14 +22,17 @@ import java.io.InputStream; import java.io.PrintStream; +import java.util.Map; +import java.util.Properties; import org.jnode.vm.IOContext; +import org.jnode.vm.VmIOContext; import org.jnode.vm.VmSystem; /** * The ProcletIOContext is an IOContext implementation that uses Proxy streams to * direct System.in/out/err traffic to different places depending on the current - * proclet. + * proclet. * * @author Levente S\u00e1ntha * @author cr...@jn... @@ -41,48 +44,8 @@ public ProcletIOContext() { } - public synchronized void setGlobalInStream(InputStream is) { - doSetIn(is, GLOBAL_STREAM_ID); - } - - public synchronized void setGlobalOutStream(PrintStream ps) { - doSetOut(ps, GLOBAL_STREAM_ID); - } - - public synchronized void setGlobalErrStream(PrintStream is) { - doSetErr(is, GLOBAL_STREAM_ID); - } - - public synchronized InputStream getGlobalInStream() { - return ((ProcletProxyInputStream) System.in).getProxiedStream(GLOBAL_STREAM_ID); - } - - public synchronized PrintStream getGlobalOutStream() { - return ((ProcletProxyPrintStream) System.out).getProxiedStream(GLOBAL_STREAM_ID); - } - - public synchronized PrintStream getGlobalErrStream() { - return ((ProcletProxyPrintStream) System.err).getProxiedStream(GLOBAL_STREAM_ID); - } - public synchronized void setSystemIn(InputStream is) { - doSetIn(is, getCurrentPid()); - } - - public synchronized void setSystemOut(PrintStream ps) { - doSetOut(ps, getCurrentPid()); - } - - public synchronized void setSystemErr(PrintStream ps) { - doSetErr(ps, getCurrentPid()); - } - - private int getCurrentPid() { - ProcletContext procletContext = ProcletContext.currentProcletContext(); - return (procletContext == null) ? GLOBAL_STREAM_ID : procletContext.getPid(); - } - - private void doSetIn(InputStream is, int pid) { + int pid = getCurrentPid(); if (is instanceof ProcletProxyInputStream) { is = ((ProcletProxyInputStream) is).getProxiedStream(pid); } @@ -91,7 +54,8 @@ VmSystem.setStaticField(System.class, "in", newProxyStream); } - private void doSetOut(PrintStream ps, int pid) { + public synchronized void setSystemOut(PrintStream ps) { + int pid = getCurrentPid(); if (ps instanceof ProcletProxyPrintStream) { ps = ((ProcletProxyPrintStream) ps).getProxiedStream(pid); } @@ -100,7 +64,8 @@ VmSystem.setStaticField(System.class, "out", newProxyStream); } - private void doSetErr(PrintStream ps, int pid) { + public synchronized void setSystemErr(PrintStream ps) { + int pid = getCurrentPid(); if (ps instanceof ProcletProxyPrintStream) { ps = ((ProcletProxyPrintStream) ps).getProxiedStream(pid); } @@ -108,7 +73,28 @@ (ProcletProxyPrintStream) System.err, ps, pid); VmSystem.setStaticField(System.class, "err", newProxyStream); } + + public Map<String, String> getEnv() { + return ProcletContext.currentProcletContext().getEnvironment(); + } + public Propert... [truncated message content] |