/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package libcore.io; import android.system.StructUcred; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.InetUnixAddress; import java.net.ServerSocket; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Locale; import junit.framework.TestCase; import static android.system.OsConstants.*; public class OsTest extends TestCase { public void testIsSocket() throws Exception { File f = new File("/dev/null"); FileInputStream fis = new FileInputStream(f); assertFalse(S_ISSOCK(Libcore.os.fstat(fis.getFD()).st_mode)); fis.close(); ServerSocket s = new ServerSocket(); assertTrue(S_ISSOCK(Libcore.os.fstat(s.getImpl$().getFD$()).st_mode)); s.close(); } public void testUnixDomainSockets_in_file_system() throws Exception { String path = System.getProperty("java.io.tmpdir") + "/test_unix_socket"; new File(path).delete(); checkUnixDomainSocket(new InetUnixAddress(path), false); } public void testUnixDomainSocket_abstract_name() throws Exception { // Linux treats a sun_path starting with a NUL byte as an abstract name. See unix(7). byte[] path = "/abstract_name_unix_socket".getBytes("UTF-8"); path[0] = 0; checkUnixDomainSocket(new InetUnixAddress(path), true); } private void checkUnixDomainSocket(final InetUnixAddress address, final boolean isAbstract) throws Exception { final FileDescriptor serverFd = Libcore.os.socket(AF_UNIX, SOCK_STREAM, 0); Libcore.os.bind(serverFd, address, 0); Libcore.os.listen(serverFd, 5); checkSockName(serverFd, isAbstract, address); Thread server = new Thread(new Runnable() { public void run() { try { InetSocketAddress peerAddress = new InetSocketAddress(); FileDescriptor clientFd = Libcore.os.accept(serverFd, peerAddress); checkSockName(clientFd, isAbstract, address); checkNoName(peerAddress); checkNoPeerName(clientFd); StructUcred credentials = Libcore.os.getsockoptUcred(clientFd, SOL_SOCKET, SO_PEERCRED); assertEquals(Libcore.os.getpid(), credentials.pid); assertEquals(Libcore.os.getuid(), credentials.uid); assertEquals(Libcore.os.getgid(), credentials.gid); byte[] request = new byte[256]; Libcore.os.read(clientFd, request, 0, request.length); String s = new String(request, "UTF-8"); byte[] response = s.toUpperCase(Locale.ROOT).getBytes("UTF-8"); Libcore.os.write(clientFd, response, 0, response.length); Libcore.os.close(clientFd); } catch (Exception ex) { throw new RuntimeException(ex); } } }); server.start(); FileDescriptor clientFd = Libcore.os.socket(AF_UNIX, SOCK_STREAM, 0); Libcore.os.connect(clientFd, address, 0); checkNoSockName(clientFd); String string = "hello, world!"; byte[] request = string.getBytes("UTF-8"); assertEquals(request.length, Libcore.os.write(clientFd, request, 0, request.length)); byte[] response = new byte[request.length]; assertEquals(response.length, Libcore.os.read(clientFd, response, 0, response.length)); assertEquals(string.toUpperCase(Locale.ROOT), new String(response, "UTF-8")); Libcore.os.close(clientFd); } private void checkSockName(FileDescriptor fd, boolean isAbstract, InetAddress address) throws Exception { InetSocketAddress isa = (InetSocketAddress) Libcore.os.getsockname(fd); if (isAbstract) { checkNoName(isa); } else { assertEquals(address, isa.getAddress()); } } private void checkNoName(SocketAddress sa) { InetSocketAddress isa = (InetSocketAddress) sa; assertEquals(0, isa.getAddress().getAddress().length); } private void checkNoPeerName(FileDescriptor fd) throws Exception { checkNoName(Libcore.os.getpeername(fd)); } private void checkNoSockName(FileDescriptor fd) throws Exception { checkNoName(Libcore.os.getsockname(fd)); } public void test_strsignal() throws Exception { assertEquals("Killed", Libcore.os.strsignal(9)); assertEquals("Unknown signal -1", Libcore.os.strsignal(-1)); } public void test_byteBufferPositions_write_pwrite() throws Exception { FileOutputStream fos = new FileOutputStream(new File("/dev/null")); FileDescriptor fd = fos.getFD(); final byte[] contents = new String("goodbye, cruel world").getBytes(StandardCharsets.US_ASCII); ByteBuffer byteBuffer = ByteBuffer.wrap(contents); byteBuffer.position(0); int written = Libcore.os.write(fd, byteBuffer); assertTrue(written > 0); assertEquals(written, byteBuffer.position()); byteBuffer.position(4); written = Libcore.os.write(fd, byteBuffer); assertTrue(written > 0); assertEquals(written + 4, byteBuffer.position()); byteBuffer.position(0); written = Libcore.os.pwrite(fd, byteBuffer, 64 /* offset */); assertTrue(written > 0); assertEquals(written, byteBuffer.position()); byteBuffer.position(4); written = Libcore.os.pwrite(fd, byteBuffer, 64 /* offset */); assertTrue(written > 0); assertEquals(written + 4, byteBuffer.position()); fos.close(); } public void test_byteBufferPositions_read_pread() throws Exception { FileInputStream fis = new FileInputStream(new File("/dev/zero")); FileDescriptor fd = fis.getFD(); ByteBuffer byteBuffer = ByteBuffer.allocate(64); byteBuffer.position(0); int read = Libcore.os.read(fd, byteBuffer); assertTrue(read > 0); assertEquals(read, byteBuffer.position()); byteBuffer.position(4); read = Libcore.os.read(fd, byteBuffer); assertTrue(read > 0); assertEquals(read + 4, byteBuffer.position()); byteBuffer.position(0); read = Libcore.os.pread(fd, byteBuffer, 64 /* offset */); assertTrue(read > 0); assertEquals(read, byteBuffer.position()); byteBuffer.position(4); read = Libcore.os.pread(fd, byteBuffer, 64 /* offset */); assertTrue(read > 0); assertEquals(read + 4, byteBuffer.position()); fis.close(); } public void test_byteBufferPositions_sendto_recvfrom() throws Exception { final FileDescriptor serverFd = Libcore.os.socket(AF_INET6, SOCK_STREAM, 0); Libcore.os.bind(serverFd, InetAddress.getLoopbackAddress(), 0); Libcore.os.listen(serverFd, 5); InetSocketAddress address = (InetSocketAddress) Libcore.os.getsockname(serverFd); final Thread server = new Thread(new Runnable() { public void run() { try { InetSocketAddress peerAddress = new InetSocketAddress(); FileDescriptor clientFd = Libcore.os.accept(serverFd, peerAddress); // Attempt to receive a maximum of 24 bytes from the client, and then // close the connection. ByteBuffer buffer = ByteBuffer.allocate(16); int received = Libcore.os.recvfrom(clientFd, buffer, 0, null); assertTrue(received > 0); assertEquals(received, buffer.position()); ByteBuffer buffer2 = ByteBuffer.allocate(16); buffer2.position(8); received = Libcore.os.recvfrom(clientFd, buffer2, 0, null); assertTrue(received > 0); assertEquals(received + 8, buffer.position()); Libcore.os.close(clientFd); } catch (Exception ex) { throw new RuntimeException(ex); } } }); server.start(); FileDescriptor clientFd = Libcore.os.socket(AF_INET6, SOCK_STREAM, 0); Libcore.os.connect(clientFd, address.getAddress(), address.getPort()); final byte[] bytes = "good bye, cruel black hole with fancy distortion".getBytes(StandardCharsets.US_ASCII); assertTrue(bytes.length > 24); ByteBuffer input = ByteBuffer.wrap(bytes); input.position(0); input.limit(16); int sent = Libcore.os.sendto(clientFd, input, 0, address.getAddress(), address.getPort()); assertTrue(sent > 0); assertEquals(sent, input.position()); input.position(16); input.limit(24); sent = Libcore.os.sendto(clientFd, input, 0, address.getAddress(), address.getPort()); assertTrue(sent > 0); assertEquals(sent + 16, input.position()); Libcore.os.close(clientFd); } }