Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 4a060185b885
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: b334224fd19b
Choose a head ref
  • 4 commits
  • 11 files changed
  • 1 contributor

Commits on Aug 5, 2016

  1. Copy the full SHA
    301c6fe View commit details
  2. Copy the full SHA
    d76fa47 View commit details
  3. Copy the full SHA
    f415ec0 View commit details
  4. Copy the full SHA
    b334224 View commit details
1 change: 1 addition & 0 deletions spec/ruby/shared/process/fixtures/env.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
print ENV["FOO"]
26 changes: 13 additions & 13 deletions spec/ruby/shared/process/spawn.rb
Original file line number Diff line number Diff line change
@@ -170,56 +170,56 @@

it "sets environment variables in the child environment" do
lambda do
Process.wait @object.spawn({"FOO" => "BAR"}, ruby_cmd('print ENV["FOO"]'))
Process.wait @object.spawn({"FOO" => "BAR"}, ruby_cmd(fixture(__FILE__, "env.rb")))
end.should output_to_fd("BAR")
end

it "unsets environment variables whose value is nil" do
ENV["FOO"] = "BAR"
lambda do
Process.wait @object.spawn({"FOO" => nil}, ruby_cmd('print ENV["FOO"]'))
Process.wait @object.spawn({"FOO" => nil}, ruby_cmd(fixture(__FILE__, "env.rb")))
end.should output_to_fd("")
end

it "calls #to_hash to convert the environment" do
o = mock("to_hash")
o.should_receive(:to_hash).and_return({"FOO" => "BAR"})
lambda do
Process.wait @object.spawn(o, ruby_cmd('print ENV["FOO"]'))
Process.wait @object.spawn(o, ruby_cmd(fixture(__FILE__, "env.rb")))
end.should output_to_fd("BAR")
end

it "calls #to_str to convert the environment keys" do
o = mock("to_str")
o.should_receive(:to_str).and_return("FOO")
lambda do
Process.wait @object.spawn({o => "BAR"}, ruby_cmd('print ENV["FOO"]'))
Process.wait @object.spawn({o => "BAR"}, ruby_cmd(fixture(__FILE__, "env.rb")))
end.should output_to_fd("BAR")
end

it "calls #to_str to convert the environment values" do
o = mock("to_str")
o.should_receive(:to_str).and_return("BAR")
lambda do
Process.wait @object.spawn({"FOO" => o}, ruby_cmd('print ENV["FOO"]'))
Process.wait @object.spawn({"FOO" => o}, ruby_cmd(fixture(__FILE__, "env.rb")))
end.should output_to_fd("BAR")
end

it "raises an ArgumentError if an environment key includes an equals sign" do
lambda do
@object.spawn({"FOO=" => "BAR"}, ruby_cmd('print ENV["FOO"]'))
@object.spawn({"FOO=" => "BAR"}, ruby_cmd(fixture(__FILE__, "env.rb")))
end.should raise_error(ArgumentError)
end

it "raises an ArgumentError if an environment key includes a null byte" do
lambda do
@object.spawn({"\000" => "BAR"}, ruby_cmd('print ENV["FOO"]'))
@object.spawn({"\000" => "BAR"}, ruby_cmd(fixture(__FILE__, "env.rb")))
end.should raise_error(ArgumentError)
end

it "raises an ArgumentError if an environment value includes a null byte" do
lambda do
@object.spawn({"FOO" => "\000"}, ruby_cmd('print ENV["FOO"]'))
@object.spawn({"FOO" => "\000"}, ruby_cmd(fixture(__FILE__, "env.rb")))
end.should raise_error(ArgumentError)
end

@@ -228,34 +228,34 @@
it "unsets other environment variables when given a true :unsetenv_others option" do
ENV["FOO"] = "BAR"
lambda do
Process.wait @object.spawn(ruby_cmd('print ENV["FOO"]'), unsetenv_others: true)
Process.wait @object.spawn(ruby_cmd(fixture(__FILE__, "env.rb")), unsetenv_others: true)
end.should output_to_fd("")
end

it "unsets other environment variables when given a non-false :unsetenv_others option" do
ENV["FOO"] = "BAR"
lambda do
Process.wait @object.spawn(ruby_cmd('print ENV["FOO"]'), unsetenv_others: :true)
Process.wait @object.spawn(ruby_cmd(fixture(__FILE__, "env.rb")), unsetenv_others: :true)
end.should output_to_fd("")
end

it "does not unset other environment variables when given a false :unsetenv_others option" do
ENV["FOO"] = "BAR"
lambda do
Process.wait @object.spawn(ruby_cmd('print ENV["FOO"]'), unsetenv_others: false)
Process.wait @object.spawn(ruby_cmd(fixture(__FILE__, "env.rb")), unsetenv_others: false)
end.should output_to_fd("BAR")
end

it "does not unset other environment variables when given a nil :unsetenv_others option" do
ENV["FOO"] = "BAR"
lambda do
Process.wait @object.spawn(ruby_cmd('print ENV["FOO"]'), unsetenv_others: nil)
Process.wait @object.spawn(ruby_cmd(fixture(__FILE__, "env.rb")), unsetenv_others: nil)
end.should output_to_fd("BAR")
end

it "does not unset environment variables included in the environment hash" do
lambda do
Process.wait @object.spawn({"FOO" => "BAR"}, ruby_cmd('print ENV["FOO"]', options: '--disable-gems'), unsetenv_others: true)
Process.wait @object.spawn({"FOO" => "BAR"}, ruby_cmd(fixture(__FILE__, "env.rb"), options: '--disable-gems'), unsetenv_others: true)
end.should output_to_fd("BAR")
end

20 changes: 0 additions & 20 deletions spec/truffle/tags/core/kernel/spawn_tags.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
fails:Kernel#spawn sets environment variables in the child environment
fails:Kernel#spawn unsets environment variables whose value is nil
fails:Kernel#spawn calls #to_hash to convert the environment
fails:Kernel#spawn calls #to_str to convert the environment keys
fails:Kernel#spawn calls #to_str to convert the environment values
fails:Kernel#spawn raises an ArgumentError if an environment key includes an equals sign
fails:Kernel#spawn raises an ArgumentError if an environment key includes a null byte
fails:Kernel#spawn raises an ArgumentError if an environment value includes a null byte
fails:Kernel#spawn unsets other environment variables when given a true :unsetenv_others option
fails:Kernel#spawn unsets other environment variables when given a non-false :unsetenv_others option
fails:Kernel#spawn does not unset environment variables included in the environment hash
fails:Kernel#spawn joins the current process if pgroup: false
fails:Kernel#spawn joins the current process if pgroup: nil
fails:Kernel#spawn joins a new process group if pgroup: true
@@ -23,17 +12,8 @@ fails:Kernel#spawn with multiple arguments raises an ArgumentError if an argumen
fails:Kernel#spawn with a command array raises an ArgumentError if the Strings in the Array include a null byte
fails:Kernel#spawn when passed :chdir changes to the directory passed for :chdir
fails:Kernel#spawn when passed :chdir calls #to_path to convert the :chdir value
fails:Kernel.spawn sets environment variables in the child environment
fails:Kernel.spawn unsets environment variables whose value is nil
fails:Kernel.spawn calls #to_hash to convert the environment
fails:Kernel.spawn calls #to_str to convert the environment keys
fails:Kernel.spawn calls #to_str to convert the environment values
fails:Kernel.spawn raises an ArgumentError if an environment key includes an equals sign
fails:Kernel.spawn raises an ArgumentError if an environment key includes a null byte
fails:Kernel.spawn raises an ArgumentError if an environment value includes a null byte
fails:Kernel.spawn unsets other environment variables when given a true :unsetenv_others option
fails:Kernel.spawn unsets other environment variables when given a non-false :unsetenv_others option
fails:Kernel.spawn does not unset environment variables included in the environment hash
fails:Kernel.spawn joins the current process if pgroup: false
fails:Kernel.spawn joins the current process if pgroup: nil
fails:Kernel.spawn joins a new process group if pgroup: true
5 changes: 4 additions & 1 deletion tool/jruby_eclipse
Original file line number Diff line number Diff line change
@@ -4,7 +4,10 @@

JRUBY = File.expand_path('../..', __FILE__)

M2REPO = "#{Dir.home}/.m2/repository"
# Handle missing $HOME variable
home = Dir.home rescue "/home/#{`whoami`.chomp}"

M2REPO = "#{home}/.m2/repository"

TRUFFLE_VERSION = File.foreach("#{JRUBY}/truffle/pom.rb") { |line|
break $1 if /'truffle\.version' => '(\d+\.\d+|\h+-SNAPSHOT)'/ =~ line
5 changes: 5 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/core/CoreLibrary.java
Original file line number Diff line number Diff line change
@@ -1168,6 +1168,11 @@ public static boolean fitsIntoInteger(long value) {
return ((int) value) == value;
}

public static int long2int(long value) {
assert fitsIntoInteger(value);
return (int) value;
}

public RubyContext getContext() {
return context;
}
Original file line number Diff line number Diff line change
@@ -34,6 +34,7 @@ public abstract class TruffleProcessNodes {
@CoreMethod(names = "spawn", onSingleton = true, required = 4, unsafe = UnsafeGroup.PROCESSES)
public abstract static class SpawnNode extends CoreMethodArrayArgumentsNode {

@TruffleBoundary
@Specialization(guards = {
"isRubyString(command)",
"isRubyArray(arguments)",
@@ -46,14 +47,11 @@ public int spawn(DynamicObject command,

Collection<SpawnFileAction> fileActions = parseOptions(options);

final long longPid = call(
int pid = call(
StringOperations.getString(command),
toStringArray(arguments),
toStringArray(environmentVariables),
fileActions);
assert longPid <= Integer.MAX_VALUE;
// VMWaitPidPrimitiveNode accepts only int
final int pid = (int) longPid;

if (pid == -1) {
// TODO (pitr 07-Sep-2015): needs compatibility improvements
@@ -126,7 +124,7 @@ private Collection<SpawnFileAction> parseOptions(DynamicObject options) {
}

@TruffleBoundary
private long call(String command, String[] arguments, String[] environmentVariables, Collection<SpawnFileAction> fileActions) {
private int call(String command, String[] arguments, String[] environmentVariables, Collection<SpawnFileAction> fileActions) {
return getContext().getNativePlatform().getPosix().posix_spawnp(
command,
fileActions,
Original file line number Diff line number Diff line change
@@ -479,7 +479,7 @@ public abstract static class VMWaitPidPrimitiveNode extends PrimitiveArrayArgume

@TruffleBoundary
@Specialization
public Object waitPID(final int input_pid, boolean no_hang) {
public Object waitPID(int input_pid, boolean no_hang) {
// Transliterated from Rubinius C++ - not tidied up significantly to make merging changes easier

int options = 0;
Original file line number Diff line number Diff line change
@@ -19,10 +19,10 @@
import jnr.posix.SignalHandler;
import jnr.posix.SpawnFileAction;
import jnr.posix.Times;

import java.io.FileDescriptor;
import java.nio.ByteBuffer;
import java.util.Collection;
import org.jruby.truffle.core.CoreLibrary;

public class JNRTrufflePosix implements TrufflePosix {

@@ -306,8 +306,8 @@ public Times times() {
}

@Override
public long posix_spawnp(String path, Collection<? extends SpawnFileAction> fileActions, Collection<? extends CharSequence> argv, Collection<? extends CharSequence> envp) {
return posix.posix_spawnp(path, fileActions, argv, envp);
public int posix_spawnp(String path, Collection<? extends SpawnFileAction> fileActions, Collection<? extends CharSequence> argv, Collection<? extends CharSequence> envp) {
return CoreLibrary.long2int(posix.posix_spawnp(path, fileActions, argv, envp));
}

@Override
Original file line number Diff line number Diff line change
@@ -78,7 +78,7 @@ public interface TrufflePosix {
int chdir(String path);
long sysconf(Sysconf name);
Times times();
long posix_spawnp(String path, Collection<? extends SpawnFileAction> fileActions, Collection<? extends CharSequence> argv, Collection<? extends CharSequence> envp);
int posix_spawnp(String path, Collection<? extends SpawnFileAction> fileActions, Collection<? extends CharSequence> argv, Collection<? extends CharSequence> envp);
int flock(int fd, int operation);
int dup(int fd);
int dup2(int oldFd, int newFd);
20 changes: 17 additions & 3 deletions truffle/src/main/ruby/core/process_mirror.rb
Original file line number Diff line number Diff line change
@@ -126,8 +126,7 @@ def initialize(env_or_cmd, *args)
key.each { |k| redirect @options, convert_io_fd(k), to }
when :unsetenv_others
if value
array = @options[:env] = []
ENV.each_key { |k| array << convert_env_key(k) << nil }
@options[:unsetenv_others] = true
end
when :pgroup
if value == true
@@ -153,7 +152,7 @@ def initialize(env_or_cmd, *args)
array = (@options[:env] ||= [])

env.each do |key, value|
array << convert_env_key(key) << convert_env_value(value)
array << [convert_env_key(key), convert_env_value(value)]
end
end
end
@@ -243,6 +242,21 @@ def convert_file_mode(obj)
end
end

def convert_env_key(key)
key = Rubinius::Type.check_null_safe(StringValue(key))

if key.include?("=")
raise ArgumentError, "environment name contains a equal : #{key}"
end

key
end

def convert_env_value(value)
return if value.nil?
Rubinius::Type.check_null_safe(StringValue(value))
end

# Mapping of string open modes to integer oflag versions.
OFLAGS = {
"r" => ::File::RDONLY,
5 changes: 5 additions & 0 deletions truffle/src/main/ruby/core/type.rb
Original file line number Diff line number Diff line change
@@ -295,6 +295,11 @@ def self.infect(host, source)
raise PrimitiveFailure, "Object.infect primitive failed"
end

def self.check_null_safe(string)
raise ArgumentError, "string contains NULL byte" if string.include? "\0"
string
end

def self.coerce_to_encoding(obj)
case obj
when Encoding