Esempio n. 1
0
  @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);
  }