summaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2002-08-30 18:16:00 +0000
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2002-08-30 18:16:00 +0000
commit31b99cc56c35a556ca59bc2009049fe4afcee73d (patch)
tree6b8d006ff1e5363ff7071fe6e79480680b240d33 /libjava
parentffed53c48e396362cc94c253cc7fe3569f730f81 (diff)
downloadgcc-31b99cc56c35a556ca59bc2009049fe4afcee73d.tar.gz
* java/net/JarURLConnection.java (getCertificates): New method
from Classpath. * java/net/URLClassLoader.java (URLClassLoader): Extends SecureClassLoader. (definePackage): New method from Classpath. (getPermissions): Likewise. (newInstance): Likewise. (findClass): Construct CodeSource for new class (from Classpath). * java/net/SocketImpl.java (shutdownInput, shutdownOutput): New methods. * java/net/URL.java (getUserInfo): New method. (set(String,String,int,String,String,String,String,String)): New method. * java/net/PlainSocketImpl.java (_Jv_SO_KEEPALIVE_): Define. (shutdownInput, shutdownOutput): Declare. * java/net/PlainDatagramSocketImpl.java (_Jv_SO_KEEPALIVE_): Define. * java/net/natPlainSocketImpl.cc (setOption): Handle keepalive. (getOption): Likewise. (shutdownInput): New method. (shutdownOutput): Likewise. * java/net/natPlainDatagramSocketImpl.cc (setOption): Handle keepalive. (getOption): Likewise. * java/net/SocketOptions.java (SO_KEEPALIVE): New constant. * java/net/Socket.java (setKeepAlive): New method. (getKeepAlive): Likewise. (shutdownInput, shutdownOutput): New methods. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@56685 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava')
-rw-r--r--libjava/ChangeLog31
-rw-r--r--libjava/java/net/JarURLConnection.java15
-rw-r--r--libjava/java/net/PlainDatagramSocketImpl.java5
-rw-r--r--libjava/java/net/PlainSocketImpl.java7
-rw-r--r--libjava/java/net/Socket.java63
-rw-r--r--libjava/java/net/SocketImpl.java16
-rw-r--r--libjava/java/net/SocketOptions.java7
-rw-r--r--libjava/java/net/URL.java33
-rw-r--r--libjava/java/net/URLClassLoader.java177
-rw-r--r--libjava/java/net/natPlainDatagramSocketImpl.cc9
-rw-r--r--libjava/java/net/natPlainSocketImpl.cc44
11 files changed, 392 insertions, 15 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 06211f11563..33c9bb40fc0 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,34 @@
+2002-08-29 Tom Tromey <tromey@redhat.com>
+
+ * java/net/JarURLConnection.java (getCertificates): New method
+ from Classpath.
+ * java/net/URLClassLoader.java (URLClassLoader): Extends
+ SecureClassLoader.
+ (definePackage): New method from Classpath.
+ (getPermissions): Likewise.
+ (newInstance): Likewise.
+ (findClass): Construct CodeSource for new class (from Classpath).
+ * java/net/SocketImpl.java (shutdownInput, shutdownOutput): New
+ methods.
+ * java/net/URL.java (getUserInfo): New method.
+ (set(String,String,int,String,String,String,String,String)): New
+ method.
+ * java/net/PlainSocketImpl.java (_Jv_SO_KEEPALIVE_): Define.
+ (shutdownInput, shutdownOutput): Declare.
+ * java/net/PlainDatagramSocketImpl.java (_Jv_SO_KEEPALIVE_):
+ Define.
+ * java/net/natPlainSocketImpl.cc (setOption): Handle keepalive.
+ (getOption): Likewise.
+ (shutdownInput): New method.
+ (shutdownOutput): Likewise.
+ * java/net/natPlainDatagramSocketImpl.cc (setOption): Handle
+ keepalive.
+ (getOption): Likewise.
+ * java/net/SocketOptions.java (SO_KEEPALIVE): New constant.
+ * java/net/Socket.java (setKeepAlive): New method.
+ (getKeepAlive): Likewise.
+ (shutdownInput, shutdownOutput): New methods.
+
2002-08-29 Michael Koch <konqueror@gmx.de>
* java/net/DatagramPacket.java: updated to JDK 1.4 API
diff --git a/libjava/java/net/JarURLConnection.java b/libjava/java/net/JarURLConnection.java
index f0b3b5df343..5ee438dd515 100644
--- a/libjava/java/net/JarURLConnection.java
+++ b/libjava/java/net/JarURLConnection.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000 Free Software Foundation
+/* Copyright (C) 1999, 2000, 2002 Free Software Foundation
This file is part of libgcj.
@@ -15,6 +15,7 @@ import java.util.zip.*;
import java.util.Map;
import java.util.Vector;
import java.util.Hashtable;
+import java.security.cert.Certificate;
/**
* @author Kresten Krab Thorup <krab@gnu.org>
@@ -316,4 +317,16 @@ public abstract class JarURLConnection extends URLConnection
hdrHash.put(key.toLowerCase(), Long.toString(len));
}
+ /**
+ * Returns an array of Certificate objects for the jar file entry specified
+ * by this URL or null if there are none
+ *
+ * @return A Certificate array
+ *
+ * @exception IOException If an error occurs
+ */
+ public Certificate[] getCertificates() throws IOException
+ {
+ return getJarEntry().getCertificates();
+ }
}
diff --git a/libjava/java/net/PlainDatagramSocketImpl.java b/libjava/java/net/PlainDatagramSocketImpl.java
index 55ea468dadc..5f8a559557c 100644
--- a/libjava/java/net/PlainDatagramSocketImpl.java
+++ b/libjava/java/net/PlainDatagramSocketImpl.java
@@ -1,6 +1,6 @@
// PlainDatagramSocketImpl.java - Implementation of DatagramSocketImpl.
-/* Copyright (C) 1999 Free Software Foundation
+/* Copyright (C) 1999, 2002 Free Software Foundation
This file is part of libgcj.
@@ -33,7 +33,8 @@ class PlainDatagramSocketImpl extends DatagramSocketImpl
_Jv_SO_LINGER_ = SocketOptions.SO_LINGER,
_Jv_SO_TIMEOUT_ = SocketOptions.SO_TIMEOUT,
_Jv_SO_SNDBUF_ = SocketOptions.SO_SNDBUF,
- _Jv_SO_RCVBUF_ = SocketOptions.SO_RCVBUF;
+ _Jv_SO_RCVBUF_ = SocketOptions.SO_RCVBUF,
+ _Jv_SO_KEEPALIVE_ = SocketOptions.SO_KEEPALIVE;
int fnum = -1;
diff --git a/libjava/java/net/PlainSocketImpl.java b/libjava/java/net/PlainSocketImpl.java
index 354d652a5bf..2146f5e9a7d 100644
--- a/libjava/java/net/PlainSocketImpl.java
+++ b/libjava/java/net/PlainSocketImpl.java
@@ -32,7 +32,8 @@ class PlainSocketImpl extends SocketImpl
_Jv_SO_LINGER_ = SocketOptions.SO_LINGER,
_Jv_SO_TIMEOUT_ = SocketOptions.SO_TIMEOUT,
_Jv_SO_SNDBUF_ = SocketOptions.SO_SNDBUF,
- _Jv_SO_RCVBUF_ = SocketOptions.SO_RCVBUF;
+ _Jv_SO_RCVBUF_ = SocketOptions.SO_RCVBUF,
+ _Jv_SO_KEEPALIVE_ = SocketOptions.SO_KEEPALIVE;
/**
* The OS file handle representing the socket.
@@ -53,6 +54,10 @@ class PlainSocketImpl extends SocketImpl
public native Object getOption(int optID) throws SocketException;
+ public native void shutdownInput () throws IOException;
+
+ public native void shutdownOutput () throws IOException;
+
protected native void create (boolean stream) throws IOException;
protected void connect (String host, int port) throws IOException
diff --git a/libjava/java/net/Socket.java b/libjava/java/net/Socket.java
index 6c0df5402b4..217e6956b5b 100644
--- a/libjava/java/net/Socket.java
+++ b/libjava/java/net/Socket.java
@@ -618,6 +618,47 @@ public class Socket
}
/**
+ * This method sets the value for the socket level socket option
+ * SO_KEEPALIVE.
+ *
+ * @param on True if SO_KEEPALIVE should be enabled
+ *
+ * @exception SocketException If an error occurs or Socket is not connected
+ *
+ * @since Java 1.3
+ */
+ public void setKeepAlive (boolean on) throws SocketException
+ {
+ if (impl == null)
+ throw new SocketException("Not connected");
+
+ impl.setOption(SocketOptions.SO_RCVBUF, new Boolean(on));
+ }
+
+ /**
+ * This method returns the value of the socket level socket option
+ * SO_KEEPALIVE.
+ *
+ * @return The setting
+ *
+ * @exception SocketException If an error occurs or Socket is not connected
+ *
+ * @since Java 1.3
+ */
+ public boolean getKeepAlive () throws SocketException
+ {
+ if (impl == null)
+ throw new SocketException("Not connected");
+
+ Object buf = impl.getOption(SocketOptions.SO_RCVBUF);
+
+ if (buf instanceof Boolean)
+ return(((Boolean)buf).booleanValue());
+ else
+ throw new SocketException("Internal Error: Unexpected type");
+ }
+
+ /**
* Closes the socket.
*
* @exception IOException If an error occurs
@@ -667,4 +708,26 @@ public class Socket
factory = fac;
}
+
+ /**
+ * Closes the input side of the socket stream.
+ *
+ * @exception IOException If an error occurs.
+ */
+ public void shutdownInput() throws IOException
+ {
+ if (impl != null)
+ impl.shutdownInput();
+ }
+
+ /**
+ * Closes the output side of the socket stream.
+ *
+ * @exception IOException If an error occurs.
+ */
+ public void shutdownOutput() throws IOException
+ {
+ if (impl != null)
+ impl.shutdownOutput();
+ }
}
diff --git a/libjava/java/net/SocketImpl.java b/libjava/java/net/SocketImpl.java
index fb5a60ca520..7dcf87de629 100644
--- a/libjava/java/net/SocketImpl.java
+++ b/libjava/java/net/SocketImpl.java
@@ -264,4 +264,20 @@ public abstract class SocketImpl implements SocketOptions
* @XXX This redeclaration from SocketOptions is a workaround to a gcj bug.
*/
public abstract Object getOption(int option_id) throws SocketException;
+
+ /**
+ * Shut down the input side of this socket. Subsequent reads will
+ * return end-of-file.
+ *
+ * @exception IOException if an error occurs
+ */
+ public abstract void shutdownInput () throws IOException;
+
+ /**
+ * Shut down the output side of this socket. Subsequent writes will
+ * fail with an IOException.
+ *
+ * @exception IOException if an error occurs
+ */
+ public abstract void shutdownOutput () throws IOException;
}
diff --git a/libjava/java/net/SocketOptions.java b/libjava/java/net/SocketOptions.java
index 7dcba2a67a6..bf57450d037 100644
--- a/libjava/java/net/SocketOptions.java
+++ b/libjava/java/net/SocketOptions.java
@@ -1,5 +1,5 @@
/* SocketOptions.java -- Implements options for sockets (duh!)
- Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -62,6 +62,11 @@ public interface SocketOptions
*/
/**
+ * Option id for the SO_KEEPALIVE value
+ */
+static final int SO_KEEPALIVE = 0x8;
+
+/**
* Option id for the SO_LINGER value
*/
static final int SO_LINGER = 0x80; // 128
diff --git a/libjava/java/net/URL.java b/libjava/java/net/URL.java
index a3e9d784cef..73edeca415d 100644
--- a/libjava/java/net/URL.java
+++ b/libjava/java/net/URL.java
@@ -175,7 +175,8 @@ public final class URL implements Serializable
this.handler = setURLStreamHandler(protocol);
if (this.handler == null)
- throw new MalformedURLException("Protocol handler not found: " + protocol);
+ throw new MalformedURLException("Protocol handler not found: "
+ + protocol);
// JDK 1.2 doc for parseURL specifically states that any '#' ref
// is to be excluded by passing the 'limit' as the indexOf the '#'
@@ -245,6 +246,12 @@ public final class URL implements Serializable
return ref;
}
+ public String getUserInfo ()
+ {
+ int at = host.indexOf('@');
+ return at < 0 ? null : host.substring(0, at);
+ }
+
public int hashCode()
{
// JCL book says this is computed using (only) the hashcodes of the
@@ -299,6 +306,30 @@ public final class URL implements Serializable
hashCode = hashCode(); // Used for serialization.
}
+ /** @since 1.3 */
+ protected void set(String protocol, String host, int port,
+ String authority, String userInfo,
+ String path, String query, String ref)
+ {
+ // TBD: Theoretically, a poorly written StreamHandler could pass an
+ // invalid protocol. It will cause the handler to be set to null
+ // thus overriding a valid handler. Callers of this method should
+ // be aware of this.
+ this.handler = setURLStreamHandler(protocol);
+ this.protocol = protocol;
+ if (userInfo == null)
+ this.host = host;
+ else
+ this.host = userInfo + "@" + host;
+ this.port = port;
+ if (query == null)
+ this.file = path;
+ else
+ this.file = path + "?" + query;
+ this.ref = ref;
+ hashCode = hashCode(); // Used for serialization.
+ }
+
public static synchronized void
setURLStreamHandlerFactory(URLStreamHandlerFactory fac)
{
diff --git a/libjava/java/net/URLClassLoader.java b/libjava/java/net/URLClassLoader.java
index 4fce6250e4a..3afb8f1861c 100644
--- a/libjava/java/net/URLClassLoader.java
+++ b/libjava/java/net/URLClassLoader.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000 Free Software Foundation
+/* Copyright (C) 1999, 2000, 2002 Free Software Foundation
This file is part of libgcj.
@@ -12,11 +12,15 @@ import java.io.*;
import java.util.jar.*;
import java.util.Enumeration;
import java.util.Vector;
+import java.security.CodeSource;
+import java.security.SecureClassLoader;
+import java.security.PermissionCollection;
+import java.security.cert.Certificate;
/**
* @since 1.2
*/
-public class URLClassLoader extends ClassLoader
+public class URLClassLoader extends SecureClassLoader
{
// The URLStreamHandlerFactory
URLStreamHandlerFactory factory = null;
@@ -228,12 +232,12 @@ public class URLClassLoader extends ClassLoader
try
{
- URL u = getResource (name.replace ('.', '/') + ".class");
+ URL url = getResource (name.replace ('.', '/') + ".class");
- if (u == null)
+ if (url == null)
throw new ClassNotFoundException (name);
- URLConnection connection = u.openConnection ();
+ URLConnection connection = url.openConnection ();
InputStream is = connection.getInputStream ();
int len = connection.getContentLength ();
@@ -250,12 +254,171 @@ public class URLClassLoader extends ClassLoader
off += c;
}
- return defineClass (name, data, 0, len);
+ // Now construct the CodeSource (if loaded from a jar file)
+ CodeSource source = null;
+ if (url.getProtocol().equals("jar"))
+ {
+ Certificate[] certificates =
+ ((JarURLConnection) connection).getCertificates();
+ String u = url.toExternalForm ();
+ u = u.substring (4); //skip "jar:"
+ int i = u.indexOf ('!');
+ if (i >= 0)
+ u = u.substring (0, i);
+ url = new URL("jar", "", u);
+
+ source = new CodeSource(url, certificates);
+ }
+ else if (url.getProtocol().equals("file"))
+ {
+ try
+ {
+ String u = url.toExternalForm();
+ // Skip "file:" and then get canonical directory name.
+ File f = new File(u.substring(5));
+ f = f.getCanonicalFile();
+ url = new URL("file", "", f.getParent());
+ source = new CodeSource (url, null);
+ }
+ catch (IOException ignore)
+ {
+ }
+ }
+
+ return defineClass (name, data, 0, len, source);
}
catch (java.io.IOException x)
{
throw new ClassNotFoundException(name);
}
}
-}
+ /**
+ * Defines a Package based on the given name and the supplied manifest
+ * information. The manifest indicates the tile, version and
+ * vendor information of the specification and implementation and wheter the
+ * package is sealed. If the Manifest indicates that the package is sealed
+ * then the Package will be sealed with respect to the supplied URL.
+ *
+ * @exception IllegalArgumentException If this package name already exists
+ * in this class loader
+ * @param name The name of the package
+ * @param manifest The manifest describing the specification,
+ * implementation and sealing details of the package
+ * @param url the code source url to seal the package
+ * @return the defined Package
+ */
+ protected Package definePackage(String name, Manifest manifest, URL url)
+ throws IllegalArgumentException
+ {
+ Attributes attr = manifest.getMainAttributes();
+ String specTitle =
+ attr.getValue(Attributes.Name.SPECIFICATION_TITLE);
+ String specVersion =
+ attr.getValue(Attributes.Name.SPECIFICATION_VERSION);
+ String specVendor =
+ attr.getValue(Attributes.Name.SPECIFICATION_VENDOR);
+ String implTitle =
+ attr.getValue(Attributes.Name.IMPLEMENTATION_TITLE);
+ String implVersion =
+ attr.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
+ String implVendor =
+ attr.getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
+
+ // Look if the Manifest indicates that this package is sealed
+ // XXX - most likely not completely correct!
+ // Shouldn't we also check the sealed attribute of the complete jar?
+ // http://java.sun.com/products/jdk/1.3/docs/guide/extensions/spec.html#bundled
+ // But how do we get that jar manifest here?
+ String sealed = attr.getValue(Attributes.Name.SEALED);
+ if ("false".equals(sealed))
+ {
+ // Make sure that the URL is null so the package is not
+ // sealed.
+ url = null;
+ }
+
+ return definePackage(name, specTitle, specVersion, specVendor,
+ implTitle, implVersion, implVendor, url);
+ }
+
+ /**
+ * Returns the permissions needed to access a particular code source.
+ * These permissions includes those returned by
+ * <CODE>SecureClassLoader.getPermissions</CODE> and the actual permissions
+ * to access the objects referenced by the URL of the code source.
+ * The extra permissions added depend on the protocol and file portion of
+ * the URL in the code source. If the URL has the "file" protocol ends with
+ * a / character then it must be a directory and a file Permission to read
+ * everthing in that directory and all subdirectories is added. If the URL
+ * had the "file" protocol and doesn't end with a / character then it must
+ * be a normal file and a file permission to read that file is added. If the
+ * URL has any other protocol then a socket permission to connect and accept
+ * connections from the host portion of the URL is added.
+ * @param source The codesource that needs the permissions to be accessed
+ * @return the collection of permissions needed to access the code resource
+ * @see SecureClassLoader.getPermissions()
+ */
+ protected PermissionCollection getPermissions(CodeSource source)
+ {
+ // XXX - This implementation does exactly as the Javadoc describes.
+ // But maybe we should/could use URLConnection.getPermissions()?
+
+ // First get the permissions that would normally be granted
+ PermissionCollection permissions = super.getPermissions(source);
+
+ // Now add the any extra permissions depending on the URL location
+ URL url = source.getLocation();
+ String protocol = url.getProtocol();
+ if (protocol.equals("file"))
+ {
+ String file = url.getFile();
+ // If the file end in / it must be an directory
+ if (file.endsWith("/"))
+ {
+ // Grant permission to read everything in that directory and
+ // all subdirectories
+ permissions.add(new FilePermission(file + "-", "read"));
+ }
+ else
+ {
+ // It is a 'normal' file
+ // Grant permission to access that file
+ permissions.add(new FilePermission(file, "read"));
+ }
+ }
+ else
+ {
+ // Grant permission to connect to and accept connections from host
+ String host = url.getHost();
+ permissions.add(new SocketPermission(host, "connect,accept"));
+ }
+
+ return permissions;
+ }
+
+ /**
+ * Creates a new instance of a URLClassLoader that gets classes from the
+ * supplied URLs. This class loader will have as parent the standard
+ * system class loader.
+ * @param urls the initial URLs used to resolve classes and resources
+ */
+ public static URLClassLoader newInstance(URL urls[]) throws
+ SecurityException
+ {
+ return new URLClassLoader(urls);
+ }
+
+ /**
+ * Creates a new instance of a URLClassLoader that gets classes from the
+ * supplied URLs and with the supplied loader as parent class loader.
+ * @param urls the initial URLs used to resolve classes and resources
+ * @param parent the parent class loader
+ */
+ public static URLClassLoader newInstance(URL urls[],
+ ClassLoader parent)
+ throws SecurityException
+ {
+ return new URLClassLoader(urls, parent);
+ }
+}
diff --git a/libjava/java/net/natPlainDatagramSocketImpl.cc b/libjava/java/net/natPlainDatagramSocketImpl.cc
index e581f08db5c..bb306e202bd 100644
--- a/libjava/java/net/natPlainDatagramSocketImpl.cc
+++ b/libjava/java/net/natPlainDatagramSocketImpl.cc
@@ -524,6 +524,10 @@ java::net::PlainDatagramSocketImpl::setOption (jint optID,
throw new java::net::SocketException (
JvNewStringUTF ("SO_LINGER not valid for UDP"));
return;
+ case _Jv_SO_KEEPALIVE_ :
+ throw new java::net::SocketException (
+ JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
+ return;
case _Jv_SO_SNDBUF_ :
case _Jv_SO_RCVBUF_ :
#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
@@ -613,11 +617,14 @@ java::net::PlainDatagramSocketImpl::getOption (jint optID)
throw new java::net::SocketException (
JvNewStringUTF ("TCP_NODELAY not valid for UDP"));
break;
-
case _Jv_SO_LINGER_ :
throw new java::net::SocketException (
JvNewStringUTF ("SO_LINGER not valid for UDP"));
break;
+ case _Jv_SO_KEEPALIVE_ :
+ throw new java::net::SocketException (
+ JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
+ break;
case _Jv_SO_RCVBUF_ :
case _Jv_SO_SNDBUF_ :
#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
diff --git a/libjava/java/net/natPlainSocketImpl.cc b/libjava/java/net/natPlainSocketImpl.cc
index 370c9946177..f82aa6bb47c 100644
--- a/libjava/java/net/natPlainSocketImpl.cc
+++ b/libjava/java/net/natPlainSocketImpl.cc
@@ -222,6 +222,20 @@ java::net::PlainSocketImpl::close(void)
JvNewStringLatin1 ("SocketImpl.close: unimplemented"));
}
+void
+java::net::PlainSocketImpl::shutdownInput (void)
+{
+ throw new SocketException (
+ JvNewStringLatin1 ("SocketImpl.shutdownInput: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::shutdownOutput (void)
+{
+ throw new SocketException (
+ JvNewStringLatin1 ("SocketImpl.shutdownOutput: unimplemented"));
+}
+
#else /* DISABLE_JAVA_NET */
union SockAddr
@@ -722,12 +736,18 @@ java::net::PlainSocketImpl::setOption (jint optID, java::lang::Object *value)
#ifdef TCP_NODELAY
if (::setsockopt (fnum, IPPROTO_TCP, TCP_NODELAY, (char *) &val,
val_len) != 0)
- goto error;
+ goto error;
#else
throw new java::lang::InternalError (
JvNewStringUTF ("TCP_NODELAY not supported"));
#endif /* TCP_NODELAY */
return;
+
+ case _Jv_SO_KEEPALIVE_ :
+ if (::setsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val,
+ val_len) != 0)
+ goto error;
+
case _Jv_SO_LINGER_ :
#ifdef SO_LINGER
struct linger l_val;
@@ -816,6 +836,14 @@ java::net::PlainSocketImpl::getOption (jint optID)
JvNewStringUTF ("SO_LINGER not supported"));
#endif
break;
+
+ case _Jv_SO_KEEPALIVE_ :
+ if (::getsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val,
+ &val_len) != 0)
+ goto error;
+ else
+ return new java::lang::Boolean (val != 0);
+
case _Jv_SO_RCVBUF_ :
case _Jv_SO_SNDBUF_ :
#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
@@ -876,4 +904,18 @@ java::net::PlainSocketImpl::getOption (jint optID)
throw new java::net::SocketException (JvNewStringUTF (strerr));
}
+void
+java::net::PlainSocketImpl::shutdownInput (void)
+{
+ if (::shutdown (fnum, 0))
+ throw new SocketException (JvNewStringUTF (strerror (errno)));
+}
+
+void
+java::net::PlainSocketImpl::shutdownOutput (void)
+{
+ if (::shutdown (fnum, 1))
+ throw new SocketException (JvNewStringUTF (strerror (errno)));
+}
+
#endif /* DISABLE_JAVA_NET */