Skip to content
Browse files

jruby support v2- now without threads!

  • Loading branch information...
1 parent fac57ee commit 3c2d7e70234e4789e64959756002666c388db300 @tmm1 tmm1 committed
Showing with 46 additions and 8 deletions.
  1. +10 −2 ext/posix-spawn.c
  2. +30 −0 lib/posix/spawn.rb
  3. +6 −6 test/test_spawn.rb
View
12 ext/posix-spawn.c
@@ -69,14 +69,22 @@ posixspawn_obj_to_fd(VALUE obj)
case T_FILE:
/* IO object */
- fd = FIX2INT(rb_funcall(obj, rb_intern("fileno"), 0));
+ if (rb_respond_to(obj, rb_intern("posix_fileno"))) {
+ fd = FIX2INT(rb_funcall(obj, rb_intern("posix_fileno"), 0));
+ } else {
+ fd = FIX2INT(rb_funcall(obj, rb_intern("fileno"), 0));
+ }
break;
case T_OBJECT:
/* some other object */
if (rb_respond_to(obj, rb_intern("to_io"))) {
obj = rb_funcall(obj, rb_intern("to_io"), 0);
- fd = FIX2INT(rb_funcall(obj, rb_intern("fileno"), 0));
+ if (rb_respond_to(obj, rb_intern("posix_fileno"))) {
+ fd = FIX2INT(rb_funcall(obj, rb_intern("posix_fileno"), 0));
+ } else {
+ fd = FIX2INT(rb_funcall(obj, rb_intern("fileno"), 0));
+ }
}
break;
}
View
30 lib/posix/spawn.rb
@@ -2,6 +2,26 @@
require 'posix/spawn/version'
require 'posix/spawn/child'
+class IO
+ if defined? JRUBY_VERSION
+ require 'jruby'
+ def posix_fileno
+ case self
+ when STDIN, $stdin
+ 0
+ when STDOUT, $stdout
+ 1
+ when STDERR, $stderr
+ 2
+ else
+ JRuby.reference(self).getOpenFile.getMainStream.getDescriptor.getChannel.getFDVal

hi @tmm1 - I started to "fix" this using ideas from childprocess, for example...

channel = ::JRuby.reference(obj).channel
begin
  channel.getFDVal
rescue NoMethodError
  fileno = channel.fd
[...]

but then I realized a lot of tests were failing anyway in JRuby 1.6.6.

Are you and @rtomayko still interested in fixing this gem for JRuby?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ end
+ end
+ else
+ alias :posix_fileno :fileno
+ end
+end
+
module POSIX
# The POSIX::Spawn module implements a compatible subset of Ruby 1.9's
# Process::spawn and related methods using the IEEE Std 1003.1 posix_spawn(2)
@@ -151,6 +171,16 @@ def spawn(*args)
def pspawn(*args)
env, argv, options = extract_process_spawn_arguments(*args)
raise NotImplementedError unless respond_to?(:_pspawn)
+
+ if defined? JRUBY_VERSION
+ # On the JVM, changes made to the environment are not propagated down
+ # to C via get/setenv, so we have to fake it here.
+ unless options[:unsetenv_others] == true
+ env = ENV.merge(env)
+ options[:unsetenv_others] = true
+ end
+ end
+
_pspawn(env, argv, options)
end
View
12 test/test_spawn.rb
@@ -68,7 +68,7 @@ def test_spawn_unset_env
def test_sanity_of_checking_clone_with_sh
rd, wr = IO.pipe
- pid = _spawn("exec 2>/dev/null 100<&#{rd.to_i} || exit 1", rd => rd)
+ pid = _spawn("exec 2>/dev/null 100<&#{rd.posix_fileno} || exit 1", rd => rd)
assert_process_exit_status pid, 0
ensure
[rd, wr].each { |fd| fd.close rescue nil }
@@ -94,7 +94,7 @@ def test_spawn_close_on_standard_stream_io_object
def test_spawn_close_option_with_fd_number
rd, wr = IO.pipe
- pid = _spawn("exec 2>/dev/null 100<&#{rd.to_i} || exit 1", rd.to_i => :close)
+ pid = _spawn("exec 2>/dev/null 100<&#{rd.posix_fileno} || exit 1", rd.posix_fileno => :close)
assert_process_exit_status pid, 1
assert !rd.closed?
@@ -105,7 +105,7 @@ def test_spawn_close_option_with_fd_number
def test_spawn_close_option_with_io_object
rd, wr = IO.pipe
- pid = _spawn("exec 2>/dev/null 100<&#{rd.to_i} || exit 1", rd => :close)
+ pid = _spawn("exec 2>/dev/null 100<&#{rd.posix_fileno} || exit 1", rd => :close)
assert_process_exit_status pid, 1
assert !rd.closed?
@@ -123,7 +123,7 @@ def test_spawn_close_invalid_fd_raises_exception
def test_spawn_closing_multiple_fds_with_array_keys
rd, wr = IO.pipe
- pid = _spawn("exec 2>/dev/null 101>&#{wr.to_i} || exit 1", [rd, wr, :out] => :close)
+ pid = _spawn("exec 2>/dev/null 101>&#{wr.posix_fileno} || exit 1", [rd, wr, :out] => :close)
assert_process_exit_status pid, 1
ensure
[rd, wr].each { |fd| fd.close rescue nil }
@@ -145,7 +145,7 @@ def test_spawn_redirect_fds_with_symbolic_names_and_io_objects
def test_spawn_redirect_fds_with_fd_numbers
rd, wr = IO.pipe
- pid = _spawn("echo", "hello world", 1 => wr.fileno, rd.fileno => :close)
+ pid = _spawn("echo", "hello world", 1 => wr.posix_fileno, rd.posix_fileno => :close)
wr.close
output = rd.read
assert_process_exit_ok pid
@@ -181,7 +181,7 @@ def test_spawn_does_not_close_fd_when_redirecting
# have to pass it explicitly as fd => fd.
def test_explicitly_passing_an_fd_as_open
rd, wr = IO.pipe
- pid = _spawn("exec 101>&#{wr.to_i} || exit 1", wr => wr)
+ pid = _spawn("exec 101>&#{wr.posix_fileno} || exit 1", wr => wr)
assert_process_exit_ok pid
ensure
[rd, wr].each { |fd| fd.close rescue nil }

0 comments on commit 3c2d7e7

Please sign in to comment.
Something went wrong with that request. Please try again.