19c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes/*
29c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes * Copyright (C) 2011 The Android Open Source Project
39c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes *
49c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
59c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes * you may not use this file except in compliance with the License.
69c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes * You may obtain a copy of the License at
79c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes *
89c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
99c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes *
109c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes * Unless required by applicable law or agreed to in writing, software
119c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
129c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes * See the License for the specific language governing permissions and
149c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes * limitations under the License.
159c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes */
169c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes
17d430cc782689a7f6a256ef6b0ebfc7210b0c31d9Tobias Thiererpackage libcore.libcore.io;
189c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes
19b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colittiimport android.system.ErrnoException;
20f66766fe735068fa6c283163c185914bab21016dTobias Thiererimport android.system.Int64Ref;
218f5b46d72e5c1b1b1dd4357580c4fb5a60e3f4deErik Klineimport android.system.NetlinkSocketAddress;
2290246a0ae7117d780e077c9e84cdb73ff5b44af7Jeff Sharkeyimport android.system.OsConstants;
2300bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colittiimport android.system.PacketSocketAddress;
24e873cd1285c04da110758df066b4bd40ad6eb93dNarayan Kamathimport android.system.StructRlimit;
25108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniakimport android.system.StructStat;
26a8b7587c5001db3489c64ac1d16c254a683f76bdLorenzo Colittiimport android.system.StructTimeval;
275d930cadc8f62aee5f18e7921296fe66a54f18abElliott Hughesimport android.system.StructUcred;
280ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fullerimport android.system.UnixSocketAddress;
290ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller
309c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughesimport java.io.File;
31482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughesimport java.io.FileDescriptor;
329c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughesimport java.io.FileInputStream;
33d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamathimport java.io.FileOutputStream;
34a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thiererimport java.io.FileWriter;
35a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thiererimport java.io.IOException;
366dd21e692ae87b75e49b23ffbecc6964604f466aYi Kongimport java.net.DatagramPacket;
376dd21e692ae87b75e49b23ffbecc6964604f466aYi Kongimport java.net.DatagramSocket;
38b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colittiimport java.net.Inet4Address;
39b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colittiimport java.net.Inet6Address;
40482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughesimport java.net.InetAddress;
41482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughesimport java.net.InetSocketAddress;
4200bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colittiimport java.net.NetworkInterface;
439c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughesimport java.net.ServerSocket;
446e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniakimport java.net.SocketOptions;
45d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamathimport java.nio.ByteBuffer;
46d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamathimport java.nio.charset.StandardCharsets;
475310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniakimport java.nio.file.Files;
48b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colittiimport java.util.Arrays;
49ee24b6322448ac919231a668e308ebd719aa52d7Yi Kongimport java.util.Collections;
50ee24b6322448ac919231a668e308ebd719aa52d7Yi Kongimport java.util.List;
51b274574b7e2681f4411852af9857b4540bf75841Elliott Hughesimport java.util.Locale;
526e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniakimport java.util.concurrent.atomic.AtomicReference;
539c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughesimport junit.framework.TestCase;
54d430cc782689a7f6a256ef6b0ebfc7210b0c31d9Tobias Thierer
55d430cc782689a7f6a256ef6b0ebfc7210b0c31d9Tobias Thiererimport libcore.io.IoBridge;
56d430cc782689a7f6a256ef6b0ebfc7210b0c31d9Tobias Thiererimport libcore.io.IoUtils;
57d430cc782689a7f6a256ef6b0ebfc7210b0c31d9Tobias Thiererimport libcore.io.Libcore;
586dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong
595d930cadc8f62aee5f18e7921296fe66a54f18abElliott Hughesimport static android.system.OsConstants.*;
60d430cc782689a7f6a256ef6b0ebfc7210b0c31d9Tobias Thiererimport static libcore.libcore.io.OsTest.SendFileImpl.ANDROID_SYSTEM_OS_INT64_REF;
61d430cc782689a7f6a256ef6b0ebfc7210b0c31d9Tobias Thiererimport static libcore.libcore.io.OsTest.SendFileImpl.LIBCORE_OS;
629c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes
639c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughespublic class OsTest extends TestCase {
64482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes  public void testIsSocket() throws Exception {
65482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    File f = new File("/dev/null");
66482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    FileInputStream fis = new FileInputStream(f);
67482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    assertFalse(S_ISSOCK(Libcore.os.fstat(fis.getFD()).st_mode));
68482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    fis.close();
69482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
70482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    ServerSocket s = new ServerSocket();
71b0ff23bbf588d76541eed5f98be94785dcba6b98Przemyslaw Szczepaniak    assertTrue(S_ISSOCK(Libcore.os.fstat(s.getImpl().getFD$()).st_mode));
72482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    s.close();
73482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes  }
74482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
75c8d9ea662de6f4856b28907b4119087cfc5a44d2Narayan Kamath  public void testFcntlInt() throws Exception {
76c8d9ea662de6f4856b28907b4119087cfc5a44d2Narayan Kamath    File f = File.createTempFile("OsTest", "tst");
77c8d9ea662de6f4856b28907b4119087cfc5a44d2Narayan Kamath    FileInputStream fis = null;
78c8d9ea662de6f4856b28907b4119087cfc5a44d2Narayan Kamath    try {
79c8d9ea662de6f4856b28907b4119087cfc5a44d2Narayan Kamath      fis = new FileInputStream(f);
80c8d9ea662de6f4856b28907b4119087cfc5a44d2Narayan Kamath      Libcore.os.fcntlInt(fis.getFD(), F_SETFD, FD_CLOEXEC);
81c8d9ea662de6f4856b28907b4119087cfc5a44d2Narayan Kamath      int flags = Libcore.os.fcntlVoid(fis.getFD(), F_GETFD);
82c8d9ea662de6f4856b28907b4119087cfc5a44d2Narayan Kamath      assertTrue((flags & FD_CLOEXEC) != 0);
83c8d9ea662de6f4856b28907b4119087cfc5a44d2Narayan Kamath    } finally {
84c8d9ea662de6f4856b28907b4119087cfc5a44d2Narayan Kamath      IoUtils.closeQuietly(fis);
85c8d9ea662de6f4856b28907b4119087cfc5a44d2Narayan Kamath      f.delete();
86c8d9ea662de6f4856b28907b4119087cfc5a44d2Narayan Kamath    }
87c8d9ea662de6f4856b28907b4119087cfc5a44d2Narayan Kamath  }
88c8d9ea662de6f4856b28907b4119087cfc5a44d2Narayan Kamath
89482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes  public void testUnixDomainSockets_in_file_system() throws Exception {
90482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    String path = System.getProperty("java.io.tmpdir") + "/test_unix_socket";
91482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    new File(path).delete();
920ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller    checkUnixDomainSocket(UnixSocketAddress.createFileSystem(path), false);
93482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes  }
94482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
95482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes  public void testUnixDomainSocket_abstract_name() throws Exception {
96482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    // Linux treats a sun_path starting with a NUL byte as an abstract name. See unix(7).
970ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller    checkUnixDomainSocket(UnixSocketAddress.createAbstract("/abstract_name_unix_socket"), true);
980ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller  }
990ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller
1000ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller  public void testUnixDomainSocket_unnamed() throws Exception {
1010ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller    final FileDescriptor fd = Libcore.os.socket(AF_UNIX, SOCK_STREAM, 0);
1020ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller    // unix(7) says an unbound socket is unnamed.
1030ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller    checkNoSockName(fd);
1040ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller    Libcore.os.close(fd);
105482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes  }
106482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
1070ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller  private void checkUnixDomainSocket(final UnixSocketAddress address, final boolean isAbstract)
1082492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      throws Exception {
109482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    final FileDescriptor serverFd = Libcore.os.socket(AF_UNIX, SOCK_STREAM, 0);
1100ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller    Libcore.os.bind(serverFd, address);
111482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    Libcore.os.listen(serverFd, 5);
112482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
113482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    checkSockName(serverFd, isAbstract, address);
114482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
115482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    Thread server = new Thread(new Runnable() {
116482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes      public void run() {
117482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes        try {
1180ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller          UnixSocketAddress peerAddress = UnixSocketAddress.createUnnamed();
119482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes          FileDescriptor clientFd = Libcore.os.accept(serverFd, peerAddress);
120482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes          checkSockName(clientFd, isAbstract, address);
121482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes          checkNoName(peerAddress);
122482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
123482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes          checkNoPeerName(clientFd);
124482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
125482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes          StructUcred credentials = Libcore.os.getsockoptUcred(clientFd, SOL_SOCKET, SO_PEERCRED);
126482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes          assertEquals(Libcore.os.getpid(), credentials.pid);
127482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes          assertEquals(Libcore.os.getuid(), credentials.uid);
128482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes          assertEquals(Libcore.os.getgid(), credentials.gid);
129482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
130482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes          byte[] request = new byte[256];
131d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath          Libcore.os.read(clientFd, request, 0, request.length);
132482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
133482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes          String s = new String(request, "UTF-8");
134b274574b7e2681f4411852af9857b4540bf75841Elliott Hughes          byte[] response = s.toUpperCase(Locale.ROOT).getBytes("UTF-8");
135482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes          Libcore.os.write(clientFd, response, 0, response.length);
136482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
137482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes          Libcore.os.close(clientFd);
138482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes        } catch (Exception ex) {
139482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes          throw new RuntimeException(ex);
140482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes        }
141482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes      }
142482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    });
143482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    server.start();
144482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
145482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    FileDescriptor clientFd = Libcore.os.socket(AF_UNIX, SOCK_STREAM, 0);
146482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
1470ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller    Libcore.os.connect(clientFd, address);
148482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    checkNoSockName(clientFd);
149482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
150482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    String string = "hello, world!";
151482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
152482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    byte[] request = string.getBytes("UTF-8");
153482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    assertEquals(request.length, Libcore.os.write(clientFd, request, 0, request.length));
154482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
155482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    byte[] response = new byte[request.length];
156482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    assertEquals(response.length, Libcore.os.read(clientFd, response, 0, response.length));
157482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
158b274574b7e2681f4411852af9857b4540bf75841Elliott Hughes    assertEquals(string.toUpperCase(Locale.ROOT), new String(response, "UTF-8"));
159482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
160482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    Libcore.os.close(clientFd);
161482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes  }
162482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
1632492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller  private static void checkSockName(FileDescriptor fd, boolean isAbstract,
1642492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      UnixSocketAddress address) throws Exception {
1650ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller    UnixSocketAddress isa = (UnixSocketAddress) Libcore.os.getsockname(fd);
1660ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller    assertEquals(address, isa);
167482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes    if (isAbstract) {
1680ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller      assertEquals(0, isa.getSunPath()[0]);
1699c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes    }
170482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes  }
171482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
1720ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller  private void checkNoName(UnixSocketAddress usa) {
1732492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    assertEquals(0, usa.getSunPath().length);
174482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes  }
175482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
176482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes  private void checkNoPeerName(FileDescriptor fd) throws Exception {
1770ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller    checkNoName((UnixSocketAddress) Libcore.os.getpeername(fd));
178482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes  }
179482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes
180482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes  private void checkNoSockName(FileDescriptor fd) throws Exception {
1810ab1a26ca767ae36fbbe27b62893670b208fa494Neil Fuller    checkNoName((UnixSocketAddress) Libcore.os.getsockname(fd));
182482a3fc5635ac431b8a7476d7fe3397af4c2e8ecElliott Hughes  }
183763f8ed6195707d0c30bfae1ca8a3bb886b746ccElliott Hughes
184763f8ed6195707d0c30bfae1ca8a3bb886b746ccElliott Hughes  public void test_strsignal() throws Exception {
185763f8ed6195707d0c30bfae1ca8a3bb886b746ccElliott Hughes    assertEquals("Killed", Libcore.os.strsignal(9));
186763f8ed6195707d0c30bfae1ca8a3bb886b746ccElliott Hughes    assertEquals("Unknown signal -1", Libcore.os.strsignal(-1));
187763f8ed6195707d0c30bfae1ca8a3bb886b746ccElliott Hughes  }
188d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
189d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath  public void test_byteBufferPositions_write_pwrite() throws Exception {
190d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    FileOutputStream fos = new FileOutputStream(new File("/dev/null"));
191d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    FileDescriptor fd = fos.getFD();
192d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    final byte[] contents = new String("goodbye, cruel world").getBytes(StandardCharsets.US_ASCII);
193d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    ByteBuffer byteBuffer = ByteBuffer.wrap(contents);
194d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
195d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    byteBuffer.position(0);
196d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    int written = Libcore.os.write(fd, byteBuffer);
197d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertTrue(written > 0);
198d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertEquals(written, byteBuffer.position());
199d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
200d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    byteBuffer.position(4);
201d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    written = Libcore.os.write(fd, byteBuffer);
202d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertTrue(written > 0);
203d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertEquals(written + 4, byteBuffer.position());
204d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
205d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    byteBuffer.position(0);
206d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    written = Libcore.os.pwrite(fd, byteBuffer, 64 /* offset */);
207d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertTrue(written > 0);
208d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertEquals(written, byteBuffer.position());
209d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
210d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    byteBuffer.position(4);
211d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    written = Libcore.os.pwrite(fd, byteBuffer, 64 /* offset */);
212d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertTrue(written > 0);
213d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertEquals(written + 4, byteBuffer.position());
214d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
215d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    fos.close();
216d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath  }
217d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
218d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath  public void test_byteBufferPositions_read_pread() throws Exception {
219d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    FileInputStream fis = new FileInputStream(new File("/dev/zero"));
220d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    FileDescriptor fd = fis.getFD();
221d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    ByteBuffer byteBuffer = ByteBuffer.allocate(64);
222d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
223d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    byteBuffer.position(0);
224d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    int read = Libcore.os.read(fd, byteBuffer);
225d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertTrue(read > 0);
226d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertEquals(read, byteBuffer.position());
227d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
228d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    byteBuffer.position(4);
229d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    read = Libcore.os.read(fd, byteBuffer);
230d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertTrue(read > 0);
231d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertEquals(read + 4, byteBuffer.position());
232d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
233d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    byteBuffer.position(0);
234d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    read = Libcore.os.pread(fd, byteBuffer, 64 /* offset */);
235d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertTrue(read > 0);
236d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertEquals(read, byteBuffer.position());
237d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
238d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    byteBuffer.position(4);
239d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    read = Libcore.os.pread(fd, byteBuffer, 64 /* offset */);
240d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertTrue(read > 0);
241d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertEquals(read + 4, byteBuffer.position());
242d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
243d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    fis.close();
244d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath  }
245d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
246b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti  static void checkByteBufferPositions_sendto_recvfrom(
2472492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      int family, InetAddress loopback) throws Exception {
248b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    final FileDescriptor serverFd = Libcore.os.socket(family, SOCK_STREAM, 0);
249b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    Libcore.os.bind(serverFd, loopback, 0);
250d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    Libcore.os.listen(serverFd, 5);
251d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
252d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    InetSocketAddress address = (InetSocketAddress) Libcore.os.getsockname(serverFd);
253d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
254d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    final Thread server = new Thread(new Runnable() {
255d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath      public void run() {
256d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath        try {
257d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath          InetSocketAddress peerAddress = new InetSocketAddress();
258d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath          FileDescriptor clientFd = Libcore.os.accept(serverFd, peerAddress);
259d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
260d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath          // Attempt to receive a maximum of 24 bytes from the client, and then
261d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath          // close the connection.
262d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath          ByteBuffer buffer = ByteBuffer.allocate(16);
263d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath          int received = Libcore.os.recvfrom(clientFd, buffer, 0, null);
264d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath          assertTrue(received > 0);
265d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath          assertEquals(received, buffer.position());
266d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
267d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath          ByteBuffer buffer2 = ByteBuffer.allocate(16);
268d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath          buffer2.position(8);
269d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath          received = Libcore.os.recvfrom(clientFd, buffer2, 0, null);
270d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath          assertTrue(received > 0);
271d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath          assertEquals(received + 8, buffer.position());
272d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
273d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath          Libcore.os.close(clientFd);
274d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath        } catch (Exception ex) {
275d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath          throw new RuntimeException(ex);
276d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath        }
277d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath      }
278d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    });
279d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
280d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    server.start();
281d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
282b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    FileDescriptor clientFd = Libcore.os.socket(family, SOCK_STREAM, 0);
283d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    Libcore.os.connect(clientFd, address.getAddress(), address.getPort());
284d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
2852492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    final byte[] bytes = "good bye, cruel black hole with fancy distortion"
2862492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller        .getBytes(StandardCharsets.US_ASCII);
287d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertTrue(bytes.length > 24);
288d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
289d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    ByteBuffer input = ByteBuffer.wrap(bytes);
290d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    input.position(0);
291d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    input.limit(16);
292d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
293d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    int sent = Libcore.os.sendto(clientFd, input, 0, address.getAddress(), address.getPort());
294d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertTrue(sent > 0);
295d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertEquals(sent, input.position());
296d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
297d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    input.position(16);
298d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    input.limit(24);
299d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    sent = Libcore.os.sendto(clientFd, input, 0, address.getAddress(), address.getPort());
300d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertTrue(sent > 0);
301d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    assertEquals(sent + 16, input.position());
302d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath
303d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath    Libcore.os.close(clientFd);
304d9f7e57f5d09b587d8c8d1bd42b895f7de8fbf54Narayan Kamath  }
3058f5b46d72e5c1b1b1dd4357580c4fb5a60e3f4deErik Kline
3068f5b46d72e5c1b1b1dd4357580c4fb5a60e3f4deErik Kline  public void test_NetlinkSocket() throws Exception {
3078f5b46d72e5c1b1b1dd4357580c4fb5a60e3f4deErik Kline    FileDescriptor nlSocket = Libcore.os.socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
3088f5b46d72e5c1b1b1dd4357580c4fb5a60e3f4deErik Kline    Libcore.os.bind(nlSocket, new NetlinkSocketAddress());
3098f5b46d72e5c1b1b1dd4357580c4fb5a60e3f4deErik Kline    NetlinkSocketAddress address = (NetlinkSocketAddress) Libcore.os.getsockname(nlSocket);
3108f5b46d72e5c1b1b1dd4357580c4fb5a60e3f4deErik Kline    assertTrue(address.getPortId() > 0);
3118f5b46d72e5c1b1b1dd4357580c4fb5a60e3f4deErik Kline    assertEquals(0, address.getGroupsMask());
3128f5b46d72e5c1b1b1dd4357580c4fb5a60e3f4deErik Kline
3138f5b46d72e5c1b1b1dd4357580c4fb5a60e3f4deErik Kline    NetlinkSocketAddress nlKernel = new NetlinkSocketAddress();
3148f5b46d72e5c1b1b1dd4357580c4fb5a60e3f4deErik Kline    Libcore.os.connect(nlSocket, nlKernel);
3158f5b46d72e5c1b1b1dd4357580c4fb5a60e3f4deErik Kline    NetlinkSocketAddress nlPeer = (NetlinkSocketAddress) Libcore.os.getpeername(nlSocket);
3168f5b46d72e5c1b1b1dd4357580c4fb5a60e3f4deErik Kline    assertEquals(0, nlPeer.getPortId());
3178f5b46d72e5c1b1b1dd4357580c4fb5a60e3f4deErik Kline    assertEquals(0, nlPeer.getGroupsMask());
3188f5b46d72e5c1b1b1dd4357580c4fb5a60e3f4deErik Kline    Libcore.os.close(nlSocket);
3198f5b46d72e5c1b1b1dd4357580c4fb5a60e3f4deErik Kline  }
320b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti
32100bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti  public void test_PacketSocketAddress() throws Exception {
32200bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti    NetworkInterface lo = NetworkInterface.getByName("lo");
323bf9a16e6edb7fe8e36fe2ea83efaceaa8eb538cdLorenzo Colitti    FileDescriptor fd = Libcore.os.socket(AF_PACKET, SOCK_DGRAM, ETH_P_IPV6);
32400bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti    PacketSocketAddress addr = new PacketSocketAddress((short) ETH_P_IPV6, lo.getIndex());
32500bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti    Libcore.os.bind(fd, addr);
32600bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti
32700bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti    PacketSocketAddress bound = (PacketSocketAddress) Libcore.os.getsockname(fd);
328bf9a16e6edb7fe8e36fe2ea83efaceaa8eb538cdLorenzo Colitti    assertEquals((short) ETH_P_IPV6, bound.sll_protocol);  // ETH_P_IPV6 is an int.
32900bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti    assertEquals(lo.getIndex(), bound.sll_ifindex);
33000bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti    assertEquals(ARPHRD_LOOPBACK, bound.sll_hatype);
33100bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti    assertEquals(0, bound.sll_pkttype);
33200bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti
33300bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti    // The loopback address is ETH_ALEN bytes long and is all zeros.
33400bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti    // http://lxr.free-electrons.com/source/drivers/net/loopback.c?v=3.10#L167
33500bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti    assertEquals(6, bound.sll_addr.length);
33600bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti    for (int i = 0; i < 6; i++) {
33700bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti      assertEquals(0, bound.sll_addr[i]);
33800bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti    }
33900bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti  }
34000bb2a5e5d619cbfd172793ca9bf7130192765ebLorenzo Colitti
341b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti  public void test_byteBufferPositions_sendto_recvfrom_af_inet() throws Exception {
342b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    checkByteBufferPositions_sendto_recvfrom(AF_INET, InetAddress.getByName("127.0.0.1"));
343b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti  }
344b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti
345b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti  public void test_byteBufferPositions_sendto_recvfrom_af_inet6() throws Exception {
346b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    checkByteBufferPositions_sendto_recvfrom(AF_INET6, InetAddress.getByName("::1"));
347b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti  }
348b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti
349f5fc4ade3ab082f545e2aafdb1942c1f14e0df5dLorenzo Colitti  private void checkSendToSocketAddress(int family, InetAddress loopback) throws Exception {
350f5fc4ade3ab082f545e2aafdb1942c1f14e0df5dLorenzo Colitti    FileDescriptor recvFd = Libcore.os.socket(family, SOCK_DGRAM, 0);
351f5fc4ade3ab082f545e2aafdb1942c1f14e0df5dLorenzo Colitti    Libcore.os.bind(recvFd, loopback, 0);
352a8b7587c5001db3489c64ac1d16c254a683f76bdLorenzo Colitti    StructTimeval tv = StructTimeval.fromMillis(20);
353a8b7587c5001db3489c64ac1d16c254a683f76bdLorenzo Colitti    Libcore.os.setsockoptTimeval(recvFd, SOL_SOCKET, SO_RCVTIMEO, tv);
354a8b7587c5001db3489c64ac1d16c254a683f76bdLorenzo Colitti
355a8b7587c5001db3489c64ac1d16c254a683f76bdLorenzo Colitti    InetSocketAddress to = ((InetSocketAddress) Libcore.os.getsockname(recvFd));
356f5fc4ade3ab082f545e2aafdb1942c1f14e0df5dLorenzo Colitti    FileDescriptor sendFd = Libcore.os.socket(family, SOCK_DGRAM, 0);
357a8b7587c5001db3489c64ac1d16c254a683f76bdLorenzo Colitti    byte[] msg = ("Hello, I'm going to a socket address: " + to.toString()).getBytes("UTF-8");
358a8b7587c5001db3489c64ac1d16c254a683f76bdLorenzo Colitti    int len = msg.length;
359a8b7587c5001db3489c64ac1d16c254a683f76bdLorenzo Colitti
360a8b7587c5001db3489c64ac1d16c254a683f76bdLorenzo Colitti    assertEquals(len, Libcore.os.sendto(sendFd, msg, 0, len, 0, to));
361a8b7587c5001db3489c64ac1d16c254a683f76bdLorenzo Colitti    byte[] received = new byte[msg.length + 42];
362a8b7587c5001db3489c64ac1d16c254a683f76bdLorenzo Colitti    InetSocketAddress from = new InetSocketAddress();
363a8b7587c5001db3489c64ac1d16c254a683f76bdLorenzo Colitti    assertEquals(len, Libcore.os.recvfrom(recvFd, received, 0, received.length, 0, from));
364f5fc4ade3ab082f545e2aafdb1942c1f14e0df5dLorenzo Colitti    assertEquals(loopback, from.getAddress());
365f5fc4ade3ab082f545e2aafdb1942c1f14e0df5dLorenzo Colitti  }
366f5fc4ade3ab082f545e2aafdb1942c1f14e0df5dLorenzo Colitti
367f5fc4ade3ab082f545e2aafdb1942c1f14e0df5dLorenzo Colitti  public void test_sendtoSocketAddress_af_inet() throws Exception {
3682492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    checkSendToSocketAddress(AF_INET, InetAddress.getByName("127.0.0.1"));
369f5fc4ade3ab082f545e2aafdb1942c1f14e0df5dLorenzo Colitti  }
370f5fc4ade3ab082f545e2aafdb1942c1f14e0df5dLorenzo Colitti
371f5fc4ade3ab082f545e2aafdb1942c1f14e0df5dLorenzo Colitti  public void test_sendtoSocketAddress_af_inet6() throws Exception {
3722492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    checkSendToSocketAddress(AF_INET6, InetAddress.getByName("::1"));
373a8b7587c5001db3489c64ac1d16c254a683f76bdLorenzo Colitti  }
374a8b7587c5001db3489c64ac1d16c254a683f76bdLorenzo Colitti
375b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti  public void test_socketFamilies() throws Exception {
376b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    FileDescriptor fd = Libcore.os.socket(AF_INET6, SOCK_STREAM, 0);
377b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    Libcore.os.bind(fd, InetAddress.getByName("::"), 0);
378b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    InetSocketAddress localSocketAddress = (InetSocketAddress) Libcore.os.getsockname(fd);
379b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    assertEquals(Inet6Address.ANY, localSocketAddress.getAddress());
380b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti
381b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    fd = Libcore.os.socket(AF_INET6, SOCK_STREAM, 0);
382b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    Libcore.os.bind(fd, InetAddress.getByName("0.0.0.0"), 0);
383b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    localSocketAddress = (InetSocketAddress) Libcore.os.getsockname(fd);
384b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    assertEquals(Inet6Address.ANY, localSocketAddress.getAddress());
385b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti
386b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    fd = Libcore.os.socket(AF_INET, SOCK_STREAM, 0);
387b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    Libcore.os.bind(fd, InetAddress.getByName("0.0.0.0"), 0);
388b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    localSocketAddress = (InetSocketAddress) Libcore.os.getsockname(fd);
389b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    assertEquals(Inet4Address.ANY, localSocketAddress.getAddress());
390b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    try {
391b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti      Libcore.os.bind(fd, InetAddress.getByName("::"), 0);
392b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti      fail("Expected ErrnoException binding IPv4 socket to ::");
393b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    } catch (ErrnoException expected) {
394b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti      assertEquals("Expected EAFNOSUPPORT binding IPv4 socket to ::", EAFNOSUPPORT, expected.errno);
395b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    }
396b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti  }
397b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti
398b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti  private static void assertArrayEquals(byte[] expected, byte[] actual) {
399b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    assertTrue("Expected=" + Arrays.toString(expected) + ", actual=" + Arrays.toString(actual),
4002492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller        Arrays.equals(expected, actual));
401b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti  }
402b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti
403b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti  private static void checkSocketPing(FileDescriptor fd, InetAddress to, byte[] packet,
4042492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      byte type, byte responseType, boolean useSendto) throws Exception {
405b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    int len = packet.length;
406b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    packet[0] = type;
407b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    if (useSendto) {
408b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti      assertEquals(len, Libcore.os.sendto(fd, packet, 0, len, 0, to, 0));
409b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    } else {
410b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti      Libcore.os.connect(fd, to, 0);
411b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti      assertEquals(len, Libcore.os.sendto(fd, packet, 0, len, 0, null, 0));
412b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    }
413b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti
414b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    int icmpId = ((InetSocketAddress) Libcore.os.getsockname(fd)).getPort();
415b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    byte[] received = new byte[4096];
416b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    InetSocketAddress srcAddress = new InetSocketAddress();
417b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    assertEquals(len, Libcore.os.recvfrom(fd, received, 0, received.length, 0, srcAddress));
418b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    assertEquals(to, srcAddress.getAddress());
419b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    assertEquals(responseType, received[0]);
420b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    assertEquals(received[4], (byte) (icmpId >> 8));
421b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    assertEquals(received[5], (byte) (icmpId & 0xff));
422b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti
423b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    received = Arrays.copyOf(received, len);
424b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    received[0] = (byte) type;
425b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    received[2] = received[3] = 0;  // Checksum.
426b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    received[4] = received[5] = 0;  // ICMP ID.
427b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    assertArrayEquals(packet, received);
428b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti  }
429b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti
430b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti  public void test_socketPing() throws Exception {
431b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    final byte ICMP_ECHO = 8, ICMP_ECHOREPLY = 0;
432b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    final byte ICMPV6_ECHO_REQUEST = (byte) 128, ICMPV6_ECHO_REPLY = (byte) 129;
433b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    final byte[] packet = ("\000\000\000\000" +  // ICMP type, code.
4342492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller        "\000\000\000\003" +  // ICMP ID (== port), sequence number.
4352492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller        "Hello myself").getBytes(StandardCharsets.US_ASCII);
436b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti
437b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    FileDescriptor fd = Libcore.os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6);
438b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    InetAddress ipv6Loopback = InetAddress.getByName("::1");
439b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    checkSocketPing(fd, ipv6Loopback, packet, ICMPV6_ECHO_REQUEST, ICMPV6_ECHO_REPLY, true);
440b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    checkSocketPing(fd, ipv6Loopback, packet, ICMPV6_ECHO_REQUEST, ICMPV6_ECHO_REPLY, false);
441b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti
442b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    fd = Libcore.os.socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
443b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    InetAddress ipv4Loopback = InetAddress.getByName("127.0.0.1");
444b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    checkSocketPing(fd, ipv4Loopback, packet, ICMP_ECHO, ICMP_ECHOREPLY, true);
445b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti    checkSocketPing(fd, ipv4Loopback, packet, ICMP_ECHO, ICMP_ECHOREPLY, false);
446b2a9923fa2006e384013734d3e1c6a7fbe3d9074Lorenzo Colitti  }
44790246a0ae7117d780e077c9e84cdb73ff5b44af7Jeff Sharkey
448b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti  public void test_Ipv4Fallback() throws Exception {
449b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti    // This number of iterations gives a ~60% chance of creating the conditions that caused
450b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti    // http://b/23088314 without making test times too long. On a hammerhead running MRZ37C using
451b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti    // vogar, this test takes about 4s.
452b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti    final int ITERATIONS = 10000;
453b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti    for (int i = 0; i < ITERATIONS; i++) {
454b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti      FileDescriptor mUdpSock = Libcore.os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
455b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti      try {
456b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti          Libcore.os.bind(mUdpSock, Inet4Address.ANY, 0);
457b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti      } catch(ErrnoException e) {
458b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti          fail("ErrnoException after " + i + " iterations: " + e);
459b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti      } finally {
460b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti          Libcore.os.close(mUdpSock);
461b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti      }
462b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti    }
463b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti  }
464b4af0b52e1190846edde87f352ca722a7d9e0259Lorenzo Colitti
4652492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller  public void test_unlink() throws Exception {
4662492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    File f = File.createTempFile("OsTest", "tst");
4672492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    assertTrue(f.exists());
4682492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    Libcore.os.unlink(f.getAbsolutePath());
4692492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    assertFalse(f.exists());
4702492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller
4712492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    try {
4722492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      Libcore.os.unlink(f.getAbsolutePath());
4732492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      fail();
4742492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    } catch (ErrnoException e) {
4752492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      assertEquals(OsConstants.ENOENT, e.errno);
47690246a0ae7117d780e077c9e84cdb73ff5b44af7Jeff Sharkey    }
4772492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller  }
47890246a0ae7117d780e077c9e84cdb73ff5b44af7Jeff Sharkey
4796e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak  // b/27294715
4806e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak  public void test_recvfrom_concurrentShutdown() throws Exception {
4816e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak      final FileDescriptor serverFd = Libcore.os.socket(AF_INET, SOCK_DGRAM, 0);
4826e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak      Libcore.os.bind(serverFd, InetAddress.getByName("127.0.0.1"), 0);
4836e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak      // Set 4s timeout
4846e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak      IoBridge.setSocketOption(serverFd, SocketOptions.SO_TIMEOUT, new Integer(4000));
4856e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak
4866e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak      final AtomicReference<Exception> killerThreadException = new AtomicReference<Exception>(null);
4876e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak      final Thread killer = new Thread(new Runnable() {
4886e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak          public void run() {
4896e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak              try {
4906e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak                  Thread.sleep(2000);
4916e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak                  try {
4926e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak                      Libcore.os.shutdown(serverFd, SHUT_RDWR);
4936e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak                  } catch (ErrnoException expected) {
4946e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak                      if (OsConstants.ENOTCONN != expected.errno) {
4956e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak                          killerThreadException.set(expected);
4966e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak                      }
4976e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak                  }
4986e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak              } catch (Exception ex) {
4996e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak                  killerThreadException.set(ex);
5006e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak              }
5016e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak          }
5026e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak      });
5036e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak      killer.start();
5046e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak
5056e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak      ByteBuffer buffer = ByteBuffer.allocate(16);
5066e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak      InetSocketAddress srcAddress = new InetSocketAddress();
5076e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak      int received = Libcore.os.recvfrom(serverFd, buffer, 0, srcAddress);
5086e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak      assertTrue(received == 0);
5096e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak      Libcore.os.close(serverFd);
5106e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak
5116e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak      killer.join();
5126e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak      assertNull(killerThreadException.get());
5136e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak  }
5146e888e9390649a9ab2557da5b28bb75be39e1b74Przemyslaw Szczepaniak
5152492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller  public void test_xattr() throws Exception {
5162492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    final String NAME_TEST = "user.meow";
51790246a0ae7117d780e077c9e84cdb73ff5b44af7Jeff Sharkey
5182492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    final byte[] VALUE_CAKE = "cake cake cake".getBytes(StandardCharsets.UTF_8);
5192492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    final byte[] VALUE_PIE = "pie".getBytes(StandardCharsets.UTF_8);
52090246a0ae7117d780e077c9e84cdb73ff5b44af7Jeff Sharkey
5212492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    File file = File.createTempFile("xattr", "test");
5222492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    String path = file.getAbsolutePath();
52390246a0ae7117d780e077c9e84cdb73ff5b44af7Jeff Sharkey
5242492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    try {
5252492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      try {
52640afa6bcd4652a16fe461a59f205dd0d65652118Yi Kong        Libcore.os.getxattr(path, NAME_TEST);
5272492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller        fail("Expected ENODATA");
5282492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      } catch (ErrnoException e) {
5292492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller        assertEquals(OsConstants.ENODATA, e.errno);
5302492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      }
53155dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      assertFalse(Arrays.asList(Libcore.os.listxattr(path)).contains(NAME_TEST));
5322492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller
5332492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      Libcore.os.setxattr(path, NAME_TEST, VALUE_CAKE, OsConstants.XATTR_CREATE);
53440afa6bcd4652a16fe461a59f205dd0d65652118Yi Kong      byte[] xattr_create = Libcore.os.getxattr(path, NAME_TEST);
53555dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      assertTrue(Arrays.asList(Libcore.os.listxattr(path)).contains(NAME_TEST));
53640afa6bcd4652a16fe461a59f205dd0d65652118Yi Kong      assertEquals(VALUE_CAKE.length, xattr_create.length);
53740afa6bcd4652a16fe461a59f205dd0d65652118Yi Kong      assertStartsWith(VALUE_CAKE, xattr_create);
5382492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller
5392492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      try {
5402492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller        Libcore.os.setxattr(path, NAME_TEST, VALUE_PIE, OsConstants.XATTR_CREATE);
5412492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller        fail("Expected EEXIST");
5422492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      } catch (ErrnoException e) {
5432492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller        assertEquals(OsConstants.EEXIST, e.errno);
5442492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      }
5452492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller
5462492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      Libcore.os.setxattr(path, NAME_TEST, VALUE_PIE, OsConstants.XATTR_REPLACE);
54740afa6bcd4652a16fe461a59f205dd0d65652118Yi Kong      byte[] xattr_replace = Libcore.os.getxattr(path, NAME_TEST);
54855dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      assertTrue(Arrays.asList(Libcore.os.listxattr(path)).contains(NAME_TEST));
54940afa6bcd4652a16fe461a59f205dd0d65652118Yi Kong      assertEquals(VALUE_PIE.length, xattr_replace.length);
55040afa6bcd4652a16fe461a59f205dd0d65652118Yi Kong      assertStartsWith(VALUE_PIE, xattr_replace);
5512492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller
5522492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      Libcore.os.removexattr(path, NAME_TEST);
5532492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      try {
55440afa6bcd4652a16fe461a59f205dd0d65652118Yi Kong        Libcore.os.getxattr(path, NAME_TEST);
5552492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller        fail("Expected ENODATA");
5562492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      } catch (ErrnoException e) {
5572492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller        assertEquals(OsConstants.ENODATA, e.errno);
5582492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      }
55955dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      assertFalse(Arrays.asList(Libcore.os.listxattr(path)).contains(NAME_TEST));
5602492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller
5612492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    } finally {
5622492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      file.delete();
56390246a0ae7117d780e077c9e84cdb73ff5b44af7Jeff Sharkey    }
5642492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller  }
5652492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller
56655dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong  public void test_xattr_NPE() throws Exception {
56755dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    File file = File.createTempFile("xattr", "test");
56855dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    final String path = file.getAbsolutePath();
56955dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    final String NAME_TEST = "user.meow";
57055dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    final byte[] VALUE_CAKE = "cake cake cake".getBytes(StandardCharsets.UTF_8);
57155dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong
57255dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    // getxattr
57355dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    try {
57455dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      Libcore.os.getxattr(null, NAME_TEST);
57555dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      fail();
57655dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    } catch (NullPointerException expected) { }
57755dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    try {
57855dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      Libcore.os.getxattr(path, null);
57955dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      fail();
58055dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    } catch (NullPointerException expected) { }
58155dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong
58255dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    // listxattr
58355dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    try {
58455dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      Libcore.os.listxattr(null);
58555dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      fail();
58655dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    } catch (NullPointerException expected) { }
58755dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong
58855dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    // removexattr
58955dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    try {
59055dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      Libcore.os.removexattr(null, NAME_TEST);
59155dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      fail();
59255dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    } catch (NullPointerException expected) { }
59355dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    try {
59455dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      Libcore.os.removexattr(path, null);
59555dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      fail();
59655dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    } catch (NullPointerException expected) { }
59755dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong
59855dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    // setxattr
59955dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    try {
60055dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      Libcore.os.setxattr(null, NAME_TEST, VALUE_CAKE, OsConstants.XATTR_CREATE);
60155dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      fail();
60255dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    } catch (NullPointerException expected) { }
60355dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    try {
60455dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      Libcore.os.setxattr(path, null, VALUE_CAKE, OsConstants.XATTR_CREATE);
60555dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      fail();
60655dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    } catch (NullPointerException expected) { }
60755dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    try {
60855dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      Libcore.os.setxattr(path, NAME_TEST, null, OsConstants.XATTR_CREATE);
60955dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      fail();
61055dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    } catch (NullPointerException expected) { }
61155dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong  }
61255dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong
61355dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong  public void test_xattr_Errno() throws Exception {
61455dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    final String NAME_TEST = "user.meow";
61555dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    final byte[] VALUE_CAKE = "cake cake cake".getBytes(StandardCharsets.UTF_8);
61655dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong
61755dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    // ENOENT, No such file or directory.
61855dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    try {
61955dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      Libcore.os.getxattr("", NAME_TEST);
62055dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      fail();
62155dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    } catch (ErrnoException e) {
62252056d7b773b585f0044827da9f385bccdfb4203Yi Kong      assertEquals(ENOENT, e.errno);
62355dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    }
62455dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    try {
62555dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      Libcore.os.listxattr("");
62655dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      fail();
62755dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    } catch (ErrnoException e) {
62852056d7b773b585f0044827da9f385bccdfb4203Yi Kong      assertEquals(ENOENT, e.errno);
62955dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    }
63055dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    try {
63155dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      Libcore.os.removexattr("", NAME_TEST);
63255dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      fail();
63355dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    } catch (ErrnoException e) {
63452056d7b773b585f0044827da9f385bccdfb4203Yi Kong      assertEquals(ENOENT, e.errno);
63555dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    }
63655dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    try {
63755dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      Libcore.os.setxattr("", NAME_TEST, VALUE_CAKE, OsConstants.XATTR_CREATE);
63855dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      fail();
63955dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    } catch (ErrnoException e) {
64052056d7b773b585f0044827da9f385bccdfb4203Yi Kong      assertEquals(ENOENT, e.errno);
64155dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    }
64255dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong
64355dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    // ENOTSUP, Extended attributes are not supported by the filesystem, or are disabled.
644aa84201f59bf8f32d622a9f3674cdf53d97f23b3Sergii Boryshchenko    // Since kernel version 4.9 (or some other version after 4.4), *xattr() methods
645aa84201f59bf8f32d622a9f3674cdf53d97f23b3Sergii Boryshchenko    // may set errno to EACCESS instead. This behavior change is likely related to
646aa84201f59bf8f32d622a9f3674cdf53d97f23b3Sergii Boryshchenko    // https://patchwork.kernel.org/patch/9294421/ which reimplemented getxattr, setxattr,
647aa84201f59bf8f32d622a9f3674cdf53d97f23b3Sergii Boryshchenko    // and removexattr on top of generic handlers.
64852056d7b773b585f0044827da9f385bccdfb4203Yi Kong    final String path = "/proc/self/stat";
64955dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    try {
65052056d7b773b585f0044827da9f385bccdfb4203Yi Kong      Libcore.os.setxattr(path, NAME_TEST, VALUE_CAKE, OsConstants.XATTR_CREATE);
65155dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      fail();
65255dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    } catch (ErrnoException e) {
653aa84201f59bf8f32d622a9f3674cdf53d97f23b3Sergii Boryshchenko      assertTrue("Unexpected errno: " + e.errno, e.errno == ENOTSUP || e.errno == EACCES);
65455dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    }
65555dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    try {
65652056d7b773b585f0044827da9f385bccdfb4203Yi Kong      Libcore.os.getxattr(path, NAME_TEST);
65755dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      fail();
65852056d7b773b585f0044827da9f385bccdfb4203Yi Kong    } catch (ErrnoException e) {
65952056d7b773b585f0044827da9f385bccdfb4203Yi Kong      assertEquals(ENOTSUP, e.errno);
66055dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    }
66155dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    try {
66252056d7b773b585f0044827da9f385bccdfb4203Yi Kong      // Linux listxattr does not set errno.
66352056d7b773b585f0044827da9f385bccdfb4203Yi Kong      Libcore.os.listxattr(path);
66455dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    } catch (ErrnoException e) {
66552056d7b773b585f0044827da9f385bccdfb4203Yi Kong      fail();
66655dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    }
66755dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    try {
66852056d7b773b585f0044827da9f385bccdfb4203Yi Kong      Libcore.os.removexattr(path, NAME_TEST);
66955dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong      fail();
67055dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    } catch (ErrnoException e) {
671aa84201f59bf8f32d622a9f3674cdf53d97f23b3Sergii Boryshchenko      assertTrue("Unexpected errno: " + e.errno, e.errno == ENOTSUP || e.errno == EACCES);
67255dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong    }
67355dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong  }
67455dd377d62cf780df94d8e0198b66e99456b6f50Yi Kong
6755d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath  public void test_realpath() throws Exception {
6765d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath      File tmpDir = new File(System.getProperty("java.io.tmpdir"));
6775d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath      // This is a chicken and egg problem. We have no way of knowing whether
6785d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath      // the temporary directory or one of its path elements were symlinked, so
6795d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath      // we'll need this call to realpath.
6805d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath      String canonicalTmpDir = Libcore.os.realpath(tmpDir.getAbsolutePath());
6815d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath
6825d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath      // Test that "." and ".." are resolved correctly.
6835d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath      assertEquals(canonicalTmpDir,
6845d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath          Libcore.os.realpath(canonicalTmpDir + "/./../" + tmpDir.getName()));
6855d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath
6865d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath      // Test that symlinks are resolved correctly.
6875d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath      File target = new File(tmpDir, "target");
6885d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath      File link = new File(tmpDir, "link");
6894f3470fe72b725d65451995dd4ae357a4676c3f4Narayan Kamath      try {
6904f3470fe72b725d65451995dd4ae357a4676c3f4Narayan Kamath          assertTrue(target.createNewFile());
6914f3470fe72b725d65451995dd4ae357a4676c3f4Narayan Kamath          Libcore.os.symlink(target.getAbsolutePath(), link.getAbsolutePath());
6925d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath
6934f3470fe72b725d65451995dd4ae357a4676c3f4Narayan Kamath          assertEquals(canonicalTmpDir + "/target",
6944f3470fe72b725d65451995dd4ae357a4676c3f4Narayan Kamath              Libcore.os.realpath(canonicalTmpDir + "/link"));
6954f3470fe72b725d65451995dd4ae357a4676c3f4Narayan Kamath      } finally {
6964f3470fe72b725d65451995dd4ae357a4676c3f4Narayan Kamath          boolean deletedTarget = target.delete();
6974f3470fe72b725d65451995dd4ae357a4676c3f4Narayan Kamath          boolean deletedLink = link.delete();
6984f3470fe72b725d65451995dd4ae357a4676c3f4Narayan Kamath          // Asserting this here to provide a definitive reason for
6994f3470fe72b725d65451995dd4ae357a4676c3f4Narayan Kamath          // a subsequent failure on the same run.
7004f3470fe72b725d65451995dd4ae357a4676c3f4Narayan Kamath          assertTrue("deletedTarget = " + deletedTarget + ", deletedLink =" + deletedLink,
7014f3470fe72b725d65451995dd4ae357a4676c3f4Narayan Kamath              deletedTarget && deletedLink);
7024f3470fe72b725d65451995dd4ae357a4676c3f4Narayan Kamath      }
7035d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath  }
7045d45c289afe04d12f41612e33e8df83e5db650d8Narayan Kamath
705ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer  /**
706ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer   * Tests that TCP_USER_TIMEOUT can be set on a TCP socket, but doesn't test
707ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer   * that it behaves as expected.
708ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer   */
709ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer  public void test_socket_tcpUserTimeout_setAndGet() throws Exception {
710ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer    final FileDescriptor fd = Libcore.os.socket(AF_INET, SOCK_STREAM, 0);
711ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer    try {
712ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer      int v = Libcore.os.getsockoptInt(fd, OsConstants.IPPROTO_TCP, OsConstants.TCP_USER_TIMEOUT);
713ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer      assertEquals(0, v); // system default value
714ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer      int newValue = 3000;
715ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer      Libcore.os.setsockoptInt(fd, OsConstants.IPPROTO_TCP, OsConstants.TCP_USER_TIMEOUT,
716ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer              newValue);
717ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer      assertEquals(newValue, Libcore.os.getsockoptInt(fd, OsConstants.IPPROTO_TCP,
718ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer              OsConstants.TCP_USER_TIMEOUT));
719ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer      // No need to reset the value to 0, since we're throwing the socket away
720ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer    } finally {
721ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer      Libcore.os.close(fd);
722ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer    }
723ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer  }
724ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer
725ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer  public void test_socket_tcpUserTimeout_doesNotWorkOnDatagramSocket() throws Exception {
726ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer    final FileDescriptor fd = Libcore.os.socket(AF_INET, SOCK_DGRAM, 0);
727ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer    try {
728ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer      Libcore.os.setsockoptInt(fd, OsConstants.IPPROTO_TCP, OsConstants.TCP_USER_TIMEOUT,
729ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer              3000);
730ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer      fail("datagram (connectionless) sockets shouldn't support TCP_USER_TIMEOUT");
731ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer    } catch (ErrnoException expected) {
732ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer      // expected
733ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer    } finally {
734ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer      Libcore.os.close(fd);
735ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer    }
736ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer  }
737ea47d5d712edcaef726a3e12065729be21699afeTobias Thierer
738ee24b6322448ac919231a668e308ebd719aa52d7Yi Kong  public void test_if_nametoindex_if_indextoname() throws Exception {
739ee24b6322448ac919231a668e308ebd719aa52d7Yi Kong    List<NetworkInterface> nis = Collections.list(NetworkInterface.getNetworkInterfaces());
740ee24b6322448ac919231a668e308ebd719aa52d7Yi Kong
741ee24b6322448ac919231a668e308ebd719aa52d7Yi Kong    assertTrue(nis.size() > 0);
742ee24b6322448ac919231a668e308ebd719aa52d7Yi Kong    for (NetworkInterface ni : nis) {
743ee24b6322448ac919231a668e308ebd719aa52d7Yi Kong      int index = ni.getIndex();
744ee24b6322448ac919231a668e308ebd719aa52d7Yi Kong      String name = ni.getName();
745ee24b6322448ac919231a668e308ebd719aa52d7Yi Kong      assertEquals(index, Libcore.os.if_nametoindex(name));
746ee24b6322448ac919231a668e308ebd719aa52d7Yi Kong      assertTrue(Libcore.os.if_indextoname(index).equals(name));
747ee24b6322448ac919231a668e308ebd719aa52d7Yi Kong    }
748ee24b6322448ac919231a668e308ebd719aa52d7Yi Kong
749ee24b6322448ac919231a668e308ebd719aa52d7Yi Kong    assertEquals(0, Libcore.os.if_nametoindex("this-interface-does-not-exist"));
750ee24b6322448ac919231a668e308ebd719aa52d7Yi Kong    assertEquals(null, Libcore.os.if_indextoname(-1000));
751507ae71a0387dbf4ec17e5eef27b9d3d6d691986Yi Kong
752507ae71a0387dbf4ec17e5eef27b9d3d6d691986Yi Kong    try {
753507ae71a0387dbf4ec17e5eef27b9d3d6d691986Yi Kong      Libcore.os.if_nametoindex(null);
754507ae71a0387dbf4ec17e5eef27b9d3d6d691986Yi Kong      fail();
755507ae71a0387dbf4ec17e5eef27b9d3d6d691986Yi Kong    } catch (NullPointerException expected) { }
756ee24b6322448ac919231a668e308ebd719aa52d7Yi Kong  }
757ee24b6322448ac919231a668e308ebd719aa52d7Yi Kong
7582492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller  private static void assertStartsWith(byte[] expectedContents, byte[] container) {
7592492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    for (int i = 0; i < expectedContents.length; i++) {
7602492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      if (expectedContents[i] != container[i]) {
7612492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller        fail("Expected " + Arrays.toString(expectedContents) + " but found "
7622492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller            + Arrays.toString(expectedContents));
7632492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller      }
7642492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller    }
7652492e430396dc297b2fb784c46d343c3f457fc7dNeil Fuller  }
7662cb2851f4a528e3e6e3e59cf3e854c2abf9f1811Elliott Hughes
7672cb2851f4a528e3e6e3e59cf3e854c2abf9f1811Elliott Hughes  public void test_readlink() throws Exception {
768265a153dfdf3c867925bf72ee119a3623903648fElliott Hughes    File path = new File(IoUtils.createTemporaryDirectory("test_readlink"), "symlink");
7692cb2851f4a528e3e6e3e59cf3e854c2abf9f1811Elliott Hughes
770265a153dfdf3c867925bf72ee119a3623903648fElliott Hughes    // ext2 and ext4 have PAGE_SIZE limits on symlink targets.
771265a153dfdf3c867925bf72ee119a3623903648fElliott Hughes    // If file encryption is enabled, there's extra overhead to store the
772265a153dfdf3c867925bf72ee119a3623903648fElliott Hughes    // size of the encrypted symlink target. There's also an off-by-one
773265a153dfdf3c867925bf72ee119a3623903648fElliott Hughes    // in current kernels (and marlin/sailfish where we're seeing this
774265a153dfdf3c867925bf72ee119a3623903648fElliott Hughes    // failure are still on 3.18, far from current). Given that we don't
775265a153dfdf3c867925bf72ee119a3623903648fElliott Hughes    // really care here, just use 2048 instead. http://b/33306057.
776265a153dfdf3c867925bf72ee119a3623903648fElliott Hughes    int size = 2048;
777265a153dfdf3c867925bf72ee119a3623903648fElliott Hughes    String xs = "";
778265a153dfdf3c867925bf72ee119a3623903648fElliott Hughes    for (int i = 0; i < size - 1; ++i) xs += "x";
7792cb2851f4a528e3e6e3e59cf3e854c2abf9f1811Elliott Hughes
780265a153dfdf3c867925bf72ee119a3623903648fElliott Hughes    Libcore.os.symlink(xs, path.getPath());
781265a153dfdf3c867925bf72ee119a3623903648fElliott Hughes
782265a153dfdf3c867925bf72ee119a3623903648fElliott Hughes    assertEquals(xs, Libcore.os.readlink(path.getPath()));
7832cb2851f4a528e3e6e3e59cf3e854c2abf9f1811Elliott Hughes  }
7846dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong
7856dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong  // Address should be correctly set for empty packets. http://b/33481605
7866dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong  public void test_recvfrom_EmptyPacket() throws Exception {
7876dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong    try (DatagramSocket ds = new DatagramSocket();
7886dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong         DatagramSocket srcSock = new DatagramSocket()) {
7896dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong      srcSock.send(new DatagramPacket(new byte[0], 0, ds.getLocalSocketAddress()));
7906dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong
7916dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong      byte[] recvBuf = new byte[16];
7926dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong      InetSocketAddress address = new InetSocketAddress();
7936dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong      int recvCount =
7946dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong          android.system.Os.recvfrom(ds.getFileDescriptor$(), recvBuf, 0, 16, 0, address);
7956dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong      assertEquals(0, recvCount);
7966dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong      assertTrue(address.getAddress().isLoopbackAddress());
7976dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong      assertEquals(srcSock.getLocalPort(), address.getPort());
7986dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong    }
7996dd21e692ae87b75e49b23ffbecc6964604f466aYi Kong  }
800108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak
801108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak  public void test_fstat_times() throws Exception {
802108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak    File file = File.createTempFile("OsTest", "fstattest");
803108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak    FileOutputStream fos = new FileOutputStream(file);
804108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak    StructStat structStat1 = Libcore.os.fstat(fos.getFD());
805108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak    assertEquals(structStat1.st_mtim.tv_sec, structStat1.st_mtime);
806108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak    assertEquals(structStat1.st_ctim.tv_sec, structStat1.st_ctime);
807108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak    assertEquals(structStat1.st_atim.tv_sec, structStat1.st_atime);
808108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak    Thread.sleep(100);
809108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak    fos.write(new byte[]{1,2,3});
810108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak    fos.flush();
811108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak    StructStat structStat2 = Libcore.os.fstat(fos.getFD());
812108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak    fos.close();
813108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak
814108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak    assertEquals(-1, structStat1.st_mtim.compareTo(structStat2.st_mtim));
815108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak    assertEquals(-1, structStat1.st_ctim.compareTo(structStat2.st_ctim));
816108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak    assertEquals(0, structStat1.st_atim.compareTo(structStat2.st_atim));
817108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak  }
818108091b6787f37a23862c7c9bb965ccf932430abPrzemyslaw Szczepaniak
819e873cd1285c04da110758df066b4bd40ad6eb93dNarayan Kamath  public void test_getrlimit() throws Exception {
820e873cd1285c04da110758df066b4bd40ad6eb93dNarayan Kamath    StructRlimit rlimit = Libcore.os.getrlimit(OsConstants.RLIMIT_NOFILE);
821e873cd1285c04da110758df066b4bd40ad6eb93dNarayan Kamath    // We can't really make any assertions about these values since they might vary from
822e873cd1285c04da110758df066b4bd40ad6eb93dNarayan Kamath    // device to device and even process to process. We do know that they will be greater
823e873cd1285c04da110758df066b4bd40ad6eb93dNarayan Kamath    // than zero, though.
824e873cd1285c04da110758df066b4bd40ad6eb93dNarayan Kamath    assertTrue(rlimit.rlim_cur > 0);
825e873cd1285c04da110758df066b4bd40ad6eb93dNarayan Kamath    assertTrue(rlimit.rlim_max > 0);
826e873cd1285c04da110758df066b4bd40ad6eb93dNarayan Kamath  }
82757a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak
82857a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak  // http://b/65051835
82957a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak  public void test_pipe2_errno() throws Exception {
83057a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak    try {
83157a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak        // flag=-1 is not a valid value for pip2, will EINVAL
83257a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak        Libcore.os.pipe2(-1);
83357a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak        fail();
83457a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak    } catch(ErrnoException expected) {
83557a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak    }
83657a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak  }
83757a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak
83857a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak  // http://b/65051835
83957a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak  public void test_sendfile_errno() throws Exception {
84057a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak    try {
84157a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak        // FileDescriptor.out is not open for input, will cause EBADF
842e3a3a06a94a50d31b7033e496f23becb0f1329c7Tobias Thierer        Int64Ref offset = new Int64Ref(10);
84357a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak        Libcore.os.sendfile(FileDescriptor.out, FileDescriptor.out, offset, 10);
84457a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak        fail();
84557a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak    } catch(ErrnoException expected) {
84657a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak    }
84757a65ad7f0be5b9d0364d36208752f66e9f13596Przemyslaw Szczepaniak  }
84844177e6982a62506127a857070a2452956c3f0f1Enrico Granata
849a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer  public void test_sendfile_null() throws Exception {
850a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer    File in = createTempFile("test_sendfile_null", "Hello, world!");
851a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer    try {
852a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer      int len = "Hello".length();
853f66766fe735068fa6c283163c185914bab21016dTobias Thierer      assertEquals("Hello", checkSendfile(ANDROID_SYSTEM_OS_INT64_REF, in, null, len, null));
854f66766fe735068fa6c283163c185914bab21016dTobias Thierer      assertEquals("Hello", checkSendfile(LIBCORE_OS, in, null, len, null));
855a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer    } finally {
856a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer      in.delete();
857a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer    }
858a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer  }
859a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer
860a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer  public void test_sendfile_offset() throws Exception {
861a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer    File in = createTempFile("test_sendfile_offset", "Hello, world!");
862a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer    try {
863f66766fe735068fa6c283163c185914bab21016dTobias Thierer      // checkSendfile(sendFileImplToUse, in, startOffset, maxBytes, expectedEndOffset)
864a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer
865f66766fe735068fa6c283163c185914bab21016dTobias Thierer      assertEquals("Hello", checkSendfile(ANDROID_SYSTEM_OS_INT64_REF, in, 0L, 5, 5L));
866f66766fe735068fa6c283163c185914bab21016dTobias Thierer      assertEquals("Hello", checkSendfile(LIBCORE_OS, in, 0L, 5, 5L));
867a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer
868f66766fe735068fa6c283163c185914bab21016dTobias Thierer      assertEquals("ello,", checkSendfile(ANDROID_SYSTEM_OS_INT64_REF, in, 1L, 5, 6L));
869f66766fe735068fa6c283163c185914bab21016dTobias Thierer      assertEquals("ello,", checkSendfile(LIBCORE_OS, in, 1L, 5, 6L));
870a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer
871a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer      // At offset 9, only 4 bytes/chars available, even though we're asking for 5.
872f66766fe735068fa6c283163c185914bab21016dTobias Thierer      assertEquals("rld!", checkSendfile(ANDROID_SYSTEM_OS_INT64_REF, in, 9L, 5, 13L));
873f66766fe735068fa6c283163c185914bab21016dTobias Thierer      assertEquals("rld!", checkSendfile(LIBCORE_OS, in, 9L, 5, 13L));
874a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer
875f66766fe735068fa6c283163c185914bab21016dTobias Thierer      assertEquals("", checkSendfile(ANDROID_SYSTEM_OS_INT64_REF, in, 1L, 0, 1L));
876f66766fe735068fa6c283163c185914bab21016dTobias Thierer      assertEquals("", checkSendfile(LIBCORE_OS, in, 1L, 0, 1L));
877a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer    } finally {
878a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer      in.delete();
879a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer    }
880a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer  }
881a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer
882f66766fe735068fa6c283163c185914bab21016dTobias Thierer  /** Which of the {@code sendfile()} implementations to use. */
883f66766fe735068fa6c283163c185914bab21016dTobias Thierer  enum SendFileImpl {
884f66766fe735068fa6c283163c185914bab21016dTobias Thierer    ANDROID_SYSTEM_OS_INT64_REF,
885f66766fe735068fa6c283163c185914bab21016dTobias Thierer    LIBCORE_OS
886f66766fe735068fa6c283163c185914bab21016dTobias Thierer  }
887f66766fe735068fa6c283163c185914bab21016dTobias Thierer
888f66766fe735068fa6c283163c185914bab21016dTobias Thierer  private static String checkSendfile(SendFileImpl sendFileImplToUse, File in, Long startOffset,
889a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer          int maxBytes, Long expectedEndOffset) throws IOException, ErrnoException {
890f66766fe735068fa6c283163c185914bab21016dTobias Thierer    File out = File.createTempFile(OsTest.class.getSimpleName() + "_checkSendFile_" +
891f66766fe735068fa6c283163c185914bab21016dTobias Thierer            sendFileImplToUse, ".out");
892a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer    try (FileInputStream inStream = new FileInputStream(in)) {
893a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer      FileDescriptor inFd = inStream.getFD();
894a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer      try (FileOutputStream outStream = new FileOutputStream(out)) {
895a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer        FileDescriptor outFd = outStream.getFD();
896f66766fe735068fa6c283163c185914bab21016dTobias Thierer        switch (sendFileImplToUse) {
897f66766fe735068fa6c283163c185914bab21016dTobias Thierer          case ANDROID_SYSTEM_OS_INT64_REF: {
898f66766fe735068fa6c283163c185914bab21016dTobias Thierer            Int64Ref offset = (startOffset == null) ? null : new Int64Ref(startOffset);
899f66766fe735068fa6c283163c185914bab21016dTobias Thierer            android.system.Os.sendfile(outFd, inFd, offset, maxBytes);
900f66766fe735068fa6c283163c185914bab21016dTobias Thierer            assertEquals(expectedEndOffset, offset == null ? null : offset.value);
901f66766fe735068fa6c283163c185914bab21016dTobias Thierer            break;
902f66766fe735068fa6c283163c185914bab21016dTobias Thierer          }
903f66766fe735068fa6c283163c185914bab21016dTobias Thierer          case LIBCORE_OS: {
904e3a3a06a94a50d31b7033e496f23becb0f1329c7Tobias Thierer            Int64Ref offset = (startOffset == null) ? null : new Int64Ref(startOffset);
905f66766fe735068fa6c283163c185914bab21016dTobias Thierer            libcore.io.Libcore.os.sendfile(outFd, inFd, offset, maxBytes);
906f66766fe735068fa6c283163c185914bab21016dTobias Thierer            assertEquals(expectedEndOffset, offset == null ? null : offset.value);
907f66766fe735068fa6c283163c185914bab21016dTobias Thierer            break;
908f66766fe735068fa6c283163c185914bab21016dTobias Thierer          }
909f66766fe735068fa6c283163c185914bab21016dTobias Thierer          default: {
910f66766fe735068fa6c283163c185914bab21016dTobias Thierer            fail();
911f66766fe735068fa6c283163c185914bab21016dTobias Thierer            break;
912f66766fe735068fa6c283163c185914bab21016dTobias Thierer          }
913a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer        }
914a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer      }
915a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer      return IoUtils.readFileAsString(out.getPath());
916a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer    } finally {
917a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer      out.delete();
918a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer    }
919a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer  }
920a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer
921a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer  private static File createTempFile(String namePart, String contents) throws IOException {
922a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer    File f = File.createTempFile(OsTest.class.getSimpleName() + namePart, ".in");
923a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer    try (FileWriter writer = new FileWriter(f)) {
924a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer      writer.write(contents);
925a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer    }
926a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer    return f;
927a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer  }
928a36b116e2e009c33e0602867cb476afcbff1dd6aTobias Thierer
929ec48559bf5f1b62b7cdddfbe729cd7674b5ef2adEnrico Granata  public void test_odirect() throws Exception {
930ec48559bf5f1b62b7cdddfbe729cd7674b5ef2adEnrico Granata    File testFile = createTempFile("test_odirect", "");
931ec48559bf5f1b62b7cdddfbe729cd7674b5ef2adEnrico Granata    try {
932ec48559bf5f1b62b7cdddfbe729cd7674b5ef2adEnrico Granata      FileDescriptor fd =
933ec48559bf5f1b62b7cdddfbe729cd7674b5ef2adEnrico Granata            Libcore.os.open(testFile.toString(), O_WRONLY | O_DIRECT, S_IRUSR | S_IWUSR);
934ec48559bf5f1b62b7cdddfbe729cd7674b5ef2adEnrico Granata      assertNotNull(fd);
935ec48559bf5f1b62b7cdddfbe729cd7674b5ef2adEnrico Granata      assertTrue(fd.valid());
936ec48559bf5f1b62b7cdddfbe729cd7674b5ef2adEnrico Granata      int flags = Libcore.os.fcntlVoid(fd, F_GETFL);
937ec48559bf5f1b62b7cdddfbe729cd7674b5ef2adEnrico Granata      assertTrue("Expected file flags to include " + O_DIRECT + ", actual value: " + flags,
938ec48559bf5f1b62b7cdddfbe729cd7674b5ef2adEnrico Granata            0 != (flags & O_DIRECT));
939ec48559bf5f1b62b7cdddfbe729cd7674b5ef2adEnrico Granata      Libcore.os.close(fd);
940ec48559bf5f1b62b7cdddfbe729cd7674b5ef2adEnrico Granata    } finally {
941ec48559bf5f1b62b7cdddfbe729cd7674b5ef2adEnrico Granata      testFile.delete();
942ec48559bf5f1b62b7cdddfbe729cd7674b5ef2adEnrico Granata    }
943ec48559bf5f1b62b7cdddfbe729cd7674b5ef2adEnrico Granata  }
944ec48559bf5f1b62b7cdddfbe729cd7674b5ef2adEnrico Granata
9455310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak  public void test_splice() throws Exception {
9465310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    FileDescriptor[] pipe = Libcore.os.pipe2(0);
9475310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    File in = createTempFile("splice1", "foobar");
9485310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    File out = createTempFile("splice2", "");
9495310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak
9505310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    Int64Ref offIn = new Int64Ref(1);
9515310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    Int64Ref offOut = new Int64Ref(0);
9525310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak
9535310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    // Splice into pipe
9545310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    try (FileInputStream streamIn = new FileInputStream(in)) {
9555310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      FileDescriptor fdIn = streamIn.getFD();
9565310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      long result = Libcore.os.splice(fdIn, offIn, pipe[1], null /* offOut */ , 10 /* len */, 0 /* flags */);
9575310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      assertEquals(5, result);
9585310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      assertEquals(6, offIn.value);
9595310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    }
9605310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak
9615310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    // Splice from pipe
9625310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    try (FileOutputStream streamOut = new FileOutputStream(out)) {
9635310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      FileDescriptor fdOut = streamOut.getFD();
9645310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      long result = Libcore.os.splice(pipe[0], null /* offIn */, fdOut, offOut, 10 /* len */, 0 /* flags */);
9655310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      assertEquals(5, result);
9665310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      assertEquals(5, offOut.value);
9675310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    }
9685310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak
9695310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    assertEquals("oobar", IoUtils.readFileAsString(out.getPath()));
9705310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak
9715310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    Libcore.os.close(pipe[0]);
9725310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    Libcore.os.close(pipe[1]);
9735310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak  }
9745310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak
9755310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak  public void test_splice_errors() throws Exception {
9765310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    File in = createTempFile("splice3", "");
9775310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    File out = createTempFile("splice4", "");
9785310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    FileDescriptor[] pipe = Libcore.os.pipe2(0);
9795310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak
9805310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    //.fdIn == null
9815310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    try {
9825310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      Libcore.os.splice(null /* fdIn */, null /* offIn */, pipe[1],
9835310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak          null /*offOut*/, 10 /* len */, 0 /* flags */);
9845310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      fail();
9855310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    } catch(ErrnoException expected) {
9865310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      assertEquals(EBADF, expected.errno);
9875310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    }
9885310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak
9895310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    //.fdOut == null
9905310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    try {
9915310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      Libcore.os.splice(pipe[0] /* fdIn */, null /* offIn */, null  /* fdOut */,
9925310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak          null /*offOut*/, 10 /* len */, 0 /* flags */);
9935310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      fail();
9945310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    } catch(ErrnoException expected) {
9955310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      assertEquals(EBADF, expected.errno);
9965310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    }
9975310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak
9985310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    // No pipe fd
9995310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    try (FileOutputStream streamOut = new FileOutputStream(out)) {
10005310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      try (FileInputStream streamIn = new FileInputStream(in)) {
10015310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak        FileDescriptor fdIn = streamIn.getFD();
10025310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak        FileDescriptor fdOut = streamOut.getFD();
10035310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak        Libcore.os.splice(fdIn, null  /* offIn */, fdOut, null /* offOut */, 10 /* len */, 0 /* flags */);
10045310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak        fail();
10055310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      } catch(ErrnoException expected) {
10065310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak        assertEquals(EINVAL, expected.errno);
10075310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak      }
10085310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    }
10095310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak
10105310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    Libcore.os.close(pipe[0]);
10115310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak    Libcore.os.close(pipe[1]);
10125310ea4af51082e4a775d31615daaa59754d003ePrzemyslaw Szczepaniak  }
10139c8130231a0e1c2a5ded68e99f782427bb5326faElliott Hughes}
1014