10f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin/*
20f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin * Copyright (C) 2010 The Android Open Source Project
30f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin *
40f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin * Licensed under the Apache License, Version 2.0 (the "License");
50f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin * you may not use this file except in compliance with the License.
60f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin * You may obtain a copy of the License at
70f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin *
80f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin *      http://www.apache.org/licenses/LICENSE-2.0
90f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin *
100f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin * Unless required by applicable law or agreed to in writing, software
110f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin * distributed under the License is distributed on an "AS IS" BASIS,
120f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin * See the License for the specific language governing permissions and
140f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin * limitations under the License.
150f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin */
160f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin
170f524004b71b732c888d10eab57008bc65d8a3e0Owen Linpackage libcore.java.io;
180f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin
1973298fc8f21a2440b4848912e95a072713b93a1aElliott Hughesimport java.io.File;
200f524004b71b732c888d10eab57008bc65d8a3e0Owen Linimport java.io.FileDescriptor;
210f524004b71b732c888d10eab57008bc65d8a3e0Owen Linimport java.io.FileInputStream;
220ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughesimport java.io.FileNotFoundException;
230f524004b71b732c888d10eab57008bc65d8a3e0Owen Linimport java.io.FileOutputStream;
240f524004b71b732c888d10eab57008bc65d8a3e0Owen Linimport java.io.IOException;
25e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamathimport java.util.ArrayList;
26e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamathimport java.util.List;
27e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath
28e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamathimport android.system.ErrnoException;
29e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamathimport android.system.OsConstants;
300f524004b71b732c888d10eab57008bc65d8a3e0Owen Linimport junit.framework.TestCase;
31b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes
320f524004b71b732c888d10eab57008bc65d8a3e0Owen Linimport libcore.io.IoUtils;
3341f0605d2c809bd9bc1c0fb68d86b49a0f59b6c5Elliott Hughesimport libcore.io.Libcore;
340f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin
350f524004b71b732c888d10eab57008bc65d8a3e0Owen Linpublic final class FileInputStreamTest extends TestCase {
360f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin    private static final int TOTAL_SIZE = 1024;
370f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin    private static final int SKIP_SIZE = 100;
380f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin
390f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin    private static class DataFeeder extends Thread {
400f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin        private FileDescriptor mOutFd;
410f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin
420f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin        public DataFeeder(FileDescriptor fd) {
430f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin            mOutFd = fd;
440f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin        }
450f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin
460f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin        @Override
470f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin        public void run() {
480f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin            try {
490f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin                FileOutputStream fos = new FileOutputStream(mOutFd);
500f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin                try {
510f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin                    byte[] buffer = new byte[TOTAL_SIZE];
520f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin                    for (int i = 0; i < buffer.length; ++i) {
530f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin                        buffer[i] = (byte) i;
540f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin                    }
550f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin                    fos.write(buffer);
560f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin                } finally {
570f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin                    IoUtils.closeQuietly(fos);
580f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin                    IoUtils.close(mOutFd);
590f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin                }
600f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin            } catch (IOException e) {
610f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin                throw new RuntimeException(e);
620f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin            }
630f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin        }
640f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin    }
650f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin
6641f0605d2c809bd9bc1c0fb68d86b49a0f59b6c5Elliott Hughes    private void verifyData(FileInputStream is, int start, int count) throws IOException {
670f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin        byte buffer[] = new byte[count];
680f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin        assertEquals(count, is.read(buffer));
690f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin        for (int i = 0; i < count; ++i) {
700f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin            assertEquals((byte) (i + start), buffer[i]);
710f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin        }
720f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin    }
730f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin
740f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin    public void testSkipInPipes() throws Exception {
750d8b5c3692c36837d22c4e7d9c4d7d95f6a10235Elliott Hughes        FileDescriptor[] pipe = Libcore.os.pipe2(0);
760f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin        DataFeeder feeder = new DataFeeder(pipe[1]);
770f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin        try {
780f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin            feeder.start();
790f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin            FileInputStream fis = new FileInputStream(pipe[0]);
800f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin            fis.skip(SKIP_SIZE);
810f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin            verifyData(fis, SKIP_SIZE, TOTAL_SIZE - SKIP_SIZE);
820f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin            assertEquals(-1, fis.read());
830f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin            feeder.join(1000);
840f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin            assertFalse(feeder.isAlive());
850f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin        } finally {
86462bdac45c10f43d88d8f07f6994e272a27c14a2Elliott Hughes            IoUtils.closeQuietly(pipe[0]);
870f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin        }
880f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin    }
890ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes
900ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes    public void testDirectories() throws Exception {
910ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes        try {
920ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes            new FileInputStream(".");
930ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes            fail();
940ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes        } catch (FileNotFoundException expected) {
950ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes        }
960ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes    }
9773298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes
98b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes    private File makeFile() throws Exception {
9973298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes        File tmp = File.createTempFile("FileOutputStreamTest", "tmp");
10073298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes        FileOutputStream fos = new FileOutputStream(tmp);
10173298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes        fos.write(1);
10273298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes        fos.write(1);
10373298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes        fos.close();
104b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        return tmp;
105b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes    }
106b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes
107b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes    public void testFileDescriptorOwnership() throws Exception {
108b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        File tmp = makeFile();
10973298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes
11073298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes        FileInputStream fis1 = new FileInputStream(tmp);
11173298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes        FileInputStream fis2 = new FileInputStream(fis1.getFD());
112b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes
113b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        // Close the second FileDescriptor and check we can't use it...
11473298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes        fis2.close();
11550164c3602af46021e434ff5047352299a36e0f0Yi Kong
116b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        try {
117b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fis2.available();
118b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fail();
119b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        } catch (IOException expected) {
120b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        }
121b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        try {
122b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fis2.read();
123b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fail();
124b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        } catch (IOException expected) {
125b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        }
126b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        try {
127b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fis2.read(new byte[1], 0, 1);
128b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fail();
129b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        } catch (IOException expected) {
130b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        }
131b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        try {
132b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fis2.skip(1);
133b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fail();
134b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        } catch (IOException expected) {
135b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        }
136b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        // ...but that we can still use the first.
13750164c3602af46021e434ff5047352299a36e0f0Yi Kong        assertTrue(fis1.getFD().valid());
13873298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes        assertFalse(fis1.read() == -1);
139b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes
140b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        // Close the first FileDescriptor and check we can't use it...
14173298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes        fis1.close();
14273298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes        try {
143b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fis1.available();
144b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fail();
145b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        } catch (IOException expected) {
146b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        }
147b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        try {
14873298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes            fis1.read();
14973298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes            fail();
15073298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes        } catch (IOException expected) {
15173298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes        }
152b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        try {
153b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fis1.read(new byte[1], 0, 1);
154b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fail();
155b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        } catch (IOException expected) {
156b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        }
157b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        try {
158b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fis1.skip(1);
159b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fail();
160b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        } catch (IOException expected) {
161b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        }
16250164c3602af46021e434ff5047352299a36e0f0Yi Kong
16350164c3602af46021e434ff5047352299a36e0f0Yi Kong        // FD is no longer owned by any stream, should be invalidated.
16450164c3602af46021e434ff5047352299a36e0f0Yi Kong        assertFalse(fis1.getFD().valid());
165b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes    }
166b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes
167b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes    public void testClose() throws Exception {
168b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        File tmp = makeFile();
169b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        FileInputStream fis = new FileInputStream(tmp);
170b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes
171b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        // Closing an already-closed stream is a no-op...
172b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        fis.close();
173b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        fis.close();
174b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes
175b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        // But any explicit activity is an error.
176b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        try {
177b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fis.available();
178b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fail();
179b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        } catch (IOException expected) {
180b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        }
181b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        try {
182b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fis.read();
183b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fail();
184b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        } catch (IOException expected) {
185b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        }
186b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        try {
187b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fis.read(new byte[1], 0, 1);
188b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fail();
189b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        } catch (IOException expected) {
190b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        }
191b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        try {
192b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fis.skip(1);
193b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fail();
194b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        } catch (IOException expected) {
195b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        }
196b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        // Including 0-byte skips...
197b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        try {
198b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fis.skip(0);
199b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes            fail();
200b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        } catch (IOException expected) {
201b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        }
202b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        // ...but not 0-byte reads...
203b1f55cb6f95928be969a8fe5c7447e13f14d0a68Elliott Hughes        fis.read(new byte[0], 0, 0);
20473298fc8f21a2440b4848912e95a072713b93a1aElliott Hughes    }
2053ef077835b6f7af06814343aab0b84f41997ad3fNarayan Kamath
2063ef077835b6f7af06814343aab0b84f41997ad3fNarayan Kamath    // http://b/26117827
2073ef077835b6f7af06814343aab0b84f41997ad3fNarayan Kamath    public void testReadProcVersion() throws IOException {
2083ef077835b6f7af06814343aab0b84f41997ad3fNarayan Kamath        File file = new File("/proc/version");
2093ef077835b6f7af06814343aab0b84f41997ad3fNarayan Kamath        FileInputStream input = new FileInputStream(file);
2103ef077835b6f7af06814343aab0b84f41997ad3fNarayan Kamath        assertTrue(input.available() == 0);
2113ef077835b6f7af06814343aab0b84f41997ad3fNarayan Kamath    }
212e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath
213e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath    // http://b/25695227
214e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath    public void testFdLeakWhenOpeningDirectory() throws Exception {
215e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath        File phile = IoUtils.createTemporaryDirectory("test_bug_25695227");
216e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath
217e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath        try {
218e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath            new FileInputStream(phile);
219e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath            fail();
220e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath        } catch (FileNotFoundException expected) {
221e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath        }
222e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath
223e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath        assertTrue(getOpenFdsForPrefix("test_bug_25695227").isEmpty());
224e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath    }
225e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath
226f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath    // http://b/28192631
227f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath    public void testSkipOnLargeFiles() throws Exception {
228f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath        File largeFile = File.createTempFile("FileInputStreamTest_testSkipOnLargeFiles", "");
229f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath        FileOutputStream fos = new FileOutputStream(largeFile);
230f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath        try {
231f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath            byte[] buffer = new byte[1024 * 1024]; // 1 MB
232f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath            for (int i = 0; i < 3 * 1024; i++) { // 3 GB
233f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath                fos.write(buffer);
234f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath            }
235f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath        } finally {
236f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath            fos.close();
237f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath        }
238f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath
239f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath        FileInputStream fis = new FileInputStream(largeFile);
240f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath        long lastByte = 3 * 1024 * 1024 * 1024L - 1;
241f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath        assertEquals(0, Libcore.os.lseek(fis.getFD(), 0, OsConstants.SEEK_CUR));
242f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath        assertEquals(lastByte, fis.skip(lastByte));
243f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath
244f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath        // Proactively cleanup - it's a pretty large file.
245f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath        assertTrue(largeFile.delete());
246f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath    }
247f7f72edb7528537ef9cbd008ad1cb204021f27bfNarayan Kamath
248e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath    private static List<Integer> getOpenFdsForPrefix(String path) throws Exception {
249e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath        File[] fds = new File("/proc/self/fd").listFiles();
250e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath        List<Integer> list = new ArrayList<>();
251e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath        for (File fd : fds) {
252e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath            try {
253e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath                File fdPath = new File(android.system.Os.readlink(fd.getAbsolutePath()));
254e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath                if (fdPath.getName().startsWith(path)) {
255e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath                    list.add(Integer.valueOf(fd.getName()));
256e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath                }
257e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath            } catch (ErrnoException e) {
258e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath                if (e.errno != OsConstants.ENOENT) {
259e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath                    throw e.rethrowAsIOException();
260e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath                }
261e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath            }
262e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath        }
263e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath
264e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath        return list;
265e3603abc77118773fc0cf5892be0df4056b1fb57Narayan Kamath    }
2660f524004b71b732c888d10eab57008bc65d8a3e0Owen Lin}
267