@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); }
@JRubyMethod public IRubyObject setsockopt( ThreadContext context, IRubyObject lev, IRubyObject optname, IRubyObject val) { int level = RubyNumeric.fix2int(lev); int opt = RubyNumeric.fix2int(optname); try { switch (SocketLevel.valueOf(level)) { case SOL_IP: case SOL_SOCKET: case SOL_TCP: case SOL_UDP: switch (SocketOption.valueOf(opt)) { case SO_BROADCAST: setBroadcast(val); break; case SO_KEEPALIVE: setKeepAlive(val); break; case SO_LINGER: setLinger(val); break; case SO_OOBINLINE: setOOBInline(val); break; case SO_RCVBUF: setRcvBuf(val); break; case SO_REUSEADDR: setReuseAddr(val); break; case SO_SNDBUF: setSndBuf(val); break; case SO_RCVTIMEO: case SO_SNDTIMEO: setTimeout(val); break; // Can't support the rest with Java case SO_TYPE: case SO_RCVLOWAT: case SO_SNDLOWAT: case SO_DEBUG: case SO_ERROR: case SO_DONTROUTE: case SO_TIMESTAMP: break; default: if (IPPROTO_TCP.value() == level && TCP_NODELAY.value() == opt) { setTcpNoDelay(val); } else { throw context.getRuntime().newErrnoENOPROTOOPTError(); } } break; default: if (IPPROTO_TCP.value() == level && TCP_NODELAY.value() == opt) { setTcpNoDelay(val); } else { throw context.getRuntime().newErrnoENOPROTOOPTError(); } } } catch (IOException e) { throw context.getRuntime().newErrnoENOPROTOOPTError(); } return context.getRuntime().newFixnum(0); }