unistd_test.cpp revision 7086ad6919feb2415c6027163f5c63323bcca27c
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>
23428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes#include <stdint.h>
24a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes#include <unistd.h>
257086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes#include <sys/syscall.h>
26764a99361130dceda62bbc4f8780bbf395dbc424Elliott Hughes#include <sys/types.h>
27764a99361130dceda62bbc4f8780bbf395dbc424Elliott Hughes#include <sys/wait.h>
28a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes
29a55f63083fb16b2595f517a3260083e5f8cddd02Elliott HughesTEST(unistd, sysconf_SC_MONOTONIC_CLOCK) {
30a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes  ASSERT_GT(sysconf(_SC_MONOTONIC_CLOCK), 0);
31a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes}
32428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes
33533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughesstatic void* get_brk() {
34533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  return sbrk(0);
35533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes}
36533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes
37533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughesstatic void* page_align(uintptr_t addr) {
38533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  uintptr_t mask = sysconf(_SC_PAGE_SIZE) - 1;
39533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  return reinterpret_cast<void*>((addr + mask) & ~mask);
40533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes}
41533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes
42533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott HughesTEST(unistd, brk) {
43533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  void* initial_break = get_brk();
44533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes
45533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  // The kernel aligns the break to a page.
46533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  void* new_break = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(initial_break) + 1);
47533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  ASSERT_EQ(0, brk(new_break));
48533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  ASSERT_GE(get_brk(), new_break);
49428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes
50533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  new_break = page_align(reinterpret_cast<uintptr_t>(initial_break) + sysconf(_SC_PAGE_SIZE));
51428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes  ASSERT_EQ(0, brk(new_break));
52533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  ASSERT_EQ(get_brk(), new_break);
53533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes}
54533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes
55533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott HughesTEST(unistd, brk_ENOMEM) {
56533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  ASSERT_EQ(-1, brk(reinterpret_cast<void*>(-1)));
57533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  ASSERT_EQ(ENOMEM, errno);
58533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes}
59533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes
60738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#if defined(__GLIBC__)
61738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#define SBRK_MIN INTPTR_MIN
62738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#define SBRK_MAX INTPTR_MAX
63738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#else
64738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#define SBRK_MIN PTRDIFF_MIN
65738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#define SBRK_MAX PTRDIFF_MAX
66738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#endif
67738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris
68533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott HughesTEST(unistd, sbrk_ENOMEM) {
69738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#if defined(__BIONIC__) && !defined(__LP64__)
70738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  // There is no way to guarantee that all overflow conditions can be tested
71738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  // without manipulating the underlying values of the current break.
72738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  extern void* __bionic_brk;
73738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris
74738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  class ScopedBrk {
75738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  public:
76738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris    ScopedBrk() : saved_brk_(__bionic_brk) {}
77738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris    virtual ~ScopedBrk() { __bionic_brk = saved_brk_; }
78738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris
79738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  private:
80738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris    void* saved_brk_;
81738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  };
82738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris
83738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  ScopedBrk scope_brk;
84738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris
85738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  // Set the current break to a point that will cause an overflow.
86738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) + 2);
87533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes
88533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  // Can't increase by so much that we'd overflow.
89533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MAX));
90533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  ASSERT_EQ(ENOMEM, errno);
91533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes
92738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  // Set the current break to a point that will cause an overflow.
93738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX));
94428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes
95533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN));
96533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes  ASSERT_EQ(ENOMEM, errno);
97738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris
98738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) - 1);
99738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris
100738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN + 1));
101738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  ASSERT_EQ(ENOMEM, errno);
102738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#else
103738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  class ScopedBrk {
104738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  public:
105738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris    ScopedBrk() : saved_brk_(get_brk()) {}
106738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris    virtual ~ScopedBrk() { brk(saved_brk_); }
107738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris
108738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  private:
109738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris    void* saved_brk_;
110738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  };
111738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris
112738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  ScopedBrk scope_brk;
113738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris
114738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  uintptr_t cur_brk = reinterpret_cast<uintptr_t>(get_brk());
115738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  if (cur_brk < static_cast<uintptr_t>(-(SBRK_MIN+1))) {
116738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris    // Do the overflow test for a max negative increment.
117738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris    ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MIN));
118738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#if defined(__BIONIC__)
119738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris    // GLIBC does not set errno in overflow case.
120738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris    ASSERT_EQ(ENOMEM, errno);
121738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#endif
122738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  }
123738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris
124738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  uintptr_t overflow_brk = static_cast<uintptr_t>(SBRK_MAX) + 2;
125738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  if (cur_brk < overflow_brk) {
126738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris    // Try and move the value to PTRDIFF_MAX + 2.
127738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris    cur_brk = reinterpret_cast<uintptr_t>(sbrk(overflow_brk));
128738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  }
129738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  if (cur_brk >= overflow_brk) {
130738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris    ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MAX));
131738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#if defined(__BIONIC__)
132738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris    // GLIBC does not set errno in overflow case.
133738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris    ASSERT_EQ(ENOMEM, errno);
134738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris#endif
135738b0cc5e95a9a650e9621603f4dd8dd16b07568Christopher Ferris  }
136533dde4dbf87d6615952be3654fc74e5ff2e1003Elliott Hughes#endif
137428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes}
138b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
139b4f7616fd618875768b8fffc122b58bdb84a9969Elliott HughesTEST(unistd, truncate) {
140b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  TemporaryFile tf;
141b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, close(tf.fd));
142b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, truncate(tf.filename, 123));
143b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
144b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  struct stat sb;
145b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, stat(tf.filename, &sb));
146b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(123, sb.st_size);
147b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes}
148b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
149b4f7616fd618875768b8fffc122b58bdb84a9969Elliott HughesTEST(unistd, truncate64) {
150b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  TemporaryFile tf;
151b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, close(tf.fd));
152b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, truncate64(tf.filename, 123));
153b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
154b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  struct stat sb;
155b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, stat(tf.filename, &sb));
156b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(123, sb.st_size);
157b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes}
158b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
159b4f7616fd618875768b8fffc122b58bdb84a9969Elliott HughesTEST(unistd, ftruncate) {
160b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  TemporaryFile tf;
161b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, ftruncate(tf.fd, 123));
162b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, close(tf.fd));
163b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
164b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  struct stat sb;
165b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, stat(tf.filename, &sb));
166b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(123, sb.st_size);
167b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes}
168b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
169b4f7616fd618875768b8fffc122b58bdb84a9969Elliott HughesTEST(unistd, ftruncate64) {
170b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  TemporaryFile tf;
171b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, ftruncate64(tf.fd, 123));
172b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, close(tf.fd));
173b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
174b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  struct stat sb;
175b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, stat(tf.filename, &sb));
176b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(123, sb.st_size);
177b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes}
17811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
1791728b2396591853345507a063ed6075dfd251706Elliott Hughesstatic bool g_pause_test_flag = false;
18011952073af22568bba0b661f7a9d4402c443a888Elliott Hughesstatic void PauseTestSignalHandler(int) {
1811728b2396591853345507a063ed6075dfd251706Elliott Hughes  g_pause_test_flag = true;
18211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes}
18311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
18411952073af22568bba0b661f7a9d4402c443a888Elliott HughesTEST(unistd, pause) {
18513613137bc4266656bffce464e525eb9ae6371f0Christopher Ferris  ScopedSignalHandler handler(SIGALRM, PauseTestSignalHandler);
18613613137bc4266656bffce464e525eb9ae6371f0Christopher Ferris
18711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  alarm(1);
1881728b2396591853345507a063ed6075dfd251706Elliott Hughes  ASSERT_FALSE(g_pause_test_flag);
18911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  ASSERT_EQ(-1, pause());
1901728b2396591853345507a063ed6075dfd251706Elliott Hughes  ASSERT_TRUE(g_pause_test_flag);
19111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes}
1923d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross
1933d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin CrossTEST(unistd, read) {
1943d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  int fd = open("/proc/version", O_RDONLY);
1953d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_TRUE(fd != -1);
1963d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross
1973d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  char buf[5];
1983d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_EQ(5, read(fd, buf, 5));
1993d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_EQ(buf[0], 'L');
2003d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_EQ(buf[1], 'i');
2013d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_EQ(buf[2], 'n');
2023d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_EQ(buf[3], 'u');
2033d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_EQ(buf[4], 'x');
2043d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  close(fd);
2053d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross}
2063d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross
2073d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin CrossTEST(unistd, read_EBADF) {
2083d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  // read returns ssize_t which is 64-bits on LP64, so it's worth explicitly checking that
2093d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  // our syscall stubs correctly return a 64-bit -1.
2103d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  char buf[1];
2113d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_EQ(-1, read(-1, buf, sizeof(buf)));
2123d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_EQ(EBADF, errno);
2133d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross}
214aedb00d04eb7f0b20b6abde702ba94a46577ca68Elliott Hughes
215aedb00d04eb7f0b20b6abde702ba94a46577ca68Elliott HughesTEST(unistd, alarm) {
216aedb00d04eb7f0b20b6abde702ba94a46577ca68Elliott Hughes  ASSERT_EQ(0U, alarm(0));
217aedb00d04eb7f0b20b6abde702ba94a46577ca68Elliott Hughes}
2189f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes
2199f525644df99cb2f7f81a23ca23840f0a8f82275Elliott HughesTEST(unistd, _exit) {
2209f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  int pid = fork();
2219f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  ASSERT_NE(-1, pid) << strerror(errno);
2229f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes
2239f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  if (pid == 0) {
2249f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes    _exit(99);
2259f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  }
2269f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes
2279f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  int status;
2289f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  ASSERT_EQ(pid, waitpid(pid, &status, 0));
2299f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  ASSERT_TRUE(WIFEXITED(status));
2309f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  ASSERT_EQ(99, WEXITSTATUS(status));
2319f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes}
232cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
233cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, getenv_unsetenv) {
234cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, setenv("test-variable", "hello", 1));
235cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_STREQ("hello", getenv("test-variable"));
236cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, unsetenv("test-variable"));
237cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_TRUE(getenv("test-variable") == NULL);
238cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov}
239cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
240cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, unsetenv_EINVAL) {
241cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, unsetenv(NULL));
242cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
243cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, unsetenv(""));
244cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
245cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, unsetenv("a=b"));
246cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
247cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov}
248cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
249cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, setenv_EINVAL) {
250cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, setenv(NULL, "value", 0));
251cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
252cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, setenv(NULL, "value", 1));
253cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
254cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, setenv("", "value", 0));
255cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
256cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, setenv("", "value", 1));
257cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
258cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, setenv("a=b", "value", 0));
259cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
260cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, setenv("a=b", "value", 1));
261cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
262cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov}
263cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
264cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, setenv) {
265cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, unsetenv("test-variable"));
266cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
267cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  char a[] = "a";
268cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  char b[] = "b";
269cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  char c[] = "c";
270cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
271cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  // New value.
272cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(0, setenv("test-variable", a, 0));
273cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_STREQ(a, getenv("test-variable"));
274cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
275cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  // Existing value, no overwrite.
276cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(0, setenv("test-variable", b, 0));
277cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_STREQ(a, getenv("test-variable"));
278cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
279cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  // Existing value, overwrite.
280cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(0, setenv("test-variable", c, 1));
281cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_STREQ(c, getenv("test-variable"));
282cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  // But the arrays backing the values are unchanged.
283cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ('a', a[0]);
284cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ('b', b[0]);
285cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ('c', c[0]);
286cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
287cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, unsetenv("test-variable"));
288cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov}
289cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
290cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, putenv) {
291cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, unsetenv("a"));
292cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
293cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  char* s1 = strdup("a=b");
294cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, putenv(s1));
295cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
296cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_STREQ("b", getenv("a"));
297cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  s1[2] = 'c';
298cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_STREQ("c", getenv("a"));
299cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
300cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  char* s2 = strdup("a=b");
301cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, putenv(s2));
302cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
303cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_STREQ("b", getenv("a"));
304cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ('c', s1[2]);
305cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
306cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, unsetenv("a"));
307cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  free(s1);
308cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  free(s2);
309cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov}
310cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
311cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, clearenv) {
312cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  extern char** environ;
313cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
314cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  // Guarantee that environ is not initially empty...
315cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, setenv("test-variable", "a", 1));
316cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
317cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  // Stash a copy.
318cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  std::vector<char*> old_environ;
319cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  for (size_t i = 0; environ[i] != NULL; ++i) {
320cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov    old_environ.push_back(strdup(environ[i]));
321cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  }
322cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
323cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, clearenv());
324cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
325cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_TRUE(environ == NULL || environ[0] == NULL);
326cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(NULL, getenv("test-variable"));
327cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(0, setenv("test-variable", "post-clear", 1));
328cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_STREQ("post-clear", getenv("test-variable"));
329cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
330cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  // Put the old environment back.
331cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  for (size_t i = 0; i < old_environ.size(); ++i) {
332cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov    EXPECT_EQ(0, putenv(old_environ[i]));
333cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  }
334cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
335cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  // Check it wasn't overwritten.
336cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_STREQ("a", getenv("test-variable"));
337cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
338cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(0, unsetenv("test-variable"));
339cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov}
340a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes
341a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughesstatic void TestFsyncFunction(int (*fn)(int)) {
342a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  int fd;
343a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes
344a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  // Can't sync an invalid fd.
345a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  errno = 0;
346a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  EXPECT_EQ(-1, fn(-1));
347a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  EXPECT_EQ(EBADF, errno);
348a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes
349a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  // It doesn't matter whether you've opened a file for write or not.
350a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  TemporaryFile tf;
351a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  ASSERT_NE(-1, tf.fd);
352a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes
353a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  EXPECT_EQ(0, fn(tf.fd));
354a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes
355a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  ASSERT_NE(-1, fd = open(tf.filename, O_RDONLY));
356a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  EXPECT_EQ(0, fn(fd));
357a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  close(fd);
358a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes
359a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  ASSERT_NE(-1, fd = open(tf.filename, O_RDWR));
360a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  EXPECT_EQ(0, fn(fd));
361a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  close(fd);
362a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes
363a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  // The fd can even be a directory.
364a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  ASSERT_NE(-1, fd = open("/", O_RDONLY));
365a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  EXPECT_EQ(0, fn(fd));
366a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  close(fd);
367a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes
368a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  // But some file systems may choose to be fussy...
369a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  errno = 0;
370a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  ASSERT_NE(-1, fd = open("/proc/version", O_RDONLY));
371a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  EXPECT_EQ(-1, fn(fd));
372a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  EXPECT_EQ(EINVAL, errno);
373a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  close(fd);
374a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes}
375a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes
376a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott HughesTEST(unistd, fdatasync) {
377a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  TestFsyncFunction(fdatasync);
378a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes}
379a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes
380a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott HughesTEST(unistd, fsync) {
381a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes  TestFsyncFunction(fsync);
382a62a28d1d9c8df7cb77e4bca19814922729b5291Elliott Hughes}
3837086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
3847086ad6919feb2415c6027163f5c63323bcca27cElliott HughesTEST(unistd, getpid_caching_and_fork) {
3857086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  pid_t parent_pid = getpid();
3867086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  ASSERT_EQ(syscall(__NR_getpid), parent_pid);
3877086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
3887086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  pid_t fork_result = fork();
3897086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  ASSERT_NE(fork_result, -1);
3907086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  if (fork_result == 0) {
3917086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    // We're the child.
3927086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    ASSERT_EQ(syscall(__NR_getpid), getpid());
3937086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    ASSERT_EQ(parent_pid, getppid());
3947086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    _exit(123);
3957086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  } else {
3967086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    // We're the parent.
3977086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    ASSERT_EQ(parent_pid, getpid());
3987086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
3997086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    int status;
4007086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    ASSERT_EQ(fork_result, waitpid(fork_result, &status, 0));
4017086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    ASSERT_TRUE(WIFEXITED(status));
4027086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    ASSERT_EQ(123, WEXITSTATUS(status));
4037086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  }
4047086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes}
4057086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
4067086ad6919feb2415c6027163f5c63323bcca27cElliott Hughesstatic void GetPidCachingHelperHelper() {
4077086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  ASSERT_EQ(syscall(__NR_getpid), getpid());
4087086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes}
4097086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
4107086ad6919feb2415c6027163f5c63323bcca27cElliott Hughesstatic void* GetPidCachingHelper(void*) {
4117086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  GetPidCachingHelperHelper(); // Can't assert in a non-void function.
4127086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  return NULL;
4137086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes}
4147086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
4157086ad6919feb2415c6027163f5c63323bcca27cElliott HughesTEST(unistd, getpid_caching_and_pthread_create) {
4167086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  pid_t parent_pid = getpid();
4177086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
4187086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  pthread_t t;
4197086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  ASSERT_EQ(0, pthread_create(&t, NULL, GetPidCachingHelper, NULL));
4207086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
4217086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  ASSERT_EQ(parent_pid, getpid());
4227086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
4237086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  void* result;
4247086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  ASSERT_EQ(0, pthread_join(t, &result));
4257086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  ASSERT_EQ(NULL, result);
4267086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes}
427