unistd_test.cpp revision 84d0683a824fa02dbaa6d1b56a79223804b54e80
1a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes/* 2a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * Copyright (C) 2012 The Android Open Source Project 3a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * 4a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * you may not use this file except in compliance with the License. 6a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * You may obtain a copy of the License at 7a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * 8a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * 10a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * Unless required by applicable law or agreed to in writing, software 11a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * See the License for the specific language governing permissions and 14a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * limitations under the License. 15a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes */ 16a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes 17a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes#include <gtest/gtest.h> 1813613137bc4266656bffce464e525eb9ae6371f0Christopher Ferris#include "ScopedSignalHandler.h" 19b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes#include "TemporaryFile.h" 20a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes 21915fefb62e1beed3da26fe299a8141645733a925Elliott Hughes#include <errno.h> 223d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross#include <fcntl.h> 2378e4f8fed2c162f8ada55180e48487ef2180cf93Elliott Hughes#include <limits.h> 24428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes#include <stdint.h> 25a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes#include <unistd.h> 267086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes#include <sys/syscall.h> 27764a99361130dceda62bbc4f8780bbf395dbc424Elliott Hughes#include <sys/types.h> 28764a99361130dceda62bbc4f8780bbf395dbc424Elliott Hughes#include <sys/wait.h> 29a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes 30a55f63083fb16b2595f517a3260083e5f8cddd02Elliott HughesTEST(unistd, sysconf_SC_MONOTONIC_CLOCK) { 31a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes ASSERT_GT(sysconf(_SC_MONOTONIC_CLOCK), 0); 32a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes} 33428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes 34533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughesstatic void* get_brk() { 35533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes return sbrk(0); 36533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes} 37533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes 38533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughesstatic void* page_align(uintptr_t addr) { 39533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes uintptr_t mask = sysconf(_SC_PAGE_SIZE) - 1; 40533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes return reinterpret_cast<void*>((addr + mask) & ~mask); 41533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes} 42533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes 43533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott HughesTEST(unistd, brk) { 44533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes void* initial_break = get_brk(); 45533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes 46533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes // The kernel aligns the break to a page. 47533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes void* new_break = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(initial_break) + 1); 48533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes ASSERT_EQ(0, brk(new_break)); 49533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes ASSERT_GE(get_brk(), new_break); 50428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes 51533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes new_break = page_align(reinterpret_cast<uintptr_t>(initial_break) + sysconf(_SC_PAGE_SIZE)); 52428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes ASSERT_EQ(0, brk(new_break)); 53533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes ASSERT_EQ(get_brk(), new_break); 54533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes} 55533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes 56533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott HughesTEST(unistd, brk_ENOMEM) { 57533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes ASSERT_EQ(-1, brk(reinterpret_cast<void*>(-1))); 58533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes ASSERT_EQ(ENOMEM, errno); 59533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes} 60533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes 61738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#if defined(__GLIBC__) 62738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#define SBRK_MIN INTPTR_MIN 63738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#define SBRK_MAX INTPTR_MAX 64738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#else 65738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#define SBRK_MIN PTRDIFF_MIN 66738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#define SBRK_MAX PTRDIFF_MAX 67738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#endif 68738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris 69533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott HughesTEST(unistd, sbrk_ENOMEM) { 70738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#if defined(__BIONIC__) && !defined(__LP64__) 71738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris // There is no way to guarantee that all overflow conditions can be tested 72738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris // without manipulating the underlying values of the current break. 73738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris extern void* __bionic_brk; 74738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris 75738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris class ScopedBrk { 76738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris public: 77738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris ScopedBrk() : saved_brk_(__bionic_brk) {} 78738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris virtual ~ScopedBrk() { __bionic_brk = saved_brk_; } 79738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris 80738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris private: 81738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris void* saved_brk_; 82738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris }; 83738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris 84738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris ScopedBrk scope_brk; 85738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris 86738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris // Set the current break to a point that will cause an overflow. 87738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) + 2); 88533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes 89533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes // Can't increase by so much that we'd overflow. 90533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MAX)); 91533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes ASSERT_EQ(ENOMEM, errno); 92533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes 93738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris // Set the current break to a point that will cause an overflow. 94738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX)); 95428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes 96533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN)); 97533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes ASSERT_EQ(ENOMEM, errno); 98738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris 99738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) - 1); 100738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris 101738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN + 1)); 102738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris ASSERT_EQ(ENOMEM, errno); 103738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#else 104738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris class ScopedBrk { 105738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris public: 106738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris ScopedBrk() : saved_brk_(get_brk()) {} 107738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris virtual ~ScopedBrk() { brk(saved_brk_); } 108738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris 109738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris private: 110738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris void* saved_brk_; 111738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris }; 112738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris 113738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris ScopedBrk scope_brk; 114738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris 115738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris uintptr_t cur_brk = reinterpret_cast<uintptr_t>(get_brk()); 116738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris if (cur_brk < static_cast<uintptr_t>(-(SBRK_MIN+1))) { 117738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris // Do the overflow test for a max negative increment. 118738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MIN)); 119738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#if defined(__BIONIC__) 120738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris // GLIBC does not set errno in overflow case. 121738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris ASSERT_EQ(ENOMEM, errno); 122738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#endif 123738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris } 124738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris 125738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris uintptr_t overflow_brk = static_cast<uintptr_t>(SBRK_MAX) + 2; 126738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris if (cur_brk < overflow_brk) { 127738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris // Try and move the value to PTRDIFF_MAX + 2. 128738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris cur_brk = reinterpret_cast<uintptr_t>(sbrk(overflow_brk)); 129738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris } 130738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris if (cur_brk >= overflow_brk) { 131738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MAX)); 132738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#if defined(__BIONIC__) 133738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris // GLIBC does not set errno in overflow case. 134738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris ASSERT_EQ(ENOMEM, errno); 135738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#endif 136738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris } 137533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes#endif 138428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes} 139b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes 140b4f7616fd618875768b8fffc122b58bdb84a9969Elliott HughesTEST(unistd, truncate) { 141b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes TemporaryFile tf; 142b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes ASSERT_EQ(0, close(tf.fd)); 143b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes ASSERT_EQ(0, truncate(tf.filename, 123)); 144b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes 145b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes struct stat sb; 146b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes ASSERT_EQ(0, stat(tf.filename, &sb)); 147b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes ASSERT_EQ(123, sb.st_size); 148b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes} 149b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes 150b4f7616fd618875768b8fffc122b58bdb84a9969Elliott HughesTEST(unistd, truncate64) { 151b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes TemporaryFile tf; 152b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes ASSERT_EQ(0, close(tf.fd)); 153b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes ASSERT_EQ(0, truncate64(tf.filename, 123)); 154b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes 155b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes struct stat sb; 156b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes ASSERT_EQ(0, stat(tf.filename, &sb)); 157b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes ASSERT_EQ(123, sb.st_size); 158b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes} 159b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes 160b4f7616fd618875768b8fffc122b58bdb84a9969Elliott HughesTEST(unistd, ftruncate) { 161b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes TemporaryFile tf; 162b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes ASSERT_EQ(0, ftruncate(tf.fd, 123)); 163b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes ASSERT_EQ(0, close(tf.fd)); 164b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes 165b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes struct stat sb; 166b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes ASSERT_EQ(0, stat(tf.filename, &sb)); 167b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes ASSERT_EQ(123, sb.st_size); 168b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes} 169b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes 170b4f7616fd618875768b8fffc122b58bdb84a9969Elliott HughesTEST(unistd, ftruncate64) { 171b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes TemporaryFile tf; 172b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes ASSERT_EQ(0, ftruncate64(tf.fd, 123)); 173b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes ASSERT_EQ(0, close(tf.fd)); 174b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes 175b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes struct stat sb; 176b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes ASSERT_EQ(0, stat(tf.filename, &sb)); 177b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes ASSERT_EQ(123, sb.st_size); 178b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes} 17911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes 1801728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic bool g_pause_test_flag = false; 18111952073af22568bba0b661f7a9d4402c443a888Elliott Hughesstatic void PauseTestSignalHandler(int) { 1821728b2396591853345507a063ed6075dfd251706Elliott Hughes g_pause_test_flag = true; 18311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes} 18411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes 18511952073af22568bba0b661f7a9d4402c443a888Elliott HughesTEST(unistd, pause) { 18613613137bc4266656bffce464e525eb9ae6371f0Christopher Ferris ScopedSignalHandler handler(SIGALRM, PauseTestSignalHandler); 18713613137bc4266656bffce464e525eb9ae6371f0Christopher Ferris 18811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes alarm(1); 1891728b2396591853345507a063ed6075dfd251706Elliott Hughes ASSERT_FALSE(g_pause_test_flag); 19011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes ASSERT_EQ(-1, pause()); 1911728b2396591853345507a063ed6075dfd251706Elliott Hughes ASSERT_TRUE(g_pause_test_flag); 19211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes} 1933d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross 1943d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin CrossTEST(unistd, read) { 1953d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross int fd = open("/proc/version", O_RDONLY); 1963d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross ASSERT_TRUE(fd != -1); 1973d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross 1983d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross char buf[5]; 1993d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross ASSERT_EQ(5, read(fd, buf, 5)); 2003d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross ASSERT_EQ(buf[0], 'L'); 2013d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross ASSERT_EQ(buf[1], 'i'); 2023d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross ASSERT_EQ(buf[2], 'n'); 2033d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross ASSERT_EQ(buf[3], 'u'); 2043d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross ASSERT_EQ(buf[4], 'x'); 2053d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross close(fd); 2063d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross} 2073d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross 2083d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin CrossTEST(unistd, read_EBADF) { 2093d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross // read returns ssize_t which is 64-bits on LP64, so it's worth explicitly checking that 2103d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross // our syscall stubs correctly return a 64-bit -1. 2113d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross char buf[1]; 2123d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross ASSERT_EQ(-1, read(-1, buf, sizeof(buf))); 2133d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross ASSERT_EQ(EBADF, errno); 2143d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross} 215aedb00d04eb7f0b20b6abde702ba94a46577ca68Elliott Hughes 21678e4f8fed2c162f8ada55180e48487ef2180cf93Elliott HughesTEST(unistd, syscall_long) { 21778e4f8fed2c162f8ada55180e48487ef2180cf93Elliott Hughes // Check that syscall(3) correctly returns long results. 21878e4f8fed2c162f8ada55180e48487ef2180cf93Elliott Hughes // https://code.google.com/p/android/issues/detail?id=73952 21978e4f8fed2c162f8ada55180e48487ef2180cf93Elliott Hughes // We assume that the break is > 4GiB, but this is potentially flaky. 22078e4f8fed2c162f8ada55180e48487ef2180cf93Elliott Hughes uintptr_t p = reinterpret_cast<uintptr_t>(sbrk(0)); 22178e4f8fed2c162f8ada55180e48487ef2180cf93Elliott Hughes ASSERT_EQ(p, static_cast<uintptr_t>(syscall(__NR_brk, 0))); 22278e4f8fed2c162f8ada55180e48487ef2180cf93Elliott Hughes} 22378e4f8fed2c162f8ada55180e48487ef2180cf93Elliott Hughes 224aedb00d04eb7f0b20b6abde702ba94a46577ca68Elliott HughesTEST(unistd, alarm) { 225aedb00d04eb7f0b20b6abde702ba94a46577ca68Elliott Hughes ASSERT_EQ(0U, alarm(0)); 226aedb00d04eb7f0b20b6abde702ba94a46577ca68Elliott Hughes} 2279f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes 2289f525644df99cb2f7f81a23ca23840f0a8f82275Elliott HughesTEST(unistd, _exit) { 2299f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes int pid = fork(); 2309f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes ASSERT_NE(-1, pid) << strerror(errno); 2319f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes 2329f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes if (pid == 0) { 2339f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes _exit(99); 2349f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes } 2359f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes 2369f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes int status; 2379f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes ASSERT_EQ(pid, waitpid(pid, &status, 0)); 2389f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes ASSERT_TRUE(WIFEXITED(status)); 2399f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes ASSERT_EQ(99, WEXITSTATUS(status)); 2409f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes} 241cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 242cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, getenv_unsetenv) { 243cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov ASSERT_EQ(0, setenv("test-variable", "hello", 1)); 244cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov ASSERT_STREQ("hello", getenv("test-variable")); 245cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov ASSERT_EQ(0, unsetenv("test-variable")); 246cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov ASSERT_TRUE(getenv("test-variable") == NULL); 247cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov} 248cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 249cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, unsetenv_EINVAL) { 250cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(-1, unsetenv(NULL)); 251cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(EINVAL, errno); 252cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(-1, unsetenv("")); 253cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(EINVAL, errno); 254cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(-1, unsetenv("a=b")); 255cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(EINVAL, errno); 256cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov} 257cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 258cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, setenv_EINVAL) { 259cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(-1, setenv(NULL, "value", 0)); 260cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(EINVAL, errno); 261cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(-1, setenv(NULL, "value", 1)); 262cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(EINVAL, errno); 263cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(-1, setenv("", "value", 0)); 264cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(EINVAL, errno); 265cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(-1, setenv("", "value", 1)); 266cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(EINVAL, errno); 267cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(-1, setenv("a=b", "value", 0)); 268cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(EINVAL, errno); 269cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(-1, setenv("a=b", "value", 1)); 270cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(EINVAL, errno); 271cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov} 272cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 273cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, setenv) { 274cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov ASSERT_EQ(0, unsetenv("test-variable")); 275cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 276cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov char a[] = "a"; 277cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov char b[] = "b"; 278cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov char c[] = "c"; 279cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 280cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov // New value. 281cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(0, setenv("test-variable", a, 0)); 282cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_STREQ(a, getenv("test-variable")); 283cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 284cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov // Existing value, no overwrite. 285cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(0, setenv("test-variable", b, 0)); 286cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_STREQ(a, getenv("test-variable")); 287cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 288cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov // Existing value, overwrite. 289cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(0, setenv("test-variable", c, 1)); 290cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_STREQ(c, getenv("test-variable")); 291cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov // But the arrays backing the values are unchanged. 292cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ('a', a[0]); 293cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ('b', b[0]); 294cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ('c', c[0]); 295cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 296cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov ASSERT_EQ(0, unsetenv("test-variable")); 297cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov} 298cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 299cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, putenv) { 300cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov ASSERT_EQ(0, unsetenv("a")); 301cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 302cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov char* s1 = strdup("a=b"); 303cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov ASSERT_EQ(0, putenv(s1)); 304cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 305cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov ASSERT_STREQ("b", getenv("a")); 306cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov s1[2] = 'c'; 307cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov ASSERT_STREQ("c", getenv("a")); 308cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 309cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov char* s2 = strdup("a=b"); 310cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov ASSERT_EQ(0, putenv(s2)); 311cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 312cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov ASSERT_STREQ("b", getenv("a")); 313cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov ASSERT_EQ('c', s1[2]); 314cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 315cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov ASSERT_EQ(0, unsetenv("a")); 316cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov free(s1); 317cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov free(s2); 318cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov} 319cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 320cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, clearenv) { 321cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov extern char** environ; 322cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 323cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov // Guarantee that environ is not initially empty... 324cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov ASSERT_EQ(0, setenv("test-variable", "a", 1)); 325cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 326cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov // Stash a copy. 327cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov std::vector<char*> old_environ; 328cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov for (size_t i = 0; environ[i] != NULL; ++i) { 329cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov old_environ.push_back(strdup(environ[i])); 330cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov } 331cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 332cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov ASSERT_EQ(0, clearenv()); 333cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 334cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_TRUE(environ == NULL || environ[0] == NULL); 335cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(NULL, getenv("test-variable")); 336cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(0, setenv("test-variable", "post-clear", 1)); 337cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_STREQ("post-clear", getenv("test-variable")); 338cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 339cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov // Put the old environment back. 340cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov for (size_t i = 0; i < old_environ.size(); ++i) { 341cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(0, putenv(old_environ[i])); 342cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov } 343cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 344cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov // Check it wasn't overwritten. 345cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_STREQ("a", getenv("test-variable")); 346cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov 347cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov EXPECT_EQ(0, unsetenv("test-variable")); 348cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov} 349a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes 350a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughesstatic void TestFsyncFunction(int (*fn)(int)) { 351a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes int fd; 352a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes 353a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes // Can't sync an invalid fd. 354a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes errno = 0; 355a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes EXPECT_EQ(-1, fn(-1)); 356a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes EXPECT_EQ(EBADF, errno); 357a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes 358a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes // It doesn't matter whether you've opened a file for write or not. 359a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes TemporaryFile tf; 360a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes ASSERT_NE(-1, tf.fd); 361a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes 362a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes EXPECT_EQ(0, fn(tf.fd)); 363a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes 364a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes ASSERT_NE(-1, fd = open(tf.filename, O_RDONLY)); 365a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes EXPECT_EQ(0, fn(fd)); 366a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes close(fd); 367a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes 368a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes ASSERT_NE(-1, fd = open(tf.filename, O_RDWR)); 369a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes EXPECT_EQ(0, fn(fd)); 370a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes close(fd); 371a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes 372a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes // The fd can even be a directory. 373a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes ASSERT_NE(-1, fd = open("/", O_RDONLY)); 374a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes EXPECT_EQ(0, fn(fd)); 375a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes close(fd); 376a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes 377a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes // But some file systems may choose to be fussy... 378a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes errno = 0; 379a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes ASSERT_NE(-1, fd = open("/proc/version", O_RDONLY)); 380a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes EXPECT_EQ(-1, fn(fd)); 381a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes EXPECT_EQ(EINVAL, errno); 382a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes close(fd); 383a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes} 384a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes 385a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott HughesTEST(unistd, fdatasync) { 386a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes TestFsyncFunction(fdatasync); 387a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes} 388a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes 389a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott HughesTEST(unistd, fsync) { 390a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes TestFsyncFunction(fsync); 391a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes} 3927086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes 393fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughesstatic void AssertGetPidCorrect() { 394fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes // The loop is just to make manual testing/debugging with strace easier. 395fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes pid_t getpid_syscall_result = syscall(__NR_getpid); 396fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes for (size_t i = 0; i < 128; ++i) { 397fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes ASSERT_EQ(getpid_syscall_result, getpid()); 398fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes } 399fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes} 400fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes 4017086ad6919feb2415c6027163f5c63323bcca27cElliott HughesTEST(unistd, getpid_caching_and_fork) { 4027086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes pid_t parent_pid = getpid(); 4037086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes ASSERT_EQ(syscall(__NR_getpid), parent_pid); 4047086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes 4057086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes pid_t fork_result = fork(); 4067086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes ASSERT_NE(fork_result, -1); 4077086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes if (fork_result == 0) { 4087086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes // We're the child. 409fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes AssertGetPidCorrect(); 4107086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes ASSERT_EQ(parent_pid, getppid()); 4117086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes _exit(123); 4127086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes } else { 4137086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes // We're the parent. 4147086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes ASSERT_EQ(parent_pid, getpid()); 4157086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes 4167086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes int status; 4177086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes ASSERT_EQ(fork_result, waitpid(fork_result, &status, 0)); 4187086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes ASSERT_TRUE(WIFEXITED(status)); 4197086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes ASSERT_EQ(123, WEXITSTATUS(status)); 4207086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes } 4217086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes} 4227086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes 423fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughesstatic int GetPidCachingCloneStartRoutine(void*) { 424fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes AssertGetPidCorrect(); 425fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes return 123; 426fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes} 427fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes 428fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott HughesTEST(unistd, getpid_caching_and_clone) { 429fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes pid_t parent_pid = getpid(); 430fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes ASSERT_EQ(syscall(__NR_getpid), parent_pid); 431fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes 432fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes void* child_stack[1024]; 433fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes int clone_result = clone(GetPidCachingCloneStartRoutine, &child_stack[1024], CLONE_NEWNS | SIGCHLD, NULL); 43484d0683a824fa02dbaa6d1b56a79223804b54e80Elliott Hughes if (clone_result == -1 && errno == EPERM && getuid() != 0) { 43584d0683a824fa02dbaa6d1b56a79223804b54e80Elliott Hughes GTEST_LOG_(INFO) << "This test only works if you have permission to CLONE_NEWNS; try running as root.\n"; 43684d0683a824fa02dbaa6d1b56a79223804b54e80Elliott Hughes return; 43784d0683a824fa02dbaa6d1b56a79223804b54e80Elliott Hughes } 438fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes ASSERT_NE(clone_result, -1); 439fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes 440fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes ASSERT_EQ(parent_pid, getpid()); 441fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes 442fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes int status; 443fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes ASSERT_EQ(clone_result, waitpid(clone_result, &status, 0)); 444fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes ASSERT_TRUE(WIFEXITED(status)); 445fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes ASSERT_EQ(123, WEXITSTATUS(status)); 4467086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes} 4477086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes 448fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughesstatic void* GetPidCachingPthreadStartRoutine(void*) { 449fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes AssertGetPidCorrect(); 4507086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes return NULL; 4517086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes} 4527086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes 4537086ad6919feb2415c6027163f5c63323bcca27cElliott HughesTEST(unistd, getpid_caching_and_pthread_create) { 4547086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes pid_t parent_pid = getpid(); 4557086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes 4567086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes pthread_t t; 457fa9e16efaf0e885f6044e725eb759ef6de10f7efElliott Hughes ASSERT_EQ(0, pthread_create(&t, NULL, GetPidCachingPthreadStartRoutine, NULL)); 4587086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes 4597086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes ASSERT_EQ(parent_pid, getpid()); 4607086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes 4617086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes void* result; 4627086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes ASSERT_EQ(0, pthread_join(t, &result)); 4637086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes ASSERT_EQ(NULL, result); 4647086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes} 465