/* * @(#) $(JCGO)/goclsp/vm/gnu/java/net/VMPlainSocketImpl.java -- * VM interface for default socket implementation. ** * Project: JCGO (http://www.ivmaisoft.com/jcgo/) * Copyright (C) 2001-2009 Ivan Maidanski <ivmai@ivmaisoft.com> * All rights reserved. ** * Class specification origin: GNU Classpath v0.93 vm/reference */ /* * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. ** * This software is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License (GPL) for more details. ** * Linking this library statically or dynamically with other modules is * making a combined work based on this library. Thus, the terms and * conditions of the GNU General Public License cover the whole * combination. ** * As a special exception, the copyright holders of this library give you * permission to link this library with independent modules to produce an * executable, regardless of the license terms of these independent * modules, and to copy and distribute the resulting executable under * terms of your choice, provided that you also meet, for each linked * independent module, the terms and conditions of the license of that * module. An independent module is a module which is not derived from * or based on this library. If you modify this library, you may extend * this exception to your version of the library, but you are not * obligated to do so. If you do not wish to do so, delete this * exception statement from your version. */ package gnu.java.net; import gnu.java.nio.VMChannel; import java.io.IOException; import java.io.InterruptedIOException; import java.net.BindException; import java.net.ConnectException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.NetworkInterface; import java.net.NoRouteToHostException; import java.net.PortUnreachableException; import java.net.SocketException; import java.net.SocketOptions; import java.net.SocketTimeoutException; import java.net.UnknownHostException; import java.util.Enumeration; import java.util.HashMap; public final class VMPlainSocketImpl { public final class State { private VMChannel.State chState; State() {} public void setChannelFD(VMChannel.State newChState) throws IOException { VMChannel.State chState = this.chState; if (chState != null && chState.isValid()) throw new IOException("file descriptor already initialized"); this.chState = newChState; } boolean isValid() { VMChannel.State chState = this.chState; return chState != null && chState.isValid(); } int getNativeFD() throws IOException { VMChannel.State chState = this.chState; if (chState == null) throw new IOException("invalid file descriptor"); return chState.getNativeFD(); } void close() throws IOException { VMChannel.State chState = this.chState; if (chState == null) throw new IOException("invalid file descriptor"); chState.close(); } } private static final int CP_IP_TTL = 0x1E61; private static final int MAX_IP_SIZE = 16; private static final int DEFAULT_TIMEOUT = 30 * 1000; private static final int DEFAULT_BACKLOG = 5; private static final int[] EMPTY_FDS = {}; private static final byte[] EMPTY_BUF = {}; private static boolean initialized; private static boolean preventBlocking; private static HashMap timeouts; private final State state = new State(); VMPlainSocketImpl() {} VMPlainSocketImpl(VMChannel channel) throws IOException { state.setChannelFD(channel.getState()); } public State getState() { return state; } void setTimeToLive(int ttl) throws SocketException { if (ttl <= 0) ttl = 0; int res; do { res = socketGetSetOption0(getNativeSocketFD(), CP_IP_TTL, ttl); } while (res < 0 && isSocketErrInterrupted0(res) != 0); checkSocketResCode(res); } int getTimeToLive() throws SocketException { int res; do { res = socketGetSetOption0(getNativeSocketFD(), CP_IP_TTL, -1); } while (res < 0 && isSocketErrInterrupted0(res) != 0); checkSocketResCode(res); return res & 0xff; } void setOption(int optionId, Object value) throws SocketException { int optval = -1; if (value instanceof Integer) { if (optionId == SocketOptions.SO_TIMEOUT) { setTimeoutFor(getNativeSocketFD(), ((Integer) value).intValue()); return; } if (optionId == SocketOptions.SO_LINGER || optionId == SocketOptions.SO_SNDBUF || optionId == SocketOptions.SO_RCVBUF || optionId == SocketOptions.IP_TOS) { optval = ((Integer) value).intValue(); if (optval < 0) optval = 0; else if (optionId == SocketOptions.SO_LINGER) optval++; } } else { if (value instanceof Boolean) { if (optionId != SocketOptions.SO_TIMEOUT && optionId != SocketOptions.SO_SNDBUF && optionId != SocketOptions.SO_RCVBUF && optionId != SocketOptions.IP_TOS) { optval = 0; if (((Boolean) value).booleanValue()) { optval = 1; if (optionId == SocketOptions.SO_LINGER) optval = -1; } } } else { if (value == null) throw new NullPointerException(); } } if (optval < 0) throw new IllegalArgumentException("invalid option value"); int res; do { res = socketGetSetOption0(getNativeSocketFD(), optionId, optval); } while (res < 0 && isSocketErrInterrupted0(res) != 0); checkSocketResCode(res); } void setMulticastInterface(int optionId, InetAddress addr) throws SocketException { socketSetMulticastAddr(getNativeSocketFD(), addr); } Object getOption(int optionId) throws SocketException { if (optionId == SocketOptions.SO_TIMEOUT) return new Integer(getTimeoutFor(getNativeSocketFD())); int res; do { res = socketGetSetOption0(getNativeSocketFD(), optionId, -1); } while (res < 0 && isSocketErrInterrupted0(res) != 0); checkSocketResCode(res); if (optionId == SocketOptions.SO_LINGER && res > 0) return new Integer(res - 1); if (optionId == SocketOptions.SO_SNDBUF || optionId == SocketOptions.SO_RCVBUF || optionId == SocketOptions.IP_TOS) return new Integer(res); return res != 0 ? Boolean.TRUE : Boolean.FALSE; } InetAddress getMulticastInterface(int optionId) throws SocketException { return socketGetMulticastAddr(getNativeSocketFD()); } void bind(InetSocketAddress address) throws IOException { InetAddress addr = address.getAddress(); int fd = state.getNativeFD(); if (addr == null) throw new SocketException("unresolved address: " + address.toString()); socketBind(fd, addr, address.getPort()); } void listen(int backlog) throws IOException { if (backlog <= 0) backlog = DEFAULT_BACKLOG; int res; do { res = socketListen0(state.getNativeFD(), backlog); } while (res < 0 && isSocketErrInterrupted0(res) != 0); checkIOSockResCode(res); } void join(InetAddress group) throws IOException { int fd = state.getNativeFD(); InetAddress addrNetIf = socketGetMulticastAddr(fd); try { socketMulticastGroup(fd, group, addrNetIf, true); } finally { socketSetMulticastAddr(fd, addrNetIf); } } void leave(InetAddress group) throws IOException { int fd = state.getNativeFD(); InetAddress addrNetIf = socketGetMulticastAddr(fd); try { socketMulticastGroup(fd, group, addrNetIf, false); } finally { socketSetMulticastAddr(fd, addrNetIf); } } void joinGroup(InetSocketAddress address, NetworkInterface netIf) throws IOException { multicastGroup(state.getNativeFD(), address, netIf, true); } void leaveGroup(InetSocketAddress address, NetworkInterface netIf) throws IOException { multicastGroup(state.getNativeFD(), address, netIf, false); } void shutdownInput() throws IOException { socketShutdown(state.getNativeFD(), true, false); } void shutdownOutput() throws IOException { socketShutdown(state.getNativeFD(), false, true); } void sendUrgentData(int b) throws IOException { socketSendTo(state.getNativeFD(), new byte[] { (byte) b }, new int[1], 1, null, true, false); } void close() throws IOException { state.close(); } static final void socketsInit() { /* used by VM classes only */ if (!initialized) synchronized (EMPTY_FDS) { if (!initialized) { if (socketsInit0() < 0) throw new InternalError("cannot initialize sockets"); preventBlocking = VMAccessorJavaLang.preventIOBlockingVMRuntime(); initialized = true; } } } static final int socketSelect(int[] readFDs, int[] writeFDs, int[] exceptFDs, int timeout) throws IOException { /* used by VM classes only */ long deadline = timeout > 0 ? getDeadlineTime(timeout) : 0L; int res; int readFDsLen = readFDs.length; int writeFDsLen = writeFDs.length; int exceptFDsLen = exceptFDs.length; do { res = socketSelect0(readFDs, readFDsLen, writeFDs, writeFDsLen, exceptFDs, exceptFDsLen, preventBlocking ? 0 : timeout); if (res >= 0) { if (res != 0 || !preventBlocking) break; } else if (isSocketErrInterrupted0(res) == 0) throw new IOException(getSocketErrorMsg0(res)); Thread.yield(); res = 0; } while (!Thread.currentThread().isInterrupted() && (timeout <= 0 || (timeout = getTimeoutOfDeadline(deadline)) > 0 || !preventBlocking)); int i; if (res != 0) { res = 0; for (i = 0; i < readFDsLen; i++) if (readFDs[i] != -1) res++; for (i = 0; i < writeFDsLen; i++) if (writeFDs[i] != -1) res++; for (i = 0; i < exceptFDsLen; i++) if (exceptFDs[i] != -1) res++; } else { for (i = 0; i < readFDsLen; i++) readFDs[i] = -1; for (i = 0; i < writeFDsLen; i++) writeFDs[i] = -1; for (i = 0; i < exceptFDsLen; i++) exceptFDs[i] = -1; } return res; } static final int socketCreate(boolean stream) throws SocketException { /* used by VM classes only */ socketsInit(); int fd; int res = 0; int[] resArr = new int[1]; boolean retrying = false; do { fd = socketCreate0(resArr, stream ? 1 : 0); if (fd != -1) break; res = resArr[0]; if (!retrying && isSocketRetryNeededOnce(res)) retrying = true; else if (isSocketErrInterrupted0(res) == 0) break; } while (true); checkSocketResCode(res); setTimeoutFor(fd, 0); if (preventBlocking) socketSetNonBlocking0(fd, 1); int optionId = stream ? SocketOptions.SO_REUSEADDR : SocketOptions.SO_BROADCAST; do { res = socketGetSetOption0(fd, optionId, 1); } while (res < 0 && isSocketErrInterrupted0(res) != 0); return fd; } static final InetSocketAddress socketGetLocalAddrPort(int fd) throws SocketException { /* used by VM classes only */ int res; byte[] ip = new byte[MAX_IP_SIZE]; int[] portArr = new int[1]; do { res = socketGetLocalAddrPort0(fd, ip, ip.length, portArr); } while (res < 0 && isSocketErrInterrupted0(res) != 0); checkSocketResCode(res); return new InetSocketAddress(toInetAddress(ip, res), portArr[0]); } static final void socketSetNonBlocking(int fd, boolean on) throws IOException { /* used by VM classes only */ if (!preventBlocking) checkIOSockResCode(socketSetNonBlocking0(fd, on ? 1 : 0)); } static final int socketAvailable(int fd) throws IOException { /* used by VM classes only */ int res = socketAvailable0(fd); if (res <= 0) { int[] readFDs = new int[1]; do { res = 0; if ((readFDs[0] = fd) == -1) break; res = socketSelect0(readFDs, 1, EMPTY_FDS, 0, EMPTY_FDS, 0, 0); } while (res < 0 && isSocketErrInterrupted0(res) != 0); checkIOSockResCode(res); if (res > 0) res = 1; } return res; } static final boolean socketConnect(int fd, InetSocketAddress address, int timeout) throws IOException { /* used by VM classes only */ InetAddress addr = address.getAddress(); if (addr == null) throw new SocketException("unresolved address: " + address.toString()); int port = address.getPort(); byte[] ip = addr.getAddress(); if (timeout < 0 && preventBlocking) timeout = DEFAULT_TIMEOUT; if (timeout != 0) checkThreadInterrupted(); int res; boolean isConnected = true; boolean retrying = false; if (timeout >= 0) { long deadline = timeout > 0 ? getDeadlineTime(timeout) : 0L; boolean connecting = false; try { if (timeout > 0 && !preventBlocking) socketSetNonBlocking0(fd, 1); do { boolean oldConnecting = connecting; res = socketConnect0(fd, ip, ip.length, port); connecting = true; if (!retrying && isSocketRetryNeededOnce(res)) { connecting = oldConnecting; retrying = true; } else { if (res >= 0) break; if (timeout == 0) { if (isSocketErrConnected0(res) == 0) { if (isSocketErrInterrupted0(res) == 0 && isSocketErrConnInProgress0(res) == 0) break; isConnected = false; } res = 0; break; } if (isSocketErrConnInProgress0(res) != 0) { if (!oldConnecting) socketSelectSingle(fd, true, true, false, deadline, false); } else { if (oldConnecting && isSocketErrConnected0(res) != 0) { res = 0; break; } connecting = oldConnecting; if (isSocketErrInterrupted0(res) == 0) break; } } Thread.yield(); if (timeout > 0) { if (getTimeoutOfDeadline(deadline) <= 0) throw new SocketTimeoutException(); checkThreadInterrupted(); } } while (true); if (res >= 0) connecting = false; } finally { if (timeout > 0 && !preventBlocking) socketSetNonBlocking0(fd, 0); if (connecting) socketShutdown(fd, true, true); } } else { do { res = socketConnect0(fd, ip, ip.length, port); if (!retrying && isSocketRetryNeededOnce(res)) retrying = true; else if (res >= 0 || isSocketErrInterrupted0(res) == 0) break; Thread.yield(); checkThreadInterrupted(); } while (true); } if (res < 0) { if (isSocketErrAddrNotAvail0(res) != 0) throw new ConnectException("Invalid destination port"); String message = getSocketErrorMsg0(res); if (isSocketErrConnRefused0(res) != 0) throw new ConnectException(message); if (isSocketErrHostUnreach0(res) != 0) throw new NoRouteToHostException(message); throw new SocketException(message); } return isConnected; } static final void socketDisconnect(int fd) throws IOException { /* used by VM classes only */ int res; do { res = socketDisconnect0(fd); } while (res < 0 && isSocketErrInterrupted0(res) != 0); checkIOSockResCode(res); } static final InetSocketAddress socketAccept(int[] fdArr, boolean isNonBlocking) throws IOException { /* used by VM classes only */ InetSocketAddress addr = null; int fd = fdArr[0]; byte[] ip = new byte[MAX_IP_SIZE]; int[] iplenPortArr = new int[2]; try { boolean retrying = false; do { fdArr[0] = socketAccept0(fd, ip, ip.length, iplenPortArr); int res = iplenPortArr[0]; if (!retrying && isSocketRetryNeededOnce(res)) retrying = true; else { if (res >= 0) { addr = new InetSocketAddress(toInetAddress(ip, res), iplenPortArr[1]); break; } if (isSocketErrInterrupted0(res) == 0) checkIOSockResCode(res); if (isNonBlocking) break; } Thread.yield(); if (!isNonBlocking) checkThreadInterrupted(); } while (true); } finally { int newfd = fdArr[0]; if (newfd != fd && newfd != -1) { if (addr == null) socketShutdown(newfd, true, true); else if (preventBlocking) socketSetNonBlocking0(newfd, 1); else if (isNonBlocking) socketSetNonBlocking0(newfd, 0); } } return addr; } static final InetSocketAddress socketRecvFrom(int fd, byte[] buffer, int[] offArr, int len, boolean urgent, boolean peek, boolean fillAddress, boolean stream, boolean isNonBlocking) throws IOException { /* used by VM classes only */ int off = offArr[0]; if ((off | len) < 0 || buffer.length - off < len) throw new ArrayIndexOutOfBoundsException(); byte[] ip = EMPTY_BUF; if (fillAddress) { ip = new byte[MAX_IP_SIZE]; stream = true; } int[] iplenPortArr = new int[2]; byte[] origBuffer = buffer; int timeout = 0; long deadline = 0L; if (!isNonBlocking) { timeout = getTimeoutFor(fd); if (timeout == 0 && preventBlocking) timeout = DEFAULT_TIMEOUT; deadline = socketSelectSingle(fd, !urgent, false, urgent, timeout, true); } do { int res = socketRecvFrom0(fd, buffer, off, len, urgent ? 1 : 0, peek ? 1 : 0, ip, stream ? ip.length : -1, iplenPortArr); if (res > 0) { if (res >= len) res = len; if (buffer != origBuffer) { off = offArr[0]; System.arraycopy(buffer, 0, origBuffer, off, res); } offArr[0] = off + res; break; } if (res == 0) { if (!fillAddress) { offArr[0]--; break; } if (off == 0) break; buffer = new byte[len]; off = 0; } else { if (isSocketErrInterrupted0(res) == 0) checkIOSockResCode(res); if (isNonBlocking) { fillAddress = false; break; } } Thread.yield(); if (!isNonBlocking) { if (timeout > 0 && getTimeoutOfDeadline(deadline) <= 0) throw new SocketTimeoutException(); checkThreadInterrupted(); } } while (true); return fillAddress ? new InetSocketAddress(toInetAddress(ip, iplenPortArr[0]), iplenPortArr[1]) : null; } static final void socketSendTo(int fd, byte[] buffer, int[] offArr, int len, InetSocketAddress address, boolean urgent, boolean isNonBlocking) throws IOException { /* used by VM classes only */ int off = offArr[0]; if ((off | len) < 0 || buffer.length - off < len) throw new ArrayIndexOutOfBoundsException(); byte[] ip = EMPTY_BUF; int port = 0; if (address != null) { InetAddress addr = address.getAddress(); if (addr == null) throw new SocketException("unresolved address: " + address.toString()); ip = addr.getAddress(); port = address.getPort(); } int remain = len; int timeout = 0; long deadline = 0L; if (!isNonBlocking) { timeout = getTimeoutFor(fd); if (timeout == 0 && preventBlocking) timeout = DEFAULT_TIMEOUT; deadline = socketSelectSingle(fd, false, true, false, timeout, true); } do { int res = socketSendTo0(fd, buffer, off, remain, urgent ? 1 : 0, ip, ip.length, port); if (res >= 0) { offArr[0] += res; if ((remain -= res) <= 0) break; if (res == 0 && off > 0) { byte[] newBuffer = new byte[remain]; System.arraycopy(buffer, off, newBuffer, 0, remain); buffer = newBuffer; off = 0; } else { if (address != null) break; off += res; } } else { if (isSocketErrInterrupted0(res) == 0) checkIOSockResCode(res); if (isNonBlocking) break; } Thread.yield(); if (!isNonBlocking) { if (res > 0) deadline = socketSelectSingle(fd, false, true, false, timeout, true); else { if (timeout > 0 && getTimeoutOfDeadline(deadline) <= 0) throw new SocketTimeoutException(); if (remain == len) checkThreadInterrupted(); } } } while (true); } static final void socketClose(int fd) throws IOException { /* used by VM classes only */ int res; do { res = socketClose0(fd); } while (res < 0 && isSocketErrInterrupted0(res) != 0); checkIOSockResCode(res); setTimeoutFor(fd, 0); } private int getNativeSocketFD() throws SocketException { try { return state.getNativeFD(); } catch (SocketException e) { throw e; } catch (IOException e) { throw (SocketException) (new SocketException()).initCause(e); } } private static long socketSelectSingle(int fd, boolean input, boolean output, boolean urgent, long deadline, boolean isTimeout) throws IOException { int timeout = 0; if (isTimeout) { checkThreadInterrupted(); timeout = (int) deadline; if (timeout <= 0) return 0L; deadline = getDeadlineTime(timeout); } if (fd != -1) { int res; int[] readFDs = input ? new int[1] : EMPTY_FDS; int[] writeFDs = output ? new int[1] : EMPTY_FDS; int[] exceptFDs = urgent ? new int[1] : EMPTY_FDS; do { if (input) readFDs[0] = fd; if (output) writeFDs[0] = fd; if (urgent) exceptFDs[0] = fd; if (!isTimeout) { timeout = getTimeoutOfDeadline(deadline); res = 0; if (timeout <= 0) break; checkThreadInterrupted(); } res = socketSelect0(readFDs, readFDs.length, writeFDs, writeFDs.length, exceptFDs, exceptFDs.length, preventBlocking ? 0 : timeout); if (res >= 0) { if (res != 0 || !preventBlocking) break; } else if (isSocketErrInterrupted0(res) == 0) break; isTimeout = false; Thread.yield(); } while (true); if (res == 0) throw new SocketTimeoutException(); } return deadline; } private static void socketBind(int fd, InetAddress addr, int port) throws SocketException { int res; byte[] ip = addr.getAddress(); boolean retrying = false; do { res = socketBind0(fd, ip, ip.length, port); if (!retrying && isSocketRetryNeededOnce(res)) retrying = true; else if (res >= 0 || isSocketErrInterrupted0(res) == 0) break; } while (true); checkSocketResCode(res); } private static void multicastGroup(int fd, InetSocketAddress address, NetworkInterface netIf, boolean join) throws IOException { InetAddress addr = address.getAddress(); if (addr == null) throw new SocketException("unresolved address: " + address.toString()); InetAddress addrNetIf = socketGetMulticastAddr(fd); try { if (netIf != null) { Enumeration en = netIf.getInetAddresses(); boolean isSet = false; IOException exception = null; while (en.hasMoreElements()) { try { socketMulticastGroup(fd, addr, (InetAddress) en.nextElement(), join); isSet = true; } catch (IOException e) { exception = e; } } if (!isSet) { if (exception == null) exception = new SocketException(); throw exception; } } else socketMulticastGroup(fd, addr, addrNetIf, join); } finally { socketSetMulticastAddr(fd, addrNetIf); } } private static void setTimeoutFor(int fd, int timeout) { synchronized (EMPTY_FDS) { if (timeouts == null) { if (timeout == 0) return; timeouts = new HashMap(); } if (timeout != 0) timeouts.put(new Integer(fd), new Integer(timeout)); else timeouts.remove(new Integer(fd)); } } private static int getTimeoutFor(int fd) { int timeout = 0; if (timeouts != null) synchronized (EMPTY_FDS) { if (timeouts != null) { Object value = timeouts.get(new Integer(fd)); if (value != null) timeout = ((Integer) value).intValue(); } } return timeout; } private static void socketSetMulticastAddr(int fd, InetAddress addr) throws SocketException { int res; byte[] ip = addr.getAddress(); do { res = socketSetMulticastAddr0(fd, ip, ip.length); } while (res < 0 && isSocketErrInterrupted0(res) != 0); checkSocketResCode(res); } private static InetAddress socketGetMulticastAddr(int fd) throws SocketException { int res; byte[] ip = new byte[MAX_IP_SIZE]; do { res = socketGetMulticastAddr0(fd, ip, ip.length); } while (res < 0 && isSocketErrInterrupted0(res) != 0); checkSocketResCode(res); return toInetAddress(ip, res); } private static void socketMulticastGroup(int fd, InetAddress addr, InetAddress addrNetIf, boolean join) throws IOException { byte[] ip = addr.getAddress(); byte[] ipNetIf = addrNetIf.getAddress(); int res; do { res = socketMulticastGroup0(fd, ip, ip.length, ipNetIf, ipNetIf.length, join ? 1 : 0); } while (res < 0 && isSocketErrInterrupted0(res) != 0); checkIOSockResCode(res); } private static void socketShutdown(int fd, boolean input, boolean output) throws IOException { if (input || output) { int res; do { res = socketShutdown0(fd, input ? 1 : 0, output ? 1 : 0); } while (res < 0 && isSocketErrInterrupted0(res) != 0); checkIOSockResCode(res); } } private static InetAddress toInetAddress(byte[] ip, int iplen) throws SocketException { try { if (ip.length != iplen) { if (ip.length < iplen) throw new UnknownHostException(); byte[] newip = new byte[iplen]; System.arraycopy(ip, 0, newip, 0, iplen); ip = newip; } return InetAddress.getByAddress(ip); } catch (UnknownHostException e) { throw new SocketException("invalid address family"); } } private static long getDeadlineTime(int timeout) { return System.currentTimeMillis() + timeout; } private static int getTimeoutOfDeadline(long deadline) { long timeleft = deadline - System.currentTimeMillis(); return timeleft > 0L ? (timeleft < (long) (-1 >>> 1) ? (int) timeleft : -1 >>> 1) : 0; } private static void checkThreadInterrupted() throws IOException { if (Thread.interrupted()) throw new InterruptedIOException(); } private static boolean isSocketRetryNeededOnce(int res) { if (res >= 0 || isSocketErrNoResources0(res) == 0) return false; Runtime runtime = Runtime.getRuntime(); runtime.gc(); runtime.runFinalization(); return true; } private static void checkIOSockResCode(int res) throws IOException { checkSocketResCode(res); } private static void checkSocketResCode(int res) throws SocketException { if (res < 0) { String message = getSocketErrorMsg0(res); if (isSocketErrAddrNotAvail0(res) != 0) throw new BindException(message); if (isSocketErrHostUnreach0(res) != 0) throw new NoRouteToHostException(message); if (isSocketErrResetConn0(res) != 0) throw new PortUnreachableException(message); throw new SocketException(message); } } private static native int socketsInit0(); private static native int isSocketErrAddrNotAvail0(int res); private static native int isSocketErrConnInProgress0(int res); private static native int isSocketErrConnRefused0(int res); private static native int isSocketErrConnected0(int res); private static native int isSocketErrHostUnreach0(int res); private static native int isSocketErrInterrupted0(int res); private static native int isSocketErrNoResources0(int res); private static native int isSocketErrResetConn0(int res); private static native String getSocketErrorMsg0(int res); private static native int socketCreate0(int[] resArr, int stream); private static native int socketBind0(int fd, byte[] ip, int iplen, int port); private static native int socketDisconnect0(int fd); private static native int socketConnect0(int fd, byte[] ip, int iplen, int port); /* blocking syscall */ private static native int socketSendTo0(int fd, byte[] buffer, int off, int len, int urgent, byte[] ip, int iplen, int port); /* blocking syscall */ private static native int socketRecvFrom0(int fd, byte[] buffer, int off, int len, int urgent, int peek, byte[] ip, int ipmaxlen, int[] iplenPortArr); /* blocking syscall */ private static native int socketAccept0(int fd, byte[] ip, int ipmaxlen, int[] iplenPortArr); /* blocking syscall */ private static native int socketGetLocalAddrPort0(int fd, byte[] ip, int ipmaxlen, int[] portArr); private static native int socketSelect0(int[] readFDs, int readFDsLen, int[] writeFDs, int writeFDsLen, int[] exceptFDs, int exceptFDsLen, int timeout); /* blocking syscall */ private static native int socketSetNonBlocking0(int fd, int on); private static native int socketAvailable0(int fd); private static native int socketListen0(int fd, int backlog); private static native int socketGetSetOption0(int fd, int optionId, int optval); private static native int socketSetMulticastAddr0(int fd, byte[] ip, int iplen); private static native int socketGetMulticastAddr0(int fd, byte[] ip, int ipmaxlen); private static native int socketMulticastGroup0(int fd, byte[] ip, int iplen, byte[] ipNetIf, int iplenNetIf, int join); private static native int socketShutdown0(int fd, int input, int output); private static native int socketClose0(int fd); }