@JRubyMethod public IRubyObject setsockopt( ThreadContext context, IRubyObject _level, IRubyObject _opt, IRubyObject val) { Ruby runtime = context.runtime; SocketLevel level = levelFromArg(_level); SocketOption opt = optionFromArg(_opt); try { Channel channel = getOpenChannel(); SocketType socketType = SocketType.forChannel(channel); switch (level) { case SOL_IP: case SOL_SOCKET: case SOL_TCP: case SOL_UDP: if (opt == SocketOption.SO_LINGER) { if (val instanceof RubyBoolean && !val.isTrue()) { socketType.setSoLinger(channel, false, 0); } else { int num = asNumber(val); if (num == -1) { socketType.setSoLinger(channel, false, 0); } else { socketType.setSoLinger(channel, true, num); } } } else { socketType.setSocketOption(channel, opt, asNumber(val)); } break; default: int intLevel = (int) _level.convertToInteger().getLongValue(); int intOpt = (int) _opt.convertToInteger().getLongValue(); if (IPPROTO_TCP.intValue() == intLevel && TCP_NODELAY.intValue() == intOpt) { socketType.setTcpNoDelay(channel, asBoolean(val)); } else if (IPPROTO_IP.intValue() == intLevel) { if (MulticastStateManager.IP_ADD_MEMBERSHIP == intOpt) { joinMulticastGroup(val); } } else { throw runtime.newErrnoENOPROTOOPTError(); } } } catch (BadDescriptorException e) { throw runtime.newErrnoEBADFError(); } catch (IOException e) { throw runtime.newErrnoENOPROTOOPTError(); } return runtime.newFixnum(0); }
public static IRubyObject doAccept(RubySocket sock, ThreadContext context, boolean ex) { Ruby runtime = context.runtime; Channel channel = sock.getChannel(); try { if (channel instanceof ServerSocketChannel) { ServerSocketChannel serverChannel = (ServerSocketChannel) sock.getChannel(); SocketChannel socket = serverChannel.accept(); if (socket == null) { // This appears to be undocumented in JDK; null as a sentinel value // for a nonblocking accept with nothing available. We raise for Ruby. // indicates that no connection is available in non-blocking mode if (!ex) return runtime.newSymbol("wait_readable"); throw runtime.newErrnoEAGAINReadableError("accept(2) would block"); } RubySocket rubySocket = new RubySocket(runtime, runtime.getClass("Socket")); rubySocket.initFromServer(runtime, sock, socket); return runtime.newArray( rubySocket, new Addrinfo(runtime, runtime.getClass("Addrinfo"), socket.getRemoteAddress())); } throw runtime.newErrnoENOPROTOOPTError(); } catch (IllegalBlockingModeException e) { // indicates that no connection is available in non-blocking mode if (!ex) return runtime.newSymbol("wait_readable"); throw runtime.newErrnoEAGAINReadableError("accept(2) would block"); } catch (IOException e) { throw sockerr(runtime, e.getLocalizedMessage(), e); } }
@JRubyMethod public IRubyObject getsockopt(ThreadContext context, IRubyObject _level, IRubyObject _opt) { Ruby runtime = context.runtime; SocketLevel level = levelFromArg(_level); SocketOption opt = optionFromArg(_opt); int value = 0; try { Channel channel = getOpenChannel(); switch (level) { case SOL_SOCKET: case SOL_IP: case SOL_TCP: case SOL_UDP: if (opt == SocketOption.__UNKNOWN_CONSTANT__) { throw runtime.newErrnoENOPROTOOPTError(); } value = SocketType.forChannel(channel).getSocketOption(channel, opt); if (runtime.is1_9()) { return new Option(runtime, ProtocolFamily.PF_INET, level, opt, value); } else { return number(runtime, SocketType.forChannel(channel).getSocketOption(channel, opt)); } default: throw runtime.newErrnoENOPROTOOPTError(); } } catch (BadDescriptorException e) { throw runtime.newErrnoEBADFError(); } catch (IOException e) { throw runtime.newErrnoENOPROTOOPTError(); } }
private void doBind( ThreadContext context, Channel channel, InetSocketAddress iaddr, int backlog) { Ruby runtime = context.runtime; try { if (channel instanceof ServerSocketChannel) { ServerSocket socket = ((ServerSocketChannel) channel).socket(); socket.bind(iaddr, backlog); } else { throw runtime.newErrnoENOPROTOOPTError(); } } catch (UnknownHostException e) { throw SocketUtils.sockerr(runtime, "bind(2): unknown host"); } catch (SocketException e) { handleSocketException(runtime, e, "bind(2)", iaddr); } catch (IOException e) { throw sockerr(runtime, "bind(2): name or service not known", e); } catch (IllegalArgumentException e) { throw sockerr(runtime, e.getMessage(), e); } }