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