コード例 #1
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);
    }
  }
コード例 #2
0
  public static IRubyObject doAcceptNonblock(RubySocket sock, ThreadContext context, boolean ex) {
    try {
      Channel channel = sock.getChannel();
      if (channel instanceof SelectableChannel) {
        SelectableChannel selectable = (SelectableChannel) channel;

        synchronized (selectable.blockingLock()) {
          boolean oldBlocking = selectable.isBlocking();

          try {
            selectable.configureBlocking(false);

            IRubyObject socket = doAccept(sock, context, ex);
            if (!(socket instanceof RubySocket)) return socket;
            SocketChannel socketChannel = (SocketChannel) ((RubySocket) socket).getChannel();
            InetSocketAddress addr =
                (InetSocketAddress) socketChannel.socket().getRemoteSocketAddress();

            return context.runtime.newArray(
                socket, Sockaddr.packSockaddrFromAddress(context, addr));
          } finally {
            selectable.configureBlocking(oldBlocking);
          }
        }
      } else {
        throw context.runtime.newErrnoENOPROTOOPTError();
      }
    } catch (IOException e) {
      throw sockerr(context.runtime, e.getLocalizedMessage(), e);
    }
  }
コード例 #3
0
ファイル: RubyBasicSocket.java プロジェクト: vvs/jruby
 @JRubyMethod(name = {"getsockname", "__getsockname"})
 public IRubyObject getsockname(ThreadContext context) {
   SocketAddress sock = getLocalSocket();
   if (null == sock) {
     return RubySocket.pack_sockaddr_in(context, null, 0, "0.0.0.0");
   }
   return context.getRuntime().newString(sock.toString());
 }
コード例 #4
0
ファイル: SocketUtils.java プロジェクト: trejkaz/jruby
  public static int getPortFrom(ThreadContext context, IRubyObject _port) {
    int port;
    if (_port instanceof RubyInteger) {
      port = RubyNumeric.fix2int(_port);
    } else {
      IRubyObject portString = _port.convertToString();
      IRubyObject portInteger = portString.convertToInteger("to_i");
      port = RubyNumeric.fix2int(portInteger);

      if (port <= 0) {
        port =
            RubyNumeric.fix2int(
                RubySocket.getservbyname(
                    context, context.runtime.getObject(), new IRubyObject[] {portString}));
      }
    }

    return port;
  }
コード例 #5
0
ファイル: RubyTCPServer.java プロジェクト: nurse/jruby
  @JRubyMethod(
      name = "initialize",
      required = 1,
      optional = 1,
      visibility = Visibility.PRIVATE,
      backtrace = true)
  public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
    IRubyObject hostname = args[0];
    IRubyObject port = args.length > 1 ? args[1] : context.getRuntime().getNil();

    if (hostname.isNil()
        || ((hostname instanceof RubyString) && ((RubyString) hostname).isEmpty())) {
      hostname = context.getRuntime().newString("0.0.0.0");
    } else if (hostname instanceof RubyFixnum) {
      // numeric host, use it for port
      port = hostname;
      hostname = context.getRuntime().newString("0.0.0.0");
    }

    String shost = hostname.convertToString().toString();
    try {
      InetAddress addr = InetAddress.getByName(shost);
      ssc = ServerSocketChannel.open();

      int portInt;
      if (port instanceof RubyInteger) {
        portInt = RubyNumeric.fix2int(port);
      } else {
        IRubyObject portString = port.convertToString();
        IRubyObject portInteger = portString.convertToInteger("to_i");
        portInt = RubyNumeric.fix2int(portInteger);

        if (portInt <= 0) {
          portInt =
              RubyNumeric.fix2int(
                  RubySocket.getservbyname(
                      context, context.getRuntime().getObject(), new IRubyObject[] {portString}));
        }
      }

      socket_address = new InetSocketAddress(addr, portInt);
      ssc.socket().bind(socket_address);
      initSocket(context.getRuntime(), new ChannelDescriptor(ssc, new ModeFlags(ModeFlags.RDWR)));
    } catch (InvalidValueException ex) {
      throw context.getRuntime().newErrnoEINVALError();
    } catch (UnknownHostException e) {
      throw sockerr(context.getRuntime(), "initialize: name or service not known");
    } catch (BindException e) {
      // e.printStackTrace();
      String msg = e.getMessage();
      if (msg == null) {
        msg = "bind";
      } else {
        msg = "bind - " + msg;
      }

      // This is ugly, but what can we do, Java provides the same BindingException
      // for both EADDRNOTAVAIL and EADDRINUSE, so we differentiate the errors
      // based on BindException's message.
      if (ADDR_NOT_AVAIL_PATTERN.matcher(msg).find()) {
        throw context.getRuntime().newErrnoEADDRNOTAVAILError(msg);
      } else {
        throw context.getRuntime().newErrnoEADDRINUSEError(msg);
      }
    } catch (SocketException e) {
      String msg = e.getMessage();
      if (msg.indexOf("Permission denied") != -1) {
        throw context.getRuntime().newErrnoEACCESError("bind(2)");
      } else {
        throw sockerr(context.getRuntime(), "initialize: name or service not known");
      }
    } catch (IOException e) {
      throw sockerr(context.getRuntime(), "initialize: name or service not known");
    } catch (IllegalArgumentException iae) {
      throw sockerr(context.getRuntime(), iae.getMessage());
    }

    return this;
  }