19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.net; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.net.SocketOptions; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2534385d352da19805ae948215e2edbeedd16b7941Elliott Hughesimport android.system.ErrnoException; 2634385d352da19805ae948215e2edbeedd16b7941Elliott Hughesimport android.system.Os; 2734385d352da19805ae948215e2edbeedd16b7941Elliott Hughesimport android.system.OsConstants; 28e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Socket implementation used for android.net.LocalSocket and 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android.net.LocalServerSocket. Supports only AF_LOCAL sockets. 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass LocalSocketImpl 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SocketInputStream fis; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SocketOutputStream fos; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Object readMonitor = new Object(); 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Object writeMonitor = new Object(); 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** null if closed or not yet created */ 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private FileDescriptor fd; 42118c85156a552440d41aaa396d42f5e938f6c38bZhihai Xu /** whether fd is created internally */ 43118c85156a552440d41aaa396d42f5e938f6c38bZhihai Xu private boolean mFdCreatedInternally; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // These fields are accessed by native code; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** file descriptor array received during a previous read */ 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileDescriptor[] inboundFileDescriptors; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** file descriptor array that should be written during next write */ 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileDescriptor[] outboundFileDescriptors; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * An input stream for local sockets. Needed because we may 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * need to read ancillary data. 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class SocketInputStream extends InputStream { 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** {@inheritDoc} */ 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int available() throws IOException { 5954d50089ee526110e42e0f8399660a012d9c6c1bIan McKellar FileDescriptor myFd = fd; 6054d50089ee526110e42e0f8399660a012d9c6c1bIan McKellar if (myFd == null) throw new IOException("socket closed"); 6154d50089ee526110e42e0f8399660a012d9c6c1bIan McKellar 6254d50089ee526110e42e0f8399660a012d9c6c1bIan McKellar return available_native(myFd); 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** {@inheritDoc} */ 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() throws IOException { 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LocalSocketImpl.this.close(); 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** {@inheritDoc} */ 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int read() throws IOException { 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (readMonitor) { 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileDescriptor myFd = fd; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (myFd == null) throw new IOException("socket closed"); 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = read_native(myFd); 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** {@inheritDoc} */ 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int read(byte[] b) throws IOException { 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return read(b, 0, b.length); 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** {@inheritDoc} */ 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int read(byte[] b, int off, int len) throws IOException { 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (readMonitor) { 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileDescriptor myFd = fd; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (myFd == null) throw new IOException("socket closed"); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (off < 0 || len < 0 || (off + len) > b.length ) { 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new ArrayIndexOutOfBoundsException(); 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret = readba_native(b, off, len, myFd); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * An output stream for local sockets. Needed because we may 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * need to read ancillary data. 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class SocketOutputStream extends OutputStream { 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** {@inheritDoc} */ 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() throws IOException { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LocalSocketImpl.this.close(); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** {@inheritDoc} */ 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void write (byte[] b) throws IOException { 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project write(b, 0, b.length); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** {@inheritDoc} */ 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void write (byte[] b, int off, int len) throws IOException { 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (writeMonitor) { 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileDescriptor myFd = fd; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (myFd == null) throw new IOException("socket closed"); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (off < 0 || len < 0 || (off + len) > b.length ) { 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new ArrayIndexOutOfBoundsException(); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project writeba_native(b, off, len, myFd); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** {@inheritDoc} */ 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void write (int b) throws IOException { 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (writeMonitor) { 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileDescriptor myFd = fd; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (myFd == null) throw new IOException("socket closed"); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project write_native(b, myFd); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14871bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy 14971bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy /** 15071bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy * Wait until the data in sending queue is emptied. A polling version 15171bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy * for flush implementation. 15271bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy * @throws IOException 15371bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy * if an i/o error occurs. 15471bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy */ 15571bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy @Override 15671bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy public void flush() throws IOException { 15771bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy FileDescriptor myFd = fd; 15871bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy if (myFd == null) throw new IOException("socket closed"); 159d073bfdb3a44f07ef5338306f9b9377532962290Matthew Xie while(pending_native(myFd) > 0) { 16071bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy try { 16171bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy Thread.sleep(10); 16271bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy } catch (InterruptedException ie) { 16371bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy return; 16471bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy } 16571bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy } 16671bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy } 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16971bfafc84af4b820748b12e1a1010b0dfa7bdea6zzy private native int pending_native(FileDescriptor fd) throws IOException; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int available_native(FileDescriptor fd) throws IOException; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int read_native(FileDescriptor fd) throws IOException; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int readba_native(byte[] b, int off, int len, 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileDescriptor fd) throws IOException; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void writeba_native(byte[] b, int off, int len, 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileDescriptor fd) throws IOException; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void write_native(int b, FileDescriptor fd) 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void connectLocal(FileDescriptor fd, String name, 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int namespace) throws IOException; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void bindLocal(FileDescriptor fd, String name, int namespace) 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void listen_native(FileDescriptor fd, int backlog) 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void shutdown(FileDescriptor fd, boolean shutdownInput); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native Credentials getPeerCredentials_native( 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileDescriptor fd) throws IOException; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int getOption_native(FileDescriptor fd, int optID) 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void setOption_native(FileDescriptor fd, int optID, 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int b, int value) throws IOException; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// private native LocalSocketAddress getSockName_native 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// (FileDescriptor fd) throws IOException; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Accepts a connection on a server socket. 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param fd file descriptor of server socket 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param s socket implementation that will become the new socket 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return file descriptor of new socket 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native FileDescriptor accept 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (FileDescriptor fd, LocalSocketImpl s) throws IOException; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a new instance. 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*package*/ LocalSocketImpl() 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a new instance from a file descriptor representing 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a bound socket. The state of the file descriptor is not checked here 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but the caller can verify socket state by calling listen(). 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param fd non-null; bound file descriptor 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*package*/ LocalSocketImpl(FileDescriptor fd) throws IOException 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.fd = fd; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.toString() + " fd:" + fd; 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a socket in the underlying OS. 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 231e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood * @param sockType either {@link LocalSocket#SOCKET_DGRAM}, {@link LocalSocket#SOCKET_STREAM} 232e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood * or {@link LocalSocket#SOCKET_SEQPACKET} 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 235e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood public void create (int sockType) throws IOException { 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // no error if socket already created 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // need this for LocalServerSocket.accept() 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd == null) { 239e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood int osType; 240e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood switch (sockType) { 241e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood case LocalSocket.SOCKET_DGRAM: 242e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood osType = OsConstants.SOCK_DGRAM; 243e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood break; 244e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood case LocalSocket.SOCKET_STREAM: 245e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood osType = OsConstants.SOCK_STREAM; 246e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood break; 247e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood case LocalSocket.SOCKET_SEQPACKET: 248e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood osType = OsConstants.SOCK_SEQPACKET; 249e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood break; 250e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood default: 251e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood throw new IllegalStateException("unknown sockType"); 252e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood } 253e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood try { 25434385d352da19805ae948215e2edbeedd16b7941Elliott Hughes fd = Os.socket(OsConstants.AF_UNIX, osType, 0); 255118c85156a552440d41aaa396d42f5e938f6c38bZhihai Xu mFdCreatedInternally = true; 256e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood } catch (ErrnoException e) { 257e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood e.rethrowAsIOException(); 258e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood } 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Closes the socket. 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() throws IOException { 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (LocalSocketImpl.this) { 269118c85156a552440d41aaa396d42f5e938f6c38bZhihai Xu if ((fd == null) || (mFdCreatedInternally == false)) { 270118c85156a552440d41aaa396d42f5e938f6c38bZhihai Xu fd = null; 271118c85156a552440d41aaa396d42f5e938f6c38bZhihai Xu return; 272118c85156a552440d41aaa396d42f5e938f6c38bZhihai Xu } 273e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood try { 27434385d352da19805ae948215e2edbeedd16b7941Elliott Hughes Os.close(fd); 275e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood } catch (ErrnoException e) { 276e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood e.rethrowAsIOException(); 277e7d309a929bf87a5752cd1fb2d48c72e47a671a2Mike Lockwood } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = null; 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** note timeout presently ignored */ 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void connect(LocalSocketAddress address, int timeout) 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd == null) { 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IOException("socket not created"); 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project connectLocal(fd, address.getName(), address.getNamespace().getId()); 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Binds this socket to an endpoint name. May only be called on an instance 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that has not yet been bound. 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param endpoint endpoint address 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void bind(LocalSocketAddress endpoint) throws IOException 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd == null) { 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IOException("socket not created"); 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bindLocal(fd, endpoint.getName(), endpoint.getNamespace().getId()); 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void listen(int backlog) throws IOException 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd == null) { 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IOException("socket not created"); 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listen_native(fd, backlog); 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Accepts a new connection to the socket. Blocks until a new 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * connection arrives. 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param s a socket that will be used to represent the new connection. 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void accept(LocalSocketImpl s) throws IOException 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd == null) { 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IOException("socket not created"); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s.fd = accept(fd, s); 332d75932b521bc23fee304c3bf9e023762cf3fbb82Dave Platt s.mFdCreatedInternally = true; 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Retrieves the input stream for this instance. 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return input stream 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException if socket has been closed or cannot be created. 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected InputStream getInputStream() throws IOException 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd == null) { 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IOException("socket not created"); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fis == null) { 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fis = new SocketInputStream(); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fis; 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Retrieves the output stream for this instance. 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return output stream 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException if socket has been closed or cannot be created. 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected OutputStream getOutputStream() throws IOException 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd == null) { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IOException("socket not created"); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fos == null) { 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fos = new SocketOutputStream(); 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fos; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the number of bytes available for reading without blocking. 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return >= 0 count bytes available 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected int available() throws IOException 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return getInputStream().available(); 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Shuts down the input side of the socket. 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void shutdownInput() throws IOException 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd == null) { 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IOException("socket not created"); 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shutdown(fd, true); 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Shuts down the output side of the socket. 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void shutdownOutput() throws IOException 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd == null) { 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IOException("socket not created"); 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shutdown(fd, false); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected FileDescriptor getFileDescriptor() 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd; 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean supportsUrgentData() 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void sendUrgentData(int data) throws IOException 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException ("not impled"); 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Object getOption(int optID) throws IOException 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd == null) { 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IOException("socket not created"); 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (optID == SocketOptions.SO_TIMEOUT) { 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int value = getOption_native(fd, optID); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (optID) 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SocketOptions.SO_RCVBUF: 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SocketOptions.SO_SNDBUF: 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return value; 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SocketOptions.SO_REUSEADDR: 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return value; 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOption(int optID, Object value) 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException { 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Boolean.FALSE is used to disable some options, so it 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is important to distinguish between FALSE and unset. 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * We define it here that -1 is unset, 0 is FALSE, and 1 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is TRUE. 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int boolValue = -1; 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int intValue = 0; 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd == null) { 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IOException("socket not created"); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Integer) { 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intValue = (Integer)value; 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (value instanceof Boolean) { 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolValue = ((Boolean) value)? 1 : 0; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IOException("bad value: " + value); 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setOption_native(fd, optID, boolValue, intValue); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Enqueues a set of file descriptors to send to the peer. The queue 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is one deep. The file descriptors will be sent with the next write 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of normal data, and will be delivered in a single ancillary message. 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See "man 7 unix" SCM_RIGHTS on a desktop Linux machine. 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param fds non-null; file descriptors to send. 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setFileDescriptorsForSend(FileDescriptor[] fds) { 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(writeMonitor) { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outboundFileDescriptors = fds; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Retrieves a set of file descriptors that a peer has sent through 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * an ancillary message. This method retrieves the most recent set sent, 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and then returns null until a new set arrives. 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * File descriptors may only be passed along with regular data, so this 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * method can only return a non-null after a read operation. 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return null or file descriptor array 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public FileDescriptor[] getAncillaryFileDescriptors() throws IOException { 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(readMonitor) { 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileDescriptor[] result = inboundFileDescriptors; 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inboundFileDescriptors = null; 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Retrieves the credentials of this socket's peer. Only valid on 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * connected sockets. 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return non-null; peer credentials 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Credentials getPeerCredentials() throws IOException 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return getPeerCredentials_native(fd); 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Retrieves the socket name from the OS. 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return non-null; socket name 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException on failure 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LocalSocketAddress getSockAddress() throws IOException 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //TODO implement this 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //return getSockName_native(fd); 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws IOException { 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(); 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 543