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

Commits on Aug 2, 2017

  1. Guard against too-large offsets here.

    This differs from MRI, since in C they can use a full pointer
    width for pointer offsets. On JVM, where we can only use 32-bit
    signed offsets.
    headius committed Aug 2, 2017
    Copy the full SHA
    d5e67cb View commit details
  2. Tag StringIO specs we won't try to fix now.

    The write overflow spec relates to the change in d5e67cb and
    the fact that JVM only supports 32-bit signed offsets.
    headius committed Aug 2, 2017
    Copy the full SHA
    0fcea87 View commit details
  3. Fix passing fd => fd options to spawn and friends.

    This may help #985 or other open3/popen/spawn issues.
    
    This makes test_open3.rb (what we run of it) green again.
    headius committed Aug 2, 2017
    Copy the full SHA
    ba2c11b View commit details
  4. Copy the full SHA
    3f682cf View commit details
  5. Minor cleanup.

    headius committed Aug 2, 2017
    Copy the full SHA
    2723055 View commit details
113 changes: 73 additions & 40 deletions core/src/main/java/org/jruby/ext/io/wait/IOWaitLibrary.java
Original file line number Diff line number Diff line change
@@ -31,8 +31,10 @@
import org.jruby.RubyClass;
import org.jruby.RubyIO;
import org.jruby.RubyNumeric;
import org.jruby.RubySymbol;
import org.jruby.RubyTime;
import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.load.Library;
@@ -90,40 +92,18 @@ public static IRubyObject ready(ThreadContext context, IRubyObject _io) {
return runtime.newBoolean(fptr.readyNow(context));
}

@JRubyMethod(name = {"wait", "wait_readable"}, optional = 1)
@JRubyMethod(optional = 1)
public static IRubyObject wait_readable(ThreadContext context, IRubyObject _io, IRubyObject[] argv) {
RubyIO io = (RubyIO)_io;
Ruby runtime = context.runtime;
OpenFile fptr;
boolean i;
// ioctl_arg n;
IRubyObject timeout;
long tv;
OpenFile fptr = io.getOpenFileChecked();

fptr = io.getOpenFileChecked();
fptr.checkReadable(context);

switch (argv.length) {
case 1:
timeout = argv[0];
break;
default:
timeout = context.nil;
}
long tv = prepareTimeout(context, argv);

if (timeout.isNil()) {
tv = -1;
}
else {
tv = (long)(RubyTime.convertTimeInterval(context, timeout) * 1000);
if (tv < 0) throw runtime.newArgumentError("time interval must be positive");
}
if (fptr.readPending() != 0) return context.tru;

if (fptr.readPending() != 0) return runtime.getTrue();
boolean ready = fptr.ready(runtime, context.getThread(), SelectionKey.OP_READ | SelectionKey.OP_ACCEPT, tv);
fptr.checkClosed();
if (ready) return io;
return context.nil;
return doWait(context, io, fptr, tv, SelectionKey.OP_READ | SelectionKey.OP_ACCEPT);
}

/**
@@ -132,34 +112,87 @@ public static IRubyObject wait_readable(ThreadContext context, IRubyObject _io,
@JRubyMethod(optional = 1)
public static IRubyObject wait_writable(ThreadContext context, IRubyObject _io, IRubyObject[] argv) {
RubyIO io = (RubyIO)_io;
Ruby runtime = context.runtime;
OpenFile fptr;
IRubyObject timeout;
long tv;

fptr = io.getOpenFileChecked();
OpenFile fptr = io.getOpenFileChecked();

fptr.checkWritable(context);

long tv = prepareTimeout(context, argv);

return doWait(context, io, fptr, tv, SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE);
}

@JRubyMethod(optional = 2)
public static IRubyObject wait(ThreadContext context, IRubyObject _io, IRubyObject[] argv) {
RubyIO io = (RubyIO)_io;

OpenFile fptr = io.getOpenFileChecked();

int ops = 0;

if (argv.length == 2) {
if (argv[1] instanceof RubySymbol) {
RubySymbol sym = (RubySymbol) argv[1];
switch (sym.toString()) {
case "r":
case "read":
case "readable":
ops |= SelectionKey.OP_ACCEPT | SelectionKey.OP_READ;
break;
case "w":
case "write":
case "writable":
ops |= SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE;
break;
case "rw":
case "read_write":
case "readable_writable":
ops |= SelectionKey.OP_ACCEPT | SelectionKey.OP_READ;
ops |= SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE;
default:
throw context.runtime.newArgumentError("unsupported mode: " + sym);
}

throw context.runtime.newArgumentError("unsupported mode: " + sym);
}
} else if (argv.length == 1) {
ops |= SelectionKey.OP_ACCEPT | SelectionKey.OP_READ;
}

if ((ops & SelectionKey.OP_READ) != 0) {
if (fptr.readPending() != 0) return context.tru;
}

long tv = prepareTimeout(context, argv);

return doWait(context, io, fptr, tv, ops);
}

private static IRubyObject doWait(ThreadContext context, RubyIO io, OpenFile fptr, long tv, int ops) {
boolean ready = fptr.ready(context.runtime, context.getThread(), ops, tv);
fptr.checkClosed();
if (ready) return io;
return context.nil;
}

private static long prepareTimeout(ThreadContext context, IRubyObject[] argv) {
IRubyObject timeout;
long tv;
switch (argv.length) {
case 1:
timeout = argv[0];
break;
default:
timeout = context.nil;
}

if (timeout.isNil()) {
tv = -1;
}
else {
tv = (long)(RubyTime.convertTimeInterval(context, timeout) * 1000);
if (tv < 0) throw runtime.newArgumentError("time interval must be positive");
if (tv < 0) throw context.runtime.newArgumentError("time interval must be positive");
}

boolean ready = fptr.ready(runtime, context.getThread(), SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE, tv);

fptr.checkClosed();
if (ready)
return io;
return context.nil;
return tv;
}
}
6 changes: 4 additions & 2 deletions core/src/main/java/org/jruby/ext/stringio/StringIO.java
Original file line number Diff line number Diff line change
@@ -727,11 +727,13 @@ public IRubyObject pos(ThreadContext context) {
public IRubyObject set_pos(IRubyObject arg) {
checkInitialized();

int p = RubyNumeric.fix2int(arg);
long p = RubyNumeric.fix2long(arg);

if (p < 0) throw getRuntime().newErrnoEINVALError(arg.toString());

ptr.pos = p;
if (p > Integer.MAX_VALUE) throw getRuntime().newArgumentError("JRuby does not support StringIO larger than " + Integer.MAX_VALUE + " bytes");

ptr.pos = (int)p;

return arg;
}
10 changes: 3 additions & 7 deletions core/src/main/java/org/jruby/util/io/PopenExecutor.java
Original file line number Diff line number Diff line change
@@ -371,19 +371,15 @@ static IRubyObject handleOptionsCommon(ThreadContext context, Ruby runtime, Exec
if (key instanceof RubySymbol) {
switch (key.toString()) {
case "gid" :
//runtime.getWarnings().warn(IRubyWarnings.ID.UNSUPPORTED_SUBPROCESS_OPTION, "popen does not support :gid option in JRuby");
//break;
throw runtime.newNotImplementedError("popen does not support :gid option in JRuby");
case "uid" :
//runtime.getWarnings().warn(IRubyWarnings.ID.UNSUPPORTED_SUBPROCESS_OPTION, "popen does not support :uid option in JRuby");
//break;
throw runtime.newNotImplementedError("popen does not support :uid option in JRuby");
default :
throw runtime.newArgumentError("wrong exec option symbol: " + key);
}
}
else {
throw runtime.newArgumentError("wrong exec option");
throw runtime.newArgumentError("wrong exec option: " + key);
}
}

@@ -1322,7 +1318,7 @@ static int execargAddopt(ThreadContext context, Ruby runtime, ExecArg eargp, IRu
// rb_secure(2);

boolean redirect = false;
switch (key.getMetaClass().getRealClass().getClassIndex()) {
switch (key.getType().getClassIndex()) {
case SYMBOL:
id = key.toString();
// #ifdef HAVE_SETPGID
@@ -1473,7 +1469,7 @@ else if (id.equals("gid") && false) { // TODO
break;

case INTEGER:
if (!(val instanceof RubyFixnum)) {
if (!(key instanceof RubyFixnum)) {
return ST_STOP;
}
case FILE:
4 changes: 3 additions & 1 deletion test/mri/excludes/TestStringIO.rb
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
exclude :test_binmode, "needs investigation #4303"
exclude :test_binmode, "needs investigation #4303"
exclude :test_overflow, "unusual subprocess test trying to overflow some value"
exclude :test_write_integer_overflow, "JVM does not support > 32bit signed array offsets, so our StringIO cannot either"