summaryrefslogtreecommitdiff
path: root/libjava/classpath/java/net/Socket.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/java/net/Socket.java')
-rw-r--r--libjava/classpath/java/net/Socket.java118
1 files changed, 60 insertions, 58 deletions
diff --git a/libjava/classpath/java/net/Socket.java b/libjava/classpath/java/net/Socket.java
index b2249ffaa0d..f4f25fe1c1b 100644
--- a/libjava/classpath/java/net/Socket.java
+++ b/libjava/classpath/java/net/Socket.java
@@ -1,5 +1,5 @@
/* Socket.java -- Client socket implementation
- Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004
+ Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2006
Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -83,13 +83,6 @@ public class Socket
SocketImpl impl;
/**
- * True if socket implementation was created by calling their
- * create() method.
- */
- // package-private because ServerSocket.implAccept() needs to access it.
- boolean implCreated;
-
- /**
* True if the socket is bound.
* Package private so it can be set from ServerSocket when accept is called.
*/
@@ -298,15 +291,33 @@ public class Socket
SecurityManager sm = System.getSecurityManager();
if (sm != null)
- sm.checkConnect(raddr.getHostName(), rport);
+ sm.checkConnect(raddr.getHostAddress(), rport);
// bind socket
SocketAddress bindaddr =
laddr == null ? null : new InetSocketAddress(laddr, lport);
bind(bindaddr);
- // connect socket
- connect(new InetSocketAddress(raddr, rport));
+ // Connect socket in case of Exceptions we must close the socket
+ // because an exception in the constructor means that the caller will
+ // not have a reference to this instance.
+ // Note: You may have the idea that the exception treatment
+ // should be moved into connect() but there is a Mauve test which
+ // shows that a failed connect should not close the socket.
+ try
+ {
+ connect(new InetSocketAddress(raddr, rport));
+ }
+ catch (IOException ioe)
+ {
+ impl.close();
+ throw ioe;
+ }
+ catch (RuntimeException re)
+ {
+ impl.close();
+ throw re;
+ }
// FIXME: JCL p. 1586 says if localPort is unspecified, bind to any port,
// i.e. '0' and if localAddr is unspecified, use getLocalAddress() as
@@ -315,21 +326,6 @@ public class Socket
private SocketImpl getImpl() throws SocketException
{
- try
- {
- if (! implCreated)
- {
- impl.create(true);
- implCreated = true;
- }
- }
- catch (IOException e)
- {
- SocketException se = new SocketException(e.toString());
- se.initCause(e);
- throw se;
- }
-
return impl;
}
@@ -363,6 +359,7 @@ public class Socket
// bind to address/port
try
{
+ getImpl().create(true);
getImpl().bind(tmp.getAddress(), tmp.getPort());
bound = true;
}
@@ -479,16 +476,22 @@ public class Socket
InetAddress addr = null;
- try
+ if (impl instanceof PlainSocketImpl)
+ addr = ((PlainSocketImpl) impl).getLocalAddress().getAddress();
+
+ if (addr == null)
{
- addr = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
- }
- catch (SocketException e)
- {
- // (hopefully) shouldn't happen
- // throw new java.lang.InternalError
- // ("Error in PlainSocketImpl.getOption");
- return null;
+ try
+ {
+ addr = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
+ }
+ catch (SocketException e)
+ {
+ // (hopefully) shouldn't happen
+ // throw new java.lang.InternalError
+ // ("Error in PlainSocketImpl.getOption");
+ return null;
+ }
}
// FIXME: According to libgcj, checkConnect() is supposed to be called
@@ -707,10 +710,10 @@ public class Socket
if (linger > 65535)
linger = 65535;
- getImpl().setOption(SocketOptions.SO_LINGER, new Integer(linger));
+ getImpl().setOption(SocketOptions.SO_LINGER, Integer.valueOf(linger));
}
else
- getImpl().setOption(SocketOptions.SO_LINGER, Boolean.valueOf(false));
+ getImpl().setOption(SocketOptions.SO_LINGER, Integer.valueOf(-1));
}
/**
@@ -1001,12 +1004,8 @@ public class Socket
if (isClosed())
return;
- getImpl().close();
+ impl.close();
impl = null;
- bound = false;
-
- if (getChannel() != null)
- getChannel().close();
}
/**
@@ -1019,16 +1018,17 @@ public class Socket
try
{
if (isConnected())
- return ("Socket[addr=" + getImpl().getInetAddress() + ",port="
- + getImpl().getPort() + ",localport="
- + getImpl().getLocalPort() + "]");
+ return (super.toString()
+ + " [addr=" + getImpl().getInetAddress() + ",port="
+ + getImpl().getPort() + ",localport="
+ + getImpl().getLocalPort() + "]");
}
catch (SocketException e)
{
// This cannot happen as we are connected.
}
- return "Socket[unconnected]";
+ return super.toString() + " [unconnected]";
}
/**
@@ -1206,17 +1206,10 @@ public class Socket
*/
public boolean isConnected()
{
- try
- {
- if (getImpl() == null)
- return false;
-
- return getImpl().getInetAddress() != null;
- }
- catch (SocketException e)
- {
- return false;
- }
+ if (impl == null)
+ return false;
+
+ return impl.getInetAddress() != null;
}
/**
@@ -1228,6 +1221,13 @@ public class Socket
*/
public boolean isBound()
{
+ if (isClosed())
+ return false;
+ if (impl instanceof PlainSocketImpl)
+ {
+ InetSocketAddress addr = ((PlainSocketImpl) impl).getLocalAddress();
+ return addr != null && addr.getAddress() != null;
+ }
return bound;
}
@@ -1240,7 +1240,9 @@ public class Socket
*/
public boolean isClosed()
{
- return impl == null;
+ SocketChannel channel = getChannel();
+
+ return impl == null || (channel != null && ! channel.isOpen());
}
/**