Skip to content

Commit

Permalink
Process::Status
Browse files Browse the repository at this point in the history
File.join fixes


git-svn-id: http://svn.codehaus.org/jruby/trunk/jruby@2093 961051c9-f516-0410-bf72-c9f7e237a7b7
  • Loading branch information
enebo committed Jun 27, 2006
1 parent 486b31d commit 7574ed6
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 12 deletions.
4 changes: 2 additions & 2 deletions src/org/jruby/RubyKernel.java
Expand Up @@ -703,7 +703,7 @@ public static IRubyObject backquote(IRubyObject recv, IRubyObject aString) {

int resultCode = runInShell(runtime, new IRubyObject[] {aString}, output);

recv.getRuntime().getGlobalVariables().set("$?", runtime.newFixnum(resultCode));
recv.getRuntime().getGlobalVariables().set("$?", RubyProcess.RubyStatus.newProcessStatus(runtime, resultCode));

return recv.getRuntime().newString(output.toString());
}
Expand Down Expand Up @@ -961,7 +961,7 @@ public static RubyBoolean system(IRubyObject recv, IRubyObject[] args) {
IRuby runtime = recv.getRuntime();
ByteArrayOutputStream output = new ByteArrayOutputStream();
int resultCode = runInShell(runtime, args, output);
recv.getRuntime().getGlobalVariables().set("$?", runtime.newFixnum(resultCode));
recv.getRuntime().getGlobalVariables().set("$?", RubyProcess.RubyStatus.newProcessStatus(runtime, resultCode));
return runtime.newBoolean(resultCode == 0);
}
}
110 changes: 108 additions & 2 deletions src/org/jruby/RubyProcess.java
Expand Up @@ -28,6 +28,9 @@
***** END LICENSE BLOCK *****/
package org.jruby;

import org.jruby.runtime.CallbackFactory;
import org.jruby.runtime.builtin.IRubyObject;


/**
*
Expand All @@ -36,8 +39,111 @@
public class RubyProcess {

public static RubyModule createProcessModule(IRuby runtime) {
RubyModule module = runtime.defineModule("Process");
RubyModule process = runtime.defineModule("Process");

RubyModule process_status = process.defineClassUnder("Status", runtime.getObject());

CallbackFactory processCallbackFactory = runtime.callbackFactory(RubyProcess.class);
CallbackFactory process_statusCallbackFactory = runtime.callbackFactory(RubyProcess.RubyStatus.class);

// process.defineModuleFunction("fork", processCallbackFactory.getSingletonMethod("fork"));
// process.defineModuleFunction("exit!", processCallbackFactory.getOptSingletonMethod("exit_bang"));
// process.defineModuleFunction("exit", processCallbackFactory.getOptSingletonMethod("exit"));
// process.defineModuleFunction("abort", processCallbackFactory.getOptSingletonMethod("abort"));
// process.defineModuleFunction("kill", processCallbackFactory.getOptSingletonMethod("kill"));
// process.defineModuleFunction("wait", processCallbackFactory.getOptSingletonMethod("wait"));
// process.defineModuleFunction("wait2", processCallbackFactory.getOptSingletonMethod("wait2"));
// process.defineModuleFunction("waitpid", processCallbackFactory.getOptSingletonMethod("waitpid"));
// process.defineModuleFunction("waitpid2", processCallbackFactory.getOptSingletonMethod("waitpid2"));
// process.defineModuleFunction("waitall", processCallbackFactory.getSingletonMethod("waitall"));
// process.defineModuleFunction("detach", processCallbackFactory.getSingletonMethod("detach", IRubyObject.class));
// process.defineModuleFunction("pid", processCallbackFactory.getSingletonMethod("pid"));
// process.defineModuleFunction("ppid", processCallbackFactory.getSingletonMethod("ppid"));
//
// process.defineModuleFunction("getpgrp", processCallbackFactory.getSingletonMethod("getprgrp"));
// process.defineModuleFunction("setpgrp", processCallbackFactory.getSingletonMethod("setpgrp"));
// process.defineModuleFunction("getpgid", processCallbackFactory.getSingletonMethod("getpgid", IRubyObject.class));
// process.defineModuleFunction("setpgid", processCallbackFactory.getSingletonMethod("setpgid", IRubyObject.class, IRubyObject.class));
//
// process.defineModuleFunction("setsid", processCallbackFactory.getSingletonMethod("setsid"));
//
// process.defineModuleFunction("getpriority", processCallbackFactory.getSingletonMethod("getpriority", IRubyObject.class, IRubyObject.class));
// process.defineModuleFunction("setpriority", processCallbackFactory.getSingletonMethod("setpriority", IRubyObject.class, IRubyObject.class, IRubyObject.class));

return module;
// #ifdef HAVE_GETPRIORITY
// rb_define_const(rb_mProcess, "PRIO_PROCESS", INT2FIX(PRIO_PROCESS));
// rb_define_const(rb_mProcess, "PRIO_PGRP", INT2FIX(PRIO_PGRP));
// rb_define_const(rb_mProcess, "PRIO_USER", INT2FIX(PRIO_USER));
// #endif

// process.defineModuleFunction("uid", processCallbackFactory.getSingletonMethod("uid"));
// process.defineModuleFunction("uid=", processCallbackFactory.getSingletonMethod("uid_set", IRubyObject.class));
// process.defineModuleFunction("gid", processCallbackFactory.getSingletonMethod("gid"));
// process.defineModuleFunction("gid=", processCallbackFactory.getSingletonMethod("gid_set", IRubyObject.class));
// process.defineModuleFunction("euid", processCallbackFactory.getSingletonMethod("euid"));
// process.defineModuleFunction("euid=", processCallbackFactory.getSingletonMethod("euid_set", IRubyObject.class));
// process.defineModuleFunction("egid", processCallbackFactory.getSingletonMethod("egid"));
// process.defineModuleFunction("egid=", processCallbackFactory.getSingletonMethod("egid_set", IRubyObject.class));
// process.defineModuleFunction("initgroups", processCallbackFactory.getSingletonMethod("initgroups", IRubyObject.class, IRubyObject.class));
// process.defineModuleFunction("groups", processCallbackFactory.getSingletonMethod("groups"));
// process.defineModuleFunction("groups=", processCallbackFactory.getSingletonMethod("groups_set", IRubyObject.class));
// process.defineModuleFunction("maxgroups", processCallbackFactory.getSingletonMethod("maxgroups"));
// process.defineModuleFunction("maxgroups=", processCallbackFactory.getSingletonMethod("maxgroups_set", IRubyObject.class));
// process.defineModuleFunction("times", processCallbackFactory.getSingletonMethod("groups"));

// Process::Status methods
// process_status.defineMethod("==", process_statusCallbackFactory.getMethod("op_eq"));
// process_status.defineMethod("&", process_statusCallbackFactory.getMethod("op_and"));
// process_status.defineMethod(">>", process_statusCallbackFactory.getMethod("rightshift_op"));
process_status.defineMethod("to_i", process_statusCallbackFactory.getMethod("to_i"));
// process_status.defineMethod("to_int", process_statusCallbackFactory.getMethod("to_int"));
process_status.defineMethod("to_s", process_statusCallbackFactory.getMethod("to_s"));
process_status.defineMethod("inspect", process_statusCallbackFactory.getMethod("inspect"));
// process_status.defineMethod("pid", process_statusCallbackFactory.getMethod("pid"));
// process_status.defineMethod("stopped?", process_statusCallbackFactory.getMethod("stopped_p"));
// process_status.defineMethod("stopsig", process_statusCallbackFactory.getMethod("stopsig"));
// process_status.defineMethod("signaled?", process_statusCallbackFactory.getMethod("signaled_p"));
// process_status.defineMethod("termsig", process_statusCallbackFactory.getMethod("termsig"));
// process_status.defineMethod("exited?", process_statusCallbackFactory.getMethod("exited_p"));
process_status.defineMethod("exitstatus", process_statusCallbackFactory.getMethod("exitstatus"));
process_status.defineMethod("success?", process_statusCallbackFactory.getMethod("success_p"));
// process_status.defineMethod("coredump?", process_statusCallbackFactory.getMethod("coredump_p"));

return process;
}

public static class RubyStatus extends RubyObject {
private long status = 0L;

private static final long EXIT_SUCCESS = 0L;
public RubyStatus(IRuby runtime, RubyClass metaClass, long status) {
super(runtime, metaClass);

this.status = status;
}

public static RubyStatus newProcessStatus(IRuby runtime, long status) {
return new RubyStatus(runtime, runtime.getModule("Process").getClass("Status"), status);
}

public IRubyObject exitstatus() {
return getRuntime().newFixnum(status);
}

public IRubyObject to_i() {
return exitstatus();
}

public IRubyObject to_s() {
return getRuntime().newString(String.valueOf(status));
}

public IRubyObject inspect() {
return to_s();
}

public IRubyObject success_p() {
return getRuntime().newBoolean(status == EXIT_SUCCESS);
}
}
}
7 changes: 7 additions & 0 deletions src/org/jruby/runtime/CallbackFactory.java
Expand Up @@ -89,6 +89,13 @@ public abstract class CallbackFactory {
**/
public abstract Callback getSingletonMethod(String method, Class arg1, Class arg2);

/**
* gets a singleton (class) method with 3 arguments.
* @param method name of the method
* @return a CallBack object corresponding to the appropriate method
**/
public abstract Callback getSingletonMethod(String method, Class arg1, Class arg2, Class arg3);

public abstract Callback getBlockMethod(String method);

/**
Expand Down
46 changes: 38 additions & 8 deletions src/org/jruby/runtime/builtin/meta/FileMetaClass.java
Expand Up @@ -359,18 +359,48 @@ public IRubyObject fnmatch(IRubyObject[] args) {
return getRuntime().newBoolean(Pattern.matches(pattern, path.toString()));
}

private static final Pattern MULTIPLE_DIR_SEPS = Pattern.compile("[/\\\\][/\\\\]+");

/*
* Fixme: This does not have exact same semantics as RubyArray.join, but they
* probably could be consolidated (perhaps as join(args[], sep, doChomp)).
*/
public RubyString join(IRubyObject[] args) {
RubyArray argArray = getRuntime().newArray(args);

RubyString str = argArray.join(RubyString.newString(getRuntime(), "/"));
boolean isTainted = false;
StringBuffer buffer = new StringBuffer();

for (int i = 0; i < args.length; i++) {
if (args[i].isTaint()) {
isTainted = true;
}
String element;
if (args[i] instanceof RubyString) {
element = args[i].toString();
} else if (args[i] instanceof RubyArray) {
// Fixme: Need infinite recursion check to put [...] and not go into a loop
element = join(((RubyArray) args[i]).toJavaArray()).toString();
} else {
element = args[i].convertToString().toString();
}

chomp(buffer);
if (i > 0 && !element.startsWith("/") && !element.startsWith("\\")) {
buffer.append("/");
}
buffer.append(element);
}

// create ruby string, cleaning out double dir separators
RubyString fixedStr = RubyString.newString(getRuntime(), MULTIPLE_DIR_SEPS.matcher(str.toString()).replaceAll("/"));
fixedStr.setTaint(str.isTaint());
RubyString fixedStr = RubyString.newString(getRuntime(), buffer.toString());
fixedStr.setTaint(isTainted);
return fixedStr;
}

private void chomp(StringBuffer buffer) {
int lastIndex = buffer.length() - 1;

while (lastIndex >= 0 && (buffer.lastIndexOf("/") == lastIndex || buffer.lastIndexOf("\\") == lastIndex)) {
buffer.setLength(lastIndex);
lastIndex--;
}
}

public IRubyObject lstat(IRubyObject filename) {
RubyString name = RubyString.stringValue(filename);
Expand Down
4 changes: 4 additions & 0 deletions src/org/jruby/runtime/callback/ReflectionCallbackFactory.java
Expand Up @@ -64,6 +64,10 @@ public Callback getSingletonMethod(String method, Class arg1, Class arg2) {
return new ReflectionCallback(type, method, new Class[] { arg1, arg2 }, false, true, Arity.fixed(2));
}

public Callback getSingletonMethod(String method, Class arg1, Class arg2, Class arg3) {
return new ReflectionCallback(type, method, new Class[] { arg1, arg2, arg3 }, false, true, Arity.fixed(3));
}

public Callback getBlockMethod(String method) {
return new ReflectionCallback(
type,
Expand Down

0 comments on commit 7574ed6

Please sign in to comment.