151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.net; 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kongimport android.system.ErrnoException; 2932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.FileDescriptor; 325dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kongimport java.util.Set; 335dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kongimport java.util.HashSet; 345dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kongimport java.util.Collections; 3532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kongimport libcore.io.AsynchronousCloseMonitor; 3632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kongimport libcore.io.IoBridge; 3732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kongimport libcore.io.IoUtils; 3832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kongimport libcore.io.Libcore; 3932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 405dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kongimport jdk.net.*; 415dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong 4232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kongimport static android.system.OsConstants.AF_INET6; 4332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kongimport static android.system.OsConstants.AF_UNIX; 4432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kongimport static android.system.OsConstants.EAGAIN; 4532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kongimport static android.system.OsConstants.EBADF; 4632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kongimport static android.system.OsConstants.EINVAL; 4732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kongimport static android.system.OsConstants.MSG_OOB; 4832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kongimport static android.system.OsConstants.POLLERR; 4932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kongimport static android.system.OsConstants.POLLIN; 5032c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kongimport static android.system.OsConstants.SOCK_DGRAM; 5132c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kongimport static android.system.OsConstants.SOCK_STREAM; 5232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kongimport static android.system.OsConstants.SHUT_RDWR; 535dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kongimport static sun.net.ExtendedOptionsImpl.*; 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong// Android-changed: Rewritten to use android.system POSIX calls and assume AF_INET6. 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * On Unix systems we simply delegate to native methods. 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Chris Hegarty 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass PlainSocketImpl extends AbstractPlainSocketImpl 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 640eb6533db1f9cdc4a0bc8605f8b4dc9e2154fa91Victor Chang // Android-removed: Android doesn't need to call native initProto. 650eb6533db1f9cdc4a0bc8605f8b4dc9e2154fa91Victor Chang /* 660eb6533db1f9cdc4a0bc8605f8b4dc9e2154fa91Victor Chang static { 670eb6533db1f9cdc4a0bc8605f8b4dc9e2154fa91Victor Chang initProto(); 680eb6533db1f9cdc4a0bc8605f8b4dc9e2154fa91Victor Chang } 690eb6533db1f9cdc4a0bc8605f8b4dc9e2154fa91Victor Chang */ 700eb6533db1f9cdc4a0bc8605f8b4dc9e2154fa91Victor Chang 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Constructs an empty instance. 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 74379c07d7ca0c5022a77b2b10782f819f5cb84985Przemyslaw Szczepaniak PlainSocketImpl() { 75379c07d7ca0c5022a77b2b10782f819f5cb84985Przemyslaw Szczepaniak this(new FileDescriptor()); 76379c07d7ca0c5022a77b2b10782f819f5cb84985Przemyslaw Szczepaniak } 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Constructs an instance with the given file descriptor. 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski PlainSocketImpl(FileDescriptor fd) { 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fd = fd; 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 855dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong protected <T> void setOption(SocketOption<T> name, T value) throws IOException { 865dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) { 875dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong super.setOption(name, value); 885dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong } else { 895dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong if (isClosedOrPending()) { 905dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong throw new SocketException("Socket closed"); 915dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong } 925dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong checkSetOptionPermission(name); 935dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong checkValueType(value, SocketFlow.class); 945dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong setFlowOption(getFileDescriptor(), (SocketFlow)value); 955dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong } 965dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong } 975dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong 985dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong protected <T> T getOption(SocketOption<T> name) throws IOException { 995dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) { 1005dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong return super.getOption(name); 1015dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong } 1025dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong if (isClosedOrPending()) { 1035dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong throw new SocketException("Socket closed"); 1045dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong } 1055dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong checkGetOptionPermission(name); 1065dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong SocketFlow flow = SocketFlow.create(); 1075dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong getFlowOption(getFileDescriptor(), flow); 1085dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong return (T)flow; 1095dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong } 1105dd14d677fbbc0ad77b4eefa82a6f7c0a17f9a37Yi Kong 1110eb6533db1f9cdc4a0bc8605f8b4dc9e2154fa91Victor Chang // BEGIN Android-changed: Rewrote on top of Libcore.io. 112f4d26eb1fcad9ae230c80ae20b59cc6bfa12816aYi Kong protected void socketSetOption(int opt, Object val) throws SocketException { 113780a0e6392567eb5d1c3425043b092d29590976bYi Kong try { 114f4d26eb1fcad9ae230c80ae20b59cc6bfa12816aYi Kong socketSetOption0(opt, val); 115780a0e6392567eb5d1c3425043b092d29590976bYi Kong } catch (SocketException se) { 116780a0e6392567eb5d1c3425043b092d29590976bYi Kong if (socket == null || !socket.isConnected()) 117780a0e6392567eb5d1c3425043b092d29590976bYi Kong throw se; 118780a0e6392567eb5d1c3425043b092d29590976bYi Kong } 119780a0e6392567eb5d1c3425043b092d29590976bYi Kong } 120780a0e6392567eb5d1c3425043b092d29590976bYi Kong 12132c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong void socketCreate(boolean isStream) throws IOException { 12232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // The fd object must not change after calling bind, because we rely on this undocumented 12332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // behaviour. See libcore.java.net.SocketTest#testFileDescriptorStaysSame. 12432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong fd.setInt$(IoBridge.socket(AF_INET6, isStream ? SOCK_STREAM : SOCK_DGRAM, 0).getInt$()); 12532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 12632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong if (serverSocket != null) { 12732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong IoUtils.setBlocking(fd, false); 12832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong IoBridge.setSocketOption(fd, SO_REUSEADDR, true); 12932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 13032c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 13132c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 13232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong void socketConnect(InetAddress address, int port, int timeout) throws IOException { 13332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong if (fd == null || !fd.valid()) { 13432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong throw new SocketException("Socket closed"); 13532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 13632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 13732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong IoBridge.connect(fd, address, port, timeout); 13832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 13932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong this.address = address; 14032c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong this.port = port; 14132c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 14232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong if (localport == 0) { 14332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // If socket is pending close, fd becomes an AF_UNIX socket and calling 14432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // getLocalInetSocketAddress will fail. 14532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // http://b/34645743 14632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong if (!isClosedOrPending()) { 14732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong localport = IoBridge.getLocalInetSocketAddress(fd).getPort(); 14832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 14932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 15032c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 15132c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 15232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong void socketBind(InetAddress address, int port) throws IOException { 15332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong if (fd == null || !fd.valid()) { 15432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong throw new SocketException("Socket closed"); 15532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 15632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 15732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong IoBridge.bind(fd, address, port); 15832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 15932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong this.address = address; 16032c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong if (port == 0) { 16132c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // Now that we're a connected socket, let's extract the port number that the system 16232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // chose for us and store it in the Socket object. 16332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong localport = IoBridge.getLocalInetSocketAddress(fd).getPort(); 16432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } else { 16532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong localport = port; 16632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 16732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 16832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 16932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong void socketListen(int count) throws IOException { 17032c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong if (fd == null || !fd.valid()) { 17132c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong throw new SocketException("Socket closed"); 17232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 17332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 17432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong try { 17532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong Libcore.os.listen(fd, count); 17632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } catch (ErrnoException errnoException) { 17732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong throw errnoException.rethrowAsSocketException(); 17832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 17932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 18032c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 18132c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong void socketAccept(SocketImpl s) throws IOException { 18232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong if (fd == null || !fd.valid()) { 18332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong throw new SocketException("Socket closed"); 18432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 18532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 18632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // poll() with a timeout of 0 means "poll for zero millis", but a Socket timeout == 0 means 18732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // "wait forever". When timeout == 0 we pass -1 to poll. 18832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong if (timeout <= 0) { 18932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong IoBridge.poll(fd, POLLIN | POLLERR, -1); 19032c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } else { 19132c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong IoBridge.poll(fd, POLLIN | POLLERR, timeout); 19232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 19332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 19432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong InetSocketAddress peerAddress = new InetSocketAddress(); 19532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong try { 19632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong FileDescriptor newfd = Libcore.os.accept(fd, peerAddress); 19732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 19832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong s.fd.setInt$(newfd.getInt$()); 19932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong s.address = peerAddress.getAddress(); 20032c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong s.port = peerAddress.getPort(); 20132c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } catch (ErrnoException errnoException) { 20232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong if (errnoException.errno == EAGAIN) { 20332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong throw new SocketTimeoutException(errnoException); 20432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } else if (errnoException.errno == EINVAL || errnoException.errno == EBADF) { 20532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong throw new SocketException("Socket closed"); 20632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 20732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong errnoException.rethrowAsSocketException(); 20832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 20932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 21032c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong s.localport = IoBridge.getLocalInetSocketAddress(s.fd).getPort(); 21132c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 21232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 21332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong int socketAvailable() throws IOException { 21432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong return IoBridge.available(fd); 21532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong void socketClose0(boolean useDeferredClose) throws IOException { 21832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong if (fd == null || !fd.valid()) { 21932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong throw new SocketException("socket already closed"); 22032c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong FileDescriptor markerFD = null; 22332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong if (useDeferredClose) { 22432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong markerFD = getMarkerFD(); 22532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong if (useDeferredClose && markerFD != null) { 22832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong try { 22932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong Libcore.os.dup2(markerFD, fd.getInt$()); 23032c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong Libcore.os.close(markerFD); 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // This effectively closes the socket, needs to signal threads that blocks on this 23332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // file descriptor. 23432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong AsynchronousCloseMonitor.signalBlockedThreads(fd); 23532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } catch (ErrnoException errnoException) { 23632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // close should not throw 23732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 23832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } else { 23932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // If requested or a markerFD cannot be created, a non-deferred close is performed 24032c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // instead. 24132c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong IoBridge.closeAndSignalBlockedThreads(fd); 24232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 24332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong /* 24632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong * Create the marker file descriptor by establishing a loopback connection which we shutdown but 24732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong * do not close the fd. The result is an fd that can be used for read/write. 24832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong * 24932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong * The purpose is to keep hold of the raw fd handle until we are sure it is not used in any 25032c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong * thread. Otherwise if we close the file descriptor directly, the system might reuse the raw fd 25132c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong * number and threads holding old fd value might behave incorrectly. 25232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong */ 25332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong private FileDescriptor getMarkerFD() throws SocketException { 25432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong FileDescriptor fd1 = new FileDescriptor(); 25532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong FileDescriptor fd2 = new FileDescriptor(); 25632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong try { 25732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd1, fd2); 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // Shutdown fd1, any reads to this fd will get EOF; any writes will get an error. 26032c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong Libcore.os.shutdown(fd1, SHUT_RDWR); 26132c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong Libcore.os.close(fd2); 26232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } catch (ErrnoException errnoException) { 26332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // We might have reached the maximum file descriptor number and socketpair(2) would 26432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // fail. In this case, return null and let caller to fall back to an alternative method 26532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong // that does not allocate more file descriptors. 26632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong return null; 26732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 26832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong return fd1; 26932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27132c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong void socketShutdown(int howto) throws IOException { 27232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong try { 27332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong Libcore.os.shutdown(fd, howto); 27432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } catch (ErrnoException errnoException) { 27532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong throw errnoException.rethrowAsIOException(); 27632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 27732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 279f4d26eb1fcad9ae230c80ae20b59cc6bfa12816aYi Kong void socketSetOption0(int cmd, Object value) throws SocketException { 280f4d26eb1fcad9ae230c80ae20b59cc6bfa12816aYi Kong // OpenJDK does not set SO_TIMEOUT on Linux. 281f4d26eb1fcad9ae230c80ae20b59cc6bfa12816aYi Kong if (cmd == SO_TIMEOUT) { 282f4d26eb1fcad9ae230c80ae20b59cc6bfa12816aYi Kong return; 283f4d26eb1fcad9ae230c80ae20b59cc6bfa12816aYi Kong } 284f4d26eb1fcad9ae230c80ae20b59cc6bfa12816aYi Kong 285f4d26eb1fcad9ae230c80ae20b59cc6bfa12816aYi Kong IoBridge.setSocketOption(fd, cmd, value); 286f4d26eb1fcad9ae230c80ae20b59cc6bfa12816aYi Kong } 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 288f4d26eb1fcad9ae230c80ae20b59cc6bfa12816aYi Kong Object socketGetOption(int opt) throws SocketException { 289f4d26eb1fcad9ae230c80ae20b59cc6bfa12816aYi Kong return IoBridge.getSocketOption(fd, opt); 290f4d26eb1fcad9ae230c80ae20b59cc6bfa12816aYi Kong } 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong void socketSendUrgentData(int data) throws IOException { 29332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong if (fd == null || !fd.valid()) { 29432c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong throw new SocketException("Socket closed"); 29532c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 29632c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong 29732c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong try { 29832c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong byte[] buffer = new byte[] { (byte) data }; 29932c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong Libcore.os.sendto(fd, buffer, 0, 1, MSG_OOB, null, 0); 30032c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } catch (ErrnoException errnoException) { 30132c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong throw errnoException.rethrowAsSocketException(); 30232c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 30332c780f411b1fe3dec80c28a79fc5442fa8304ebYi Kong } 3040eb6533db1f9cdc4a0bc8605f8b4dc9e2154fa91Victor Chang // END Android-changed: Rewrote on top of Libcore.io. 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 307