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

Commits on Feb 4, 2016

  1. Copy the full SHA
    451987d View commit details
  2. Copy the full SHA
    3b03295 View commit details
Showing with 53 additions and 48 deletions.
  1. +39 −34 core/src/main/java/org/jruby/RubyIO.java
  2. +14 −14 core/src/main/java/org/jruby/util/io/ChannelStream.java
73 changes: 39 additions & 34 deletions core/src/main/java/org/jruby/RubyIO.java
Original file line number Diff line number Diff line change
@@ -1297,33 +1297,34 @@ public IRubyObject op_binmode(ThreadContext context) {

@JRubyMethod(name = "syswrite", required = 1)
public IRubyObject syswrite(ThreadContext context, IRubyObject obj) {
Ruby runtime = context.runtime;
final Ruby runtime = context.runtime;

try {
RubyString string = obj.asString();
OpenFile myOpenFile = getOpenFileChecked();
try {
final OpenFile openFile = getOpenFileChecked();

myOpenFile.checkWritable(runtime);
openFile.checkWritable(runtime);

Stream writeStream = myOpenFile.getWriteStream();
Stream writeStream = openFile.getWriteStream();

if (myOpenFile.isWriteBuffered()) {
if (writeStream.writeDataBuffered()) {
runtime.getWarnings().warn(ID.SYSWRITE_BUFFERED_IO, "syswrite for buffered IO");
}

if (!writeStream.getDescriptor().isWritable()) {
myOpenFile.checkClosed(runtime);
openFile.checkClosed(runtime);
}

RubyString string = obj.asString();

context.getThread().beforeBlockingCall();
int read = writeStream.getDescriptor().write(string.getByteList());
int bytesWritten = writeStream.getDescriptor().write(string.getByteList());

if (read == -1) {
if (bytesWritten == -1) {
// TODO? I think this ends up propagating from normal Java exceptions
// sys_fail(openFile.getPath())
}

return runtime.newFixnum(read);
return runtime.newFixnum(bytesWritten);
} catch (InvalidValueException ex) {
throw runtime.newErrnoEINVALError();
} catch (BadDescriptorException e) {
@@ -1347,19 +1348,19 @@ public IRubyObject write_nonblock(ThreadContext context, IRubyObject obj) {
}

public IRubyObject doWriteNonblock(ThreadContext context, IRubyObject obj, boolean useException) {
Ruby runtime = context.runtime;
final Ruby runtime = context.runtime;

OpenFile myOpenFile = getOpenFileChecked();

try {
myOpenFile.checkWritable(context.runtime);
myOpenFile.checkWritable(runtime);
RubyString str = obj.asString();
if (str.getByteList().length() == 0) {
return context.runtime.newFixnum(0);
return runtime.newFixnum(0);
}

if (myOpenFile.isWriteBuffered()) {
context.runtime.getWarnings().warn(ID.SYSWRITE_BUFFERED_IO, "write_nonblock for buffered IO");
runtime.getWarnings().warn(ID.SYSWRITE_BUFFERED_IO, "write_nonblock for buffered IO");
}

ChannelStream stream = (ChannelStream)myOpenFile.getWriteStream();
@@ -1838,20 +1839,20 @@ public RubyFixnum sysseek(ThreadContext context, IRubyObject[] args) {
whence = RubyNumeric.fix2int(args[1].convertToInteger());
}

OpenFile myOpenFile = getOpenFileChecked();
final OpenFile openFile = getOpenFileChecked();

try {

if (myOpenFile.isReadable() && myOpenFile.isReadBuffered()) {
if (openFile.isReadable() && openFile.isReadBuffered()) {
throw context.runtime.newIOError("sysseek for buffered IO");
}
if (myOpenFile.isWritable() && myOpenFile.isWriteBuffered()) {
if (openFile.isWritable() && openFile.isWriteBuffered()) {
context.runtime.getWarnings().warn(ID.SYSSEEK_BUFFERED_IO, "sysseek for buffered IO");
}

pos = myOpenFile.getMainStreamSafe().getDescriptor().lseek(offset, whence);
pos = openFile.getMainStreamSafe().getDescriptor().lseek(offset, whence);

myOpenFile.getMainStreamSafe().clearerr();
openFile.getMainStreamSafe().clearerr();
} catch (BadDescriptorException ex) {
throw context.runtime.newErrnoEBADFError();
} catch (InvalidValueException e) {
@@ -2957,19 +2958,21 @@ private IRubyObject getPartial(ThreadContext context, IRubyObject[] args, boolea

@JRubyMethod(name = "sysread", required = 1, optional = 1)
public IRubyObject sysread(ThreadContext context, IRubyObject[] args) {
int len = (int)RubyNumeric.num2long(args[0]);
if (len < 0) throw getRuntime().newArgumentError("Negative size");
final Ruby runtime = context.runtime;

final int len = (int) RubyNumeric.num2long(args[0]);
if (len < 0) throw runtime.newArgumentError("Negative size");

try {
RubyString str;
ByteList buffer;
if (args.length == 1 || args[1].isNil()) {
if (len == 0) {
return RubyString.newEmptyString(getRuntime());
return RubyString.newEmptyString(runtime);
}

buffer = new ByteList(len);
str = RubyString.newString(getRuntime(), buffer);
str = RubyString.newString(runtime, buffer);
} else {
str = args[1].convertToString();
str.modify(len);
@@ -2982,39 +2985,41 @@ public IRubyObject sysread(ThreadContext context, IRubyObject[] args) {
buffer.length(0);
}

OpenFile myOpenFile = getOpenFileChecked();
final OpenFile openFile = getOpenFileChecked();

myOpenFile.checkReadable(getRuntime());
openFile.checkReadable(runtime);

if (myOpenFile.getMainStreamSafe().readDataBuffered()) {
Stream readStream = openFile.getMainStreamSafe();

if (readStream.readDataBuffered()) {
throw getRuntime().newIOError("sysread for buffered IO");
}

// TODO: Ruby locks the string here

waitReadable(myOpenFile.getMainStreamSafe());
myOpenFile.checkClosed(getRuntime());
waitReadable(readStream);
openFile.checkClosed(runtime);

// We don't check RubyString modification since JRuby doesn't have
// GIL. Other threads are free to change anytime.

int bytesRead = myOpenFile.getMainStreamSafe().getDescriptor().read(len, str.getByteList());
int bytesRead = readStream.getDescriptor().read(len, str.getByteList());

// TODO: Ruby unlocks the string here

if (bytesRead == -1 || (bytesRead == 0 && len > 0)) {
throw getRuntime().newEOFError();
throw runtime.newEOFError();
}

str.setTaint(true);

return str;
} catch (BadDescriptorException e) {
throw getRuntime().newErrnoEBADFError();
throw runtime.newErrnoEBADFError();
} catch (InvalidValueException e) {
throw getRuntime().newErrnoEINVALError();
throw runtime.newErrnoEINVALError();
} catch (EOFException e) {
throw getRuntime().newEOFError();
throw runtime.newEOFError();
} catch (IOException e) {
synthesizeSystemCallError(e);
return null;
28 changes: 14 additions & 14 deletions core/src/main/java/org/jruby/util/io/ChannelStream.java
Original file line number Diff line number Diff line change
@@ -146,7 +146,7 @@ public void checkPermissionsSubsetOf(ModeFlags subsetModes) {
public ModeFlags getModes() {
return modes;
}

public void setModes(ModeFlags modes) {
this.modes = modes;
}
@@ -162,7 +162,7 @@ public void setSync(boolean sync) {
public void setBinmode() {
// No-op here, no binmode handling needed.
}

public boolean isBinmode() {
return false;
}
@@ -187,15 +187,15 @@ public void waitUntilReady() throws IOException, InterruptedException {
}
}

public boolean readDataBuffered() {
return reading && (hasUngotChars() || buffer.hasRemaining());
public final boolean readDataBuffered() {
return hasBufferedInputBytes();
}

private boolean hasUngotChars() {
return ungotChars.length() > 0;
}

public boolean writeDataBuffered() {
public final boolean writeDataBuffered() {
return !reading && buffer.position() > 0;
}

@@ -295,7 +295,7 @@ public synchronized int getline(ByteList dst, byte terminator) throws IOExceptio

int totalRead = 0;
boolean found = false;

if (hasUngotChars()) {
for(int i = 0; i < ungotChars.length(); i++){
byte ungotc = (byte) ungotChars.get(i);
@@ -305,7 +305,7 @@ public synchronized int getline(ByteList dst, byte terminator) throws IOExceptio
}
clearUngotChars();
}

while (!found) {
final byte[] bytes = buffer.array();
final int begin = buffer.arrayOffset() + buffer.position();
@@ -339,7 +339,7 @@ public synchronized int getline(ByteList dst, byte terminator, long limit) throw

int totalRead = 0;
boolean found = false;

if (hasUngotChars()) {
for(int i = 0; i < ungotChars.length(); i++){
byte ungotc = (byte) ungotChars.get(i);
@@ -350,7 +350,7 @@ public synchronized int getline(ByteList dst, byte terminator, long limit) throw
}
clearUngotChars();
}

while (!found) {
final byte[] bytes = buffer.array();
final int begin = buffer.arrayOffset() + buffer.position();
@@ -380,7 +380,7 @@ public synchronized int getline(ByteList dst, byte terminator, long limit) throw
}

/**
*
*
*/
private void clearUngotChars() {
if(ungotChars.length() > 0) {
@@ -481,7 +481,7 @@ public synchronized ByteList readall() throws IOException, BadDescriptorExceptio
*/
private final int copyBufferedBytes(ByteBuffer dst) {
final int bytesToCopy = dst.remaining();

if (hasUngotChars() && dst.hasRemaining()) {
for(int i = 0; i < ungotChars.length(); i++){
byte ungotc = (byte) ungotChars.get(i);
@@ -520,7 +520,7 @@ private final int copyBufferedBytes(ByteBuffer dst) {
*/
private final int copyBufferedBytes(byte[] dst, int off, int len) {
int bytesCopied = 0;

if (hasUngotChars() && len > 0) {
for(int i = 0; i < ungotChars.length(); i++){
byte ungotc = (byte) ungotChars.get(i);
@@ -548,7 +548,7 @@ private final int copyBufferedBytes(ByteList dst, int len) {
int bytesCopied = 0;

dst.ensure(Math.min(len, bufferedInputBytesRemaining()));

if (hasUngotChars() && hasUngotChars()) {
for(int i = 0; i < ungotChars.length(); i++){
byte ungotc = (byte) ungotChars.get(i);
@@ -1195,7 +1195,7 @@ private void invalidateBuffer() throws IOException, BadDescriptorException {
@Override
public void finalize() throws Throwable {
super.finalize();

if (closedExplicitly) return;

if (DEBUG) {