blob: 19d4017733bf8a1fdf8d7bb2532ea5841cc98805 [file] [log] [blame]
Elliott Hughesa55f6302013-01-02 14:23:43 -08001/*
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>
Yabin Cui9df70402014-11-05 18:01:01 -080018#include "BionicDeathTest.h"
Christopher Ferris13613132013-10-28 15:24:04 -070019#include "ScopedSignalHandler.h"
Elliott Hughesb4f76162013-09-19 16:27:24 -070020#include "TemporaryFile.h"
Elliott Hughesa55f6302013-01-02 14:23:43 -080021
Elliott Hughes915fefb2014-02-18 12:34:51 -080022#include <errno.h>
Colin Cross3d19a832014-02-14 18:56:23 -080023#include <fcntl.h>
Elliott Hughes21972b62014-07-28 12:24:22 -070024#include <limits.h>
Elliott Hughes428f5562013-02-05 16:10:59 -080025#include <stdint.h>
Elliott Hughes7086ad62014-06-19 16:39:01 -070026#include <sys/syscall.h>
Elliott Hughes764a9932014-04-08 19:44:36 -070027#include <sys/types.h>
Derek Xued94e7f02014-09-25 11:12:01 +010028#include <sys/utsname.h>
Elliott Hughes764a9932014-04-08 19:44:36 -070029#include <sys/wait.h>
Yabin Cui9df70402014-11-05 18:01:01 -080030#include <unistd.h>
31
Elliott Hughesa55f6302013-01-02 14:23:43 -080032
33TEST(unistd, sysconf_SC_MONOTONIC_CLOCK) {
34 ASSERT_GT(sysconf(_SC_MONOTONIC_CLOCK), 0);
35}
Elliott Hughes428f5562013-02-05 16:10:59 -080036
Elliott Hughes533dde42014-04-25 18:27:38 -070037static void* get_brk() {
38 return sbrk(0);
39}
Elliott Hughes428f5562013-02-05 16:10:59 -080040
Elliott Hughes533dde42014-04-25 18:27:38 -070041static void* page_align(uintptr_t addr) {
42 uintptr_t mask = sysconf(_SC_PAGE_SIZE) - 1;
43 return reinterpret_cast<void*>((addr + mask) & ~mask);
44}
45
46TEST(unistd, brk) {
47 void* initial_break = get_brk();
48
49 // The kernel aligns the break to a page.
50 void* new_break = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(initial_break) + 1);
Elliott Hughes428f5562013-02-05 16:10:59 -080051 ASSERT_EQ(0, brk(new_break));
Elliott Hughes533dde42014-04-25 18:27:38 -070052 ASSERT_GE(get_brk(), new_break);
Elliott Hughes428f5562013-02-05 16:10:59 -080053
Elliott Hughes533dde42014-04-25 18:27:38 -070054 new_break = page_align(reinterpret_cast<uintptr_t>(initial_break) + sysconf(_SC_PAGE_SIZE));
55 ASSERT_EQ(0, brk(new_break));
56 ASSERT_EQ(get_brk(), new_break);
57}
58
59TEST(unistd, brk_ENOMEM) {
60 ASSERT_EQ(-1, brk(reinterpret_cast<void*>(-1)));
61 ASSERT_EQ(ENOMEM, errno);
62}
63
Christopher Ferris738b0cc2014-05-21 19:03:34 -070064#if defined(__GLIBC__)
65#define SBRK_MIN INTPTR_MIN
66#define SBRK_MAX INTPTR_MAX
67#else
68#define SBRK_MIN PTRDIFF_MIN
69#define SBRK_MAX PTRDIFF_MAX
70#endif
71
Elliott Hughes533dde42014-04-25 18:27:38 -070072TEST(unistd, sbrk_ENOMEM) {
Christopher Ferris738b0cc2014-05-21 19:03:34 -070073#if defined(__BIONIC__) && !defined(__LP64__)
74 // There is no way to guarantee that all overflow conditions can be tested
75 // without manipulating the underlying values of the current break.
76 extern void* __bionic_brk;
77
78 class ScopedBrk {
79 public:
80 ScopedBrk() : saved_brk_(__bionic_brk) {}
81 virtual ~ScopedBrk() { __bionic_brk = saved_brk_; }
82
83 private:
84 void* saved_brk_;
85 };
86
87 ScopedBrk scope_brk;
88
89 // Set the current break to a point that will cause an overflow.
90 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) + 2);
Elliott Hughes533dde42014-04-25 18:27:38 -070091
92 // Can't increase by so much that we'd overflow.
93 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MAX));
94 ASSERT_EQ(ENOMEM, errno);
95
Christopher Ferris738b0cc2014-05-21 19:03:34 -070096 // Set the current break to a point that will cause an overflow.
97 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX));
Elliott Hughes533dde42014-04-25 18:27:38 -070098
Elliott Hughes533dde42014-04-25 18:27:38 -070099 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN));
100 ASSERT_EQ(ENOMEM, errno);
Christopher Ferris738b0cc2014-05-21 19:03:34 -0700101
102 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) - 1);
103
104 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN + 1));
105 ASSERT_EQ(ENOMEM, errno);
106#else
107 class ScopedBrk {
108 public:
109 ScopedBrk() : saved_brk_(get_brk()) {}
110 virtual ~ScopedBrk() { brk(saved_brk_); }
111
112 private:
113 void* saved_brk_;
114 };
115
116 ScopedBrk scope_brk;
117
118 uintptr_t cur_brk = reinterpret_cast<uintptr_t>(get_brk());
119 if (cur_brk < static_cast<uintptr_t>(-(SBRK_MIN+1))) {
120 // Do the overflow test for a max negative increment.
121 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MIN));
122#if defined(__BIONIC__)
123 // GLIBC does not set errno in overflow case.
124 ASSERT_EQ(ENOMEM, errno);
125#endif
126 }
127
128 uintptr_t overflow_brk = static_cast<uintptr_t>(SBRK_MAX) + 2;
129 if (cur_brk < overflow_brk) {
130 // Try and move the value to PTRDIFF_MAX + 2.
131 cur_brk = reinterpret_cast<uintptr_t>(sbrk(overflow_brk));
132 }
133 if (cur_brk >= overflow_brk) {
134 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MAX));
135#if defined(__BIONIC__)
136 // GLIBC does not set errno in overflow case.
137 ASSERT_EQ(ENOMEM, errno);
138#endif
139 }
Elliott Hughes533dde42014-04-25 18:27:38 -0700140#endif
Elliott Hughes428f5562013-02-05 16:10:59 -0800141}
Elliott Hughesb4f76162013-09-19 16:27:24 -0700142
143TEST(unistd, truncate) {
144 TemporaryFile tf;
145 ASSERT_EQ(0, close(tf.fd));
146 ASSERT_EQ(0, truncate(tf.filename, 123));
147
148 struct stat sb;
149 ASSERT_EQ(0, stat(tf.filename, &sb));
150 ASSERT_EQ(123, sb.st_size);
151}
152
153TEST(unistd, truncate64) {
154 TemporaryFile tf;
155 ASSERT_EQ(0, close(tf.fd));
156 ASSERT_EQ(0, truncate64(tf.filename, 123));
157
158 struct stat sb;
159 ASSERT_EQ(0, stat(tf.filename, &sb));
160 ASSERT_EQ(123, sb.st_size);
161}
162
163TEST(unistd, ftruncate) {
164 TemporaryFile tf;
165 ASSERT_EQ(0, ftruncate(tf.fd, 123));
166 ASSERT_EQ(0, close(tf.fd));
167
168 struct stat sb;
169 ASSERT_EQ(0, stat(tf.filename, &sb));
170 ASSERT_EQ(123, sb.st_size);
171}
172
173TEST(unistd, ftruncate64) {
174 TemporaryFile tf;
175 ASSERT_EQ(0, ftruncate64(tf.fd, 123));
176 ASSERT_EQ(0, close(tf.fd));
177
178 struct stat sb;
179 ASSERT_EQ(0, stat(tf.filename, &sb));
180 ASSERT_EQ(123, sb.st_size);
181}
Elliott Hughes11952072013-10-24 15:15:14 -0700182
Elliott Hughes1728b232014-05-14 10:02:03 -0700183static bool g_pause_test_flag = false;
Elliott Hughes11952072013-10-24 15:15:14 -0700184static void PauseTestSignalHandler(int) {
Elliott Hughes1728b232014-05-14 10:02:03 -0700185 g_pause_test_flag = true;
Elliott Hughes11952072013-10-24 15:15:14 -0700186}
187
188TEST(unistd, pause) {
Christopher Ferris13613132013-10-28 15:24:04 -0700189 ScopedSignalHandler handler(SIGALRM, PauseTestSignalHandler);
190
Elliott Hughes11952072013-10-24 15:15:14 -0700191 alarm(1);
Elliott Hughes1728b232014-05-14 10:02:03 -0700192 ASSERT_FALSE(g_pause_test_flag);
Elliott Hughes11952072013-10-24 15:15:14 -0700193 ASSERT_EQ(-1, pause());
Elliott Hughes1728b232014-05-14 10:02:03 -0700194 ASSERT_TRUE(g_pause_test_flag);
Elliott Hughes11952072013-10-24 15:15:14 -0700195}
Colin Cross3d19a832014-02-14 18:56:23 -0800196
197TEST(unistd, read) {
198 int fd = open("/proc/version", O_RDONLY);
199 ASSERT_TRUE(fd != -1);
200
201 char buf[5];
202 ASSERT_EQ(5, read(fd, buf, 5));
203 ASSERT_EQ(buf[0], 'L');
204 ASSERT_EQ(buf[1], 'i');
205 ASSERT_EQ(buf[2], 'n');
206 ASSERT_EQ(buf[3], 'u');
207 ASSERT_EQ(buf[4], 'x');
208 close(fd);
209}
210
211TEST(unistd, read_EBADF) {
212 // read returns ssize_t which is 64-bits on LP64, so it's worth explicitly checking that
213 // our syscall stubs correctly return a 64-bit -1.
214 char buf[1];
215 ASSERT_EQ(-1, read(-1, buf, sizeof(buf)));
216 ASSERT_EQ(EBADF, errno);
217}
Elliott Hughesaedb00d2014-03-03 14:38:20 -0800218
Elliott Hughes21972b62014-07-28 12:24:22 -0700219TEST(unistd, syscall_long) {
220 // Check that syscall(3) correctly returns long results.
221 // https://code.google.com/p/android/issues/detail?id=73952
222 // We assume that the break is > 4GiB, but this is potentially flaky.
223 uintptr_t p = reinterpret_cast<uintptr_t>(sbrk(0));
224 ASSERT_EQ(p, static_cast<uintptr_t>(syscall(__NR_brk, 0)));
225}
226
Elliott Hughesaedb00d2014-03-03 14:38:20 -0800227TEST(unistd, alarm) {
228 ASSERT_EQ(0U, alarm(0));
229}
Elliott Hughes9f525642014-04-08 17:14:01 -0700230
231TEST(unistd, _exit) {
232 int pid = fork();
233 ASSERT_NE(-1, pid) << strerror(errno);
234
235 if (pid == 0) {
236 _exit(99);
237 }
238
239 int status;
240 ASSERT_EQ(pid, waitpid(pid, &status, 0));
241 ASSERT_TRUE(WIFEXITED(status));
242 ASSERT_EQ(99, WEXITSTATUS(status));
243}
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400244
245TEST(unistd, getenv_unsetenv) {
246 ASSERT_EQ(0, setenv("test-variable", "hello", 1));
247 ASSERT_STREQ("hello", getenv("test-variable"));
248 ASSERT_EQ(0, unsetenv("test-variable"));
249 ASSERT_TRUE(getenv("test-variable") == NULL);
250}
251
252TEST(unistd, unsetenv_EINVAL) {
253 EXPECT_EQ(-1, unsetenv(NULL));
254 EXPECT_EQ(EINVAL, errno);
255 EXPECT_EQ(-1, unsetenv(""));
256 EXPECT_EQ(EINVAL, errno);
257 EXPECT_EQ(-1, unsetenv("a=b"));
258 EXPECT_EQ(EINVAL, errno);
259}
260
261TEST(unistd, setenv_EINVAL) {
262 EXPECT_EQ(-1, setenv(NULL, "value", 0));
263 EXPECT_EQ(EINVAL, errno);
264 EXPECT_EQ(-1, setenv(NULL, "value", 1));
265 EXPECT_EQ(EINVAL, errno);
266 EXPECT_EQ(-1, setenv("", "value", 0));
267 EXPECT_EQ(EINVAL, errno);
268 EXPECT_EQ(-1, setenv("", "value", 1));
269 EXPECT_EQ(EINVAL, errno);
270 EXPECT_EQ(-1, setenv("a=b", "value", 0));
271 EXPECT_EQ(EINVAL, errno);
272 EXPECT_EQ(-1, setenv("a=b", "value", 1));
273 EXPECT_EQ(EINVAL, errno);
274}
275
276TEST(unistd, setenv) {
277 ASSERT_EQ(0, unsetenv("test-variable"));
278
279 char a[] = "a";
280 char b[] = "b";
281 char c[] = "c";
282
283 // New value.
284 EXPECT_EQ(0, setenv("test-variable", a, 0));
285 EXPECT_STREQ(a, getenv("test-variable"));
286
287 // Existing value, no overwrite.
288 EXPECT_EQ(0, setenv("test-variable", b, 0));
289 EXPECT_STREQ(a, getenv("test-variable"));
290
291 // Existing value, overwrite.
292 EXPECT_EQ(0, setenv("test-variable", c, 1));
293 EXPECT_STREQ(c, getenv("test-variable"));
294 // But the arrays backing the values are unchanged.
295 EXPECT_EQ('a', a[0]);
296 EXPECT_EQ('b', b[0]);
297 EXPECT_EQ('c', c[0]);
298
299 ASSERT_EQ(0, unsetenv("test-variable"));
300}
301
302TEST(unistd, putenv) {
303 ASSERT_EQ(0, unsetenv("a"));
304
305 char* s1 = strdup("a=b");
306 ASSERT_EQ(0, putenv(s1));
307
308 ASSERT_STREQ("b", getenv("a"));
309 s1[2] = 'c';
310 ASSERT_STREQ("c", getenv("a"));
311
312 char* s2 = strdup("a=b");
313 ASSERT_EQ(0, putenv(s2));
314
315 ASSERT_STREQ("b", getenv("a"));
316 ASSERT_EQ('c', s1[2]);
317
318 ASSERT_EQ(0, unsetenv("a"));
319 free(s1);
320 free(s2);
321}
322
323TEST(unistd, clearenv) {
324 extern char** environ;
325
326 // Guarantee that environ is not initially empty...
327 ASSERT_EQ(0, setenv("test-variable", "a", 1));
328
329 // Stash a copy.
330 std::vector<char*> old_environ;
331 for (size_t i = 0; environ[i] != NULL; ++i) {
332 old_environ.push_back(strdup(environ[i]));
333 }
334
335 ASSERT_EQ(0, clearenv());
336
337 EXPECT_TRUE(environ == NULL || environ[0] == NULL);
338 EXPECT_EQ(NULL, getenv("test-variable"));
339 EXPECT_EQ(0, setenv("test-variable", "post-clear", 1));
340 EXPECT_STREQ("post-clear", getenv("test-variable"));
341
342 // Put the old environment back.
343 for (size_t i = 0; i < old_environ.size(); ++i) {
344 EXPECT_EQ(0, putenv(old_environ[i]));
345 }
346
347 // Check it wasn't overwritten.
348 EXPECT_STREQ("a", getenv("test-variable"));
349
350 EXPECT_EQ(0, unsetenv("test-variable"));
351}
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700352
353static void TestFsyncFunction(int (*fn)(int)) {
354 int fd;
355
356 // Can't sync an invalid fd.
357 errno = 0;
358 EXPECT_EQ(-1, fn(-1));
359 EXPECT_EQ(EBADF, errno);
360
361 // It doesn't matter whether you've opened a file for write or not.
362 TemporaryFile tf;
363 ASSERT_NE(-1, tf.fd);
364
365 EXPECT_EQ(0, fn(tf.fd));
366
367 ASSERT_NE(-1, fd = open(tf.filename, O_RDONLY));
368 EXPECT_EQ(0, fn(fd));
369 close(fd);
370
371 ASSERT_NE(-1, fd = open(tf.filename, O_RDWR));
372 EXPECT_EQ(0, fn(fd));
373 close(fd);
374
375 // The fd can even be a directory.
376 ASSERT_NE(-1, fd = open("/", O_RDONLY));
377 EXPECT_EQ(0, fn(fd));
378 close(fd);
379
380 // But some file systems may choose to be fussy...
381 errno = 0;
382 ASSERT_NE(-1, fd = open("/proc/version", O_RDONLY));
383 EXPECT_EQ(-1, fn(fd));
384 EXPECT_EQ(EINVAL, errno);
385 close(fd);
386}
387
388TEST(unistd, fdatasync) {
389 TestFsyncFunction(fdatasync);
390}
391
392TEST(unistd, fsync) {
393 TestFsyncFunction(fsync);
394}
Elliott Hughes7086ad62014-06-19 16:39:01 -0700395
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700396static void AssertGetPidCorrect() {
397 // The loop is just to make manual testing/debugging with strace easier.
398 pid_t getpid_syscall_result = syscall(__NR_getpid);
399 for (size_t i = 0; i < 128; ++i) {
400 ASSERT_EQ(getpid_syscall_result, getpid());
401 }
402}
403
Elliott Hughes7086ad62014-06-19 16:39:01 -0700404TEST(unistd, getpid_caching_and_fork) {
405 pid_t parent_pid = getpid();
406 ASSERT_EQ(syscall(__NR_getpid), parent_pid);
407
408 pid_t fork_result = fork();
409 ASSERT_NE(fork_result, -1);
410 if (fork_result == 0) {
411 // We're the child.
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700412 AssertGetPidCorrect();
Elliott Hughes7086ad62014-06-19 16:39:01 -0700413 ASSERT_EQ(parent_pid, getppid());
414 _exit(123);
415 } else {
416 // We're the parent.
417 ASSERT_EQ(parent_pid, getpid());
418
419 int status;
420 ASSERT_EQ(fork_result, waitpid(fork_result, &status, 0));
421 ASSERT_TRUE(WIFEXITED(status));
422 ASSERT_EQ(123, WEXITSTATUS(status));
423 }
424}
425
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700426static int GetPidCachingCloneStartRoutine(void*) {
427 AssertGetPidCorrect();
428 return 123;
Elliott Hughes7086ad62014-06-19 16:39:01 -0700429}
430
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700431TEST(unistd, getpid_caching_and_clone) {
432 pid_t parent_pid = getpid();
433 ASSERT_EQ(syscall(__NR_getpid), parent_pid);
434
435 void* child_stack[1024];
436 int clone_result = clone(GetPidCachingCloneStartRoutine, &child_stack[1024], CLONE_NEWNS | SIGCHLD, NULL);
Elliott Hughes2b3b2ec2014-08-21 19:23:53 -0700437 if (clone_result == -1 && errno == EPERM && getuid() != 0) {
438 GTEST_LOG_(INFO) << "This test only works if you have permission to CLONE_NEWNS; try running as root.\n";
439 return;
440 }
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700441 ASSERT_NE(clone_result, -1);
442
443 ASSERT_EQ(parent_pid, getpid());
444
445 int status;
446 ASSERT_EQ(clone_result, waitpid(clone_result, &status, 0));
447 ASSERT_TRUE(WIFEXITED(status));
448 ASSERT_EQ(123, WEXITSTATUS(status));
449}
450
451static void* GetPidCachingPthreadStartRoutine(void*) {
452 AssertGetPidCorrect();
Elliott Hughes7086ad62014-06-19 16:39:01 -0700453 return NULL;
454}
455
456TEST(unistd, getpid_caching_and_pthread_create) {
457 pid_t parent_pid = getpid();
458
459 pthread_t t;
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700460 ASSERT_EQ(0, pthread_create(&t, NULL, GetPidCachingPthreadStartRoutine, NULL));
Elliott Hughes7086ad62014-06-19 16:39:01 -0700461
462 ASSERT_EQ(parent_pid, getpid());
463
464 void* result;
465 ASSERT_EQ(0, pthread_join(t, &result));
466 ASSERT_EQ(NULL, result);
467}
Elliott Hughes60452a22014-09-22 14:41:30 -0700468
Yabin Cui9df70402014-11-05 18:01:01 -0800469class unistd_DeathTest : public BionicDeathTest {};
470
471TEST_F(unistd_DeathTest, abort) {
Elliott Hughes60452a22014-09-22 14:41:30 -0700472 ASSERT_EXIT(abort(), testing::KilledBySignal(SIGABRT), "");
473}
Elliott Hughesb86a4c72014-11-07 16:07:13 -0800474
475TEST(unistd, sethostname) {
476 // The permissions check happens before the argument check, so this will
477 // fail for a different reason if you're running as root than if you're
478 // not, but it'll fail either way. Checking that we have the symbol is about
479 // all we can do for sethostname(2).
480 ASSERT_EQ(-1, sethostname("", -1));
481}
Derek Xued94e7f02014-09-25 11:12:01 +0100482
483TEST(unistd, gethostname) {
484 char hostname[HOST_NAME_MAX + 1];
Derek Xued94e7f02014-09-25 11:12:01 +0100485 memset(hostname, 0, sizeof(hostname));
486
Yongqin Liu2f954ba2014-10-30 16:34:55 +0800487 // Can we get the hostname with a big buffer?
Derek Xued94e7f02014-09-25 11:12:01 +0100488 ASSERT_EQ(0, gethostname(hostname, HOST_NAME_MAX));
Yongqin Liu2f954ba2014-10-30 16:34:55 +0800489
490 // Can we get the hostname with a right-sized buffer?
491 errno = 0;
492 ASSERT_EQ(0, gethostname(hostname, strlen(hostname) + 1));
493
494 // Does uname(2) agree?
Derek Xued94e7f02014-09-25 11:12:01 +0100495 utsname buf;
496 ASSERT_EQ(0, uname(&buf));
497 ASSERT_EQ(0, strncmp(hostname, buf.nodename, SYS_NMLN));
498 ASSERT_GT(strlen(hostname), 0U);
499
Yongqin Liu2f954ba2014-10-30 16:34:55 +0800500 // Do we correctly detect truncation?
Derek Xued94e7f02014-09-25 11:12:01 +0100501 errno = 0;
502 ASSERT_EQ(-1, gethostname(hostname, strlen(hostname)));
503 ASSERT_EQ(ENAMETOOLONG, errno);
Derek Xued94e7f02014-09-25 11:12:01 +0100504}