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