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

Commits on Dec 22, 2015

  1. Copy the full SHA
    4a39254 View commit details
  2. Copy the full SHA
    c37e31d View commit details
  3. Copy the full SHA
    27c556c View commit details
  4. Copy the full SHA
    fd3ccb2 View commit details
  5. Copy the full SHA
    fe48f98 View commit details
  6. Copy the full SHA
    75b2a5a View commit details
  7. Copy the full SHA
    cc5f1f0 View commit details
  8. Copy the full SHA
    3cadb0c View commit details
61 changes: 32 additions & 29 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -3958,40 +3958,43 @@ public RaiseException newStandardError(String message) {
* TODO: Should ECONNABORTED get thrown earlier in the descriptor itself or is it ok to handle this late?
* TODO: Should we include this into Errno code somewhere do we can use this from other places as well?
*/
public RaiseException newIOErrorFromException(IOException e) {
if (e instanceof ClosedChannelException || "Bad file descriptor".equals(e.getMessage())) {
throw newErrnoEBADFError();
}

// TODO: this is kinda gross
if(e.getMessage() != null) {
String errorMessage = e.getMessage();
public RaiseException newIOErrorFromException(final IOException ex) {
final String errorMessage = ex.getMessage();
if ( errorMessage != null ) {
// All errors to sysread should be SystemCallErrors, but on a closed stream
// Ruby returns an IOError. Java throws same exception for all errors so
// we resort to this hack...
if ("File not open".equals(errorMessage)) {
return newIOError(e.getMessage());
} else if ("An established connection was aborted by the software in your host machine".equals(errorMessage)) {
return newErrnoECONNABORTEDError();
} else if (e.getMessage().equals("Broken pipe")) {
return newErrnoEPIPEError();
} else if ("Connection reset by peer".equals(e.getMessage())
|| "An existing connection was forcibly closed by the remote host".equals(e.getMessage()) ||
(Platform.IS_WINDOWS && e.getMessage().contains("connection was aborted"))) {
return newErrnoECONNRESETError();
} else if ("Too many levels of symbolic links".equals(e.getMessage())) {
return newErrnoELOOPError();
} else if ("Too many open files".equals(e.getMessage())) {
return newErrnoEMFILEError();
} else if ("Too many open files in system".equals(e.getMessage())) {
return newErrnoENFILEError();
} else if ("Network is unreachable".equals(e.getMessage())) {
return newErrnoENETUNREACHError();
switch ( errorMessage ) {
case "Bad file descriptor" :
if ( ex instanceof ClosedChannelException ) throw newErrnoEBADFError();
break;
case "File not open" :
return newIOError(errorMessage);
case "An established connection was aborted by the software in your host machine" :
return newErrnoECONNABORTEDError();
case "Broken pipe" :
return newErrnoEPIPEError();
case "Connection reset by peer" :
case "An existing connection was forcibly closed by the remote host" :
return newErrnoECONNRESETError();
case "Too many levels of symbolic links" :
return newErrnoELOOPError();
case "Too many open files" :
return newErrnoEMFILEError();
case "Too many open files in system" :
return newErrnoENFILEError();
case "Network is unreachable" :
return newErrnoENETUNREACHError();
default :
if ( Platform.IS_WINDOWS ) {
if ( errorMessage.contains("connection was aborted") ) {
return newErrnoECONNRESETError();
}
}
}
return newRaiseException(getIOError(), e.getMessage());
} else {
return newRaiseException(getIOError(), "IO Error");
return newRaiseException(getIOError(), errorMessage);
}
return newRaiseException(getIOError(), "IO Error");
}

public RaiseException newTypeError(IRubyObject receivedObject, RubyClass expectedType) {
36 changes: 14 additions & 22 deletions core/src/main/java/org/jruby/RubyIO.java
Original file line number Diff line number Diff line change
@@ -2891,21 +2891,15 @@ private IRubyObject getPartial(ThreadContext context, IRubyObject[] args, boolea
// MRI: rb_io_sysread
@JRubyMethod(name = "sysread", required = 1, optional = 1)
public IRubyObject sysread(ThreadContext context, IRubyObject[] args) {
Ruby runtime = context.runtime;
IRubyObject len, str;
OpenFile fptr;
int ilen, n;
// struct read_internal_arg arg;

len = args.length >= 1 ? args[0] : context.nil;
str = args.length >= 2 ? args[1] : context.nil;
ilen = RubyNumeric.num2int(len);
final Ruby runtime = context.runtime;

str = EncodingUtils.setStrBuf(runtime, str, (int)ilen);
if (ilen == 0) return str;
final int length = RubyNumeric.num2int(args.length >= 1 ? args[0] : context.nil);
RubyString str = EncodingUtils.setStrBuf(runtime, args.length >= 2 ? args[1] : context.nil, length);
if (length == 0) return str;

fptr = getOpenFileChecked();
final OpenFile fptr = getOpenFileChecked();

final int n;
boolean locked = fptr.lock();
try {
fptr.checkByteReadable(context);
@@ -2926,23 +2920,21 @@ public IRubyObject sysread(ThreadContext context, IRubyObject[] args) {

fptr.checkClosed();

str = EncodingUtils.setStrBuf(runtime, str, ilen);
ByteList strByteList = ((RubyString) str).getByteList();
n = OpenFile.readInternal(context, fptr, fptr.fd(), strByteList.unsafeBytes(), strByteList.begin(), ilen);
ByteList strByteList = str.getByteList();
n = OpenFile.readInternal(context, fptr, fptr.fd(), strByteList.unsafeBytes(), strByteList.begin(), length);

if (n == -1) {
throw runtime.newErrnoFromErrno(fptr.errno(), fptr.getPath());
}
} finally {
}
finally {
if (locked) fptr.unlock();
}

((RubyString)str).setReadLength(n);
if (n == 0 && ilen > 0) {
throw runtime.newEOFError();
}
if (n == 0 && length > 0) throw runtime.newEOFError();

str.setReadLength(n);
str.setTaint(true);

return str;
}

@@ -4654,7 +4646,7 @@ private static int rb_io_fptr_finalize(Ruby runtime, OpenFile fptr) {
return 1;
}

private static final byte[] NEWLINE_BYTES = {(byte)'\n'};
private static final byte[] NEWLINE_BYTES = { (byte) '\n' };

@Deprecated
public IRubyObject getline(Ruby runtime, ByteList separator) {
26 changes: 11 additions & 15 deletions core/src/main/java/org/jruby/ext/socket/RubyBasicSocket.java
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
* rights and limitations under the License.
*
* Copyright (C) 2007 Ola Bini <ola@ologix.com>
*
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
@@ -28,10 +28,6 @@

package org.jruby.ext.socket;

import static jnr.constants.platform.IPProto.IPPROTO_TCP;
import static jnr.constants.platform.IPProto.IPPROTO_IP;
import static jnr.constants.platform.TCP.TCP_NODELAY;

import java.io.IOException;
import java.net.Inet6Address;
import java.net.InetSocketAddress;
@@ -44,6 +40,9 @@
import jnr.constants.platform.Fcntl;
import jnr.constants.platform.ProtocolFamily;
import jnr.constants.platform.Sock;
import jnr.constants.platform.SocketLevel;
import jnr.constants.platform.SocketOption;

import org.jruby.Ruby;
import org.jruby.RubyBoolean;
import org.jruby.RubyClass;
@@ -64,13 +63,12 @@
import org.jruby.util.Pack;
import org.jruby.util.io.BadDescriptorException;
import org.jruby.util.io.ChannelFD;
import org.jruby.util.io.FilenoUtil;
import org.jruby.util.io.OpenFile;

import jnr.constants.platform.SocketLevel;
import jnr.constants.platform.SocketOption;
import org.jruby.util.io.Sockaddr;

import static jnr.constants.platform.IPProto.IPPROTO_TCP;
import static jnr.constants.platform.IPProto.IPPROTO_IP;
import static jnr.constants.platform.TCP.TCP_NODELAY;

/**
* Implementation of the BasicSocket class from Ruby.
@@ -166,7 +164,7 @@ public IRubyObject recv(ThreadContext context, IRubyObject _length) {

return RubyString.newString(runtime, bytes);
}

@JRubyMethod
public IRubyObject recv(ThreadContext context, IRubyObject _length, IRubyObject _flags) {
// TODO: implement flags
@@ -199,8 +197,6 @@ public IRubyObject getsockopt(ThreadContext context, IRubyObject _level, IRubyOb
SocketLevel level = levelFromArg(_level);
SocketOption opt = optionFromArg(_opt);

int value = 0;

try {
Channel channel = getOpenChannel();

@@ -215,8 +211,8 @@ public IRubyObject getsockopt(ThreadContext context, IRubyObject _level, IRubyOb
throw runtime.newErrnoENOPROTOOPTError();
}

value = SocketType.forChannel(channel).getSocketOption(channel, opt);
int value = SocketType.forChannel(channel).getSocketOption(channel, opt);

return new Option(runtime, ProtocolFamily.PF_INET, level, opt, value);

default:
@@ -626,7 +622,7 @@ protected void initSocket(ChannelFD fd) {
// see rsock_init_sock in MRI; sockets are initialized to binary
setAscii8bitBinmode();
}

private Channel getOpenChannel() {
return getOpenFileChecked().channel();
}
101 changes: 48 additions & 53 deletions core/src/main/java/org/jruby/ext/socket/RubySocket.java
Original file line number Diff line number Diff line change
@@ -27,6 +27,25 @@
***** END LICENSE BLOCK *****/
package org.jruby.ext.socket;

import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.channels.AlreadyConnectedException;
import java.nio.channels.Channel;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.ConnectionPendingException;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SocketChannel;
import java.util.Enumeration;
import java.util.regex.Pattern;

import jnr.constants.platform.AddressFamily;
import jnr.constants.platform.INAddr;
import jnr.constants.platform.IPProto;
@@ -40,45 +59,22 @@
import jnr.netdb.Protocol;
import jnr.unixsocket.UnixSocketAddress;
import jnr.unixsocket.UnixSocketChannel;

import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyClass;
import org.jruby.RubyFixnum;
import org.jruby.RubyModule;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.exceptions.RaiseException;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.io.ChannelFD;
import org.jruby.util.io.FilenoUtil;
import org.jruby.util.io.ModeFlags;
import org.jruby.util.io.Sockaddr;

import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.channels.AlreadyConnectedException;
import java.nio.channels.Channel;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.ConnectionPendingException;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SocketChannel;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
import org.jruby.RubyArray;

import static org.jruby.runtime.Helpers.arrayOf;

/**
@@ -212,7 +208,7 @@ public IRubyObject connect(ThreadContext context, IRubyObject arg) {

@JRubyMethod()
public IRubyObject bind(ThreadContext context, IRubyObject arg) {
InetSocketAddress iaddr = null;
final InetSocketAddress iaddr;

if (arg instanceof Addrinfo){
Addrinfo addr = (Addrinfo) arg;
@@ -390,7 +386,7 @@ private void initFieldsFromArgs(Ruby runtime, IRubyObject domain, IRubyObject ty

initType(runtime, type);

initProtocol(runtime, protocol);
initProtocol(protocol);
}

private void initFieldsFromArgs(Ruby runtime, IRubyObject domain, IRubyObject type) {
@@ -408,39 +404,38 @@ protected void initFromServer(Ruby runtime, RubyServerSocket serverSocket, Socke
}

protected ChannelFD initChannelFD(Ruby runtime) {
Channel channel;

try {
if(soType == Sock.SOCK_STREAM) {

if (soProtocolFamily == ProtocolFamily.PF_UNIX ||
soProtocolFamily == ProtocolFamily.PF_LOCAL) {
channel = UnixSocketChannel.open();
} else if (soProtocolFamily == ProtocolFamily.PF_INET ||
soProtocolFamily == ProtocolFamily.PF_INET6 ||
soProtocolFamily == ProtocolFamily.PF_UNSPEC) {
channel = SocketChannel.open();
} else {
throw runtime.newArgumentError("unsupported protocol family `" + soProtocolFamily + "'");
}

} else if(soType == Sock.SOCK_DGRAM) {
channel = DatagramChannel.open();

} else {
throw runtime.newArgumentError("unsupported socket type `" + soType + "'");

Channel channel;
switch (soType) {
case SOCK_STREAM:
if ( soProtocolFamily == ProtocolFamily.PF_UNIX ||
soProtocolFamily == ProtocolFamily.PF_LOCAL ) {
channel = UnixSocketChannel.open();
}
else if ( soProtocolFamily == ProtocolFamily.PF_INET ||
soProtocolFamily == ProtocolFamily.PF_INET6 ||
soProtocolFamily == ProtocolFamily.PF_UNSPEC ) {
channel = SocketChannel.open();
}
else {
throw runtime.newArgumentError("unsupported protocol family `" + soProtocolFamily + "'");
}
break;
case SOCK_DGRAM:
channel = DatagramChannel.open();
break;
default:
throw runtime.newArgumentError("unsupported socket type `" + soType + "'");
}

return newChannelFD(runtime, channel);

} catch(IOException e) {
}
catch(IOException e) {
throw SocketUtils.sockerr(runtime, "initialize: " + e.toString());

}
}

private void initProtocol(Ruby runtime, IRubyObject protocol) {
private void initProtocol(IRubyObject protocol) {
soProtocol = SocketUtils.protocolFromArg(protocol);
}

@@ -501,7 +496,7 @@ protected void doConnect(ThreadContext context, Channel channel, SocketAddress a
if (channel instanceof SocketChannel) {
SocketChannel socket = (SocketChannel)channel;
boolean result;

if (socket.isConnectionPending()) {
// connection initiated but not finished
result = socket.finishConnect();
Loading