Skip to content

Commit

Permalink
Fix JRUBY-5531: Process.spawn("ruby") gives garbage PID
Browse files Browse the repository at this point in the history
I believe spawn should behave like popen, in that it never launches the command in-process. No need to set that precedent now and worry about it later.
  • Loading branch information
headius committed Mar 7, 2011
1 parent 864087b commit 35a1935
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/org/jruby/RubyKernel.java
Expand Up @@ -1667,7 +1667,7 @@ private static RubyNumeric randCommon(ThreadContext context, Ruby runtime, Rando
@JRubyMethod(name = "spawn", required = 1, rest = true, module = true, visibility = PRIVATE, compat = RUBY1_9)
public static RubyFixnum spawn(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
Ruby runtime = context.getRuntime();
long pid = ShellLauncher.runWithoutWait(runtime, args);
long pid = ShellLauncher.runExternalWithoutWait(runtime, args);
return RubyFixnum.newFixnum(runtime, pid);
}

Expand Down
2 changes: 1 addition & 1 deletion src/org/jruby/RubyProcess.java
Expand Up @@ -950,7 +950,7 @@ public static IRubyObject fork(ThreadContext context, IRubyObject recv, Block bl
@JRubyMethod(name = "spawn", required = 1, rest = true, module = true, compat = CompatVersion.RUBY1_9)
public static RubyFixnum spawn(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
Ruby runtime = context.getRuntime();
long pid = ShellLauncher.runWithoutWait(runtime, args);
long pid = ShellLauncher.runExternalWithoutWait(runtime, args);
return RubyFixnum.newFixnum(runtime, pid);
}

Expand Down
23 changes: 21 additions & 2 deletions src/org/jruby/util/ShellLauncher.java
Expand Up @@ -371,6 +371,10 @@ public static long runWithoutWait(Ruby runtime, IRubyObject[] rawArgs) {
return runWithoutWait(runtime, rawArgs, runtime.getOutputStream());
}

public static long runExternalWithoutWait(Ruby runtime, IRubyObject[] rawArgs) {
return runWithoutWait(runtime, rawArgs, runtime.getOutputStream());
}

public static int execAndWait(Ruby runtime, IRubyObject[] rawArgs) {
File pwd = new File(runtime.getCurrentDirectory());
LaunchConfig cfg = new LaunchConfig(runtime, rawArgs, true);
Expand Down Expand Up @@ -414,7 +418,7 @@ public static int runAndWait(Ruby runtime, IRubyObject[] rawArgs, OutputStream o
}
}

public static long runWithoutWait(Ruby runtime, IRubyObject[] rawArgs, OutputStream output) {
private static long runWithoutWait(Ruby runtime, IRubyObject[] rawArgs, OutputStream output) {
OutputStream error = runtime.getErrorStream();
try {
Process aProcess = run(runtime, rawArgs, true);
Expand All @@ -425,6 +429,17 @@ public static long runWithoutWait(Ruby runtime, IRubyObject[] rawArgs, OutputStr
}
}

private static long runExternalWithoutWait(Ruby runtime, IRubyObject[] rawArgs, OutputStream output) {
OutputStream error = runtime.getErrorStream();
try {
Process aProcess = run(runtime, rawArgs, true, true);
handleStreamsNonblocking(runtime, aProcess, output, error);
return getPidFromProcess(aProcess);
} catch (IOException e) {
throw runtime.newIOErrorFromException(e);
}
}

public static long getPidFromProcess(Process process) {
if (process instanceof ScriptThreadProcess) {
return process.hashCode();
Expand Down Expand Up @@ -1119,12 +1134,16 @@ private static boolean shouldVerifyPathExecutable(String cmdline) {
}

public static Process run(Ruby runtime, IRubyObject[] rawArgs, boolean doExecutableSearch) throws IOException {
return run(runtime, rawArgs, doExecutableSearch, false);
}

public static Process run(Ruby runtime, IRubyObject[] rawArgs, boolean doExecutableSearch, boolean forceExternalProcess) throws IOException {
Process aProcess = null;
File pwd = new File(runtime.getCurrentDirectory());
LaunchConfig cfg = new LaunchConfig(runtime, rawArgs, doExecutableSearch);

try {
if (cfg.shouldRunInProcess()) {
if (!forceExternalProcess && cfg.shouldRunInProcess()) {
log(runtime, "Launching in-process");
ScriptThreadProcess ipScript = new ScriptThreadProcess(
runtime, cfg.getExecArgs(), getCurrentEnv(runtime), pwd);
Expand Down

0 comments on commit 35a1935

Please sign in to comment.