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

Commits on Apr 23, 2015

  1. Copy the full SHA
    589676b View commit details
  2. Copy the full SHA
    4d464dc View commit details
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/io/copy_stream_tags.txt
Original file line number Diff line number Diff line change
@@ -32,12 +32,10 @@ fails:IO.copy_stream from a pipe IO to a file name copies the entire IO contents
fails:IO.copy_stream from a pipe IO to a file name returns the number of bytes copied
fails:IO.copy_stream from a pipe IO to a file name copies only length bytes when specified
fails:IO.copy_stream from a pipe IO to a file name calls #to_path to convert on object to a file name
fails:IO.copy_stream from a pipe IO to a file name raises a TypeError if #to_path does not return a String
fails:IO.copy_stream from a pipe IO to an IO copies the entire IO contents to the IO
fails:IO.copy_stream from a pipe IO to an IO returns the number of bytes copied
fails:IO.copy_stream from a pipe IO to an IO starts writing at the destination IO's current position
fails:IO.copy_stream from a pipe IO to an IO leaves the destination IO position at the last write
fails:IO.copy_stream from a pipe IO to an IO raises an IOError if the destination IO is not open for writing
fails:IO.copy_stream from a pipe IO to an IO does not close the destination IO
fails:IO.copy_stream from a pipe IO to an IO copies only length bytes when specified
fails:IO.copy_stream with non-IO Objects calls #readpartial on the source Object if defined
1 change: 0 additions & 1 deletion spec/truffle/tags/core/io/eof_tags.txt
Original file line number Diff line number Diff line change
@@ -4,5 +4,4 @@ fails:IO#eof? returns false on just opened non-empty stream
fails:IO#eof? does not consume the data from the stream
fails:IO#eof? raises IOError on closed stream
fails:IO#eof? raises IOError on stream closed for reading by close_read
fails:IO#eof? returns true on receiving side of Pipe when writing side is closed
fails:IO#eof? returns false on receiving side of Pipe when writing side wrote some data
1 change: 0 additions & 1 deletion spec/truffle/tags/core/io/inspect_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
fails:IO#inspect contains the file descriptor number
fails:IO#inspect contains "(closed)" if the stream is closed
19 changes: 0 additions & 19 deletions spec/truffle/tags/core/io/pipe_tags.txt
Original file line number Diff line number Diff line change
@@ -1,25 +1,6 @@
fails:IO.pipe creates a two-ended pipe
fails:IO.pipe returns two IO objects
fails:IO.pipe returns instances of a subclass when called on a subclass
fails:IO.pipe passed a block yields two IO objects
fails:IO.pipe passed a block returns the result of the block
fails:IO.pipe passed a block closes both IO objects
fails:IO.pipe passed a block closes both IO objects when the block raises
fails:IO.pipe passed a block allows IO objects to be closed within the block
fails:IO.pipe sets the external encoding of the read end to the default when passed no arguments
fails:IO.pipe sets the internal encoding of the read end to the default when passed no arguments
fails:IO.pipe sets the internal encoding to nil if the same as the external
fails:IO.pipe sets the external encoding of the read end when passed an Encoding argument
fails:IO.pipe sets the external and internal encodings of the read end when passed two Encoding arguments
fails:IO.pipe sets the external encoding of the read end when passed the name of an Encoding
fails:IO.pipe accepts 'bom|' prefix for external encoding
fails:IO.pipe sets the external and internal encodings specified as a String and separated with a colon
fails:IO.pipe accepts 'bom|' prefix for external encoding when specifying 'external:internal'
fails:IO.pipe sets the external and internal encoding when passed two String arguments
fails:IO.pipe accepts an options Hash with one String encoding argument
fails:IO.pipe accepts an options Hash with two String encoding arguments
fails:IO.pipe calls #to_hash to convert an options argument
fails:IO.pipe calls #to_str to convert the first argument to a String
fails:IO.pipe calls #to_str to convert the second argument to a String
fails:IO.pipe sets no external encoding for the write end
fails:IO.pipe sets no internal encoding for the write end
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/io/readpartial_tags.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
fails:IO#readpartial raises IOError on closed stream
fails:IO#readpartial reads at most the specified number of bytes
fails:IO#readpartial reads after ungetc with data in the buffer
fails:IO#readpartial reads after ungetc with multibyte characters in the buffer
fails:IO#readpartial reads after ungetc without data in the buffer
fails:IO#readpartial discards the existing buffer content upon successful read
fails:IO#readpartial raises EOFError on EOF
fails:IO#readpartial discards the existing buffer content upon error
fails:IO#readpartial raises IOError if the stream is closed
fails:IO#readpartial raises ArgumentError if the negative argument is provided
fails:IO#readpartial immediately returns an empty string if the length argument is 0
4 changes: 0 additions & 4 deletions spec/truffle/tags/core/io/select_tags.txt
Original file line number Diff line number Diff line change
@@ -5,9 +5,5 @@ fails:IO.select returns supplied objects when they are ready for I/O
fails:IO.select leaves out IO objects for which there is no I/O ready
fails:IO.select returns supplied objects correctly even when monitoring the same object in different arrays
fails:IO.select invokes to_io on supplied objects that are not IO and returns the supplied objects
fails:IO.select raises TypeError if supplied objects are not IO
fails:IO.select raises a TypeError if the specified timeout value is not Numeric
fails:IO.select raises TypeError if the first three arguments are not Arrays
fails:IO.select raises an ArgumentError when passed a negative timeout
fails:IO.select when passed nil for timeout sleeps forever
fails:IO.select when passed nil for timeout sets the thread's status to 'sleep'
4 changes: 4 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/nodes/RubyNode.java
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.source.SourceSection;

import jnr.posix.POSIX;
import org.jruby.truffle.nodes.dispatch.DispatchAction;
import org.jruby.truffle.nodes.instrument.RubyWrapperNode;
import org.jruby.truffle.nodes.yield.YieldDispatchNode;
@@ -483,4 +484,7 @@ protected RubyNilClass nil() {
return getContext().getCoreLibrary().getNilObject();
}

protected POSIX posix() {
return getContext().getPosix();
}
}
Original file line number Diff line number Diff line change
@@ -100,7 +100,7 @@ public KillNode(KillNode prev) {
public int kill(RubySymbol signalName, int pid) {
notDesignedForCompilation();

int self = getContext().getPosix().getpid();
int self = posix().getpid();

if (self == pid) {
Signal signal = new Signal(signalName.toString());
@@ -129,7 +129,7 @@ public PidNode(PidNode prev) {
public int pid() {
notDesignedForCompilation();

return getContext().getPosix().getpid();
return posix().getpid();
}

}
Original file line number Diff line number Diff line change
@@ -922,7 +922,7 @@ public Object crypt(RubyString string, RubyString salt) {
throw new RaiseException(getContext().getCoreLibrary().argumentError("salt too short (need >= 2 bytes)", this));
}

final POSIX posix = getContext().getPosix();
final POSIX posix = posix();
final byte[] keyBytes = Arrays.copyOfRange(value.unsafeBytes(), value.begin(), value.realSize());
final byte[] saltBytes = Arrays.copyOfRange(otherBL.unsafeBytes(), otherBL.begin(), otherBL.realSize());

Original file line number Diff line number Diff line change
@@ -141,10 +141,10 @@ public int fill(VirtualFrame frame, RubyBasicObject ioBuffer, RubyBasicObject io
int bytesRead;

while (true) {
bytesRead = getContext().getPosix().read(fd, readBuffer, count);
bytesRead = posix().read(fd, readBuffer, count);

if (bytesRead == -1) {
final int errno = getContext().getPosix().errno();
final int errno = posix().errno();

if (errno == Errno.ECONNRESET.intValue() || errno == Errno.ETIMEDOUT.intValue()) {
// Treat as seeing eof
Original file line number Diff line number Diff line change
@@ -13,8 +13,9 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.runtime.DebugOperations;
import jnr.constants.platform.Fcntl;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.truffle.runtime.core.RubyNilClass;
@@ -46,6 +47,59 @@ public RubyBasicObject allocate(VirtualFrame frame, RubyClass classToAllocate) {

}

@RubiniusPrimitive(name = "io_connect_pipe", needsSelf = false)
public static abstract class IOConnectPipeNode extends RubiniusPrimitiveNode {

public IOConnectPipeNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public IOConnectPipeNode(IOConnectPipeNode prev) {
super(prev);
}

@Specialization
public boolean connectPipe(VirtualFrame frame, RubyBasicObject lhs, RubyBasicObject rhs) {
final int[] fds = new int[2];

if (posix().pipe(fds) == -1) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().errnoError(posix().errno(), this));
}

newOpenFd(fds[0]);
newOpenFd(fds[1]);

rubyWithSelf(frame, lhs, "@descriptor = fd", "fd", fds[0]);
rubyWithSelf(frame, lhs, "@mode = File::Constants::RDONLY");

rubyWithSelf(frame, rhs, "@descriptor = fd", "fd", fds[1]);
rubyWithSelf(frame, rhs, "@mode = File::Constants::WRONLY");

return true;
}

private void newOpenFd(int newFd) {
final int FD_CLOEXEC = 1;

if (newFd > 2) {
int flags = posix().fcntl(newFd, Fcntl.F_GETFD);

if (flags == -1) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().errnoError(posix().errno(), this));
}

flags = posix().fcntlInt(newFd, Fcntl.F_SETFD, flags | FD_CLOEXEC);

if (flags == -1) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().errnoError(posix().errno(), this));
}
}
}
}

@RubiniusPrimitive(name = "io_open", needsSelf = false)
public static abstract class IOOpenPrimitiveNode extends RubiniusPrimitiveNode {

@@ -59,7 +113,7 @@ public IOOpenPrimitiveNode(IOOpenPrimitiveNode prev) {

@Specialization
public int open(RubyString path, int mode, int permission) {
return getContext().getPosix().open(path.getByteList(), mode, permission);
return posix().open(path.getByteList(), mode, permission);
}

}
@@ -130,7 +184,7 @@ public int write(VirtualFrame frame, RubyBasicObject file, RubyString string) {
while (bytes.length > 0) {
getContext().getSafepointManager().poll(this);

int written = getContext().getPosix().write(fd, bytes, bytes.length);
int written = posix().write(fd, bytes, bytes.length);

if (written == -1) {
throw new UnsupportedOperationException();
@@ -161,7 +215,7 @@ public IOClosePrimitiveNode(IOClosePrimitiveNode prev) {
public int close(VirtualFrame frame, RubyBasicObject io) {
// In Rubinius this does a lot more, but we'll stick with this for now
final int fd = (int) rubyWithSelf(frame, io, "@descriptor");
return getContext().getPosix().close(fd);
return posix().close(fd);
}

}
@@ -180,7 +234,7 @@ public IOSeekPrimitiveNode(IOSeekPrimitiveNode prev) {
@Specialization
public int seek(VirtualFrame frame, RubyBasicObject io, int amount, int whence) {
final int fd = (int) rubyWithSelf(frame, io, "@descriptor");
return getContext().getPosix().lseek(fd, amount, whence);
return posix().lseek(fd, amount, whence);
}

}
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ public GetEGIDNode(GetEGIDNode prev) {

@Specialization
public int getEGID() {
return getContext().getPosix().getegid();
return posix().getegid();
}

}
@@ -65,7 +65,7 @@ public GetEUIDNode(GetEUIDNode prev) {

@Specialization
public int getEUID() {
return getContext().getPosix().geteuid();
return posix().geteuid();
}

}
@@ -83,7 +83,7 @@ public GetGIDNode(GetGIDNode prev) {

@Specialization
public int getGID() {
return getContext().getPosix().getgid();
return posix().getgid();
}

}
@@ -127,7 +127,7 @@ public GetUIDNode(GetUIDNode prev) {

@Specialization
public int getUID() {
return getContext().getPosix().getuid();
return posix().getuid();
}

}
@@ -170,7 +170,7 @@ public UnlinkNode(UnlinkNode prev) {

@Specialization
public int unlink(RubyString path) {
return getContext().getPosix().unlink(path.toString());
return posix().unlink(path.toString());
}

}
@@ -188,7 +188,7 @@ public MkdirNode(MkdirNode prev) {

@Specialization
public int mkdir(RubyString path, int mode) {
return getContext().getPosix().mkdir(path.toString(), mode);
return posix().mkdir(path.toString(), mode);
}

}
@@ -208,7 +208,7 @@ public ChdirNode(ChdirNode prev) {
public int chdir(RubyString path) {
final String pathString = path.toString();

final int result = getContext().getPosix().chdir(pathString);
final int result = posix().chdir(pathString);

if (result == 0) {
getContext().getRuntime().setCurrentDirectory(pathString);
@@ -232,7 +232,7 @@ public RmdirNode(RmdirNode prev) {

@Specialization
public int rmdir(RubyString path) {
return getContext().getPosix().rmdir(path.toString());
return posix().rmdir(path.toString());
}

}
@@ -272,7 +272,7 @@ public ErrnoNode(ErrnoNode prev) {

@Specialization
public int errno() {
return getContext().getPosix().errno();
return posix().errno();
}

}
@@ -290,12 +290,12 @@ public FcntlNode(FcntlNode prev) {

@Specialization
public int fcntl(int fd, int fcntl, RubyNilClass nil) {
return getContext().getPosix().fcntl(fd, Fcntl.valueOf(fcntl));
return posix().fcntl(fd, Fcntl.valueOf(fcntl));
}

@Specialization
public int fcntl(int fd, int fcntl, int arg) {
return getContext().getPosix().fcntlInt(fd, Fcntl.valueOf(fcntl), arg);
return posix().fcntlInt(fd, Fcntl.valueOf(fcntl), arg);
}

}
@@ -313,7 +313,7 @@ public IsATTYNode(IsATTYNode prev) {

@Specialization
public int isATTY(int fd) {
return getContext().getPosix().libc().isatty(fd);
return posix().libc().isatty(fd);
}

}
Original file line number Diff line number Diff line change
@@ -40,8 +40,8 @@ public StatStatPrimitiveNode(StatStatPrimitiveNode prev) {

@Specialization
public int stat(RubyBasicObject rubyStat, RubyString path) {
final FileStat stat = getContext().getPosix().allocateStat();
final int code = getContext().getPosix().stat(path.toString(), stat);
final FileStat stat = posix().allocateStat();
final int code = posix().stat(path.toString(), stat);

if (code == 0) {
writeStatNode.execute(rubyStat, stat);
@@ -74,8 +74,8 @@ public StatLStatPrimitiveNode(StatLStatPrimitiveNode prev) {

@Specialization
public int lstat(RubyBasicObject rubyStat, RubyString path) {
final FileStat stat = getContext().getPosix().allocateStat();
final int code = getContext().getPosix().lstat(path.toString(), stat);
final FileStat stat = posix().allocateStat();
final int code = posix().lstat(path.toString(), stat);

if (code == 0) {
writeStatNode.execute(rubyStat, stat);
Original file line number Diff line number Diff line change
@@ -445,7 +445,7 @@ public TimesNode(TimesNode prev) {
public RubyArray times() {
// Copied from org/jruby/RubyProcess.java - see copyright and license information there

Times tms = getContext().getPosix().times();
Times tms = posix().times();
double utime = 0.0d, stime = 0.0d, cutime = 0.0d, cstime = 0.0d;
if (tms == null) {
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
@@ -460,7 +460,7 @@ public RubyArray times() {
cstime = (double)tms.cstime();
}

long hz = getContext().getPosix().sysconf(Sysconf._SC_CLK_TCK);
long hz = posix().sysconf(Sysconf._SC_CLK_TCK);
if (hz == -1) {
hz = 60; //https://github.com/ruby/ruby/blob/trunk/process.c#L6616
}
@@ -610,11 +610,11 @@ public Object waitPID(final int input_pid, boolean no_hang) {
pid = getContext().getThreadManager().runOnce(new ThreadManager.BlockingActionWithoutGlobalLock<Integer>() {
@Override
public Integer block() throws InterruptedException {
return getContext().getPosix().waitpid(input_pid, statusReference, finalOptions);
return posix().waitpid(input_pid, statusReference, finalOptions);
}
});

final int errno = getContext().getPosix().errno();
final int errno = posix().errno();

if (pid == -1) {
if (errno == ECHILD.intValue()) {