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; }
@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; }