blob: f3b08c3f47e94113ccdafb2c690b8e98b1d37681 [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>
Elliott Hughes33697a02016-01-26 13:04:57 -080018
Yabin Cui9df70402014-11-05 18:01:01 -080019#include "BionicDeathTest.h"
Elliott Hughes71ba5892018-02-07 12:44:45 -080020#include "SignalUtils.h"
Elliott Hughes33697a02016-01-26 13:04:57 -080021#include "utils.h"
Elliott Hughesa55f6302013-01-02 14:23:43 -080022
Elliott Hughes915fefb2014-02-18 12:34:51 -080023#include <errno.h>
Colin Cross3d19a832014-02-14 18:56:23 -080024#include <fcntl.h>
Elliott Hughes3c115902016-08-24 19:27:04 -070025#include <libgen.h>
Elliott Hughes21972b62014-07-28 12:24:22 -070026#include <limits.h>
Elliott Hughes428f5562013-02-05 16:10:59 -080027#include <stdint.h>
Greg Hackmanne2faf072016-03-03 08:37:53 -080028#include <sys/capability.h>
Yabin Cuib5e581a2014-11-08 14:58:12 -080029#include <sys/param.h>
Elliott Hughesdb602e82019-11-15 09:04:27 -080030#include <sys/resource.h>
Elliott Hughes7086ad62014-06-19 16:39:01 -070031#include <sys/syscall.h>
Elliott Hughes764a9932014-04-08 19:44:36 -070032#include <sys/types.h>
Derek Xued94e7f02014-09-25 11:12:01 +010033#include <sys/utsname.h>
Elliott Hughes764a9932014-04-08 19:44:36 -070034#include <sys/wait.h>
Yabin Cui9df70402014-11-05 18:01:01 -080035#include <unistd.h>
36
Elliott Hughesca3f8e42019-10-28 15:59:38 -070037#include <chrono>
38
Elliott Hughes939a7e02015-12-04 15:27:46 -080039#include <android-base/file.h>
40#include <android-base/strings.h>
Yabin Cuicb6f5992015-09-29 16:11:45 -070041
42#include "private/get_cpu_count_from_string.h"
43
Christopher Ferris13f26a72016-01-13 13:47:58 -080044#if defined(NOFORTIFY)
45#define UNISTD_TEST unistd_nofortify
46#define UNISTD_DEATHTEST unistd_nofortify_DeathTest
47#else
48#define UNISTD_TEST unistd
49#define UNISTD_DEATHTEST unistd_DeathTest
50#endif
51
Elliott Hughesca3f8e42019-10-28 15:59:38 -070052using namespace std::chrono_literals;
53
Elliott Hughes533dde42014-04-25 18:27:38 -070054static void* get_brk() {
55 return sbrk(0);
56}
Elliott Hughes428f5562013-02-05 16:10:59 -080057
Elliott Hughes533dde42014-04-25 18:27:38 -070058static void* page_align(uintptr_t addr) {
59 uintptr_t mask = sysconf(_SC_PAGE_SIZE) - 1;
60 return reinterpret_cast<void*>((addr + mask) & ~mask);
61}
62
Christopher Ferris13f26a72016-01-13 13:47:58 -080063TEST(UNISTD_TEST, brk) {
Elliott Hughes533dde42014-04-25 18:27:38 -070064 void* initial_break = get_brk();
65
Elliott Hughes533dde42014-04-25 18:27:38 -070066 void* new_break = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(initial_break) + 1);
Daniel Micay126ab122015-12-31 08:04:53 -050067 int ret = brk(new_break);
68 if (ret == -1) {
69 ASSERT_EQ(errno, ENOMEM);
70 } else {
71 ASSERT_EQ(0, ret);
72 ASSERT_GE(get_brk(), new_break);
73 }
Elliott Hughes428f5562013-02-05 16:10:59 -080074
Daniel Micay126ab122015-12-31 08:04:53 -050075 // Expand by a full page to force the mapping to expand
Elliott Hughes533dde42014-04-25 18:27:38 -070076 new_break = page_align(reinterpret_cast<uintptr_t>(initial_break) + sysconf(_SC_PAGE_SIZE));
Daniel Micay126ab122015-12-31 08:04:53 -050077 ret = brk(new_break);
78 if (ret == -1) {
79 ASSERT_EQ(errno, ENOMEM);
80 } else {
81 ASSERT_EQ(0, ret);
82 ASSERT_EQ(get_brk(), new_break);
83 }
Elliott Hughes533dde42014-04-25 18:27:38 -070084}
85
Christopher Ferris13f26a72016-01-13 13:47:58 -080086TEST(UNISTD_TEST, brk_ENOMEM) {
Elliott Hughes533dde42014-04-25 18:27:38 -070087 ASSERT_EQ(-1, brk(reinterpret_cast<void*>(-1)));
88 ASSERT_EQ(ENOMEM, errno);
89}
90
Christopher Ferris738b0cc2014-05-21 19:03:34 -070091#if defined(__GLIBC__)
92#define SBRK_MIN INTPTR_MIN
93#define SBRK_MAX INTPTR_MAX
94#else
95#define SBRK_MIN PTRDIFF_MIN
96#define SBRK_MAX PTRDIFF_MAX
97#endif
98
Christopher Ferris13f26a72016-01-13 13:47:58 -080099TEST(UNISTD_TEST, sbrk_ENOMEM) {
Christopher Ferris738b0cc2014-05-21 19:03:34 -0700100#if defined(__BIONIC__) && !defined(__LP64__)
101 // There is no way to guarantee that all overflow conditions can be tested
102 // without manipulating the underlying values of the current break.
103 extern void* __bionic_brk;
104
105 class ScopedBrk {
106 public:
107 ScopedBrk() : saved_brk_(__bionic_brk) {}
108 virtual ~ScopedBrk() { __bionic_brk = saved_brk_; }
109
110 private:
111 void* saved_brk_;
112 };
113
114 ScopedBrk scope_brk;
115
116 // Set the current break to a point that will cause an overflow.
117 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) + 2);
Elliott Hughes533dde42014-04-25 18:27:38 -0700118
119 // Can't increase by so much that we'd overflow.
120 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MAX));
121 ASSERT_EQ(ENOMEM, errno);
122
Christopher Ferris738b0cc2014-05-21 19:03:34 -0700123 // Set the current break to a point that will cause an overflow.
124 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX));
Elliott Hughes533dde42014-04-25 18:27:38 -0700125
Elliott Hughes533dde42014-04-25 18:27:38 -0700126 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN));
127 ASSERT_EQ(ENOMEM, errno);
Christopher Ferris738b0cc2014-05-21 19:03:34 -0700128
129 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) - 1);
130
131 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN + 1));
132 ASSERT_EQ(ENOMEM, errno);
133#else
134 class ScopedBrk {
135 public:
136 ScopedBrk() : saved_brk_(get_brk()) {}
137 virtual ~ScopedBrk() { brk(saved_brk_); }
138
139 private:
140 void* saved_brk_;
141 };
142
143 ScopedBrk scope_brk;
144
145 uintptr_t cur_brk = reinterpret_cast<uintptr_t>(get_brk());
146 if (cur_brk < static_cast<uintptr_t>(-(SBRK_MIN+1))) {
147 // Do the overflow test for a max negative increment.
148 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MIN));
149#if defined(__BIONIC__)
150 // GLIBC does not set errno in overflow case.
151 ASSERT_EQ(ENOMEM, errno);
152#endif
153 }
154
155 uintptr_t overflow_brk = static_cast<uintptr_t>(SBRK_MAX) + 2;
156 if (cur_brk < overflow_brk) {
157 // Try and move the value to PTRDIFF_MAX + 2.
158 cur_brk = reinterpret_cast<uintptr_t>(sbrk(overflow_brk));
159 }
160 if (cur_brk >= overflow_brk) {
161 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MAX));
162#if defined(__BIONIC__)
163 // GLIBC does not set errno in overflow case.
164 ASSERT_EQ(ENOMEM, errno);
165#endif
166 }
Elliott Hughes533dde42014-04-25 18:27:38 -0700167#endif
Elliott Hughes428f5562013-02-05 16:10:59 -0800168}
Elliott Hughesb4f76162013-09-19 16:27:24 -0700169
Christopher Ferris13f26a72016-01-13 13:47:58 -0800170TEST(UNISTD_TEST, truncate) {
Elliott Hughesb4f76162013-09-19 16:27:24 -0700171 TemporaryFile tf;
172 ASSERT_EQ(0, close(tf.fd));
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800173 ASSERT_EQ(0, truncate(tf.path, 123));
Elliott Hughesb4f76162013-09-19 16:27:24 -0700174
175 struct stat sb;
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800176 ASSERT_EQ(0, stat(tf.path, &sb));
Elliott Hughesb4f76162013-09-19 16:27:24 -0700177 ASSERT_EQ(123, sb.st_size);
178}
179
Christopher Ferris13f26a72016-01-13 13:47:58 -0800180TEST(UNISTD_TEST, truncate64) {
Elliott Hughesb4f76162013-09-19 16:27:24 -0700181 TemporaryFile tf;
182 ASSERT_EQ(0, close(tf.fd));
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800183 ASSERT_EQ(0, truncate64(tf.path, 123));
Elliott Hughesb4f76162013-09-19 16:27:24 -0700184
185 struct stat sb;
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800186 ASSERT_EQ(0, stat(tf.path, &sb));
Elliott Hughesb4f76162013-09-19 16:27:24 -0700187 ASSERT_EQ(123, sb.st_size);
188}
189
Christopher Ferris13f26a72016-01-13 13:47:58 -0800190TEST(UNISTD_TEST, ftruncate) {
Elliott Hughesb4f76162013-09-19 16:27:24 -0700191 TemporaryFile tf;
192 ASSERT_EQ(0, ftruncate(tf.fd, 123));
193 ASSERT_EQ(0, close(tf.fd));
194
195 struct stat sb;
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800196 ASSERT_EQ(0, stat(tf.path, &sb));
Elliott Hughesb4f76162013-09-19 16:27:24 -0700197 ASSERT_EQ(123, sb.st_size);
198}
199
Christopher Ferris13f26a72016-01-13 13:47:58 -0800200TEST(UNISTD_TEST, ftruncate64) {
Elliott Hughesb4f76162013-09-19 16:27:24 -0700201 TemporaryFile tf;
202 ASSERT_EQ(0, ftruncate64(tf.fd, 123));
203 ASSERT_EQ(0, close(tf.fd));
204
205 struct stat sb;
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800206 ASSERT_EQ(0, stat(tf.path, &sb));
Elliott Hughesb4f76162013-09-19 16:27:24 -0700207 ASSERT_EQ(123, sb.st_size);
208}
Elliott Hughes11952072013-10-24 15:15:14 -0700209
Christopher Ferris13f26a72016-01-13 13:47:58 -0800210TEST(UNISTD_TEST, ftruncate_negative) {
Dan Albertc05554e2015-05-19 18:17:31 -0700211 TemporaryFile tf;
212 errno = 0;
Dan Albert9d476a02015-06-01 11:28:31 -0700213 ASSERT_EQ(-1, ftruncate(tf.fd, -123));
214 ASSERT_EQ(EINVAL, errno);
Dan Albertc05554e2015-05-19 18:17:31 -0700215}
216
Elliott Hughes1728b232014-05-14 10:02:03 -0700217static bool g_pause_test_flag = false;
Elliott Hughes11952072013-10-24 15:15:14 -0700218static void PauseTestSignalHandler(int) {
Elliott Hughes1728b232014-05-14 10:02:03 -0700219 g_pause_test_flag = true;
Elliott Hughes11952072013-10-24 15:15:14 -0700220}
221
Christopher Ferris13f26a72016-01-13 13:47:58 -0800222TEST(UNISTD_TEST, pause) {
Christopher Ferris13613132013-10-28 15:24:04 -0700223 ScopedSignalHandler handler(SIGALRM, PauseTestSignalHandler);
224
Elliott Hughes11952072013-10-24 15:15:14 -0700225 alarm(1);
Elliott Hughes1728b232014-05-14 10:02:03 -0700226 ASSERT_FALSE(g_pause_test_flag);
Elliott Hughes11952072013-10-24 15:15:14 -0700227 ASSERT_EQ(-1, pause());
Elliott Hughes1728b232014-05-14 10:02:03 -0700228 ASSERT_TRUE(g_pause_test_flag);
Elliott Hughes11952072013-10-24 15:15:14 -0700229}
Colin Cross3d19a832014-02-14 18:56:23 -0800230
Christopher Ferris13f26a72016-01-13 13:47:58 -0800231TEST(UNISTD_TEST, read) {
Colin Cross3d19a832014-02-14 18:56:23 -0800232 int fd = open("/proc/version", O_RDONLY);
233 ASSERT_TRUE(fd != -1);
234
235 char buf[5];
236 ASSERT_EQ(5, read(fd, buf, 5));
237 ASSERT_EQ(buf[0], 'L');
238 ASSERT_EQ(buf[1], 'i');
239 ASSERT_EQ(buf[2], 'n');
240 ASSERT_EQ(buf[3], 'u');
241 ASSERT_EQ(buf[4], 'x');
242 close(fd);
243}
244
Christopher Ferris13f26a72016-01-13 13:47:58 -0800245TEST(UNISTD_TEST, read_EBADF) {
Colin Cross3d19a832014-02-14 18:56:23 -0800246 // read returns ssize_t which is 64-bits on LP64, so it's worth explicitly checking that
247 // our syscall stubs correctly return a 64-bit -1.
248 char buf[1];
249 ASSERT_EQ(-1, read(-1, buf, sizeof(buf)));
250 ASSERT_EQ(EBADF, errno);
251}
Elliott Hughesaedb00d2014-03-03 14:38:20 -0800252
Christopher Ferris13f26a72016-01-13 13:47:58 -0800253TEST(UNISTD_TEST, syscall_long) {
Elliott Hughes21972b62014-07-28 12:24:22 -0700254 // Check that syscall(3) correctly returns long results.
255 // https://code.google.com/p/android/issues/detail?id=73952
256 // We assume that the break is > 4GiB, but this is potentially flaky.
257 uintptr_t p = reinterpret_cast<uintptr_t>(sbrk(0));
258 ASSERT_EQ(p, static_cast<uintptr_t>(syscall(__NR_brk, 0)));
259}
260
Christopher Ferris13f26a72016-01-13 13:47:58 -0800261TEST(UNISTD_TEST, alarm) {
Elliott Hughesaedb00d2014-03-03 14:38:20 -0800262 ASSERT_EQ(0U, alarm(0));
263}
Elliott Hughes9f525642014-04-08 17:14:01 -0700264
Christopher Ferris13f26a72016-01-13 13:47:58 -0800265TEST(UNISTD_TEST, _exit) {
Elliott Hughes33697a02016-01-26 13:04:57 -0800266 pid_t pid = fork();
Elliott Hughes9f525642014-04-08 17:14:01 -0700267 ASSERT_NE(-1, pid) << strerror(errno);
268
269 if (pid == 0) {
270 _exit(99);
271 }
272
Elliott Hughes33697a02016-01-26 13:04:57 -0800273 AssertChildExited(pid, 99);
Elliott Hughes9f525642014-04-08 17:14:01 -0700274}
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400275
Christopher Ferris13f26a72016-01-13 13:47:58 -0800276TEST(UNISTD_TEST, getenv_unsetenv) {
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400277 ASSERT_EQ(0, setenv("test-variable", "hello", 1));
278 ASSERT_STREQ("hello", getenv("test-variable"));
279 ASSERT_EQ(0, unsetenv("test-variable"));
Yi Kong32bc0fc2018-08-02 17:31:13 -0700280 ASSERT_TRUE(getenv("test-variable") == nullptr);
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400281}
282
Christopher Ferris13f26a72016-01-13 13:47:58 -0800283TEST(UNISTD_TEST, unsetenv_EINVAL) {
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400284 EXPECT_EQ(-1, unsetenv(""));
285 EXPECT_EQ(EINVAL, errno);
286 EXPECT_EQ(-1, unsetenv("a=b"));
287 EXPECT_EQ(EINVAL, errno);
288}
289
Christopher Ferris13f26a72016-01-13 13:47:58 -0800290TEST(UNISTD_TEST, setenv_EINVAL) {
Yi Kong32bc0fc2018-08-02 17:31:13 -0700291 EXPECT_EQ(-1, setenv(nullptr, "value", 0));
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400292 EXPECT_EQ(EINVAL, errno);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700293 EXPECT_EQ(-1, setenv(nullptr, "value", 1));
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400294 EXPECT_EQ(EINVAL, errno);
295 EXPECT_EQ(-1, setenv("", "value", 0));
296 EXPECT_EQ(EINVAL, errno);
297 EXPECT_EQ(-1, setenv("", "value", 1));
298 EXPECT_EQ(EINVAL, errno);
299 EXPECT_EQ(-1, setenv("a=b", "value", 0));
300 EXPECT_EQ(EINVAL, errno);
301 EXPECT_EQ(-1, setenv("a=b", "value", 1));
302 EXPECT_EQ(EINVAL, errno);
303}
304
Christopher Ferris13f26a72016-01-13 13:47:58 -0800305TEST(UNISTD_TEST, setenv) {
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400306 ASSERT_EQ(0, unsetenv("test-variable"));
307
308 char a[] = "a";
309 char b[] = "b";
310 char c[] = "c";
311
312 // New value.
313 EXPECT_EQ(0, setenv("test-variable", a, 0));
314 EXPECT_STREQ(a, getenv("test-variable"));
315
316 // Existing value, no overwrite.
317 EXPECT_EQ(0, setenv("test-variable", b, 0));
318 EXPECT_STREQ(a, getenv("test-variable"));
319
320 // Existing value, overwrite.
321 EXPECT_EQ(0, setenv("test-variable", c, 1));
322 EXPECT_STREQ(c, getenv("test-variable"));
323 // But the arrays backing the values are unchanged.
324 EXPECT_EQ('a', a[0]);
325 EXPECT_EQ('b', b[0]);
326 EXPECT_EQ('c', c[0]);
327
328 ASSERT_EQ(0, unsetenv("test-variable"));
329}
330
Christopher Ferris13f26a72016-01-13 13:47:58 -0800331TEST(UNISTD_TEST, putenv) {
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400332 ASSERT_EQ(0, unsetenv("a"));
333
334 char* s1 = strdup("a=b");
335 ASSERT_EQ(0, putenv(s1));
336
337 ASSERT_STREQ("b", getenv("a"));
338 s1[2] = 'c';
339 ASSERT_STREQ("c", getenv("a"));
340
341 char* s2 = strdup("a=b");
342 ASSERT_EQ(0, putenv(s2));
343
344 ASSERT_STREQ("b", getenv("a"));
345 ASSERT_EQ('c', s1[2]);
346
347 ASSERT_EQ(0, unsetenv("a"));
348 free(s1);
349 free(s2);
350}
351
Christopher Ferris13f26a72016-01-13 13:47:58 -0800352TEST(UNISTD_TEST, clearenv) {
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400353 extern char** environ;
354
355 // Guarantee that environ is not initially empty...
356 ASSERT_EQ(0, setenv("test-variable", "a", 1));
357
358 // Stash a copy.
359 std::vector<char*> old_environ;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700360 for (size_t i = 0; environ[i] != nullptr; ++i) {
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400361 old_environ.push_back(strdup(environ[i]));
362 }
363
364 ASSERT_EQ(0, clearenv());
365
Yi Kong32bc0fc2018-08-02 17:31:13 -0700366 EXPECT_TRUE(environ == nullptr || environ[0] == nullptr);
367 EXPECT_EQ(nullptr, getenv("test-variable"));
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400368 EXPECT_EQ(0, setenv("test-variable", "post-clear", 1));
369 EXPECT_STREQ("post-clear", getenv("test-variable"));
370
371 // Put the old environment back.
372 for (size_t i = 0; i < old_environ.size(); ++i) {
373 EXPECT_EQ(0, putenv(old_environ[i]));
374 }
375
376 // Check it wasn't overwritten.
377 EXPECT_STREQ("a", getenv("test-variable"));
378
379 EXPECT_EQ(0, unsetenv("test-variable"));
380}
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700381
Elliott Hughes896362e2017-08-24 16:31:49 -0700382static void TestSyncFunction(int (*fn)(int)) {
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700383 int fd;
384
385 // Can't sync an invalid fd.
386 errno = 0;
387 EXPECT_EQ(-1, fn(-1));
388 EXPECT_EQ(EBADF, errno);
389
390 // It doesn't matter whether you've opened a file for write or not.
391 TemporaryFile tf;
392 ASSERT_NE(-1, tf.fd);
393
394 EXPECT_EQ(0, fn(tf.fd));
395
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800396 ASSERT_NE(-1, fd = open(tf.path, O_RDONLY));
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700397 EXPECT_EQ(0, fn(fd));
398 close(fd);
399
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800400 ASSERT_NE(-1, fd = open(tf.path, O_RDWR));
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700401 EXPECT_EQ(0, fn(fd));
402 close(fd);
403
404 // The fd can even be a directory.
Christopher Ferrisa948a4e2016-05-20 15:32:47 -0700405 ASSERT_NE(-1, fd = open("/data/local/tmp", O_RDONLY));
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700406 EXPECT_EQ(0, fn(fd));
407 close(fd);
Elliott Hughes896362e2017-08-24 16:31:49 -0700408}
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700409
Elliott Hughes896362e2017-08-24 16:31:49 -0700410static void TestFsyncFunction(int (*fn)(int)) {
411 TestSyncFunction(fn);
412
413 // But some file systems are fussy about fsync/fdatasync...
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700414 errno = 0;
Elliott Hughes896362e2017-08-24 16:31:49 -0700415 int fd = open("/proc/version", O_RDONLY);
416 ASSERT_NE(-1, fd);
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700417 EXPECT_EQ(-1, fn(fd));
418 EXPECT_EQ(EINVAL, errno);
419 close(fd);
420}
421
Christopher Ferris13f26a72016-01-13 13:47:58 -0800422TEST(UNISTD_TEST, fdatasync) {
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700423 TestFsyncFunction(fdatasync);
424}
425
Christopher Ferris13f26a72016-01-13 13:47:58 -0800426TEST(UNISTD_TEST, fsync) {
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700427 TestFsyncFunction(fsync);
428}
Elliott Hughes7086ad62014-06-19 16:39:01 -0700429
Elliott Hughes896362e2017-08-24 16:31:49 -0700430TEST(UNISTD_TEST, syncfs) {
431 TestSyncFunction(syncfs);
432}
433
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700434static void AssertGetPidCorrect() {
435 // The loop is just to make manual testing/debugging with strace easier.
436 pid_t getpid_syscall_result = syscall(__NR_getpid);
437 for (size_t i = 0; i < 128; ++i) {
438 ASSERT_EQ(getpid_syscall_result, getpid());
439 }
440}
441
Robert Seseke4621172016-11-03 15:00:53 -0400442static void TestGetPidCachingWithFork(int (*fork_fn)(), void (*exit_fn)(int)) {
Elliott Hughes7086ad62014-06-19 16:39:01 -0700443 pid_t parent_pid = getpid();
444 ASSERT_EQ(syscall(__NR_getpid), parent_pid);
445
Elliott Hughes5891abd2015-08-07 18:27:47 -0700446 pid_t fork_result = fork_fn();
Elliott Hughes7086ad62014-06-19 16:39:01 -0700447 ASSERT_NE(fork_result, -1);
448 if (fork_result == 0) {
449 // We're the child.
Robert Seseka4edf7a2016-10-25 10:29:02 -0400450 ASSERT_NO_FATAL_FAILURE(AssertGetPidCorrect());
Elliott Hughes7086ad62014-06-19 16:39:01 -0700451 ASSERT_EQ(parent_pid, getppid());
Robert Seseke4621172016-11-03 15:00:53 -0400452 exit_fn(123);
Elliott Hughes7086ad62014-06-19 16:39:01 -0700453 } else {
454 // We're the parent.
455 ASSERT_EQ(parent_pid, getpid());
Elliott Hughes33697a02016-01-26 13:04:57 -0800456 AssertChildExited(fork_result, 123);
Elliott Hughes7086ad62014-06-19 16:39:01 -0700457 }
458}
459
Robert Seseka4edf7a2016-10-25 10:29:02 -0400460// gettid() is marked as __attribute_const__, which will have the compiler
461// optimize out multiple calls to gettid in the same function. This wrapper
462// defeats that optimization.
463static __attribute__((__noinline__)) pid_t GetTidForTest() {
464 __asm__("");
465 return gettid();
466}
467
468static void AssertGetTidCorrect() {
469 // The loop is just to make manual testing/debugging with strace easier.
470 pid_t gettid_syscall_result = syscall(__NR_gettid);
471 for (size_t i = 0; i < 128; ++i) {
472 ASSERT_EQ(gettid_syscall_result, GetTidForTest());
473 }
474}
475
Robert Seseke4621172016-11-03 15:00:53 -0400476static void TestGetTidCachingWithFork(int (*fork_fn)(), void (*exit_fn)(int)) {
Robert Seseka4edf7a2016-10-25 10:29:02 -0400477 pid_t parent_tid = GetTidForTest();
478 ASSERT_EQ(syscall(__NR_gettid), parent_tid);
479
480 pid_t fork_result = fork_fn();
481 ASSERT_NE(fork_result, -1);
482 if (fork_result == 0) {
483 // We're the child.
484 EXPECT_EQ(syscall(__NR_getpid), syscall(__NR_gettid));
485 EXPECT_EQ(getpid(), GetTidForTest()) << "real tid is " << syscall(__NR_gettid)
486 << ", pid is " << syscall(__NR_getpid);
487 ASSERT_NO_FATAL_FAILURE(AssertGetTidCorrect());
Robert Seseke4621172016-11-03 15:00:53 -0400488 exit_fn(123);
Robert Seseka4edf7a2016-10-25 10:29:02 -0400489 } else {
490 // We're the parent.
491 ASSERT_EQ(parent_tid, GetTidForTest());
492 AssertChildExited(fork_result, 123);
493 }
494}
495
Christopher Ferris13f26a72016-01-13 13:47:58 -0800496TEST(UNISTD_TEST, getpid_caching_and_fork) {
Robert Seseke4621172016-11-03 15:00:53 -0400497 TestGetPidCachingWithFork(fork, exit);
Elliott Hughes5891abd2015-08-07 18:27:47 -0700498}
499
Robert Seseka4edf7a2016-10-25 10:29:02 -0400500TEST(UNISTD_TEST, gettid_caching_and_fork) {
Robert Seseke4621172016-11-03 15:00:53 -0400501 TestGetTidCachingWithFork(fork, exit);
Robert Seseka4edf7a2016-10-25 10:29:02 -0400502}
503
Christopher Ferris13f26a72016-01-13 13:47:58 -0800504TEST(UNISTD_TEST, getpid_caching_and_vfork) {
Robert Seseke4621172016-11-03 15:00:53 -0400505 TestGetPidCachingWithFork(vfork, _exit);
Elliott Hughes5891abd2015-08-07 18:27:47 -0700506}
507
Robert Seseka4edf7a2016-10-25 10:29:02 -0400508static int CloneLikeFork() {
509 return clone(nullptr, nullptr, SIGCHLD, nullptr);
510}
511
512TEST(UNISTD_TEST, getpid_caching_and_clone_process) {
Robert Seseke4621172016-11-03 15:00:53 -0400513 TestGetPidCachingWithFork(CloneLikeFork, exit);
Robert Seseka4edf7a2016-10-25 10:29:02 -0400514}
515
516TEST(UNISTD_TEST, gettid_caching_and_clone_process) {
Robert Seseke4621172016-11-03 15:00:53 -0400517 TestGetTidCachingWithFork(CloneLikeFork, exit);
Robert Seseka4edf7a2016-10-25 10:29:02 -0400518}
519
520static int CloneAndSetTid() {
521 pid_t child_tid = 0;
522 pid_t parent_tid = GetTidForTest();
523
524 int rv = clone(nullptr, nullptr, CLONE_CHILD_SETTID | SIGCHLD, nullptr, nullptr, nullptr, &child_tid);
525 EXPECT_NE(-1, rv);
526
527 if (rv == 0) {
528 // Child.
529 EXPECT_EQ(child_tid, GetTidForTest());
530 EXPECT_NE(child_tid, parent_tid);
531 } else {
532 EXPECT_NE(child_tid, GetTidForTest());
533 EXPECT_NE(child_tid, parent_tid);
534 EXPECT_EQ(GetTidForTest(), parent_tid);
535 }
536
537 return rv;
538}
539
540TEST(UNISTD_TEST, gettid_caching_and_clone_process_settid) {
Robert Seseke4621172016-11-03 15:00:53 -0400541 TestGetTidCachingWithFork(CloneAndSetTid, exit);
Robert Seseka4edf7a2016-10-25 10:29:02 -0400542}
543
544static int CloneStartRoutine(int (*start_routine)(void*)) {
545 void* child_stack[1024];
Evgenii Stepanov7cc67062019-02-05 18:43:34 -0800546 return clone(start_routine, untag_address(&child_stack[1024]), SIGCHLD, nullptr);
Robert Seseka4edf7a2016-10-25 10:29:02 -0400547}
548
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700549static int GetPidCachingCloneStartRoutine(void*) {
550 AssertGetPidCorrect();
551 return 123;
Elliott Hughes7086ad62014-06-19 16:39:01 -0700552}
553
Christopher Ferris13f26a72016-01-13 13:47:58 -0800554TEST(UNISTD_TEST, getpid_caching_and_clone) {
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700555 pid_t parent_pid = getpid();
556 ASSERT_EQ(syscall(__NR_getpid), parent_pid);
557
Robert Seseka4edf7a2016-10-25 10:29:02 -0400558 int clone_result = CloneStartRoutine(GetPidCachingCloneStartRoutine);
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700559 ASSERT_NE(clone_result, -1);
560
561 ASSERT_EQ(parent_pid, getpid());
562
Elliott Hughes33697a02016-01-26 13:04:57 -0800563 AssertChildExited(clone_result, 123);
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700564}
565
Robert Seseka4edf7a2016-10-25 10:29:02 -0400566static int GetTidCachingCloneStartRoutine(void*) {
567 AssertGetTidCorrect();
568 return 123;
569}
570
571TEST(UNISTD_TEST, gettid_caching_and_clone) {
572 pid_t parent_tid = GetTidForTest();
573 ASSERT_EQ(syscall(__NR_gettid), parent_tid);
574
575 int clone_result = CloneStartRoutine(GetTidCachingCloneStartRoutine);
576 ASSERT_NE(clone_result, -1);
577
578 ASSERT_EQ(parent_tid, GetTidForTest());
579
580 AssertChildExited(clone_result, 123);
581}
582
Robert Seseke4621172016-11-03 15:00:53 -0400583static int CloneChildExit(void*) {
584 AssertGetPidCorrect();
585 AssertGetTidCorrect();
586 exit(33);
587}
588
589TEST(UNISTD_TEST, clone_fn_and_exit) {
590 int clone_result = CloneStartRoutine(CloneChildExit);
591 ASSERT_NE(-1, clone_result);
592
593 AssertGetPidCorrect();
594 AssertGetTidCorrect();
595
596 AssertChildExited(clone_result, 33);
597}
598
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700599static void* GetPidCachingPthreadStartRoutine(void*) {
600 AssertGetPidCorrect();
Yi Kong32bc0fc2018-08-02 17:31:13 -0700601 return nullptr;
Elliott Hughes7086ad62014-06-19 16:39:01 -0700602}
603
Christopher Ferris13f26a72016-01-13 13:47:58 -0800604TEST(UNISTD_TEST, getpid_caching_and_pthread_create) {
Elliott Hughes7086ad62014-06-19 16:39:01 -0700605 pid_t parent_pid = getpid();
606
607 pthread_t t;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700608 ASSERT_EQ(0, pthread_create(&t, nullptr, GetPidCachingPthreadStartRoutine, nullptr));
Elliott Hughes7086ad62014-06-19 16:39:01 -0700609
610 ASSERT_EQ(parent_pid, getpid());
611
612 void* result;
613 ASSERT_EQ(0, pthread_join(t, &result));
Yi Kong32bc0fc2018-08-02 17:31:13 -0700614 ASSERT_EQ(nullptr, result);
Elliott Hughes7086ad62014-06-19 16:39:01 -0700615}
Elliott Hughes60452a22014-09-22 14:41:30 -0700616
Robert Seseka4edf7a2016-10-25 10:29:02 -0400617static void* GetTidCachingPthreadStartRoutine(void*) {
618 AssertGetTidCorrect();
619 uint64_t tid = GetTidForTest();
620 return reinterpret_cast<void*>(tid);
621}
622
623TEST(UNISTD_TEST, gettid_caching_and_pthread_create) {
624 pid_t parent_tid = GetTidForTest();
625
626 pthread_t t;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700627 ASSERT_EQ(0, pthread_create(&t, nullptr, GetTidCachingPthreadStartRoutine, &parent_tid));
Robert Seseka4edf7a2016-10-25 10:29:02 -0400628
629 ASSERT_EQ(parent_tid, GetTidForTest());
630
631 void* result;
632 ASSERT_EQ(0, pthread_join(t, &result));
633 ASSERT_NE(static_cast<uint64_t>(parent_tid), reinterpret_cast<uint64_t>(result));
634}
635
Evgenii Stepanov505168e2019-02-28 18:44:56 -0800636static void optimization_barrier(void* arg) {
637 asm volatile("" : : "r"(arg) : "memory");
638}
639
640__attribute__((noinline)) static void HwasanVforkTestChild() {
641 // Allocate a tagged region on stack and leave it there.
642 char x[10000];
643 optimization_barrier(x);
644 _exit(0);
645}
646
647__attribute__((noinline)) static void HwasanReadMemory(const char* p, size_t size) {
648 // Read memory byte-by-byte. This will blow up if the pointer tag in p does not match any memory
649 // tag in [p, p+size).
650 volatile char z;
651 for (size_t i = 0; i < size; ++i) {
652 z = p[i];
653 }
654}
655
656__attribute__((noinline, no_sanitize("hwaddress"))) static void HwasanVforkTestParent() {
657 // Allocate a region on stack, but don't tag it (see the function attribute).
658 // This depends on unallocated stack space at current function entry being untagged.
659 char x[10000];
660 optimization_barrier(x);
661 // Verify that contents of x[] are untagged.
662 HwasanReadMemory(x, sizeof(x));
663}
664
665TEST(UNISTD_TEST, hwasan_vfork) {
666 // Test hwasan annotation in vfork. This test is only interesting when built with hwasan, but it
667 // is supposed to work correctly either way.
668 if (vfork()) {
669 HwasanVforkTestParent();
670 } else {
671 HwasanVforkTestChild();
672 }
673}
674
Christopher Ferris13f26a72016-01-13 13:47:58 -0800675class UNISTD_DEATHTEST : public BionicDeathTest {};
Yabin Cui9df70402014-11-05 18:01:01 -0800676
Christopher Ferris13f26a72016-01-13 13:47:58 -0800677TEST_F(UNISTD_DEATHTEST, abort) {
Elliott Hughes60452a22014-09-22 14:41:30 -0700678 ASSERT_EXIT(abort(), testing::KilledBySignal(SIGABRT), "");
679}
Elliott Hughesb86a4c72014-11-07 16:07:13 -0800680
Christopher Ferris13f26a72016-01-13 13:47:58 -0800681TEST(UNISTD_TEST, sethostname) {
Elliott Hughesb86a4c72014-11-07 16:07:13 -0800682 // The permissions check happens before the argument check, so this will
683 // fail for a different reason if you're running as root than if you're
684 // not, but it'll fail either way. Checking that we have the symbol is about
685 // all we can do for sethostname(2).
686 ASSERT_EQ(-1, sethostname("", -1));
687}
Derek Xued94e7f02014-09-25 11:12:01 +0100688
Christopher Ferris13f26a72016-01-13 13:47:58 -0800689TEST(UNISTD_TEST, gethostname) {
Derek Xued94e7f02014-09-25 11:12:01 +0100690 char hostname[HOST_NAME_MAX + 1];
Derek Xued94e7f02014-09-25 11:12:01 +0100691 memset(hostname, 0, sizeof(hostname));
692
Yongqin Liu2f954ba2014-10-30 16:34:55 +0800693 // Can we get the hostname with a big buffer?
Derek Xued94e7f02014-09-25 11:12:01 +0100694 ASSERT_EQ(0, gethostname(hostname, HOST_NAME_MAX));
Yongqin Liu2f954ba2014-10-30 16:34:55 +0800695
696 // Can we get the hostname with a right-sized buffer?
697 errno = 0;
698 ASSERT_EQ(0, gethostname(hostname, strlen(hostname) + 1));
699
700 // Does uname(2) agree?
Derek Xued94e7f02014-09-25 11:12:01 +0100701 utsname buf;
702 ASSERT_EQ(0, uname(&buf));
703 ASSERT_EQ(0, strncmp(hostname, buf.nodename, SYS_NMLN));
704 ASSERT_GT(strlen(hostname), 0U);
705
Yongqin Liu2f954ba2014-10-30 16:34:55 +0800706 // Do we correctly detect truncation?
Derek Xued94e7f02014-09-25 11:12:01 +0100707 errno = 0;
708 ASSERT_EQ(-1, gethostname(hostname, strlen(hostname)));
709 ASSERT_EQ(ENAMETOOLONG, errno);
Derek Xued94e7f02014-09-25 11:12:01 +0100710}
Yabin Cuib5e581a2014-11-08 14:58:12 -0800711
Christopher Ferris13f26a72016-01-13 13:47:58 -0800712TEST(UNISTD_TEST, pathconf_fpathconf) {
Yabin Cuib5e581a2014-11-08 14:58:12 -0800713 TemporaryFile tf;
714 long rc = 0L;
715 // As a file system's block size is always power of 2, the configure values
716 // for ALLOC and XFER should be power of 2 as well.
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800717 rc = pathconf(tf.path, _PC_ALLOC_SIZE_MIN);
Yabin Cuib5e581a2014-11-08 14:58:12 -0800718 ASSERT_TRUE(rc > 0 && powerof2(rc));
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800719 rc = pathconf(tf.path, _PC_REC_MIN_XFER_SIZE);
Yabin Cuib5e581a2014-11-08 14:58:12 -0800720 ASSERT_TRUE(rc > 0 && powerof2(rc));
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800721 rc = pathconf(tf.path, _PC_REC_XFER_ALIGN);
Yabin Cuib5e581a2014-11-08 14:58:12 -0800722 ASSERT_TRUE(rc > 0 && powerof2(rc));
723
724 rc = fpathconf(tf.fd, _PC_ALLOC_SIZE_MIN);
725 ASSERT_TRUE(rc > 0 && powerof2(rc));
726 rc = fpathconf(tf.fd, _PC_REC_MIN_XFER_SIZE);
727 ASSERT_TRUE(rc > 0 && powerof2(rc));
728 rc = fpathconf(tf.fd, _PC_REC_XFER_ALIGN);
729 ASSERT_TRUE(rc > 0 && powerof2(rc));
730}
Derek Xuebc644762014-09-25 10:55:34 +0100731
Elliott Hughes19d76852017-10-18 13:27:01 -0700732TEST(UNISTD_TEST, _POSIX_constants) {
Yabin Cui1c191942014-11-19 19:49:14 -0800733 // Make a tight verification of _POSIX_* / _POSIX2_* / _XOPEN_* macros, to prevent change by mistake.
734 // Verify according to POSIX.1-2008.
735 EXPECT_EQ(200809L, _POSIX_VERSION);
736
Elliott Hughes19d76852017-10-18 13:27:01 -0700737 EXPECT_EQ(2, _POSIX_AIO_LISTIO_MAX);
738 EXPECT_EQ(1, _POSIX_AIO_MAX);
739 EXPECT_EQ(4096, _POSIX_ARG_MAX);
740 EXPECT_EQ(25, _POSIX_CHILD_MAX);
741 EXPECT_EQ(20000000, _POSIX_CLOCKRES_MIN);
742 EXPECT_EQ(32, _POSIX_DELAYTIMER_MAX);
743 EXPECT_EQ(255, _POSIX_HOST_NAME_MAX);
744 EXPECT_EQ(8, _POSIX_LINK_MAX);
745 EXPECT_EQ(9, _POSIX_LOGIN_NAME_MAX);
746 EXPECT_EQ(255, _POSIX_MAX_CANON);
747 EXPECT_EQ(255, _POSIX_MAX_INPUT);
748 EXPECT_EQ(8, _POSIX_MQ_OPEN_MAX);
749 EXPECT_EQ(32, _POSIX_MQ_PRIO_MAX);
750 EXPECT_EQ(14, _POSIX_NAME_MAX);
751 EXPECT_EQ(8, _POSIX_NGROUPS_MAX);
752 EXPECT_EQ(20, _POSIX_OPEN_MAX);
753 EXPECT_EQ(256, _POSIX_PATH_MAX);
754 EXPECT_EQ(512, _POSIX_PIPE_BUF);
755 EXPECT_EQ(255, _POSIX_RE_DUP_MAX);
756 EXPECT_EQ(8, _POSIX_RTSIG_MAX);
757 EXPECT_EQ(256, _POSIX_SEM_NSEMS_MAX);
758 EXPECT_EQ(32767, _POSIX_SEM_VALUE_MAX);
759 EXPECT_EQ(32, _POSIX_SIGQUEUE_MAX);
760 EXPECT_EQ(32767, _POSIX_SSIZE_MAX);
761 EXPECT_EQ(8, _POSIX_STREAM_MAX);
762#if !defined(__GLIBC__)
763 EXPECT_EQ(4, _POSIX_SS_REPL_MAX);
764#endif
765 EXPECT_EQ(255, _POSIX_SYMLINK_MAX);
766 EXPECT_EQ(8, _POSIX_SYMLOOP_MAX);
767 EXPECT_EQ(4, _POSIX_THREAD_DESTRUCTOR_ITERATIONS);
768 EXPECT_EQ(128, _POSIX_THREAD_KEYS_MAX);
769 EXPECT_EQ(64, _POSIX_THREAD_THREADS_MAX);
770 EXPECT_EQ(32, _POSIX_TIMER_MAX);
771#if !defined(__GLIBC__)
772 EXPECT_EQ(30, _POSIX_TRACE_EVENT_NAME_MAX);
773 EXPECT_EQ(8, _POSIX_TRACE_NAME_MAX);
774 EXPECT_EQ(8, _POSIX_TRACE_SYS_MAX);
775 EXPECT_EQ(32, _POSIX_TRACE_USER_EVENT_MAX);
776#endif
777 EXPECT_EQ(9, _POSIX_TTY_NAME_MAX);
778 EXPECT_EQ(6, _POSIX_TZNAME_MAX);
779 EXPECT_EQ(99, _POSIX2_BC_BASE_MAX);
780 EXPECT_EQ(2048, _POSIX2_BC_DIM_MAX);
781 EXPECT_EQ(99, _POSIX2_BC_SCALE_MAX);
782 EXPECT_EQ(1000, _POSIX2_BC_STRING_MAX);
783 EXPECT_EQ(14, _POSIX2_CHARCLASS_NAME_MAX);
784 EXPECT_EQ(2, _POSIX2_COLL_WEIGHTS_MAX);
785 EXPECT_EQ(32, _POSIX2_EXPR_NEST_MAX);
786 EXPECT_EQ(2048, _POSIX2_LINE_MAX);
787 EXPECT_EQ(255, _POSIX2_RE_DUP_MAX);
788
789 EXPECT_EQ(16, _XOPEN_IOV_MAX);
790#if !defined(__GLIBC__)
791 EXPECT_EQ(255, _XOPEN_NAME_MAX);
792 EXPECT_EQ(1024, _XOPEN_PATH_MAX);
793#endif
794}
795
796TEST(UNISTD_TEST, _POSIX_options) {
Yabin Cui5afae642014-11-25 20:17:27 -0800797 EXPECT_EQ(_POSIX_VERSION, _POSIX_ADVISORY_INFO);
Elliott Hughes73c44a42016-10-19 09:27:02 -0700798 EXPECT_GT(_POSIX_BARRIERS, 0);
799 EXPECT_GT(_POSIX_SPIN_LOCKS, 0);
Yabin Cui1c191942014-11-19 19:49:14 -0800800 EXPECT_NE(_POSIX_CHOWN_RESTRICTED, -1);
801 EXPECT_EQ(_POSIX_VERSION, _POSIX_CLOCK_SELECTION);
Elliott Hughes19d76852017-10-18 13:27:01 -0700802#if !defined(__GLIBC__) // glibc supports ancient kernels.
Elliott Hughes3a8f75d2017-10-05 10:33:18 -0700803 EXPECT_EQ(_POSIX_VERSION, _POSIX_CPUTIME);
Elliott Hughes19d76852017-10-18 13:27:01 -0700804#endif
Yabin Cui1c191942014-11-19 19:49:14 -0800805 EXPECT_EQ(_POSIX_VERSION, _POSIX_FSYNC);
Yabin Cui1c191942014-11-19 19:49:14 -0800806 EXPECT_EQ(_POSIX_VERSION, _POSIX_IPV6);
807 EXPECT_GT(_POSIX_JOB_CONTROL, 0);
Yabin Cui1c191942014-11-19 19:49:14 -0800808 EXPECT_EQ(_POSIX_VERSION, _POSIX_MAPPED_FILES);
Yabin Cui1c191942014-11-19 19:49:14 -0800809 EXPECT_EQ(_POSIX_VERSION, _POSIX_MEMLOCK);
810 EXPECT_EQ(_POSIX_VERSION, _POSIX_MEMLOCK_RANGE);
811 EXPECT_EQ(_POSIX_VERSION, _POSIX_MEMORY_PROTECTION);
Elliott Hughes19d76852017-10-18 13:27:01 -0700812#if !defined(__GLIBC__) // glibc supports ancient kernels.
Elliott Hughes3a8f75d2017-10-05 10:33:18 -0700813 EXPECT_EQ(_POSIX_VERSION, _POSIX_MONOTONIC_CLOCK);
Elliott Hughes19d76852017-10-18 13:27:01 -0700814#endif
Yabin Cui1c191942014-11-19 19:49:14 -0800815 EXPECT_GT(_POSIX_NO_TRUNC, 0);
Yabin Cui1c191942014-11-19 19:49:14 -0800816 EXPECT_EQ(_POSIX_VERSION, _POSIX_PRIORITY_SCHEDULING);
817 EXPECT_EQ(_POSIX_VERSION, _POSIX_RAW_SOCKETS);
818 EXPECT_EQ(_POSIX_VERSION, _POSIX_READER_WRITER_LOCKS);
Yabin Cui63481602014-12-01 17:41:04 -0800819 EXPECT_EQ(_POSIX_VERSION, _POSIX_REALTIME_SIGNALS);
Yabin Cui1c191942014-11-19 19:49:14 -0800820 EXPECT_GT(_POSIX_REGEXP, 0);
Yabin Cui1c191942014-11-19 19:49:14 -0800821 EXPECT_GT(_POSIX_SAVED_IDS, 0);
822 EXPECT_EQ(_POSIX_VERSION, _POSIX_SEMAPHORES);
Yabin Cui1c191942014-11-19 19:49:14 -0800823 EXPECT_GT(_POSIX_SHELL, 0);
Elliott Hughes14e3ff92017-10-06 16:58:36 -0700824 EXPECT_EQ(_POSIX_VERSION, _POSIX_SPAWN);
Elliott Hughes19d76852017-10-18 13:27:01 -0700825 EXPECT_EQ(-1, _POSIX_SPORADIC_SERVER);
Yabin Cui1c191942014-11-19 19:49:14 -0800826 EXPECT_EQ(_POSIX_VERSION, _POSIX_SYNCHRONIZED_IO);
827 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREADS);
828 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKADDR);
829 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKSIZE);
Elliott Hughes19d76852017-10-18 13:27:01 -0700830#if !defined(__GLIBC__) // glibc supports ancient kernels.
Elliott Hughes3a8f75d2017-10-05 10:33:18 -0700831 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_CPUTIME);
Elliott Hughes19d76852017-10-18 13:27:01 -0700832#endif
Yabin Cui1c191942014-11-19 19:49:14 -0800833 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PRIORITY_SCHEDULING);
Elliott Hughes468c8082017-05-20 12:47:14 -0700834 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PROCESS_SHARED);
Yabin Cui1c191942014-11-19 19:49:14 -0800835 EXPECT_EQ(-1, _POSIX_THREAD_ROBUST_PRIO_PROTECT);
836 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_SAFE_FUNCTIONS);
Elliott Hughes19d76852017-10-18 13:27:01 -0700837 EXPECT_EQ(-1, _POSIX_THREAD_SPORADIC_SERVER);
Yabin Cui1c191942014-11-19 19:49:14 -0800838 EXPECT_EQ(_POSIX_VERSION, _POSIX_TIMEOUTS);
839 EXPECT_EQ(_POSIX_VERSION, _POSIX_TIMERS);
Yabin Cui1c191942014-11-19 19:49:14 -0800840 EXPECT_EQ(-1, _POSIX_TRACE);
841 EXPECT_EQ(-1, _POSIX_TRACE_EVENT_FILTER);
842 EXPECT_EQ(-1, _POSIX_TRACE_INHERIT);
843 EXPECT_EQ(-1, _POSIX_TRACE_LOG);
Yabin Cui1c191942014-11-19 19:49:14 -0800844 EXPECT_EQ(-1, _POSIX_TYPED_MEMORY_OBJECTS);
Yabin Cui1c191942014-11-19 19:49:14 -0800845 EXPECT_NE(-1, _POSIX_VDISABLE);
846
Elliott Hughesa3529352017-07-13 10:20:41 -0700847 EXPECT_EQ(_POSIX_VERSION, _POSIX2_VERSION);
Yabin Cui1c191942014-11-19 19:49:14 -0800848 EXPECT_EQ(_POSIX_VERSION, _POSIX2_C_BIND);
Elliott Hughes19d76852017-10-18 13:27:01 -0700849 EXPECT_EQ(_POSIX_VERSION, _POSIX2_CHAR_TERM);
Yabin Cui1c191942014-11-19 19:49:14 -0800850
851 EXPECT_EQ(700, _XOPEN_VERSION);
Elliott Hughes19d76852017-10-18 13:27:01 -0700852 EXPECT_EQ(1, _XOPEN_ENH_I18N);
853 EXPECT_EQ(1, _XOPEN_REALTIME);
854 EXPECT_EQ(1, _XOPEN_REALTIME_THREADS);
855 EXPECT_EQ(1, _XOPEN_SHM);
856 EXPECT_EQ(1, _XOPEN_UNIX);
Yabin Cui1c191942014-11-19 19:49:14 -0800857
858#if defined(__BIONIC__)
859 // These tests only pass on bionic, as bionic and glibc has different support on these macros.
Yabin Cui5afae642014-11-25 20:17:27 -0800860 // Macros like _POSIX_ASYNCHRONOUS_IO are not supported on bionic yet.
Yabin Cui1c191942014-11-19 19:49:14 -0800861 EXPECT_EQ(-1, _POSIX_ASYNCHRONOUS_IO);
Yabin Cui1c191942014-11-19 19:49:14 -0800862 EXPECT_EQ(-1, _POSIX_MESSAGE_PASSING);
863 EXPECT_EQ(-1, _POSIX_PRIORITIZED_IO);
Yabin Cui1c191942014-11-19 19:49:14 -0800864 EXPECT_EQ(-1, _POSIX_SHARED_MEMORY_OBJECTS);
Elliott Hughes19d76852017-10-18 13:27:01 -0700865 EXPECT_EQ(-1, _POSIX_THREAD_PRIO_INHERIT);
866 EXPECT_EQ(-1, _POSIX_THREAD_PRIO_PROTECT);
Yabin Cui1c191942014-11-19 19:49:14 -0800867 EXPECT_EQ(-1, _POSIX_THREAD_ROBUST_PRIO_INHERIT);
868
Yabin Cui1c191942014-11-19 19:49:14 -0800869 EXPECT_EQ(-1, _POSIX2_C_DEV);
Elliott Hughes19d76852017-10-18 13:27:01 -0700870 EXPECT_EQ(-1, _POSIX2_FORT_DEV);
871 EXPECT_EQ(-1, _POSIX2_FORT_RUN);
Yabin Cui1c191942014-11-19 19:49:14 -0800872 EXPECT_EQ(-1, _POSIX2_LOCALEDEF);
873 EXPECT_EQ(-1, _POSIX2_SW_DEV);
874 EXPECT_EQ(-1, _POSIX2_UPE);
875
Yabin Cui1c191942014-11-19 19:49:14 -0800876 EXPECT_EQ(-1, _XOPEN_CRYPT);
877 EXPECT_EQ(-1, _XOPEN_LEGACY);
Elliott Hughes19d76852017-10-18 13:27:01 -0700878 EXPECT_EQ(-1, _XOPEN_STREAMS);
Yabin Cui1c191942014-11-19 19:49:14 -0800879#endif // defined(__BIONIC__)
880}
881
Elliott Hughesd6f57302018-04-25 22:13:14 -0700882#define VERIFY_SYSCONF_UNKNOWN(name) \
883 VerifySysconf(name, #name, [](long v){return v == -1 && errno == EINVAL;})
884
885#define VERIFY_SYSCONF_UNSUPPORTED(name) \
886 VerifySysconf(name, #name, [](long v){return v == -1 && errno == 0;})
Yabin Cui1c191942014-11-19 19:49:14 -0800887
888// sysconf() means unlimited when it returns -1 with errno unchanged.
889#define VERIFY_SYSCONF_POSITIVE(name) \
Elliott Hughesd6f57302018-04-25 22:13:14 -0700890 VerifySysconf(name, #name, [](long v){return (v > 0 || v == -1) && errno == 0;})
Yabin Cui1c191942014-11-19 19:49:14 -0800891
892#define VERIFY_SYSCONF_POSIX_VERSION(name) \
Elliott Hughesd6f57302018-04-25 22:13:14 -0700893 VerifySysconf(name, #name, [](long v){return v == _POSIX_VERSION && errno == 0;})
Yabin Cui1c191942014-11-19 19:49:14 -0800894
895static void VerifySysconf(int option, const char *option_name, bool (*verify)(long)) {
896 errno = 0;
897 long ret = sysconf(option);
Elliott Hughesd6f57302018-04-25 22:13:14 -0700898 EXPECT_TRUE(verify(ret)) << "name = " << option_name << ", ret = "
Yabin Cui1c191942014-11-19 19:49:14 -0800899 << ret <<", Error Message: " << strerror(errno);
900}
Derek Xuebc644762014-09-25 10:55:34 +0100901
Christopher Ferris13f26a72016-01-13 13:47:58 -0800902TEST(UNISTD_TEST, sysconf) {
Yabin Cui5afae642014-11-25 20:17:27 -0800903 VERIFY_SYSCONF_POSIX_VERSION(_SC_ADVISORY_INFO);
Yabin Cui1c191942014-11-19 19:49:14 -0800904 VERIFY_SYSCONF_POSITIVE(_SC_ARG_MAX);
Elliott Hughes73c44a42016-10-19 09:27:02 -0700905 VERIFY_SYSCONF_POSIX_VERSION(_SC_BARRIERS);
Yabin Cui1c191942014-11-19 19:49:14 -0800906 VERIFY_SYSCONF_POSITIVE(_SC_BC_BASE_MAX);
907 VERIFY_SYSCONF_POSITIVE(_SC_BC_DIM_MAX);
908 VERIFY_SYSCONF_POSITIVE(_SC_BC_SCALE_MAX);
909 VERIFY_SYSCONF_POSITIVE(_SC_CHILD_MAX);
910 VERIFY_SYSCONF_POSITIVE(_SC_CLK_TCK);
911 VERIFY_SYSCONF_POSITIVE(_SC_COLL_WEIGHTS_MAX);
Yabin Cuid5c65272014-11-26 14:04:26 -0800912 VERIFY_SYSCONF_POSIX_VERSION(_SC_CPUTIME);
Yabin Cui1c191942014-11-19 19:49:14 -0800913 VERIFY_SYSCONF_POSITIVE(_SC_EXPR_NEST_MAX);
914 VERIFY_SYSCONF_POSITIVE(_SC_LINE_MAX);
915 VERIFY_SYSCONF_POSITIVE(_SC_NGROUPS_MAX);
916 VERIFY_SYSCONF_POSITIVE(_SC_OPEN_MAX);
917 VERIFY_SYSCONF_POSITIVE(_SC_PASS_MAX);
918 VERIFY_SYSCONF_POSIX_VERSION(_SC_2_C_BIND);
Elliott Hughes72927252016-07-27 14:05:10 -0700919 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_FORT_DEV);
920 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_FORT_RUN);
921 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_UPE);
Elliott Hughes6c135f42017-07-28 16:53:32 -0700922 VERIFY_SYSCONF_POSIX_VERSION(_SC_2_VERSION);
Yabin Cui1c191942014-11-19 19:49:14 -0800923 VERIFY_SYSCONF_POSITIVE(_SC_JOB_CONTROL);
924 VERIFY_SYSCONF_POSITIVE(_SC_SAVED_IDS);
925 VERIFY_SYSCONF_POSIX_VERSION(_SC_VERSION);
926 VERIFY_SYSCONF_POSITIVE(_SC_RE_DUP_MAX);
927 VERIFY_SYSCONF_POSITIVE(_SC_STREAM_MAX);
928 VERIFY_SYSCONF_POSITIVE(_SC_TZNAME_MAX);
Elliott Hughesd6f57302018-04-25 22:13:14 -0700929 VerifySysconf(_SC_XOPEN_VERSION, "_SC_XOPEN_VERSION", [](long v){return v == _XOPEN_VERSION && errno == 0;});
Yabin Cui1c191942014-11-19 19:49:14 -0800930 VERIFY_SYSCONF_POSITIVE(_SC_ATEXIT_MAX);
931 VERIFY_SYSCONF_POSITIVE(_SC_IOV_MAX);
Elliott Hughes82ab4812018-10-09 13:56:06 -0700932 VERIFY_SYSCONF_POSITIVE(_SC_UIO_MAXIOV);
933 EXPECT_EQ(sysconf(_SC_IOV_MAX), sysconf(_SC_UIO_MAXIOV));
Yabin Cui1c191942014-11-19 19:49:14 -0800934 VERIFY_SYSCONF_POSITIVE(_SC_PAGESIZE);
935 VERIFY_SYSCONF_POSITIVE(_SC_PAGE_SIZE);
Elliott Hughes189394b2015-07-24 23:22:07 -0700936 VerifySysconf(_SC_PAGE_SIZE, "_SC_PAGE_SIZE",
Elliott Hughesd6f57302018-04-25 22:13:14 -0700937 [](long v){return v == sysconf(_SC_PAGESIZE) && errno == 0 && v == getpagesize();});
Yabin Cui1c191942014-11-19 19:49:14 -0800938 VERIFY_SYSCONF_POSITIVE(_SC_XOPEN_UNIX);
939 VERIFY_SYSCONF_POSITIVE(_SC_AIO_LISTIO_MAX);
940 VERIFY_SYSCONF_POSITIVE(_SC_AIO_MAX);
Elliott Hughesd6f57302018-04-25 22:13:14 -0700941 VerifySysconf(_SC_AIO_PRIO_DELTA_MAX, "_SC_AIO_PRIO_DELTA_MAX", [](long v){return v >= 0 && errno == 0;});
Yabin Cui1c191942014-11-19 19:49:14 -0800942 VERIFY_SYSCONF_POSITIVE(_SC_DELAYTIMER_MAX);
943 VERIFY_SYSCONF_POSITIVE(_SC_MQ_OPEN_MAX);
944 VERIFY_SYSCONF_POSITIVE(_SC_MQ_PRIO_MAX);
945 VERIFY_SYSCONF_POSITIVE(_SC_RTSIG_MAX);
946 VERIFY_SYSCONF_POSITIVE(_SC_SEM_NSEMS_MAX);
947 VERIFY_SYSCONF_POSITIVE(_SC_SEM_VALUE_MAX);
Elliott Hughes73c44a42016-10-19 09:27:02 -0700948 VERIFY_SYSCONF_POSIX_VERSION(_SC_SPIN_LOCKS);
Yabin Cui1c191942014-11-19 19:49:14 -0800949 VERIFY_SYSCONF_POSITIVE(_SC_TIMER_MAX);
950 VERIFY_SYSCONF_POSIX_VERSION(_SC_FSYNC);
951 VERIFY_SYSCONF_POSIX_VERSION(_SC_MAPPED_FILES);
952 VERIFY_SYSCONF_POSIX_VERSION(_SC_MEMLOCK);
953 VERIFY_SYSCONF_POSIX_VERSION(_SC_MEMLOCK_RANGE);
954 VERIFY_SYSCONF_POSIX_VERSION(_SC_MEMORY_PROTECTION);
955 VERIFY_SYSCONF_POSIX_VERSION(_SC_PRIORITY_SCHEDULING);
Yabin Cui63481602014-12-01 17:41:04 -0800956 VERIFY_SYSCONF_POSIX_VERSION(_SC_REALTIME_SIGNALS);
Yabin Cui1c191942014-11-19 19:49:14 -0800957 VERIFY_SYSCONF_POSIX_VERSION(_SC_SEMAPHORES);
958 VERIFY_SYSCONF_POSIX_VERSION(_SC_SYNCHRONIZED_IO);
959 VERIFY_SYSCONF_POSIX_VERSION(_SC_TIMERS);
960 VERIFY_SYSCONF_POSITIVE(_SC_GETGR_R_SIZE_MAX);
961 VERIFY_SYSCONF_POSITIVE(_SC_GETPW_R_SIZE_MAX);
962 VERIFY_SYSCONF_POSITIVE(_SC_LOGIN_NAME_MAX);
963 VERIFY_SYSCONF_POSITIVE(_SC_THREAD_DESTRUCTOR_ITERATIONS);
964 VERIFY_SYSCONF_POSITIVE(_SC_THREAD_KEYS_MAX);
965 VERIFY_SYSCONF_POSITIVE(_SC_THREAD_STACK_MIN);
966 VERIFY_SYSCONF_POSITIVE(_SC_THREAD_THREADS_MAX);
967 VERIFY_SYSCONF_POSITIVE(_SC_TTY_NAME_MAX);
968 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREADS);
969 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_ATTR_STACKADDR);
970 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_ATTR_STACKSIZE);
971 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_PRIORITY_SCHEDULING);
Elliott Hughes72927252016-07-27 14:05:10 -0700972 VERIFY_SYSCONF_UNSUPPORTED(_SC_THREAD_PRIO_INHERIT);
973 VERIFY_SYSCONF_UNSUPPORTED(_SC_THREAD_PRIO_PROTECT);
Yabin Cui1c191942014-11-19 19:49:14 -0800974 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_SAFE_FUNCTIONS);
975 VERIFY_SYSCONF_POSITIVE(_SC_NPROCESSORS_CONF);
976 VERIFY_SYSCONF_POSITIVE(_SC_NPROCESSORS_ONLN);
977 VERIFY_SYSCONF_POSITIVE(_SC_PHYS_PAGES);
978 VERIFY_SYSCONF_POSITIVE(_SC_AVPHYS_PAGES);
979 VERIFY_SYSCONF_POSIX_VERSION(_SC_MONOTONIC_CLOCK);
Elliott Hughes72927252016-07-27 14:05:10 -0700980 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_PBS);
981 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_PBS_ACCOUNTING);
982 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_PBS_CHECKPOINT);
983 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_PBS_LOCATE);
984 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_PBS_MESSAGE);
985 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_PBS_TRACK);
Yabin Cui1c191942014-11-19 19:49:14 -0800986 VERIFY_SYSCONF_POSIX_VERSION(_SC_CLOCK_SELECTION);
987 VERIFY_SYSCONF_POSITIVE(_SC_HOST_NAME_MAX);
988 VERIFY_SYSCONF_POSIX_VERSION(_SC_IPV6);
989 VERIFY_SYSCONF_POSIX_VERSION(_SC_RAW_SOCKETS);
990 VERIFY_SYSCONF_POSIX_VERSION(_SC_READER_WRITER_LOCKS);
991 VERIFY_SYSCONF_POSITIVE(_SC_REGEXP);
992 VERIFY_SYSCONF_POSITIVE(_SC_SHELL);
Elliott Hughes14e3ff92017-10-06 16:58:36 -0700993 VERIFY_SYSCONF_POSIX_VERSION(_SC_SPAWN);
Elliott Hughes19d76852017-10-18 13:27:01 -0700994 VERIFY_SYSCONF_UNSUPPORTED(_SC_SPORADIC_SERVER);
Yabin Cui1c191942014-11-19 19:49:14 -0800995 VERIFY_SYSCONF_POSITIVE(_SC_SYMLOOP_MAX);
996 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_CPUTIME);
Elliott Hughes468c8082017-05-20 12:47:14 -0700997 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_PROCESS_SHARED);
Elliott Hughes19d76852017-10-18 13:27:01 -0700998 VERIFY_SYSCONF_UNSUPPORTED(_SC_THREAD_SPORADIC_SERVER);
Yabin Cui1c191942014-11-19 19:49:14 -0800999 VERIFY_SYSCONF_POSIX_VERSION(_SC_TIMEOUTS);
Elliott Hughes72927252016-07-27 14:05:10 -07001000 VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE);
1001 VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE_EVENT_FILTER);
1002 VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE_EVENT_NAME_MAX);
1003 VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE_INHERIT);
1004 VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE_LOG);
1005 VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE_NAME_MAX);
1006 VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE_SYS_MAX);
1007 VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE_USER_EVENT_MAX);
1008 VERIFY_SYSCONF_UNSUPPORTED(_SC_TYPED_MEMORY_OBJECTS);
1009 VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_STREAMS);
Derek Xuebc644762014-09-25 10:55:34 +01001010
Yabin Cui1c191942014-11-19 19:49:14 -08001011#if defined(__LP64__)
Elliott Hughes72927252016-07-27 14:05:10 -07001012 VERIFY_SYSCONF_UNSUPPORTED(_SC_V7_ILP32_OFF32);
1013 VERIFY_SYSCONF_UNSUPPORTED(_SC_V7_ILP32_OFFBIG);
Yabin Cui1c191942014-11-19 19:49:14 -08001014 VERIFY_SYSCONF_POSITIVE(_SC_V7_LP64_OFF64);
1015 VERIFY_SYSCONF_POSITIVE(_SC_V7_LPBIG_OFFBIG);
1016#else
1017 VERIFY_SYSCONF_POSITIVE(_SC_V7_ILP32_OFF32);
1018#if defined(__BIONIC__)
1019 // bionic does not support 64 bits off_t type on 32bit machine.
Elliott Hughes72927252016-07-27 14:05:10 -07001020 VERIFY_SYSCONF_UNSUPPORTED(_SC_V7_ILP32_OFFBIG);
Yabin Cui1c191942014-11-19 19:49:14 -08001021#endif
Elliott Hughes72927252016-07-27 14:05:10 -07001022 VERIFY_SYSCONF_UNSUPPORTED(_SC_V7_LP64_OFF64);
1023 VERIFY_SYSCONF_UNSUPPORTED(_SC_V7_LPBIG_OFFBIG);
Yabin Cui1c191942014-11-19 19:49:14 -08001024#endif
Derek Xuebc644762014-09-25 10:55:34 +01001025
Yabin Cui1c191942014-11-19 19:49:14 -08001026#if defined(__BIONIC__)
1027 // Tests can only run on bionic, as bionic and glibc have different support for these options.
1028 // Below options are not supported on bionic yet.
Elliott Hughes72927252016-07-27 14:05:10 -07001029 VERIFY_SYSCONF_UNSUPPORTED(_SC_ASYNCHRONOUS_IO);
Elliott Hughes72927252016-07-27 14:05:10 -07001030 VERIFY_SYSCONF_UNSUPPORTED(_SC_MESSAGE_PASSING);
1031 VERIFY_SYSCONF_UNSUPPORTED(_SC_PRIORITIZED_IO);
1032 VERIFY_SYSCONF_UNSUPPORTED(_SC_SHARED_MEMORY_OBJECTS);
Elliott Hughes72927252016-07-27 14:05:10 -07001033 VERIFY_SYSCONF_UNSUPPORTED(_SC_THREAD_ROBUST_PRIO_INHERIT);
1034 VERIFY_SYSCONF_UNSUPPORTED(_SC_THREAD_ROBUST_PRIO_PROTECT);
Derek Xuebc644762014-09-25 10:55:34 +01001035
Elliott Hughes72927252016-07-27 14:05:10 -07001036 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_C_DEV);
Elliott Hughes72927252016-07-27 14:05:10 -07001037 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_LOCALEDEF);
1038 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_SW_DEV);
Derek Xuebc644762014-09-25 10:55:34 +01001039
Elliott Hughes72927252016-07-27 14:05:10 -07001040 VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_CRYPT);
Elliott Hughes72927252016-07-27 14:05:10 -07001041 VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_LEGACY);
Elliott Hughes72927252016-07-27 14:05:10 -07001042 VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_UUCP);
Yabin Cui1c191942014-11-19 19:49:14 -08001043#endif // defined(__BIONIC__)
Derek Xuebc644762014-09-25 10:55:34 +01001044}
Elliott Hughesbe52e652015-02-23 18:02:29 -08001045
Christopher Ferris13f26a72016-01-13 13:47:58 -08001046TEST(UNISTD_TEST, get_cpu_count_from_string) {
Yabin Cuicb6f5992015-09-29 16:11:45 -07001047 ASSERT_EQ(0, GetCpuCountFromString(" "));
1048 ASSERT_EQ(1, GetCpuCountFromString("0"));
1049 ASSERT_EQ(40, GetCpuCountFromString("0-39"));
1050 ASSERT_EQ(4, GetCpuCountFromString("0, 1-2, 4\n"));
1051}
1052
Christopher Ferris13f26a72016-01-13 13:47:58 -08001053TEST(UNISTD_TEST, sysconf_SC_NPROCESSORS_ONLN) {
Elliott Hughes0b2acdf2015-10-02 18:25:19 -07001054 std::string line;
1055 ASSERT_TRUE(android::base::ReadFileToString("/sys/devices/system/cpu/online", &line));
Yabin Cuicb6f5992015-09-29 16:11:45 -07001056 long online_cpus = 0;
Elliott Hughes0b2acdf2015-10-02 18:25:19 -07001057 for (const std::string& s : android::base::Split(line, ",")) {
Yabin Cuicb6f5992015-09-29 16:11:45 -07001058 std::vector<std::string> numbers = android::base::Split(s, "-");
1059 if (numbers.size() == 1u) {
1060 online_cpus++;
1061 } else {
1062 online_cpus += atoi(numbers[1].c_str()) - atoi(numbers[0].c_str()) + 1;
1063 }
1064 }
1065 ASSERT_EQ(online_cpus, sysconf(_SC_NPROCESSORS_ONLN));
1066}
1067
Elliott Hughes38dba2e2016-08-10 15:51:06 -07001068TEST(UNISTD_TEST, sysconf_SC_ARG_MAX) {
Elliott Hughesdb602e82019-11-15 09:04:27 -08001069 // Since Linux 2.6.23, ARG_MAX isn't a constant and depends on RLIMIT_STACK.
1070 // See prepare_arg_pages() in the kernel for the gory details:
1071 // https://elixir.bootlin.com/linux/v5.3.11/source/fs/exec.c#L451
1072
1073 // Get our current limit, and set things up so we restore the limit.
1074 rlimit rl;
1075 ASSERT_EQ(0, getrlimit(RLIMIT_STACK, &rl));
1076 uint64_t original_rlim_cur = rl.rlim_cur;
1077 if (rl.rlim_cur == RLIM_INFINITY) {
1078 rl.rlim_cur = 8 * 1024 * 1024; // Bionic reports unlimited stacks as 8MiB.
1079 }
1080 auto guard = android::base::make_scope_guard([&rl, original_rlim_cur]() {
1081 rl.rlim_cur = original_rlim_cur;
1082 ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
1083 });
1084
1085 // _SC_ARG_MAX should be 1/4 the stack size.
1086 EXPECT_EQ(static_cast<long>(rl.rlim_cur / 4), sysconf(_SC_ARG_MAX));
1087
1088 // If you have a really small stack, the kernel still guarantees "32 pages" (see fs/exec.c).
1089 rl.rlim_cur = 1024;
1090 rl.rlim_max = RLIM_INFINITY;
1091 ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
1092
1093 EXPECT_EQ(static_cast<long>(32 * sysconf(_SC_PAGE_SIZE)), sysconf(_SC_ARG_MAX));
1094
1095 // With a 128-page stack limit, we know exactly what _SC_ARG_MAX should be...
1096 rl.rlim_cur = 128 * sysconf(_SC_PAGE_SIZE);
1097 rl.rlim_max = RLIM_INFINITY;
1098 ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
1099
1100 EXPECT_EQ(static_cast<long>((128 * sysconf(_SC_PAGE_SIZE)) / 4), sysconf(_SC_ARG_MAX));
Elliott Hughes38dba2e2016-08-10 15:51:06 -07001101}
1102
Elliott Hughesd6f57302018-04-25 22:13:14 -07001103TEST(UNISTD_TEST, sysconf_unknown) {
1104 VERIFY_SYSCONF_UNKNOWN(-1);
1105 VERIFY_SYSCONF_UNKNOWN(666);
1106}
1107
Christopher Ferris13f26a72016-01-13 13:47:58 -08001108TEST(UNISTD_TEST, dup2_same) {
Elliott Hughesbe52e652015-02-23 18:02:29 -08001109 // POSIX says of dup2:
1110 // If fildes2 is already a valid open file descriptor ...
1111 // [and] fildes is equal to fildes2 ... dup2() shall return
1112 // fildes2 without closing it.
1113 // This isn't true of dup3(2), so we need to manually implement that.
1114
1115 // Equal and valid.
1116 int fd = open("/proc/version", O_RDONLY);
1117 ASSERT_TRUE(fd != -1);
1118 ASSERT_EQ(fd, dup2(fd, fd));
1119 ASSERT_EQ(0, close(fd)); // Check that dup2 didn't close fd.
1120
1121 // Equal, but invalid.
1122 errno = 0;
1123 ASSERT_EQ(-1, dup2(fd, fd));
1124 ASSERT_EQ(EBADF, errno);
1125}
Elliott Hughes5704c422016-01-25 18:06:24 -08001126
Elliott Hughesa7f12942017-12-15 13:55:53 -08001127TEST(UNISTD_TEST, dup3) {
1128 int fd = open("/proc/version", O_RDONLY);
1129 ASSERT_EQ(666, dup3(fd, 666, 0));
1130 AssertCloseOnExec(666, false);
1131 close(666);
1132 ASSERT_EQ(667, dup3(fd, 667, O_CLOEXEC));
1133 AssertCloseOnExec(667, true);
1134 close(667);
1135 close(fd);
1136}
1137
Elliott Hughes5704c422016-01-25 18:06:24 -08001138TEST(UNISTD_TEST, lockf_smoke) {
1139 constexpr off64_t file_size = 32*1024LL;
1140
1141 TemporaryFile tf;
1142 ASSERT_EQ(0, ftruncate(tf.fd, file_size));
1143
1144 // Lock everything.
1145 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1146 ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, file_size));
1147
1148 // Try-lock everything, this should succeed too.
1149 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1150 ASSERT_EQ(0, lockf64(tf.fd, F_TLOCK, file_size));
1151
1152 // Check status.
1153 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1154 ASSERT_EQ(0, lockf64(tf.fd, F_TEST, file_size));
1155
1156 // Unlock file.
1157 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1158 ASSERT_EQ(0, lockf64(tf.fd, F_ULOCK, file_size));
1159}
1160
1161TEST(UNISTD_TEST, lockf_zero) {
1162 constexpr off64_t file_size = 32*1024LL;
1163
1164 TemporaryFile tf;
1165 ASSERT_EQ(0, ftruncate(tf.fd, file_size));
1166
1167 // Lock everything by specifying a size of 0 (meaning "to the end, even if it changes").
1168 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1169 ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, 0));
1170
1171 // Check that it's locked.
1172 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1173 ASSERT_EQ(0, lockf64(tf.fd, F_TEST, file_size));
1174
1175 // Move the end.
1176 ASSERT_EQ(0, ftruncate(tf.fd, 2*file_size));
1177
1178 // Check that the new section is locked too.
1179 ASSERT_EQ(file_size, lseek64(tf.fd, file_size, SEEK_SET));
1180 ASSERT_EQ(0, lockf64(tf.fd, F_TEST, 2*file_size));
1181}
1182
1183TEST(UNISTD_TEST, lockf_negative) {
1184 constexpr off64_t file_size = 32*1024LL;
1185
1186 TemporaryFile tf;
1187 ASSERT_EQ(0, ftruncate(tf.fd, file_size));
1188
1189 // Lock everything, but specifying the range in reverse.
1190 ASSERT_EQ(file_size, lseek64(tf.fd, file_size, SEEK_SET));
1191 ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, -file_size));
1192
1193 // Check that it's locked.
1194 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1195 ASSERT_EQ(0, lockf64(tf.fd, F_TEST, file_size));
1196}
1197
1198TEST(UNISTD_TEST, lockf_with_child) {
1199 constexpr off64_t file_size = 32*1024LL;
1200
1201 TemporaryFile tf;
1202 ASSERT_EQ(0, ftruncate(tf.fd, file_size));
1203
1204 // Lock everything.
1205 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1206 ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, file_size));
1207
1208 // Fork a child process
1209 pid_t pid = fork();
1210 ASSERT_NE(-1, pid);
1211 if (pid == 0) {
1212 // Check that the child cannot lock the file.
1213 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1214 ASSERT_EQ(-1, lockf64(tf.fd, F_TLOCK, file_size));
1215 ASSERT_EQ(EAGAIN, errno);
1216 // Check also that it reports itself as locked.
1217 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1218 ASSERT_EQ(-1, lockf64(tf.fd, F_TEST, file_size));
1219 ASSERT_EQ(EACCES, errno);
1220 _exit(0);
1221 }
Elliott Hughes33697a02016-01-26 13:04:57 -08001222 AssertChildExited(pid, 0);
Elliott Hughes5704c422016-01-25 18:06:24 -08001223}
1224
1225TEST(UNISTD_TEST, lockf_partial_with_child) {
1226 constexpr off64_t file_size = 32*1024LL;
1227
1228 TemporaryFile tf;
1229 ASSERT_EQ(0, ftruncate(tf.fd, file_size));
1230
1231 // Lock the first half of the file.
1232 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1233 ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, file_size/2));
1234
1235 // Fork a child process.
1236 pid_t pid = fork();
1237 ASSERT_NE(-1, pid);
1238 if (pid == 0) {
1239 // Check that the child can lock the other half.
1240 ASSERT_EQ(file_size/2, lseek64(tf.fd, file_size/2, SEEK_SET));
1241 ASSERT_EQ(0, lockf64(tf.fd, F_TLOCK, file_size/2));
1242 // Check that the child cannot lock the first half.
1243 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1244 ASSERT_EQ(-1, lockf64(tf.fd, F_TEST, file_size/2));
1245 ASSERT_EQ(EACCES, errno);
1246 // Check also that it reports itself as locked.
1247 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1248 ASSERT_EQ(-1, lockf64(tf.fd, F_TEST, file_size/2));
1249 ASSERT_EQ(EACCES, errno);
1250 _exit(0);
1251 }
Elliott Hughes33697a02016-01-26 13:04:57 -08001252 AssertChildExited(pid, 0);
Elliott Hughes5704c422016-01-25 18:06:24 -08001253
1254 // The second half was locked by the child, but the lock disappeared
1255 // when the process exited, so check it can be locked now.
1256 ASSERT_EQ(file_size/2, lseek64(tf.fd, file_size/2, SEEK_SET));
1257 ASSERT_EQ(0, lockf64(tf.fd, F_TLOCK, file_size/2));
1258}
Greg Hackmanne2faf072016-03-03 08:37:53 -08001259
1260TEST(UNISTD_TEST, getdomainname) {
1261 struct utsname u;
1262 ASSERT_EQ(0, uname(&u));
1263
1264 char buf[sizeof(u.domainname)];
1265 ASSERT_EQ(0, getdomainname(buf, sizeof(buf)));
1266 EXPECT_STREQ(u.domainname, buf);
1267
1268#if defined(__BIONIC__)
1269 // bionic and glibc have different behaviors when len is too small
1270 ASSERT_EQ(-1, getdomainname(buf, strlen(u.domainname)));
1271 EXPECT_EQ(EINVAL, errno);
1272#endif
1273}
1274
1275TEST(UNISTD_TEST, setdomainname) {
1276 __user_cap_header_struct header;
1277 memset(&header, 0, sizeof(header));
1278 header.version = _LINUX_CAPABILITY_VERSION_3;
1279
1280 __user_cap_data_struct old_caps[_LINUX_CAPABILITY_U32S_3];
1281 ASSERT_EQ(0, capget(&header, &old_caps[0]));
1282
1283 auto admin_idx = CAP_TO_INDEX(CAP_SYS_ADMIN);
1284 auto admin_mask = CAP_TO_MASK(CAP_SYS_ADMIN);
1285 bool has_admin = old_caps[admin_idx].effective & admin_mask;
1286 if (has_admin) {
1287 __user_cap_data_struct new_caps[_LINUX_CAPABILITY_U32S_3];
1288 memcpy(new_caps, old_caps, sizeof(new_caps));
1289 new_caps[admin_idx].effective &= ~admin_mask;
1290
1291 ASSERT_EQ(0, capset(&header, &new_caps[0])) << "failed to drop admin privileges";
1292 }
1293
1294 const char* name = "newdomainname";
1295 ASSERT_EQ(-1, setdomainname(name, strlen(name)));
1296 ASSERT_EQ(EPERM, errno);
1297
1298 if (has_admin) {
1299 ASSERT_EQ(0, capset(&header, &old_caps[0])) << "failed to restore admin privileges";
1300 }
1301}
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001302
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001303TEST(UNISTD_TEST, execve_failure) {
1304 ExecTestHelper eth;
1305 errno = 0;
1306 ASSERT_EQ(-1, execve("/", eth.GetArgs(), eth.GetEnv()));
1307 ASSERT_EQ(EACCES, errno);
1308}
1309
Elliott Hughes3c115902016-08-24 19:27:04 -07001310TEST(UNISTD_TEST, execve_args) {
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001311 // int execve(const char* path, char* argv[], char* envp[]);
1312
1313 // Test basic argument passing.
1314 ExecTestHelper eth;
1315 eth.SetArgs({"echo", "hello", "world", nullptr});
1316 eth.Run([&]() { execve(BIN_DIR "echo", eth.GetArgs(), eth.GetEnv()); }, 0, "hello world\n");
1317
1318 // Test environment variable setting too.
1319 eth.SetArgs({"printenv", nullptr});
1320 eth.SetEnv({"A=B", nullptr});
1321 eth.Run([&]() { execve(BIN_DIR "printenv", eth.GetArgs(), eth.GetEnv()); }, 0, "A=B\n");
1322}
1323
1324TEST(UNISTD_TEST, execl_failure) {
1325 errno = 0;
1326 ASSERT_EQ(-1, execl("/", "/", nullptr));
1327 ASSERT_EQ(EACCES, errno);
1328}
1329
1330TEST(UNISTD_TEST, execl) {
1331 ExecTestHelper eth;
1332 // int execl(const char* path, const char* arg, ...);
1333 eth.Run([&]() { execl(BIN_DIR "echo", "echo", "hello", "world", nullptr); }, 0, "hello world\n");
1334}
1335
1336TEST(UNISTD_TEST, execle_failure) {
1337 ExecTestHelper eth;
1338 errno = 0;
1339 ASSERT_EQ(-1, execle("/", "/", nullptr, eth.GetEnv()));
1340 ASSERT_EQ(EACCES, errno);
1341}
1342
1343TEST(UNISTD_TEST, execle) {
1344 ExecTestHelper eth;
1345 eth.SetEnv({"A=B", nullptr});
1346 // int execle(const char* path, const char* arg, ..., char* envp[]);
1347 eth.Run([&]() { execle(BIN_DIR "printenv", "printenv", nullptr, eth.GetEnv()); }, 0, "A=B\n");
1348}
1349
1350TEST(UNISTD_TEST, execv_failure) {
1351 ExecTestHelper eth;
1352 errno = 0;
1353 ASSERT_EQ(-1, execv("/", eth.GetArgs()));
1354 ASSERT_EQ(EACCES, errno);
1355}
1356
1357TEST(UNISTD_TEST, execv) {
1358 ExecTestHelper eth;
1359 eth.SetArgs({"echo", "hello", "world", nullptr});
1360 // int execv(const char* path, char* argv[]);
1361 eth.Run([&]() { execv(BIN_DIR "echo", eth.GetArgs()); }, 0, "hello world\n");
1362}
1363
1364TEST(UNISTD_TEST, execlp_failure) {
1365 errno = 0;
1366 ASSERT_EQ(-1, execlp("/", "/", nullptr));
1367 ASSERT_EQ(EACCES, errno);
1368}
1369
1370TEST(UNISTD_TEST, execlp) {
1371 ExecTestHelper eth;
1372 // int execlp(const char* file, const char* arg, ...);
1373 eth.Run([&]() { execlp("echo", "echo", "hello", "world", nullptr); }, 0, "hello world\n");
1374}
1375
1376TEST(UNISTD_TEST, execvp_failure) {
1377 ExecTestHelper eth;
Elliott Hughes3c115902016-08-24 19:27:04 -07001378 eth.SetArgs({nullptr});
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001379 errno = 0;
1380 ASSERT_EQ(-1, execvp("/", eth.GetArgs()));
1381 ASSERT_EQ(EACCES, errno);
1382}
1383
1384TEST(UNISTD_TEST, execvp) {
1385 ExecTestHelper eth;
1386 eth.SetArgs({"echo", "hello", "world", nullptr});
1387 // int execvp(const char* file, char* argv[]);
1388 eth.Run([&]() { execvp("echo", eth.GetArgs()); }, 0, "hello world\n");
1389}
1390
1391TEST(UNISTD_TEST, execvpe_failure) {
1392 ExecTestHelper eth;
1393 errno = 0;
1394 ASSERT_EQ(-1, execvpe("this-does-not-exist", eth.GetArgs(), eth.GetEnv()));
Elliott Hughes5965bf02016-12-01 17:12:49 -08001395 // Running in CTS we might not even be able to search all directories in $PATH.
1396 ASSERT_TRUE(errno == ENOENT || errno == EACCES);
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001397}
1398
1399TEST(UNISTD_TEST, execvpe) {
1400 // int execvpe(const char* file, char* argv[], char* envp[]);
1401
1402 // Test basic argument passing.
1403 ExecTestHelper eth;
1404 eth.SetArgs({"echo", "hello", "world", nullptr});
1405 eth.Run([&]() { execvpe("echo", eth.GetArgs(), eth.GetEnv()); }, 0, "hello world\n");
1406
1407 // Test environment variable setting too.
1408 eth.SetArgs({"printenv", nullptr});
1409 eth.SetEnv({"A=B", nullptr});
1410 eth.Run([&]() { execvpe("printenv", eth.GetArgs(), eth.GetEnv()); }, 0, "A=B\n");
1411}
Elliott Hughes3c115902016-08-24 19:27:04 -07001412
1413TEST(UNISTD_TEST, execvpe_ENOEXEC) {
1414 // Create a shell script with #!.
1415 TemporaryFile tf;
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001416 ASSERT_TRUE(android::base::WriteStringToFile("#!" BIN_DIR "sh\necho script\n", tf.path));
Elliott Hughes3c115902016-08-24 19:27:04 -07001417
1418 // Set $PATH so we can find it.
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001419 setenv("PATH", dirname(tf.path), 1);
Elliott Hughes3c115902016-08-24 19:27:04 -07001420
1421 ExecTestHelper eth;
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001422 eth.SetArgs({basename(tf.path), nullptr});
Elliott Hughes3c115902016-08-24 19:27:04 -07001423
1424 // It's not inherently executable.
1425 errno = 0;
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001426 ASSERT_EQ(-1, execvpe(basename(tf.path), eth.GetArgs(), eth.GetEnv()));
Elliott Hughes3c115902016-08-24 19:27:04 -07001427 ASSERT_EQ(EACCES, errno);
1428
Elliott Hughes5965bf02016-12-01 17:12:49 -08001429 // Make it executable (and keep it writable because we're going to rewrite it below).
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001430 ASSERT_EQ(0, chmod(tf.path, 0777));
Elliott Hughes3c115902016-08-24 19:27:04 -07001431
1432 // TemporaryFile will have a writable fd, so we can test ETXTBSY while we're here...
1433 errno = 0;
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001434 ASSERT_EQ(-1, execvpe(basename(tf.path), eth.GetArgs(), eth.GetEnv()));
Elliott Hughes3c115902016-08-24 19:27:04 -07001435 ASSERT_EQ(ETXTBSY, errno);
1436
1437 // 1. The simplest test: the kernel should handle this.
1438 ASSERT_EQ(0, close(tf.fd));
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001439 eth.Run([&]() { execvpe(basename(tf.path), eth.GetArgs(), eth.GetEnv()); }, 0, "script\n");
Elliott Hughes3c115902016-08-24 19:27:04 -07001440
1441 // 2. Try again without a #!. We should have to handle this ourselves.
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001442 ASSERT_TRUE(android::base::WriteStringToFile("echo script\n", tf.path));
1443 eth.Run([&]() { execvpe(basename(tf.path), eth.GetArgs(), eth.GetEnv()); }, 0, "script\n");
Elliott Hughes3c115902016-08-24 19:27:04 -07001444
1445 // 3. Again without a #!, but also with a leading '/', since that's a special case in the
1446 // implementation.
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001447 eth.Run([&]() { execvpe(tf.path, eth.GetArgs(), eth.GetEnv()); }, 0, "script\n");
Elliott Hughes3c115902016-08-24 19:27:04 -07001448}
Elliott Hughes63615062016-08-25 17:40:27 -07001449
1450TEST(UNISTD_TEST, execvp_libcore_test_55017) {
1451 ExecTestHelper eth;
1452 eth.SetArgs({"/system/bin/does-not-exist", nullptr});
1453
1454 errno = 0;
1455 ASSERT_EQ(-1, execvp("/system/bin/does-not-exist", eth.GetArgs()));
1456 ASSERT_EQ(ENOENT, errno);
1457}
Elliott Hughes30a36272017-02-22 17:31:41 -08001458
1459TEST(UNISTD_TEST, exec_argv0_null) {
1460 // http://b/33276926
1461 char* args[] = {nullptr};
1462 char* envs[] = {nullptr};
1463 ASSERT_EXIT(execve("/system/bin/run-as", args, envs), testing::ExitedWithCode(1),
1464 "<unknown>: usage: run-as");
1465}
Elliott Hughes06bd5862017-07-28 16:27:49 -07001466
Elliott Hughes4d215aa2017-10-18 15:54:56 -07001467TEST(UNISTD_TEST, fexecve_failure) {
1468 ExecTestHelper eth;
1469 errno = 0;
1470 int fd = open("/", O_RDONLY);
1471 ASSERT_NE(-1, fd);
1472 ASSERT_EQ(-1, fexecve(fd, eth.GetArgs(), eth.GetEnv()));
1473 ASSERT_EQ(EACCES, errno);
1474 close(fd);
1475}
1476
1477TEST(UNISTD_TEST, fexecve_bad_fd) {
1478 ExecTestHelper eth;
1479 errno = 0;
1480 ASSERT_EQ(-1, fexecve(-1, eth.GetArgs(), eth.GetEnv()));
1481 ASSERT_EQ(EBADF, errno);
1482}
1483
1484TEST(UNISTD_TEST, fexecve_args) {
1485 // Test basic argument passing.
1486 int echo_fd = open(BIN_DIR "echo", O_RDONLY | O_CLOEXEC);
1487 ASSERT_NE(-1, echo_fd);
1488 ExecTestHelper eth;
1489 eth.SetArgs({"echo", "hello", "world", nullptr});
1490 eth.Run([&]() { fexecve(echo_fd, eth.GetArgs(), eth.GetEnv()); }, 0, "hello world\n");
1491 close(echo_fd);
1492
1493 // Test environment variable setting too.
1494 int printenv_fd = open(BIN_DIR "printenv", O_RDONLY | O_CLOEXEC);
1495 ASSERT_NE(-1, printenv_fd);
1496 eth.SetArgs({"printenv", nullptr});
1497 eth.SetEnv({"A=B", nullptr});
1498 eth.Run([&]() { fexecve(printenv_fd, eth.GetArgs(), eth.GetEnv()); }, 0, "A=B\n");
1499 close(printenv_fd);
1500}
1501
Elliott Hughes06bd5862017-07-28 16:27:49 -07001502TEST(UNISTD_TEST, getlogin_r) {
1503 char buf[LOGIN_NAME_MAX] = {};
1504 EXPECT_EQ(ERANGE, getlogin_r(buf, 0));
1505 EXPECT_EQ(0, getlogin_r(buf, sizeof(buf)));
1506 EXPECT_STREQ(getlogin(), buf);
1507}
Elliott Hughesfa386e02017-10-18 13:34:32 -07001508
1509TEST(UNISTD_TEST, swab) {
1510 // POSIX: "The swab() function shall copy nbytes bytes, which are pointed to by src,
1511 // to the object pointed to by dest, exchanging adjacent bytes."
1512 char buf[BUFSIZ];
1513 memset(buf, 'x', sizeof(buf));
1514 swab("ehll oowlr\0d", buf, 12);
1515 ASSERT_STREQ("hello world", buf);
1516}
1517
1518TEST(UNISTD_TEST, swab_odd_byte_count) {
1519 // POSIX: "If nbytes is odd, swab() copies and exchanges nbytes-1 bytes and the disposition
1520 // of the last byte is unspecified."
1521 // ...but it seems unreasonable to not just leave the last byte alone.
1522 char buf[BUFSIZ];
1523 memset(buf, 'x', sizeof(buf));
1524 swab("012345", buf, 3);
1525 ASSERT_EQ('1', buf[0]);
1526 ASSERT_EQ('0', buf[1]);
1527 ASSERT_EQ('x', buf[2]);
1528}
1529
1530TEST(UNISTD_TEST, swab_overlap) {
1531 // POSIX: "If copying takes place between objects that overlap, the behavior is undefined."
1532 // ...but it seems unreasonable to not just do the right thing.
1533 char buf[] = "012345";
1534 swab(buf, buf, 4);
1535 ASSERT_EQ('1', buf[0]);
1536 ASSERT_EQ('0', buf[1]);
1537 ASSERT_EQ('3', buf[2]);
1538 ASSERT_EQ('2', buf[3]);
1539 ASSERT_EQ('4', buf[4]);
1540 ASSERT_EQ('5', buf[5]);
1541 ASSERT_EQ(0, buf[6]);
1542}
1543
1544TEST(UNISTD_TEST, swab_negative_byte_count) {
1545 // POSIX: "If nbytes is negative, swab() does nothing."
1546 char buf[BUFSIZ];
1547 memset(buf, 'x', sizeof(buf));
1548 swab("hello", buf, -1);
1549 ASSERT_EQ('x', buf[0]);
1550}
Elliott Hughesca3f8e42019-10-28 15:59:38 -07001551
1552TEST(UNISTD_TEST, usleep) {
1553 auto t0 = std::chrono::steady_clock::now();
1554 ASSERT_EQ(0, usleep(5000));
1555 auto t1 = std::chrono::steady_clock::now();
1556 ASSERT_GE(t1-t0, 5000us);
1557}
1558
1559TEST(UNISTD_TEST, sleep) {
1560 auto t0 = std::chrono::steady_clock::now();
1561 ASSERT_EQ(0U, sleep(1));
1562 auto t1 = std::chrono::steady_clock::now();
1563 ASSERT_GE(t1-t0, 1s);
1564}