Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix gets on Windows.
Browse files Browse the repository at this point in the history
* Don't unwrap stdin streams; the direct FileChannel does not seem
  to be usable and reads result in IOException: Not enough storage
  is available to process this command.
* Tweaks for argf logic.
* Always treat FileChannel as ready for read, since files always
  select immediately and processes can't be selected without
  native support.
headius committed May 28, 2015
1 parent d0c1512 commit ead7549
Showing 4 changed files with 24 additions and 34 deletions.
17 changes: 4 additions & 13 deletions core/src/main/java/org/jruby/RubyArgsFile.java
Original file line number Diff line number Diff line change
@@ -36,6 +36,7 @@
import java.io.IOException;
import static org.jruby.RubyEnumerator.enumeratorize;

import org.jruby.anno.FrameField;
import org.jruby.anno.JRubyMethod;
import org.jruby.exceptions.RaiseException;
import jnr.posix.FileStat;
@@ -239,6 +240,7 @@ public static IRubyObject external_encoding(ThreadContext context, IRubyObject r
return ((RubyIO) getData(context, recv, "no stream to set encoding").currentFile).external_encoding(context);
}

// MRI: argf_getline
private static IRubyObject argf_getline(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
ArgsFileData data = ArgsFileData.getDataFrom(recv);

@@ -269,21 +271,10 @@ private static IRubyObject argf_getline(ThreadContext context, IRubyObject recv,
/** Read a line.
*
*/
@JRubyMethod(name = "gets", optional = 1)
@JRubyMethod(name = "gets", optional = 1, writes = FrameField.LASTLINE)
public static IRubyObject gets(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
ArgsFileData data = ArgsFileData.getDataFrom(recv);

if (!data.next_argv(context)) return context.runtime.getNil();

IRubyObject line;
if (!(data.currentFile instanceof RubyIO)) {
line = data.currentFile.callMethod(context, "gets", args);
} else {
line = argf_getline(context, recv, args);
}

IRubyObject line = argf_getline(context, recv, args);
context.setLastLine(line);
context.runtime.getGlobalVariables().set("$_", line);

return line;
}
10 changes: 0 additions & 10 deletions core/src/main/java/org/jruby/RubyGlobal.java
Original file line number Diff line number Diff line change
@@ -286,19 +286,9 @@ private static Channel prepareStdioChannel(Ruby runtime, STDIO stdio, Object str
} else {
switch (stdio) {
case IN:
stream = ShellLauncher.unwrapFilterInputStream((InputStream)stream);
if (stream instanceof FileInputStream) {
return ((FileInputStream)stream).getChannel();
}

return Channels.newChannel((InputStream)stream);
case OUT:
case ERR:
stream = ShellLauncher.unwrapFilterOutputStream((OutputStream)stream);
if (stream instanceof FileOutputStream) {
return ((FileOutputStream)stream).getChannel();
}

return Channels.newChannel((OutputStream)stream);
default: throw new RuntimeException("invalid stdio: " + stdio);
}
8 changes: 7 additions & 1 deletion core/src/main/java/org/jruby/RubyKernel.java
Original file line number Diff line number Diff line change
@@ -318,9 +318,15 @@ public static IRubyObject getc(ThreadContext context, IRubyObject recv) {
return defin.callMethod(context, "getc");
}

// MRI: rb_f_gets
@JRubyMethod(optional = 1, module = true, visibility = PRIVATE)
public static IRubyObject gets(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
return RubyArgsFile.gets(context, context.runtime.getArgsFile(), args);
Ruby runtime = context.runtime;

if (recv == runtime.getArgsFile()) {
return RubyArgsFile.gets(context, runtime.getArgsFile(), args);
}
return runtime.getArgsFile().callMethod(context, "gets", args);
}

@JRubyMethod(optional = 1, module = true, visibility = PRIVATE)
23 changes: 13 additions & 10 deletions core/src/main/java/org/jruby/util/io/OpenFile.java
Original file line number Diff line number Diff line change
@@ -1400,16 +1400,19 @@ boolean waitReadable(ThreadContext context, ChannelFD fd) {

// kinda-hacky way to see if there's more data to read from a seekable channel
if (fd.chSeek != null) {
FileChannel fdSeek = fd.chSeek;
try {
// not a real file, can't get size...we'll have to just read and block
if (fdSeek.size() < 0) return true;

// if current position is less than file size, read should not block
return fdSeek.position() < fdSeek.size();
} catch (IOException ioe) {
throw context.runtime.newIOErrorFromException(ioe);
}
return true;
// FileChannel fdSeek = fd.chSeek;
// try {
// // not a real file, can't get size...we'll have to just read and block
// if (fdSeek.size() < 0) return true;
//
// // if current position is less than file size, read should not block
// return fdSeek.position() < fdSeek.size();
// } catch (IOException ioe) {
// System.out.println("chSeek: " + fd.chSeek);
// ioe.printStackTrace();
// throw context.runtime.newIOErrorFromException(ioe);
// }
}
} finally {
if (locked) unlock();

0 comments on commit ead7549

Please sign in to comment.