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