diff options
Diffstat (limited to 'libjava/classpath/java/net/ServerSocket.java')
-rw-r--r-- | libjava/classpath/java/net/ServerSocket.java | 109 |
1 files changed, 70 insertions, 39 deletions
diff --git a/libjava/classpath/java/net/ServerSocket.java b/libjava/classpath/java/net/ServerSocket.java index 2b889531a7c..d5f2a176b81 100644 --- a/libjava/classpath/java/net/ServerSocket.java +++ b/libjava/classpath/java/net/ServerSocket.java @@ -79,6 +79,7 @@ public class ServerSocket * We need to retain the local address even after the socket is closed. */ private InetSocketAddress local; + private int port; /* * This constructor is only used by java.nio. @@ -93,6 +94,7 @@ public class ServerSocket this.impl = impl; this.impl.create(true); + setReuseAddress(true); } /* @@ -219,43 +221,53 @@ public class ServerSocket if (isClosed()) throw new SocketException("ServerSocket is closed"); - if (! (endpoint instanceof InetSocketAddress)) - throw new IllegalArgumentException("Address type not supported"); + if (isBound()) + throw new SocketException("Already bound"); - InetSocketAddress tmp = (InetSocketAddress) endpoint; + InetAddress addr; + int port; + + if (endpoint == null) + { + addr = InetAddress.ANY_IF; + port = 0; + } + else if (! (endpoint instanceof InetSocketAddress)) + { + throw new IllegalArgumentException("Address type not supported"); + } + else + { + InetSocketAddress tmp = (InetSocketAddress) endpoint; + if (tmp.isUnresolved()) + throw new SocketException("Unresolved address"); + addr = tmp.getAddress(); + port = tmp.getPort(); + } SecurityManager s = System.getSecurityManager(); if (s != null) - s.checkListen(tmp.getPort()); - - InetAddress addr = tmp.getAddress(); - - // Initialize addr with 0.0.0.0. - if (addr == null) - addr = InetAddress.ANY_IF; + s.checkListen(port); try { - impl.bind(addr, tmp.getPort()); + impl.bind(addr, port); impl.listen(backlog); - local = new InetSocketAddress( + this.port = port; + local = new InetSocketAddress( (InetAddress) impl.getOption(SocketOptions.SO_BINDADDR), impl.getLocalPort()); } - catch (IOException exception) - { - close(); - throw exception; - } - catch (RuntimeException exception) - { - close(); - throw exception; - } - catch (Error error) + finally { - close(); - throw error; + try + { + if (local == null) + close(); + } + catch (IOException _) + { + } } } @@ -333,6 +345,19 @@ public class ServerSocket throw e; } + catch (SecurityException e) + { + try + { + socket.close(); + } + catch (IOException e2) + { + // Ignore. + } + + throw e; + } return socket; } @@ -355,9 +380,6 @@ public class ServerSocket if (isClosed()) throw new SocketException("ServerSocket is closed"); - // FIXME: Add a security check to make sure we're allowed to - // connect to the remote host. - // The Sun spec says that if we have an associated channel and // it is in non-blocking mode, we throw an IllegalBlockingModeException. // However, in our implementation if the channel itself initiated this @@ -367,8 +389,12 @@ public class ServerSocket throw new IllegalBlockingModeException(); impl.accept(socket.impl); - socket.implCreated = true; socket.bound = true; + + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkAccept(socket.getInetAddress().getHostAddress(), + socket.getPort()); } /** @@ -378,14 +404,11 @@ public class ServerSocket */ public void close() throws IOException { - if (isClosed()) - return; - - impl.close(); - impl = null; - - if (getChannel() != null) - getChannel().close(); + if (impl != null) + { + impl.close(); + impl = null; + } } /** @@ -425,7 +448,8 @@ public class ServerSocket */ public boolean isClosed() { - return impl == null; + ServerSocketChannel channel = getChannel(); + return impl == null || (channel != null && ! channel.isOpen()); } /** @@ -573,7 +597,7 @@ public class ServerSocket return "ServerSocket[unbound]"; return ("ServerSocket[addr=" + getInetAddress() + ",port=" - + impl.getPort() + ",localport=" + impl.getLocalPort() + "]"); + + port + ",localport=" + getLocalPort() + "]"); } /** @@ -594,6 +618,13 @@ public class ServerSocket public static synchronized void setSocketFactory(SocketImplFactory fac) throws IOException { + if (factory != null) + throw new SocketException("SocketFactory already defined"); + + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkSetFactory(); + factory = fac; } } |