unistd_test.cpp revision 738b0cc5e95a9a650e9621603f4dd8dd16b07568
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <gtest/gtest.h>
18#include "ScopedSignalHandler.h"
19#include "TemporaryFile.h"
20
21#include <errno.h>
22#include <fcntl.h>
23#include <stdint.h>
24#include <unistd.h>
25#include <sys/types.h>
26#include <sys/wait.h>
27
28TEST(unistd, sysconf_SC_MONOTONIC_CLOCK) {
29  ASSERT_GT(sysconf(_SC_MONOTONIC_CLOCK), 0);
30}
31
32static void* get_brk() {
33  return sbrk(0);
34}
35
36static void* page_align(uintptr_t addr) {
37  uintptr_t mask = sysconf(_SC_PAGE_SIZE) - 1;
38  return reinterpret_cast<void*>((addr + mask) & ~mask);
39}
40
41TEST(unistd, brk) {
42  void* initial_break = get_brk();
43
44  // The kernel aligns the break to a page.
45  void* new_break = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(initial_break) + 1);
46  ASSERT_EQ(0, brk(new_break));
47  ASSERT_GE(get_brk(), new_break);
48
49  new_break = page_align(reinterpret_cast<uintptr_t>(initial_break) + sysconf(_SC_PAGE_SIZE));
50  ASSERT_EQ(0, brk(new_break));
51  ASSERT_EQ(get_brk(), new_break);
52}
53
54TEST(unistd, brk_ENOMEM) {
55  ASSERT_EQ(-1, brk(reinterpret_cast<void*>(-1)));
56  ASSERT_EQ(ENOMEM, errno);
57}
58
59#if defined(__GLIBC__)
60#define SBRK_MIN INTPTR_MIN
61#define SBRK_MAX INTPTR_MAX
62#else
63#define SBRK_MIN PTRDIFF_MIN
64#define SBRK_MAX PTRDIFF_MAX
65#endif
66
67TEST(unistd, sbrk_ENOMEM) {
68#if defined(__BIONIC__) && !defined(__LP64__)
69  // There is no way to guarantee that all overflow conditions can be tested
70  // without manipulating the underlying values of the current break.
71  extern void* __bionic_brk;
72
73  class ScopedBrk {
74  public:
75    ScopedBrk() : saved_brk_(__bionic_brk) {}
76    virtual ~ScopedBrk() { __bionic_brk = saved_brk_; }
77
78  private:
79    void* saved_brk_;
80  };
81
82  ScopedBrk scope_brk;
83
84  // Set the current break to a point that will cause an overflow.
85  __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) + 2);
86
87  // Can't increase by so much that we'd overflow.
88  ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MAX));
89  ASSERT_EQ(ENOMEM, errno);
90
91  // Set the current break to a point that will cause an overflow.
92  __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX));
93
94  ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN));
95  ASSERT_EQ(ENOMEM, errno);
96
97  __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) - 1);
98
99  ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN + 1));
100  ASSERT_EQ(ENOMEM, errno);
101#else
102  class ScopedBrk {
103  public:
104    ScopedBrk() : saved_brk_(get_brk()) {}
105    virtual ~ScopedBrk() { brk(saved_brk_); }
106
107  private:
108    void* saved_brk_;
109  };
110
111  ScopedBrk scope_brk;
112
113  uintptr_t cur_brk = reinterpret_cast<uintptr_t>(get_brk());
114  if (cur_brk < static_cast<uintptr_t>(-(SBRK_MIN+1))) {
115    // Do the overflow test for a max negative increment.
116    ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MIN));
117#if defined(__BIONIC__)
118    // GLIBC does not set errno in overflow case.
119    ASSERT_EQ(ENOMEM, errno);
120#endif
121  }
122
123  uintptr_t overflow_brk = static_cast<uintptr_t>(SBRK_MAX) + 2;
124  if (cur_brk < overflow_brk) {
125    // Try and move the value to PTRDIFF_MAX + 2.
126    cur_brk = reinterpret_cast<uintptr_t>(sbrk(overflow_brk));
127  }
128  if (cur_brk >= overflow_brk) {
129    ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MAX));
130#if defined(__BIONIC__)
131    // GLIBC does not set errno in overflow case.
132    ASSERT_EQ(ENOMEM, errno);
133#endif
134  }
135#endif
136}
137
138TEST(unistd, truncate) {
139  TemporaryFile tf;
140  ASSERT_EQ(0, close(tf.fd));
141  ASSERT_EQ(0, truncate(tf.filename, 123));
142
143  struct stat sb;
144  ASSERT_EQ(0, stat(tf.filename, &sb));
145  ASSERT_EQ(123, sb.st_size);
146}
147
148TEST(unistd, truncate64) {
149  TemporaryFile tf;
150  ASSERT_EQ(0, close(tf.fd));
151  ASSERT_EQ(0, truncate64(tf.filename, 123));
152
153  struct stat sb;
154  ASSERT_EQ(0, stat(tf.filename, &sb));
155  ASSERT_EQ(123, sb.st_size);
156}
157
158TEST(unistd, ftruncate) {
159  TemporaryFile tf;
160  ASSERT_EQ(0, ftruncate(tf.fd, 123));
161  ASSERT_EQ(0, close(tf.fd));
162
163  struct stat sb;
164  ASSERT_EQ(0, stat(tf.filename, &sb));
165  ASSERT_EQ(123, sb.st_size);
166}
167
168TEST(unistd, ftruncate64) {
169  TemporaryFile tf;
170  ASSERT_EQ(0, ftruncate64(tf.fd, 123));
171  ASSERT_EQ(0, close(tf.fd));
172
173  struct stat sb;
174  ASSERT_EQ(0, stat(tf.filename, &sb));
175  ASSERT_EQ(123, sb.st_size);
176}
177
178static bool g_pause_test_flag = false;
179static void PauseTestSignalHandler(int) {
180  g_pause_test_flag = true;
181}
182
183TEST(unistd, pause) {
184  ScopedSignalHandler handler(SIGALRM, PauseTestSignalHandler);
185
186  alarm(1);
187  ASSERT_FALSE(g_pause_test_flag);
188  ASSERT_EQ(-1, pause());
189  ASSERT_TRUE(g_pause_test_flag);
190}
191
192TEST(unistd, read) {
193  int fd = open("/proc/version", O_RDONLY);
194  ASSERT_TRUE(fd != -1);
195
196  char buf[5];
197  ASSERT_EQ(5, read(fd, buf, 5));
198  ASSERT_EQ(buf[0], 'L');
199  ASSERT_EQ(buf[1], 'i');
200  ASSERT_EQ(buf[2], 'n');
201  ASSERT_EQ(buf[3], 'u');
202  ASSERT_EQ(buf[4], 'x');
203  close(fd);
204}
205
206TEST(unistd, read_EBADF) {
207  // read returns ssize_t which is 64-bits on LP64, so it's worth explicitly checking that
208  // our syscall stubs correctly return a 64-bit -1.
209  char buf[1];
210  ASSERT_EQ(-1, read(-1, buf, sizeof(buf)));
211  ASSERT_EQ(EBADF, errno);
212}
213
214TEST(unistd, alarm) {
215  ASSERT_EQ(0U, alarm(0));
216}
217
218TEST(unistd, _exit) {
219  int pid = fork();
220  ASSERT_NE(-1, pid) << strerror(errno);
221
222  if (pid == 0) {
223    _exit(99);
224  }
225
226  int status;
227  ASSERT_EQ(pid, waitpid(pid, &status, 0));
228  ASSERT_TRUE(WIFEXITED(status));
229  ASSERT_EQ(99, WEXITSTATUS(status));
230}
231
232TEST(unistd, getenv_unsetenv) {
233  ASSERT_EQ(0, setenv("test-variable", "hello", 1));
234  ASSERT_STREQ("hello", getenv("test-variable"));
235  ASSERT_EQ(0, unsetenv("test-variable"));
236  ASSERT_TRUE(getenv("test-variable") == NULL);
237}
238
239TEST(unistd, unsetenv_EINVAL) {
240  EXPECT_EQ(-1, unsetenv(NULL));
241  EXPECT_EQ(EINVAL, errno);
242  EXPECT_EQ(-1, unsetenv(""));
243  EXPECT_EQ(EINVAL, errno);
244  EXPECT_EQ(-1, unsetenv("a=b"));
245  EXPECT_EQ(EINVAL, errno);
246}
247
248TEST(unistd, setenv_EINVAL) {
249  EXPECT_EQ(-1, setenv(NULL, "value", 0));
250  EXPECT_EQ(EINVAL, errno);
251  EXPECT_EQ(-1, setenv(NULL, "value", 1));
252  EXPECT_EQ(EINVAL, errno);
253  EXPECT_EQ(-1, setenv("", "value", 0));
254  EXPECT_EQ(EINVAL, errno);
255  EXPECT_EQ(-1, setenv("", "value", 1));
256  EXPECT_EQ(EINVAL, errno);
257  EXPECT_EQ(-1, setenv("a=b", "value", 0));
258  EXPECT_EQ(EINVAL, errno);
259  EXPECT_EQ(-1, setenv("a=b", "value", 1));
260  EXPECT_EQ(EINVAL, errno);
261}
262
263TEST(unistd, setenv) {
264  ASSERT_EQ(0, unsetenv("test-variable"));
265
266  char a[] = "a";
267  char b[] = "b";
268  char c[] = "c";
269
270  // New value.
271  EXPECT_EQ(0, setenv("test-variable", a, 0));
272  EXPECT_STREQ(a, getenv("test-variable"));
273
274  // Existing value, no overwrite.
275  EXPECT_EQ(0, setenv("test-variable", b, 0));
276  EXPECT_STREQ(a, getenv("test-variable"));
277
278  // Existing value, overwrite.
279  EXPECT_EQ(0, setenv("test-variable", c, 1));
280  EXPECT_STREQ(c, getenv("test-variable"));
281  // But the arrays backing the values are unchanged.
282  EXPECT_EQ('a', a[0]);
283  EXPECT_EQ('b', b[0]);
284  EXPECT_EQ('c', c[0]);
285
286  ASSERT_EQ(0, unsetenv("test-variable"));
287}
288
289TEST(unistd, putenv) {
290  ASSERT_EQ(0, unsetenv("a"));
291
292  char* s1 = strdup("a=b");
293  ASSERT_EQ(0, putenv(s1));
294
295  ASSERT_STREQ("b", getenv("a"));
296  s1[2] = 'c';
297  ASSERT_STREQ("c", getenv("a"));
298
299  char* s2 = strdup("a=b");
300  ASSERT_EQ(0, putenv(s2));
301
302  ASSERT_STREQ("b", getenv("a"));
303  ASSERT_EQ('c', s1[2]);
304
305  ASSERT_EQ(0, unsetenv("a"));
306  free(s1);
307  free(s2);
308}
309
310TEST(unistd, clearenv) {
311  extern char** environ;
312
313  // Guarantee that environ is not initially empty...
314  ASSERT_EQ(0, setenv("test-variable", "a", 1));
315
316  // Stash a copy.
317  std::vector<char*> old_environ;
318  for (size_t i = 0; environ[i] != NULL; ++i) {
319    old_environ.push_back(strdup(environ[i]));
320  }
321
322  ASSERT_EQ(0, clearenv());
323
324  EXPECT_TRUE(environ == NULL || environ[0] == NULL);
325  EXPECT_EQ(NULL, getenv("test-variable"));
326  EXPECT_EQ(0, setenv("test-variable", "post-clear", 1));
327  EXPECT_STREQ("post-clear", getenv("test-variable"));
328
329  // Put the old environment back.
330  for (size_t i = 0; i < old_environ.size(); ++i) {
331    EXPECT_EQ(0, putenv(old_environ[i]));
332  }
333
334  // Check it wasn't overwritten.
335  EXPECT_STREQ("a", getenv("test-variable"));
336
337  EXPECT_EQ(0, unsetenv("test-variable"));
338}
339
340static void TestFsyncFunction(int (*fn)(int)) {
341  int fd;
342
343  // Can't sync an invalid fd.
344  errno = 0;
345  EXPECT_EQ(-1, fn(-1));
346  EXPECT_EQ(EBADF, errno);
347
348  // It doesn't matter whether you've opened a file for write or not.
349  TemporaryFile tf;
350  ASSERT_NE(-1, tf.fd);
351
352  EXPECT_EQ(0, fn(tf.fd));
353
354  ASSERT_NE(-1, fd = open(tf.filename, O_RDONLY));
355  EXPECT_EQ(0, fn(fd));
356  close(fd);
357
358  ASSERT_NE(-1, fd = open(tf.filename, O_RDWR));
359  EXPECT_EQ(0, fn(fd));
360  close(fd);
361
362  // The fd can even be a directory.
363  ASSERT_NE(-1, fd = open("/", O_RDONLY));
364  EXPECT_EQ(0, fn(fd));
365  close(fd);
366
367  // But some file systems may choose to be fussy...
368  errno = 0;
369  ASSERT_NE(-1, fd = open("/proc/version", O_RDONLY));
370  EXPECT_EQ(-1, fn(fd));
371  EXPECT_EQ(EINVAL, errno);
372  close(fd);
373}
374
375TEST(unistd, fdatasync) {
376  TestFsyncFunction(fdatasync);
377}
378
379TEST(unistd, fsync) {
380  TestFsyncFunction(fsync);
381}
382