summaryrefslogtreecommitdiff
path: root/core/java/android/net/LocalSocketImpl.java
diff options
context:
space:
mode:
authorNeil Fuller <nfuller@google.com>2015-07-03 10:59:17 +0100
committerNeil Fuller <nfuller@google.com>2015-07-03 13:02:08 +0100
commitc80af6d84d8fb729f17028ac533fac07bb7c4c5d (patch)
tree6b74361d6062471246c8a9cd36fa7c05070905a1 /core/java/android/net/LocalSocketImpl.java
parent78db19c25a3a18d9ccf19b91be17e791e4fd782c (diff)
Switch to using android.system.Os for more calls
The methods being switched here should involve no important semantic changes. socket.getSoTimeout() is now implemented: previously it would have returned 0 in all cases. Some tidy up of unimplemented / commented code. Switching other calls to use Os would carry more risk and will be handled separately they can be switched safely. Bug: 3106438 Change-Id: I5526249395565fee6e43f159a2b5975b0d41d058
Diffstat (limited to 'core/java/android/net/LocalSocketImpl.java')
-rw-r--r--core/java/android/net/LocalSocketImpl.java123
1 files changed, 90 insertions, 33 deletions
diff --git a/core/java/android/net/LocalSocketImpl.java b/core/java/android/net/LocalSocketImpl.java
index fa9f4790389f..8823ab14aa80 100644
--- a/core/java/android/net/LocalSocketImpl.java
+++ b/core/java/android/net/LocalSocketImpl.java
@@ -25,6 +25,8 @@ import java.net.SocketOptions;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
+import android.system.StructLinger;
+import android.system.StructTimeval;
/**
* Socket implementation used for android.net.LocalSocket and
@@ -184,13 +186,6 @@ class LocalSocketImpl
private native void shutdown(FileDescriptor fd, boolean shutdownInput);
private native Credentials getPeerCredentials_native(
FileDescriptor fd) throws IOException;
- private native int getOption_native(FileDescriptor fd, int optID)
- throws IOException;
- private native void setOption_native(FileDescriptor fd, int optID,
- int b, int value) throws IOException;
-
-// private native LocalSocketAddress getSockName_native
-// (FileDescriptor fd) throws IOException;
/**
* Accepts a connection on a server socket.
@@ -232,7 +227,7 @@ class LocalSocketImpl
* or {@link LocalSocket#SOCKET_SEQPACKET}
* @throws IOException
*/
- public void create (int sockType) throws IOException {
+ public void create(int sockType) throws IOException {
// no error if socket already created
// need this for LocalServerSocket.accept()
if (fd == null) {
@@ -434,24 +429,49 @@ class LocalSocketImpl
throw new IOException("socket not created");
}
- if (optID == SocketOptions.SO_TIMEOUT) {
- return 0;
- }
-
- int value = getOption_native(fd, optID);
- switch (optID)
- {
- case SocketOptions.SO_RCVBUF:
- case SocketOptions.SO_SNDBUF:
- return value;
- case SocketOptions.SO_REUSEADDR:
- default:
- return value;
+ try {
+ Object toReturn;
+ switch (optID) {
+ case SocketOptions.SO_TIMEOUT:
+ StructTimeval timeval = Os.getsockoptTimeval(fd, OsConstants.SOL_SOCKET,
+ OsConstants.SO_SNDTIMEO);
+ toReturn = (int) timeval.toMillis();
+ break;
+ case SocketOptions.SO_RCVBUF:
+ case SocketOptions.SO_SNDBUF:
+ case SocketOptions.SO_REUSEADDR:
+ int osOpt = javaSoToOsOpt(optID);
+ toReturn = Os.getsockoptInt(fd, OsConstants.SOL_SOCKET, osOpt);
+ break;
+ case SocketOptions.SO_LINGER:
+ StructLinger linger=
+ Os.getsockoptLinger(fd, OsConstants.SOL_SOCKET, OsConstants.SO_LINGER);
+ if (!linger.isOn()) {
+ toReturn = -1;
+ } else {
+ toReturn = linger.l_linger;
+ }
+ break;
+ case SocketOptions.TCP_NODELAY:
+ toReturn = Os.getsockoptInt(fd, OsConstants.IPPROTO_TCP,
+ OsConstants.TCP_NODELAY);
+ break;
+ default:
+ throw new IOException("Unknown option: " + optID);
+ }
+ return toReturn;
+ } catch (ErrnoException e) {
+ throw e.rethrowAsIOException();
}
}
public void setOption(int optID, Object value)
throws IOException {
+
+ if (fd == null) {
+ throw new IOException("socket not created");
+ }
+
/*
* Boolean.FALSE is used to disable some options, so it
* is important to distinguish between FALSE and unset.
@@ -460,11 +480,6 @@ class LocalSocketImpl
*/
int boolValue = -1;
int intValue = 0;
-
- if (fd == null) {
- throw new IOException("socket not created");
- }
-
if (value instanceof Integer) {
intValue = (Integer)value;
} else if (value instanceof Boolean) {
@@ -473,7 +488,39 @@ class LocalSocketImpl
throw new IOException("bad value: " + value);
}
- setOption_native(fd, optID, boolValue, intValue);
+ try {
+ switch (optID) {
+ case SocketOptions.SO_LINGER:
+ StructLinger linger = new StructLinger(boolValue, intValue);
+ Os.setsockoptLinger(fd, OsConstants.SOL_SOCKET, OsConstants.SO_LINGER, linger);
+ break;
+ case SocketOptions.SO_TIMEOUT:
+ /*
+ * SO_TIMEOUT from the core library gets converted to
+ * SO_SNDTIMEO, but the option is supposed to set both
+ * send and receive timeouts. Note: The incoming timeout
+ * value is in milliseconds.
+ */
+ StructTimeval timeval = StructTimeval.fromMillis(intValue);
+ Os.setsockoptTimeval(fd, OsConstants.SOL_SOCKET, OsConstants.SO_SNDTIMEO,
+ timeval);
+ break;
+ case SocketOptions.SO_RCVBUF:
+ case SocketOptions.SO_SNDBUF:
+ case SocketOptions.SO_REUSEADDR:
+ int osOpt = javaSoToOsOpt(optID);
+ Os.setsockoptInt(fd, OsConstants.SOL_SOCKET, osOpt, intValue);
+ break;
+ case SocketOptions.TCP_NODELAY:
+ Os.setsockoptInt(fd, OsConstants.IPPROTO_TCP, OsConstants.TCP_NODELAY,
+ intValue);
+ break;
+ default:
+ throw new IOException("Unknown option: " + optID);
+ }
+ } catch (ErrnoException e) {
+ throw e.rethrowAsIOException();
+ }
}
/**
@@ -517,8 +564,7 @@ class LocalSocketImpl
* @return non-null; peer credentials
* @throws IOException
*/
- public Credentials getPeerCredentials() throws IOException
- {
+ public Credentials getPeerCredentials() throws IOException {
return getPeerCredentials_native(fd);
}
@@ -528,15 +574,26 @@ class LocalSocketImpl
* @return non-null; socket name
* @throws IOException on failure
*/
- public LocalSocketAddress getSockAddress() throws IOException
- {
+ public LocalSocketAddress getSockAddress() throws IOException {
+ // This method has never been implemented.
return null;
- //TODO implement this
- //return getSockName_native(fd);
}
@Override
protected void finalize() throws IOException {
close();
}
+
+ private static int javaSoToOsOpt(int optID) {
+ switch (optID) {
+ case SocketOptions.SO_SNDBUF:
+ return OsConstants.SO_SNDBUF;
+ case SocketOptions.SO_RCVBUF:
+ return OsConstants.SO_RCVBUF;
+ case SocketOptions.SO_REUSEADDR:
+ return OsConstants.SO_REUSEADDR;
+ default:
+ throw new UnsupportedOperationException("Unknown option: " + optID);
+ }
+ }
}