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: 313ab775b551^
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 430a591b75fd
Choose a head ref
  • 2 commits
  • 4 files changed
  • 1 contributor

Commits on Dec 2, 2016

  1. Copy the full SHA
    313ab77 View commit details
  2. Copy the full SHA
    430a591 View commit details
1 change: 0 additions & 1 deletion spec/truffle/tags/language/predefined_tags.txt
Original file line number Diff line number Diff line change
@@ -3,6 +3,5 @@ slow:The predefined global constant STDIN retains the encoding set by #set_encod
slow:The predefined global constant STDIN has the encodings set by #set_encoding
slow:The predefined global constant STDOUT has the encodings set by #set_encoding
slow:The predefined global constant ARGV contains Strings encoded in locale Encoding
linux:Global variable $0 actually sets the program name
slow:Global variable $0 is the path given as the main script and the same as __FILE__
slow:Global variable $? is thread-local
4 changes: 4 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/core/CoreLibrary.java
Original file line number Diff line number Diff line change
@@ -1357,6 +1357,10 @@ public DynamicObject getProcClass() {
return procClass;
}

public DynamicObject getProcessModule() {
return processModule;
}

public DynamicObject getRangeClass() {
return rangeClass;
}
Original file line number Diff line number Diff line change
@@ -1765,8 +1765,10 @@ public RubyNode visitGlobalAsgnNode(GlobalAsgnParseNode node) {
final RubyNode translated;

if (name.equals("$0")) {
translated = VMPrimitiveNodesFactory.VMSetProcessTitleNodeFactory.create(
new RubyNode[]{ writeGlobalVariableNode });
// Call Process.setproctitle
RubyNode processClass = new ObjectLiteralNode(context, fullSourceSection, context.getCoreLibrary().getProcessModule());
translated = new RubyCallNode(new RubyCallNodeParameters(context, fullSourceSection, processClass, "setproctitle", null,
new RubyNode[]{writeGlobalVariableNode}, false, false));
} else {
translated = writeGlobalVariableNode;
}
39 changes: 38 additions & 1 deletion truffle/src/main/ruby/core/process.rb
Original file line number Diff line number Diff line change
@@ -129,8 +129,45 @@ def self.cpu_times
#
def self.setproctitle(title)
val = Rubinius::Type.coerce_to(title, String, :to_str)
Truffle.invoke_primitive(:vm_set_process_title, val)
if RbConfig::CONFIG["host_os"] == "linux"
setproctitle_linux_from_proc_maps(val)
else
Truffle.invoke_primitive(:vm_set_process_title, val)
end
end

# Very hacky implementation to pass the specs, since the JVM doesn't give us argv[0]
# Overwrite *argv inplace because finding the argv pointer itself is harder.
def self.setproctitle_linux_from_proc_maps(title)
command = `ps -ocommand -p#{Process.pid}`.lines.last.chomp

stack = File.readlines("/proc/self/maps").grep(/\[stack\]/)
raise stack.to_s unless stack.size == 1

from, to = stack[0].split[0].split('-').map { |addr| Integer(addr, 16) }
raise unless from < to

page = 4096
size = 2 * page
base = to - size
base_ptr = FFI::Pointer.new(FFI::Type::CHAR, base)
haystack = base_ptr.read_string(size)

needle = command.split[0..5].join("\x00")
i = haystack.index("\x00\x00#{needle}")
raise "argv[0] not found" unless i
i += 2

argv0 = base + i
argv0_ptr = FFI::Pointer.new(FFI::Type::CHAR, argv0)
argv0_ptr.write_string("#{title}\x00")

new_command = `ps -ocommand -p#{Process.pid}`.lines.last.chomp
raise "failed" unless new_command.start_with?(title)

title
end
private_class_method :setproctitle_linux_from_proc_maps

def self.setrlimit(resource, cur_limit, max_limit=undefined)
resource = coerce_rlimit_resource(resource)