@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);
  }
Beispiel #2
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);
  }