Skip to content

Commit

Permalink
Process chdir option sooner so execFillarg sees it
Browse files Browse the repository at this point in the history
This is a bit hacky due to the way we handle chdir on top of
posix_spawn. The logic for making the command line use sh and cd
lives in execFillarg, since it must handle the case where the
virtual CWD is not the same as the JVM CWD. In order to make sure
that processing also happens for incoming chdir: options, this
patch pre-processes the options hash just for chdir.

Fixes #8126
  • Loading branch information
headius committed Apr 30, 2024
1 parent 3afe3fd commit 280061e
Showing 1 changed file with 16 additions and 8 deletions.
24 changes: 16 additions & 8 deletions core/src/main/java/org/jruby/util/io/PopenExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public static RubyFixnum spawn(ThreadContext context, IRubyObject[] argv) {
ExecArg eargp;
IRubyObject fail_str;

eargp = execargNew(context, argv, true, false);
eargp = execargNew(context, argv, context.nil, true, false);
execargFixup(context, runtime, eargp);
fail_str = eargp.use_shell ? eargp.command_name : eargp.command_name;

Expand All @@ -110,7 +110,7 @@ public IRubyObject systemInternal(ThreadContext context, IRubyObject[] argv, Str
ExecArg eargp;
long pid;

eargp = execargNew(context, argv, true, true);
eargp = execargNew(context, argv, context.nil, true, true);
execargFixup(context, runtime, eargp);
pid = spawnProcess(context, runtime, eargp, errmsg);

Expand Down Expand Up @@ -297,7 +297,7 @@ public static IRubyObject pipeOpen(ThreadContext context, IRubyObject prog, Stri
ExecArg execArg = null;

if (!isPopenFork(context.runtime, (RubyString)prog))
execArg = execargNew(context, argv, true, false);
execArg = execargNew(context, argv, context.nil, true, false);
return new PopenExecutor().pipeOpen(context, execArg, modestr, fmode, convconfig);
}

Expand Down Expand Up @@ -340,14 +340,14 @@ public static IRubyObject popen(ThreadContext context, IRubyObject[] argv, RubyC
// #endif
tmp = ((RubyArray)tmp).aryDup();
// RBASIC_CLEAR_CLASS(tmp);
eargp = execargNew(context, ((RubyArray)tmp).toJavaArray(), false, false);
eargp = execargNew(context, ((RubyArray)tmp).toJavaArray(), opt, false, false);
((RubyArray)tmp).clear();
} else {
pname = pname.convertToString();
eargp = null;
if (!isPopenFork(runtime, (RubyString)pname)) {
IRubyObject[] pname_p = {pname};
eargp = execargNew(context, pname_p, true, false);
eargp = execargNew(context, pname_p, opt, true, false);
pname = pname_p[0];
}
}
Expand Down Expand Up @@ -1678,14 +1678,14 @@ static RubyArray checkExecRedirect1(Ruby runtime, RubyArray ary, IRubyObject key
private static final int ST_STOP = 1;

// rb_execarg_new
public static ExecArg execargNew(ThreadContext context, IRubyObject[] argv, boolean accept_shell, boolean allow_exc_opt) {
public static ExecArg execargNew(ThreadContext context, IRubyObject[] argv, IRubyObject optForChdir, boolean accept_shell, boolean allow_exc_opt) {
ExecArg eargp = new ExecArg();
execargInit(context, argv, accept_shell, eargp, allow_exc_opt);
execargInit(context, argv, optForChdir, accept_shell, eargp, allow_exc_opt);
return eargp;
}

// rb_execarg_init
private static RubyString execargInit(ThreadContext context, IRubyObject[] argv, boolean accept_shell, ExecArg eargp, boolean allow_exc_opt) {
private static RubyString execargInit(ThreadContext context, IRubyObject[] argv, IRubyObject optForChdir, boolean accept_shell, ExecArg eargp, boolean allow_exc_opt) {
RubyString prog, ret;
IRubyObject[] env_opt = {context.nil, context.nil};
IRubyObject[][] argv_p = {argv};
Expand All @@ -1698,6 +1698,14 @@ private static RubyString execargInit(ThreadContext context, IRubyObject[] argv,
optHash = optHash.dupFast(context);
exception = optHash.delete(context, exceptionSym);
}

RubySymbol chdirSym = context.runtime.newSymbol("chdir");
IRubyObject chdir;
if (!optForChdir.isNil() && (chdir = ((RubyHash) optForChdir).delete(chdirSym)) != null) {
eargp.chdirGiven = true;
eargp.chdir_dir = chdir.convertToString().toString();
}

execFillarg(context, prog, argv_p[0], env_opt[0], env_opt[1], eargp);
if (exception.isTrue()) {
eargp.exception = true;
Expand Down

0 comments on commit 280061e

Please sign in to comment.