On Apr 4, 2006, at 8:47 AM, Thomas E Enebo wrote:

  Thanks Marc,

Sourceforge has had a major CVS outtage and I am waiting until it is back up to look at this (since I would be able to uncommit it anyways). If you end up fixing that last rubicon test by then, then feel free to send another
patch.

Hold off applying this patch, i think I've found the root of the wildcard expansion problem and should have something better soon.

Marc.

   CVS is supposed to be back up tonight or tommmorow.

-Tom

On Mon, 03 Apr 2006, Marc Hadley defenestrated me:

Here's a patch for Kernel#system that executes ruby scripts in the
current jruby process rather than forking a new JVM and adds support
for the multi-argument variant of Kernel#system. Its based in large
part on a patch provided by Charles.

The new code still fails one of the rubicon tests due to some shell
wildcard expansion differences that I haven't yet figured out.

Marc.

---
Marc Hadley <marc.hadley at sun.com>

Index: RubyKernel.java
*** /Users/mh124079/Development/Ruby/jruby/src/org/jruby/
RubyKernel.java Base (1.45)
--- /Users/mh124079/Development/Ruby/jruby/src/org/jruby/
RubyKernel.java Locally Modified (Based On 1.45)
***************
*** 40,46 ****
--- 40,48 ----
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.util.Iterator;
+ import java.util.Stack;
  import java.util.StringTokenizer;
+ import java.util.Vector;
  import java.util.regex.Pattern;

  import org.jruby.ast.util.ArgsUtil;
***************
*** 686,692 ****
          StringBuffer output = new StringBuffer();
          IRuby runtime = recv.getRuntime();
          runtime.getGlobalVariables().set("$?", runtime.newFixnum(
!             runInShell(runtime, aString.toString(), output)));

          return recv.getRuntime().newString(output.toString());
      }
--- 688,694 ----
          StringBuffer output = new StringBuffer();
          IRuby runtime = recv.getRuntime();
          runtime.getGlobalVariables().set("$?", runtime.newFixnum(
!             runInShell(runtime, new IRubyObject[] {aString},
output)));

          return recv.getRuntime().newString(output.toString());
      }
***************
*** 745,770 ****
          return PATH_SEPARATORS.matcher(executable).replaceAll
(replacement) + remainder;
      }

!     private static int runInShell(IRuby runtime, String command,
StringBuffer output) {
          try {
              String shell = System.getProperty("jruby.shell");
!             Process aProcess;
!             String shellSwitch = "-c";

!             command = repairDirSeps(command);

!             if (shell != null) {
!                 if (!shell.endsWith("sh")) {
!                     shellSwitch = "/c";
                  }
!                 aProcess = Runtime.getRuntime().exec(new String[]
{ shell, shellSwitch, command });
              } else {
!                 aProcess = Runtime.getRuntime().exec(command);
              }

              final BufferedReader reader = new BufferedReader(new
InputStreamReader(aProcess.getInputStream()));

--- 747,845 ----
          return PATH_SEPARATORS.matcher(executable).replaceAll
(replacement) + remainder;
      }

!     private static Vector parseCommandLine(IRubyObject[] rawArgs) {
!         // first parse the first element of rawArgs since this may
contain
!         // the whole command line
!         String command = rawArgs[0].toString();
!         Stack args = new Stack();
!         StringTokenizer st = new StringTokenizer(command, " ");
!         String quoteChar = null;
!
!         while (st.hasMoreTokens()) {
!             String token = st.nextToken();
!             if (quoteChar == null) {
!                 // not currently in the middle of a quoted token
! if (token.startsWith("'") || token.startsWith ("\"")) {
!                     // note quote char and remove from beginning of
token
!                     quoteChar = token.substring(0, 1);
!                     token = token.substring(1);
!                 }
!                 if (quoteChar!=null && token.endsWith(quoteChar)) {
!                     // quoted token self contained, remove from end
of token
!                     token = token.substring(0, token.length()-1);
!                     quoteChar = null;
!                 }
!                 // add new token to list
!                 args.push(token);
!             } else {
!                 // in the middle of quoted token
!                 if (token.endsWith(quoteChar)) {
!                     // end of quoted token
!                     token = token.substring(0, token.length()-1);
!                     quoteChar = null;
!                 }
!                 // update token at end of list
!                 token = args.pop() + " " + token;
!                 args.push(token);
!             }
!         }
!
!         // now append the remaining raw args to the cooked arg list
!         for (int i=1;i<rawArgs.length;i++) {
!             args.push(rawArgs[i].toString());
!         }
!
!         return args;
!     }
!
!     private static int runInShell(IRuby runtime, IRubyObject[]
rawArgs, StringBuffer output) {
          try {
+             // startup scripts set jruby.shell to /bin/sh for Unix,
cmd.exe for Windows
              String shell = System.getProperty("jruby.shell");
!             Process aProcess = null;

!             final Vector args = parseCommandLine(rawArgs);
!             String command = (String)args.get(0);

!             // this will match ruby anywhere in the path to the
command.
!             // it might be better to restrict matches to the final
token after
!             // tokenizing with '/'
! if (command.contains("ruby") || command.endsWith (".rb")) {
!                 // use existing JRuby process to execute command
!                 Thread t = new Thread() {
!                     public void run() {
!                         try {
! String[] argArray = new String [args.size
()-1];
!                             // snip off ruby or jruby command from
list of arguments
!                             args.subList(1,args.size()).toArray
(argArray);
!                             org.jruby.Main.main(argArray);
!                         } catch (Throwable t) {
                          }
!                     }
!                 };
!                 t.start();
!                 t.join();
!             } else if (shell != null) {
!                 // execute command with sh -c or cmd.exe /c
!                 String shellSwitch = shell.endsWith("sh") ? "-c" :
"/c";
!                 String[] argArray = new String[3];
!                 argArray[0] = shell;
!                 argArray[1] = shellSwitch;
!                 StringBuffer buf = new StringBuffer();
!                 for (int i=0;i<args.size();i++) {
!                     buf.append(args.get(i));
!                     buf.append(' ');
!                 }
!                 argArray[2] = buf.toString();
!                 aProcess = Runtime.getRuntime().exec(argArray);
              } else {
!                 // execute command directly
!                 String[] argArray = new String[args.size()];
!                 args.toArray(argArray);
!                 aProcess = Runtime.getRuntime().exec(argArray);
              }

+             if (aProcess != null) {
                  final BufferedReader reader = new BufferedReader
(new InputStreamReader(aProcess.getInputStream()));

                  // Fairly innefficient impl, but readLine is
unable to tell
***************
*** 789,794 ****
--- 867,875 ----
                  reader.close();

                  return aProcess.waitFor();
+             } else {
+                 return 0;
+             }
          } catch (IOException e) {
              throw runtime.newIOErrorFromException(e);
          } catch (InterruptedException e) {
***************
*** 839,849 ****

      public static RubyBoolean system(IRubyObject recv, IRubyObject
[] args) {
          IRuby runtime = recv.getRuntime();
-         if (args.length > 1) {
-             throw runtime.newArgumentError("more arguments not yet
supported");
-         }
          StringBuffer output = new StringBuffer();
!         int resultCode = runInShell(runtime, args[0].toString(),
output);
          recv.getRuntime().getGlobalVariables().set("$?",
runtime.newFixnum(resultCode));
          return runtime.newBoolean(resultCode == 0);
      }
--- 920,928 ----

      public static RubyBoolean system(IRubyObject recv, IRubyObject
[] args) {
          IRuby runtime = recv.getRuntime();
          StringBuffer output = new StringBuffer();
!         int resultCode = runInShell(runtime, args, output);
!         System.out.println(output.toString());
          recv.getRuntime().getGlobalVariables().set("$?",
runtime.newFixnum(resultCode));
          return runtime.newBoolean(resultCode == 0);
      }



-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel? cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Jruby-devel mailing list
Jruby-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jruby-devel

--
+ http://www.tc.umn.edu/~enebo +---- mailto:[EMAIL PROTECTED] ----+
| Thomas E Enebo, Protagonist  | "Luck favors the prepared    |
|                              |  mind." -Louis Pasteur       |


-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel? cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Jruby-devel mailing list
Jruby-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jruby-devel

---
Marc Hadley <marc.hadley at sun.com>
Business Alliances, CTO Office, Sun Microsystems.




-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Jruby-devel mailing list
Jruby-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jruby-devel

Reply via email to