blob: 94ce4aa772540f4c8ca15559e10cdfc74f858155 [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
Elliott Hughes71ba5892018-02-07 12:44:45 -080019#include "SignalUtils.h"
Tamas Petz36927f52025-05-13 12:12:43 +020020#include "sme_utils.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>
Elliott Hughes141b9172021-04-09 17:13:09 -070040#include <android-base/silent_death_test.h>
Elliott Hughes939a7e02015-12-04 15:27:46 -080041#include <android-base/strings.h>
Elliott Hughes734a0c92025-08-12 10:33:24 -070042#include <android-base/test_utils.h>
Yabin Cuicb6f5992015-09-29 16:11:45 -070043
44#include "private/get_cpu_count_from_string.h"
45
Josh Gao23032832020-05-07 17:02:19 -070046#if defined(__BIONIC__)
47#include "bionic/pthread_internal.h"
48#endif
49
Christopher Ferris13f26a72016-01-13 13:47:58 -080050#if defined(NOFORTIFY)
51#define UNISTD_TEST unistd_nofortify
52#define UNISTD_DEATHTEST unistd_nofortify_DeathTest
53#else
54#define UNISTD_TEST unistd
55#define UNISTD_DEATHTEST unistd_DeathTest
56#endif
57
Elliott Hughes141b9172021-04-09 17:13:09 -070058using UNISTD_DEATHTEST = SilentDeathTest;
59
Elliott Hughesca3f8e42019-10-28 15:59:38 -070060using namespace std::chrono_literals;
61
Elliott Hughes533dde42014-04-25 18:27:38 -070062static void* get_brk() {
63 return sbrk(0);
64}
Elliott Hughes428f5562013-02-05 16:10:59 -080065
Elliott Hughes533dde42014-04-25 18:27:38 -070066static void* page_align(uintptr_t addr) {
67 uintptr_t mask = sysconf(_SC_PAGE_SIZE) - 1;
68 return reinterpret_cast<void*>((addr + mask) & ~mask);
69}
70
Christopher Ferris13f26a72016-01-13 13:47:58 -080071TEST(UNISTD_TEST, brk) {
Elliott Hughes533dde42014-04-25 18:27:38 -070072 void* initial_break = get_brk();
73
Elliott Hughes533dde42014-04-25 18:27:38 -070074 void* new_break = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(initial_break) + 1);
Daniel Micay126ab122015-12-31 08:04:53 -050075 int ret = brk(new_break);
76 if (ret == -1) {
Elliott Hughes95646e62023-09-21 14:11:19 -070077 ASSERT_ERRNO(ENOMEM);
Daniel Micay126ab122015-12-31 08:04:53 -050078 } else {
79 ASSERT_EQ(0, ret);
80 ASSERT_GE(get_brk(), new_break);
81 }
Elliott Hughes428f5562013-02-05 16:10:59 -080082
Daniel Micay126ab122015-12-31 08:04:53 -050083 // Expand by a full page to force the mapping to expand
Elliott Hughes533dde42014-04-25 18:27:38 -070084 new_break = page_align(reinterpret_cast<uintptr_t>(initial_break) + sysconf(_SC_PAGE_SIZE));
Daniel Micay126ab122015-12-31 08:04:53 -050085 ret = brk(new_break);
86 if (ret == -1) {
Elliott Hughes95646e62023-09-21 14:11:19 -070087 ASSERT_ERRNO(ENOMEM);
Daniel Micay126ab122015-12-31 08:04:53 -050088 } else {
89 ASSERT_EQ(0, ret);
90 ASSERT_EQ(get_brk(), new_break);
91 }
Elliott Hughes533dde42014-04-25 18:27:38 -070092}
93
Christopher Ferris13f26a72016-01-13 13:47:58 -080094TEST(UNISTD_TEST, brk_ENOMEM) {
Elliott Hughes533dde42014-04-25 18:27:38 -070095 ASSERT_EQ(-1, brk(reinterpret_cast<void*>(-1)));
Elliott Hughes95646e62023-09-21 14:11:19 -070096 ASSERT_ERRNO(ENOMEM);
Elliott Hughes533dde42014-04-25 18:27:38 -070097}
98
Christopher Ferris738b0cc2014-05-21 19:03:34 -070099#if defined(__GLIBC__)
100#define SBRK_MIN INTPTR_MIN
101#define SBRK_MAX INTPTR_MAX
102#else
103#define SBRK_MIN PTRDIFF_MIN
104#define SBRK_MAX PTRDIFF_MAX
105#endif
106
Christopher Ferris13f26a72016-01-13 13:47:58 -0800107TEST(UNISTD_TEST, sbrk_ENOMEM) {
Christopher Ferris738b0cc2014-05-21 19:03:34 -0700108#if defined(__BIONIC__) && !defined(__LP64__)
109 // There is no way to guarantee that all overflow conditions can be tested
110 // without manipulating the underlying values of the current break.
111 extern void* __bionic_brk;
112
113 class ScopedBrk {
114 public:
115 ScopedBrk() : saved_brk_(__bionic_brk) {}
116 virtual ~ScopedBrk() { __bionic_brk = saved_brk_; }
117
118 private:
119 void* saved_brk_;
120 };
121
122 ScopedBrk scope_brk;
123
124 // Set the current break to a point that will cause an overflow.
125 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) + 2);
Elliott Hughes533dde42014-04-25 18:27:38 -0700126
127 // Can't increase by so much that we'd overflow.
128 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MAX));
Elliott Hughes95646e62023-09-21 14:11:19 -0700129 ASSERT_ERRNO(ENOMEM);
Elliott Hughes533dde42014-04-25 18:27:38 -0700130
Christopher Ferris738b0cc2014-05-21 19:03:34 -0700131 // Set the current break to a point that will cause an overflow.
132 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX));
Elliott Hughes533dde42014-04-25 18:27:38 -0700133
Elliott Hughes533dde42014-04-25 18:27:38 -0700134 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN));
Elliott Hughes95646e62023-09-21 14:11:19 -0700135 ASSERT_ERRNO(ENOMEM);
Christopher Ferris738b0cc2014-05-21 19:03:34 -0700136
137 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) - 1);
138
139 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN + 1));
Elliott Hughes95646e62023-09-21 14:11:19 -0700140 ASSERT_ERRNO(ENOMEM);
Christopher Ferris738b0cc2014-05-21 19:03:34 -0700141#else
142 class ScopedBrk {
143 public:
144 ScopedBrk() : saved_brk_(get_brk()) {}
145 virtual ~ScopedBrk() { brk(saved_brk_); }
146
147 private:
148 void* saved_brk_;
149 };
150
151 ScopedBrk scope_brk;
152
153 uintptr_t cur_brk = reinterpret_cast<uintptr_t>(get_brk());
154 if (cur_brk < static_cast<uintptr_t>(-(SBRK_MIN+1))) {
155 // Do the overflow test for a max negative increment.
156 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MIN));
157#if defined(__BIONIC__)
158 // GLIBC does not set errno in overflow case.
Elliott Hughes95646e62023-09-21 14:11:19 -0700159 ASSERT_ERRNO(ENOMEM);
Christopher Ferris738b0cc2014-05-21 19:03:34 -0700160#endif
161 }
162
163 uintptr_t overflow_brk = static_cast<uintptr_t>(SBRK_MAX) + 2;
164 if (cur_brk < overflow_brk) {
165 // Try and move the value to PTRDIFF_MAX + 2.
166 cur_brk = reinterpret_cast<uintptr_t>(sbrk(overflow_brk));
167 }
168 if (cur_brk >= overflow_brk) {
169 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MAX));
170#if defined(__BIONIC__)
171 // GLIBC does not set errno in overflow case.
Elliott Hughes95646e62023-09-21 14:11:19 -0700172 ASSERT_ERRNO(ENOMEM);
Christopher Ferris738b0cc2014-05-21 19:03:34 -0700173#endif
174 }
Elliott Hughes533dde42014-04-25 18:27:38 -0700175#endif
Elliott Hughes428f5562013-02-05 16:10:59 -0800176}
Elliott Hughesb4f76162013-09-19 16:27:24 -0700177
Christopher Ferris13f26a72016-01-13 13:47:58 -0800178TEST(UNISTD_TEST, truncate) {
Elliott Hughesb4f76162013-09-19 16:27:24 -0700179 TemporaryFile tf;
180 ASSERT_EQ(0, close(tf.fd));
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800181 ASSERT_EQ(0, truncate(tf.path, 123));
Elliott Hughesb4f76162013-09-19 16:27:24 -0700182
183 struct stat sb;
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800184 ASSERT_EQ(0, stat(tf.path, &sb));
Elliott Hughesb4f76162013-09-19 16:27:24 -0700185 ASSERT_EQ(123, sb.st_size);
186}
187
Colin Cross7da20342021-07-28 11:18:11 -0700188TEST(UNISTD_TEST, truncate64_smoke) {
Elliott Hughesb4f76162013-09-19 16:27:24 -0700189 TemporaryFile tf;
190 ASSERT_EQ(0, close(tf.fd));
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800191 ASSERT_EQ(0, truncate64(tf.path, 123));
Elliott Hughesb4f76162013-09-19 16:27:24 -0700192
193 struct stat sb;
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800194 ASSERT_EQ(0, stat(tf.path, &sb));
Elliott Hughesb4f76162013-09-19 16:27:24 -0700195 ASSERT_EQ(123, sb.st_size);
196}
197
Christopher Ferris13f26a72016-01-13 13:47:58 -0800198TEST(UNISTD_TEST, ftruncate) {
Elliott Hughesb4f76162013-09-19 16:27:24 -0700199 TemporaryFile tf;
200 ASSERT_EQ(0, ftruncate(tf.fd, 123));
201 ASSERT_EQ(0, close(tf.fd));
202
203 struct stat sb;
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800204 ASSERT_EQ(0, stat(tf.path, &sb));
Elliott Hughesb4f76162013-09-19 16:27:24 -0700205 ASSERT_EQ(123, sb.st_size);
206}
207
Colin Cross7da20342021-07-28 11:18:11 -0700208TEST(UNISTD_TEST, ftruncate64_smoke) {
Elliott Hughesb4f76162013-09-19 16:27:24 -0700209 TemporaryFile tf;
210 ASSERT_EQ(0, ftruncate64(tf.fd, 123));
211 ASSERT_EQ(0, close(tf.fd));
212
213 struct stat sb;
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800214 ASSERT_EQ(0, stat(tf.path, &sb));
Elliott Hughesb4f76162013-09-19 16:27:24 -0700215 ASSERT_EQ(123, sb.st_size);
216}
Elliott Hughes11952072013-10-24 15:15:14 -0700217
Christopher Ferris13f26a72016-01-13 13:47:58 -0800218TEST(UNISTD_TEST, ftruncate_negative) {
Dan Albertc05554e2015-05-19 18:17:31 -0700219 TemporaryFile tf;
220 errno = 0;
Dan Albert9d476a02015-06-01 11:28:31 -0700221 ASSERT_EQ(-1, ftruncate(tf.fd, -123));
Elliott Hughes95646e62023-09-21 14:11:19 -0700222 ASSERT_ERRNO(EINVAL);
Dan Albertc05554e2015-05-19 18:17:31 -0700223}
224
Elliott Hughes1728b232014-05-14 10:02:03 -0700225static bool g_pause_test_flag = false;
Elliott Hughes11952072013-10-24 15:15:14 -0700226static void PauseTestSignalHandler(int) {
Elliott Hughes1728b232014-05-14 10:02:03 -0700227 g_pause_test_flag = true;
Elliott Hughes11952072013-10-24 15:15:14 -0700228}
229
Christopher Ferris13f26a72016-01-13 13:47:58 -0800230TEST(UNISTD_TEST, pause) {
Christopher Ferris13613132013-10-28 15:24:04 -0700231 ScopedSignalHandler handler(SIGALRM, PauseTestSignalHandler);
232
Elliott Hughes11952072013-10-24 15:15:14 -0700233 alarm(1);
Elliott Hughes1728b232014-05-14 10:02:03 -0700234 ASSERT_FALSE(g_pause_test_flag);
Elliott Hughes11952072013-10-24 15:15:14 -0700235 ASSERT_EQ(-1, pause());
Elliott Hughes1728b232014-05-14 10:02:03 -0700236 ASSERT_TRUE(g_pause_test_flag);
Elliott Hughes11952072013-10-24 15:15:14 -0700237}
Colin Cross3d19a832014-02-14 18:56:23 -0800238
Christopher Ferris13f26a72016-01-13 13:47:58 -0800239TEST(UNISTD_TEST, read) {
Colin Cross3d19a832014-02-14 18:56:23 -0800240 int fd = open("/proc/version", O_RDONLY);
241 ASSERT_TRUE(fd != -1);
242
243 char buf[5];
244 ASSERT_EQ(5, read(fd, buf, 5));
245 ASSERT_EQ(buf[0], 'L');
246 ASSERT_EQ(buf[1], 'i');
247 ASSERT_EQ(buf[2], 'n');
248 ASSERT_EQ(buf[3], 'u');
249 ASSERT_EQ(buf[4], 'x');
250 close(fd);
251}
252
Christopher Ferris13f26a72016-01-13 13:47:58 -0800253TEST(UNISTD_TEST, read_EBADF) {
Colin Cross3d19a832014-02-14 18:56:23 -0800254 // read returns ssize_t which is 64-bits on LP64, so it's worth explicitly checking that
255 // our syscall stubs correctly return a 64-bit -1.
256 char buf[1];
257 ASSERT_EQ(-1, read(-1, buf, sizeof(buf)));
Elliott Hughes95646e62023-09-21 14:11:19 -0700258 ASSERT_ERRNO(EBADF);
Colin Cross3d19a832014-02-14 18:56:23 -0800259}
Elliott Hughesaedb00d2014-03-03 14:38:20 -0800260
Christopher Ferris13f26a72016-01-13 13:47:58 -0800261TEST(UNISTD_TEST, syscall_long) {
Elliott Hughes21972b62014-07-28 12:24:22 -0700262 // Check that syscall(3) correctly returns long results.
263 // https://code.google.com/p/android/issues/detail?id=73952
264 // We assume that the break is > 4GiB, but this is potentially flaky.
265 uintptr_t p = reinterpret_cast<uintptr_t>(sbrk(0));
266 ASSERT_EQ(p, static_cast<uintptr_t>(syscall(__NR_brk, 0)));
267}
268
Christopher Ferris13f26a72016-01-13 13:47:58 -0800269TEST(UNISTD_TEST, alarm) {
Elliott Hughesaedb00d2014-03-03 14:38:20 -0800270 ASSERT_EQ(0U, alarm(0));
271}
Elliott Hughes9f525642014-04-08 17:14:01 -0700272
Christopher Ferris13f26a72016-01-13 13:47:58 -0800273TEST(UNISTD_TEST, _exit) {
Elliott Hughes33697a02016-01-26 13:04:57 -0800274 pid_t pid = fork();
Elliott Hughes9f525642014-04-08 17:14:01 -0700275 ASSERT_NE(-1, pid) << strerror(errno);
276
277 if (pid == 0) {
278 _exit(99);
279 }
280
Elliott Hughes33697a02016-01-26 13:04:57 -0800281 AssertChildExited(pid, 99);
Elliott Hughes9f525642014-04-08 17:14:01 -0700282}
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400283
Christopher Ferris13f26a72016-01-13 13:47:58 -0800284TEST(UNISTD_TEST, getenv_unsetenv) {
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400285 ASSERT_EQ(0, setenv("test-variable", "hello", 1));
286 ASSERT_STREQ("hello", getenv("test-variable"));
287 ASSERT_EQ(0, unsetenv("test-variable"));
Yi Kong32bc0fc2018-08-02 17:31:13 -0700288 ASSERT_TRUE(getenv("test-variable") == nullptr);
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400289}
290
Christopher Ferris13f26a72016-01-13 13:47:58 -0800291TEST(UNISTD_TEST, unsetenv_EINVAL) {
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400292 EXPECT_EQ(-1, unsetenv(""));
Elliott Hughes95646e62023-09-21 14:11:19 -0700293 EXPECT_ERRNO(EINVAL);
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400294 EXPECT_EQ(-1, unsetenv("a=b"));
Elliott Hughes95646e62023-09-21 14:11:19 -0700295 EXPECT_ERRNO(EINVAL);
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400296}
297
Christopher Ferris13f26a72016-01-13 13:47:58 -0800298TEST(UNISTD_TEST, setenv_EINVAL) {
zijunzhao5a918d92022-11-28 21:05:55 +0000299#pragma clang diagnostic push
300#pragma clang diagnostic ignored "-Wnonnull"
Yi Kong32bc0fc2018-08-02 17:31:13 -0700301 EXPECT_EQ(-1, setenv(nullptr, "value", 0));
Elliott Hughes95646e62023-09-21 14:11:19 -0700302 EXPECT_ERRNO(EINVAL);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700303 EXPECT_EQ(-1, setenv(nullptr, "value", 1));
Elliott Hughes95646e62023-09-21 14:11:19 -0700304 EXPECT_ERRNO(EINVAL);
zijunzhao5a918d92022-11-28 21:05:55 +0000305#pragma clang diagnostic pop
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400306 EXPECT_EQ(-1, setenv("", "value", 0));
Elliott Hughes95646e62023-09-21 14:11:19 -0700307 EXPECT_ERRNO(EINVAL);
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400308 EXPECT_EQ(-1, setenv("", "value", 1));
Elliott Hughes95646e62023-09-21 14:11:19 -0700309 EXPECT_ERRNO(EINVAL);
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400310 EXPECT_EQ(-1, setenv("a=b", "value", 0));
Elliott Hughes95646e62023-09-21 14:11:19 -0700311 EXPECT_ERRNO(EINVAL);
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400312 EXPECT_EQ(-1, setenv("a=b", "value", 1));
Elliott Hughes95646e62023-09-21 14:11:19 -0700313 EXPECT_ERRNO(EINVAL);
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400314}
315
Christopher Ferris13f26a72016-01-13 13:47:58 -0800316TEST(UNISTD_TEST, setenv) {
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400317 ASSERT_EQ(0, unsetenv("test-variable"));
318
319 char a[] = "a";
320 char b[] = "b";
321 char c[] = "c";
322
323 // New value.
324 EXPECT_EQ(0, setenv("test-variable", a, 0));
325 EXPECT_STREQ(a, getenv("test-variable"));
326
327 // Existing value, no overwrite.
328 EXPECT_EQ(0, setenv("test-variable", b, 0));
329 EXPECT_STREQ(a, getenv("test-variable"));
330
331 // Existing value, overwrite.
332 EXPECT_EQ(0, setenv("test-variable", c, 1));
333 EXPECT_STREQ(c, getenv("test-variable"));
334 // But the arrays backing the values are unchanged.
335 EXPECT_EQ('a', a[0]);
336 EXPECT_EQ('b', b[0]);
337 EXPECT_EQ('c', c[0]);
338
339 ASSERT_EQ(0, unsetenv("test-variable"));
340}
341
Christopher Ferris13f26a72016-01-13 13:47:58 -0800342TEST(UNISTD_TEST, putenv) {
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400343 ASSERT_EQ(0, unsetenv("a"));
344
345 char* s1 = strdup("a=b");
346 ASSERT_EQ(0, putenv(s1));
347
348 ASSERT_STREQ("b", getenv("a"));
349 s1[2] = 'c';
350 ASSERT_STREQ("c", getenv("a"));
351
352 char* s2 = strdup("a=b");
353 ASSERT_EQ(0, putenv(s2));
354
355 ASSERT_STREQ("b", getenv("a"));
356 ASSERT_EQ('c', s1[2]);
357
358 ASSERT_EQ(0, unsetenv("a"));
359 free(s1);
360 free(s2);
361}
362
Christopher Ferris13f26a72016-01-13 13:47:58 -0800363TEST(UNISTD_TEST, clearenv) {
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400364 extern char** environ;
365
366 // Guarantee that environ is not initially empty...
367 ASSERT_EQ(0, setenv("test-variable", "a", 1));
368
369 // Stash a copy.
370 std::vector<char*> old_environ;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700371 for (size_t i = 0; environ[i] != nullptr; ++i) {
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400372 old_environ.push_back(strdup(environ[i]));
373 }
374
375 ASSERT_EQ(0, clearenv());
376
Yi Kong32bc0fc2018-08-02 17:31:13 -0700377 EXPECT_TRUE(environ == nullptr || environ[0] == nullptr);
378 EXPECT_EQ(nullptr, getenv("test-variable"));
Grigoriy Kraynovcbf6df02013-09-17 15:44:22 +0400379 EXPECT_EQ(0, setenv("test-variable", "post-clear", 1));
380 EXPECT_STREQ("post-clear", getenv("test-variable"));
381
382 // Put the old environment back.
383 for (size_t i = 0; i < old_environ.size(); ++i) {
384 EXPECT_EQ(0, putenv(old_environ[i]));
385 }
386
387 // Check it wasn't overwritten.
388 EXPECT_STREQ("a", getenv("test-variable"));
389
390 EXPECT_EQ(0, unsetenv("test-variable"));
391}
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700392
Elliott Hughes896362e2017-08-24 16:31:49 -0700393static void TestSyncFunction(int (*fn)(int)) {
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700394 int fd;
395
396 // Can't sync an invalid fd.
397 errno = 0;
398 EXPECT_EQ(-1, fn(-1));
Elliott Hughes95646e62023-09-21 14:11:19 -0700399 EXPECT_ERRNO(EBADF);
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700400
401 // It doesn't matter whether you've opened a file for write or not.
402 TemporaryFile tf;
403 ASSERT_NE(-1, tf.fd);
404
405 EXPECT_EQ(0, fn(tf.fd));
406
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800407 ASSERT_NE(-1, fd = open(tf.path, O_RDONLY));
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700408 EXPECT_EQ(0, fn(fd));
409 close(fd);
410
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800411 ASSERT_NE(-1, fd = open(tf.path, O_RDWR));
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700412 EXPECT_EQ(0, fn(fd));
413 close(fd);
414
415 // The fd can even be a directory.
Christopher Ferrisa948a4e2016-05-20 15:32:47 -0700416 ASSERT_NE(-1, fd = open("/data/local/tmp", O_RDONLY));
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700417 EXPECT_EQ(0, fn(fd));
418 close(fd);
Elliott Hughes896362e2017-08-24 16:31:49 -0700419}
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700420
Elliott Hughes896362e2017-08-24 16:31:49 -0700421static void TestFsyncFunction(int (*fn)(int)) {
422 TestSyncFunction(fn);
423
424 // But some file systems are fussy about fsync/fdatasync...
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700425 errno = 0;
Elliott Hughes896362e2017-08-24 16:31:49 -0700426 int fd = open("/proc/version", O_RDONLY);
427 ASSERT_NE(-1, fd);
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700428 EXPECT_EQ(-1, fn(fd));
Elliott Hughes95646e62023-09-21 14:11:19 -0700429 EXPECT_ERRNO(EINVAL);
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700430 close(fd);
431}
432
Christopher Ferris13f26a72016-01-13 13:47:58 -0800433TEST(UNISTD_TEST, fdatasync) {
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700434 TestFsyncFunction(fdatasync);
435}
436
Christopher Ferris13f26a72016-01-13 13:47:58 -0800437TEST(UNISTD_TEST, fsync) {
Elliott Hughesa62a28d2014-05-07 14:30:33 -0700438 TestFsyncFunction(fsync);
439}
Elliott Hughes7086ad62014-06-19 16:39:01 -0700440
Elliott Hughes896362e2017-08-24 16:31:49 -0700441TEST(UNISTD_TEST, syncfs) {
442 TestSyncFunction(syncfs);
443}
444
Elliott Hughes2411fff2024-02-24 23:55:58 +0000445TEST(UNISTD_TEST, _Fork) {
446#if defined(__BIONIC__)
447 pid_t rc = _Fork();
448 ASSERT_NE(-1, rc);
449 if (rc == 0) {
450 _exit(66);
451 }
452
453 int status;
454 pid_t wait_result = waitpid(rc, &status, 0);
455 ASSERT_EQ(wait_result, rc);
456 ASSERT_TRUE(WIFEXITED(status));
457 ASSERT_EQ(66, WEXITSTATUS(status));
458#endif
459}
460
Josh Gao23032832020-05-07 17:02:19 -0700461TEST(UNISTD_TEST, vfork) {
462#if defined(__BIONIC__)
463 pthread_internal_t* self = __get_thread();
464
465 pid_t cached_pid;
466 ASSERT_TRUE(self->get_cached_pid(&cached_pid));
467 ASSERT_EQ(syscall(__NR_getpid), cached_pid);
468 ASSERT_FALSE(self->is_vforked());
469
470 pid_t rc = vfork();
471 ASSERT_NE(-1, rc);
472 if (rc == 0) {
473 if (self->get_cached_pid(&cached_pid)) {
474 const char* error = "__get_thread()->cached_pid_ set after vfork\n";
475 write(STDERR_FILENO, error, strlen(error));
476 _exit(1);
477 }
478
479 if (!self->is_vforked()) {
480 const char* error = "__get_thread()->vforked_ not set after vfork\n";
481 write(STDERR_FILENO, error, strlen(error));
482 _exit(1);
483 }
484
485 _exit(0);
486 } else {
487 ASSERT_TRUE(self->get_cached_pid(&cached_pid));
488 ASSERT_EQ(syscall(__NR_getpid), cached_pid);
489 ASSERT_FALSE(self->is_vforked());
490
491 int status;
492 pid_t wait_result = waitpid(rc, &status, 0);
493 ASSERT_EQ(wait_result, rc);
494 ASSERT_TRUE(WIFEXITED(status));
495 ASSERT_EQ(0, WEXITSTATUS(status));
496 }
497#endif
498}
499
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700500static void AssertGetPidCorrect() {
501 // The loop is just to make manual testing/debugging with strace easier.
502 pid_t getpid_syscall_result = syscall(__NR_getpid);
503 for (size_t i = 0; i < 128; ++i) {
504 ASSERT_EQ(getpid_syscall_result, getpid());
505 }
506}
507
Elliott Hughes3b888b62025-07-17 08:16:23 -0700508static void TestGetPidWorksAfterFork(int (*fork_fn)(), void (*exit_fn)(int)) {
Elliott Hughes7086ad62014-06-19 16:39:01 -0700509 pid_t parent_pid = getpid();
510 ASSERT_EQ(syscall(__NR_getpid), parent_pid);
511
Elliott Hughes5891abd2015-08-07 18:27:47 -0700512 pid_t fork_result = fork_fn();
Elliott Hughes7086ad62014-06-19 16:39:01 -0700513 ASSERT_NE(fork_result, -1);
514 if (fork_result == 0) {
515 // We're the child.
Robert Seseka4edf7a2016-10-25 10:29:02 -0400516 ASSERT_NO_FATAL_FAILURE(AssertGetPidCorrect());
Elliott Hughes7086ad62014-06-19 16:39:01 -0700517 ASSERT_EQ(parent_pid, getppid());
Robert Seseke4621172016-11-03 15:00:53 -0400518 exit_fn(123);
Elliott Hughes7086ad62014-06-19 16:39:01 -0700519 } else {
520 // We're the parent.
521 ASSERT_EQ(parent_pid, getpid());
Elliott Hughes33697a02016-01-26 13:04:57 -0800522 AssertChildExited(fork_result, 123);
Elliott Hughes7086ad62014-06-19 16:39:01 -0700523 }
524}
525
Robert Seseka4edf7a2016-10-25 10:29:02 -0400526// gettid() is marked as __attribute_const__, which will have the compiler
527// optimize out multiple calls to gettid in the same function. This wrapper
528// defeats that optimization.
529static __attribute__((__noinline__)) pid_t GetTidForTest() {
530 __asm__("");
531 return gettid();
532}
533
534static void AssertGetTidCorrect() {
535 // The loop is just to make manual testing/debugging with strace easier.
536 pid_t gettid_syscall_result = syscall(__NR_gettid);
537 for (size_t i = 0; i < 128; ++i) {
538 ASSERT_EQ(gettid_syscall_result, GetTidForTest());
539 }
540}
541
Elliott Hughes3b888b62025-07-17 08:16:23 -0700542static void TestGetTidWorksAfterFork(int (*fork_fn)(), void (*exit_fn)(int)) {
Robert Seseka4edf7a2016-10-25 10:29:02 -0400543 pid_t parent_tid = GetTidForTest();
544 ASSERT_EQ(syscall(__NR_gettid), parent_tid);
545
546 pid_t fork_result = fork_fn();
547 ASSERT_NE(fork_result, -1);
548 if (fork_result == 0) {
549 // We're the child.
550 EXPECT_EQ(syscall(__NR_getpid), syscall(__NR_gettid));
551 EXPECT_EQ(getpid(), GetTidForTest()) << "real tid is " << syscall(__NR_gettid)
552 << ", pid is " << syscall(__NR_getpid);
553 ASSERT_NO_FATAL_FAILURE(AssertGetTidCorrect());
Robert Seseke4621172016-11-03 15:00:53 -0400554 exit_fn(123);
Robert Seseka4edf7a2016-10-25 10:29:02 -0400555 } else {
556 // We're the parent.
557 ASSERT_EQ(parent_tid, GetTidForTest());
558 AssertChildExited(fork_result, 123);
559 }
560}
561
Elliott Hughes3b888b62025-07-17 08:16:23 -0700562TEST(UNISTD_TEST, getpid_works_after_fork) {
563 TestGetPidWorksAfterFork(fork, exit);
Elliott Hughes5891abd2015-08-07 18:27:47 -0700564}
565
Elliott Hughes3b888b62025-07-17 08:16:23 -0700566TEST(UNISTD_TEST, gettid_works_after_fork) {
567 TestGetTidWorksAfterFork(fork, exit);
Robert Seseka4edf7a2016-10-25 10:29:02 -0400568}
569
Elliott Hughes3b888b62025-07-17 08:16:23 -0700570TEST(UNISTD_TEST, getpid_works_after_vfork) {
571 TestGetPidWorksAfterFork(vfork, _exit);
Elliott Hughes5891abd2015-08-07 18:27:47 -0700572}
573
Robert Seseka4edf7a2016-10-25 10:29:02 -0400574static int CloneLikeFork() {
575 return clone(nullptr, nullptr, SIGCHLD, nullptr);
576}
577
Elliott Hughes3b888b62025-07-17 08:16:23 -0700578TEST(UNISTD_TEST, getpid_works_after_clone_process) {
579 TestGetPidWorksAfterFork(CloneLikeFork, exit);
Robert Seseka4edf7a2016-10-25 10:29:02 -0400580}
581
Elliott Hughes3b888b62025-07-17 08:16:23 -0700582TEST(UNISTD_TEST, gettid_works_after_clone_process) {
583 TestGetTidWorksAfterFork(CloneLikeFork, exit);
Robert Seseka4edf7a2016-10-25 10:29:02 -0400584}
585
586static int CloneAndSetTid() {
587 pid_t child_tid = 0;
588 pid_t parent_tid = GetTidForTest();
589
590 int rv = clone(nullptr, nullptr, CLONE_CHILD_SETTID | SIGCHLD, nullptr, nullptr, nullptr, &child_tid);
591 EXPECT_NE(-1, rv);
592
593 if (rv == 0) {
594 // Child.
595 EXPECT_EQ(child_tid, GetTidForTest());
596 EXPECT_NE(child_tid, parent_tid);
597 } else {
598 EXPECT_NE(child_tid, GetTidForTest());
599 EXPECT_NE(child_tid, parent_tid);
600 EXPECT_EQ(GetTidForTest(), parent_tid);
601 }
602
603 return rv;
604}
605
Elliott Hughes3b888b62025-07-17 08:16:23 -0700606TEST(UNISTD_TEST, gettid_works_after_clone_process_settid) {
607 TestGetTidWorksAfterFork(CloneAndSetTid, exit);
Robert Seseka4edf7a2016-10-25 10:29:02 -0400608}
609
Peter Collingbourne955f0442023-03-21 22:52:40 -0700610__attribute__((no_sanitize("hwaddress", "memtag")))
Robert Seseka4edf7a2016-10-25 10:29:02 -0400611static int CloneStartRoutine(int (*start_routine)(void*)) {
612 void* child_stack[1024];
Peter Collingbourne955f0442023-03-21 22:52:40 -0700613 return clone(start_routine, &child_stack[1024], SIGCHLD, nullptr);
Robert Seseka4edf7a2016-10-25 10:29:02 -0400614}
615
Elliott Hughes3b888b62025-07-17 08:16:23 -0700616static int GetPidWorksInCloneStartRoutine(void*) {
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700617 AssertGetPidCorrect();
618 return 123;
Elliott Hughes7086ad62014-06-19 16:39:01 -0700619}
620
Elliott Hughes3b888b62025-07-17 08:16:23 -0700621TEST(UNISTD_TEST, getpid_works_after_clone) {
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700622 pid_t parent_pid = getpid();
623 ASSERT_EQ(syscall(__NR_getpid), parent_pid);
624
Elliott Hughes3b888b62025-07-17 08:16:23 -0700625 int clone_result = CloneStartRoutine(GetPidWorksInCloneStartRoutine);
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700626 ASSERT_NE(clone_result, -1);
627
628 ASSERT_EQ(parent_pid, getpid());
629
Elliott Hughes33697a02016-01-26 13:04:57 -0800630 AssertChildExited(clone_result, 123);
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700631}
632
Elliott Hughes3b888b62025-07-17 08:16:23 -0700633static int GetTidWorksInCloneStartRoutine(void*) {
Robert Seseka4edf7a2016-10-25 10:29:02 -0400634 AssertGetTidCorrect();
635 return 123;
636}
637
Elliott Hughes3b888b62025-07-17 08:16:23 -0700638TEST(UNISTD_TEST, gettid_works_after_clone) {
Robert Seseka4edf7a2016-10-25 10:29:02 -0400639 pid_t parent_tid = GetTidForTest();
640 ASSERT_EQ(syscall(__NR_gettid), parent_tid);
641
Elliott Hughes3b888b62025-07-17 08:16:23 -0700642 int clone_result = CloneStartRoutine(GetTidWorksInCloneStartRoutine);
Robert Seseka4edf7a2016-10-25 10:29:02 -0400643 ASSERT_NE(clone_result, -1);
644
645 ASSERT_EQ(parent_tid, GetTidForTest());
646
647 AssertChildExited(clone_result, 123);
648}
649
Robert Seseke4621172016-11-03 15:00:53 -0400650static int CloneChildExit(void*) {
651 AssertGetPidCorrect();
652 AssertGetTidCorrect();
653 exit(33);
654}
655
656TEST(UNISTD_TEST, clone_fn_and_exit) {
657 int clone_result = CloneStartRoutine(CloneChildExit);
658 ASSERT_NE(-1, clone_result);
659
660 AssertGetPidCorrect();
661 AssertGetTidCorrect();
662
663 AssertChildExited(clone_result, 33);
664}
665
Elliott Hughes3b888b62025-07-17 08:16:23 -0700666static void* GetPidWorksInPthreadStartRoutine(void*) {
Elliott Hughesfa9e16e2014-06-23 17:49:45 -0700667 AssertGetPidCorrect();
Yi Kong32bc0fc2018-08-02 17:31:13 -0700668 return nullptr;
Elliott Hughes7086ad62014-06-19 16:39:01 -0700669}
670
Elliott Hughes3b888b62025-07-17 08:16:23 -0700671TEST(UNISTD_TEST, getpid_works_after_pthread_create) {
Elliott Hughes7086ad62014-06-19 16:39:01 -0700672 pid_t parent_pid = getpid();
673
674 pthread_t t;
Elliott Hughes3b888b62025-07-17 08:16:23 -0700675 ASSERT_EQ(0, pthread_create(&t, nullptr, GetPidWorksInPthreadStartRoutine, nullptr));
Elliott Hughes7086ad62014-06-19 16:39:01 -0700676
677 ASSERT_EQ(parent_pid, getpid());
678
679 void* result;
680 ASSERT_EQ(0, pthread_join(t, &result));
Yi Kong32bc0fc2018-08-02 17:31:13 -0700681 ASSERT_EQ(nullptr, result);
Elliott Hughes7086ad62014-06-19 16:39:01 -0700682}
Elliott Hughes60452a22014-09-22 14:41:30 -0700683
Elliott Hughes3b888b62025-07-17 08:16:23 -0700684static void* GetTidWorksInPthreadStartRoutine(void*) {
Robert Seseka4edf7a2016-10-25 10:29:02 -0400685 AssertGetTidCorrect();
686 uint64_t tid = GetTidForTest();
687 return reinterpret_cast<void*>(tid);
688}
689
Elliott Hughes3b888b62025-07-17 08:16:23 -0700690TEST(UNISTD_TEST, gettid_works_after_pthread_create) {
Robert Seseka4edf7a2016-10-25 10:29:02 -0400691 pid_t parent_tid = GetTidForTest();
692
693 pthread_t t;
Elliott Hughes3b888b62025-07-17 08:16:23 -0700694 ASSERT_EQ(0, pthread_create(&t, nullptr, GetTidWorksInPthreadStartRoutine, &parent_tid));
Robert Seseka4edf7a2016-10-25 10:29:02 -0400695
696 ASSERT_EQ(parent_tid, GetTidForTest());
697
698 void* result;
699 ASSERT_EQ(0, pthread_join(t, &result));
700 ASSERT_NE(static_cast<uint64_t>(parent_tid), reinterpret_cast<uint64_t>(result));
701}
702
Evgenii Stepanov505168e2019-02-28 18:44:56 -0800703__attribute__((noinline)) static void HwasanVforkTestChild() {
704 // Allocate a tagged region on stack and leave it there.
705 char x[10000];
Elliott Hughes734a0c92025-08-12 10:33:24 -0700706 android::base::DoNotOptimize(x);
Evgenii Stepanov505168e2019-02-28 18:44:56 -0800707 _exit(0);
708}
709
710__attribute__((noinline)) static void HwasanReadMemory(const char* p, size_t size) {
711 // Read memory byte-by-byte. This will blow up if the pointer tag in p does not match any memory
712 // tag in [p, p+size).
Christopher Ferris724efbb2021-12-14 06:28:40 +0000713 char z;
Evgenii Stepanov505168e2019-02-28 18:44:56 -0800714 for (size_t i = 0; i < size; ++i) {
Elliott Hughes734a0c92025-08-12 10:33:24 -0700715 android::base::DoNotOptimize(z = p[i]);
Evgenii Stepanov505168e2019-02-28 18:44:56 -0800716 }
717}
718
719__attribute__((noinline, no_sanitize("hwaddress"))) static void HwasanVforkTestParent() {
720 // Allocate a region on stack, but don't tag it (see the function attribute).
721 // This depends on unallocated stack space at current function entry being untagged.
722 char x[10000];
Elliott Hughes734a0c92025-08-12 10:33:24 -0700723 android::base::DoNotOptimize(x);
Evgenii Stepanov505168e2019-02-28 18:44:56 -0800724 // Verify that contents of x[] are untagged.
725 HwasanReadMemory(x, sizeof(x));
726}
727
728TEST(UNISTD_TEST, hwasan_vfork) {
729 // Test hwasan annotation in vfork. This test is only interesting when built with hwasan, but it
730 // is supposed to work correctly either way.
731 if (vfork()) {
732 HwasanVforkTestParent();
733 } else {
734 HwasanVforkTestChild();
735 }
736}
737
Christopher Ferris13f26a72016-01-13 13:47:58 -0800738TEST_F(UNISTD_DEATHTEST, abort) {
Elliott Hughes60452a22014-09-22 14:41:30 -0700739 ASSERT_EXIT(abort(), testing::KilledBySignal(SIGABRT), "");
740}
Elliott Hughesb86a4c72014-11-07 16:07:13 -0800741
Christopher Ferris13f26a72016-01-13 13:47:58 -0800742TEST(UNISTD_TEST, sethostname) {
Elliott Hughesb86a4c72014-11-07 16:07:13 -0800743 // The permissions check happens before the argument check, so this will
744 // fail for a different reason if you're running as root than if you're
745 // not, but it'll fail either way. Checking that we have the symbol is about
746 // all we can do for sethostname(2).
747 ASSERT_EQ(-1, sethostname("", -1));
748}
Derek Xued94e7f02014-09-25 11:12:01 +0100749
Christopher Ferris13f26a72016-01-13 13:47:58 -0800750TEST(UNISTD_TEST, gethostname) {
Derek Xued94e7f02014-09-25 11:12:01 +0100751 char hostname[HOST_NAME_MAX + 1];
Derek Xued94e7f02014-09-25 11:12:01 +0100752 memset(hostname, 0, sizeof(hostname));
753
Yongqin Liu2f954ba2014-10-30 16:34:55 +0800754 // Can we get the hostname with a big buffer?
Derek Xued94e7f02014-09-25 11:12:01 +0100755 ASSERT_EQ(0, gethostname(hostname, HOST_NAME_MAX));
Yongqin Liu2f954ba2014-10-30 16:34:55 +0800756
757 // Can we get the hostname with a right-sized buffer?
Yongqin Liu2f954ba2014-10-30 16:34:55 +0800758 ASSERT_EQ(0, gethostname(hostname, strlen(hostname) + 1));
759
760 // Does uname(2) agree?
Derek Xued94e7f02014-09-25 11:12:01 +0100761 utsname buf;
762 ASSERT_EQ(0, uname(&buf));
Colin Cross7da20342021-07-28 11:18:11 -0700763 ASSERT_EQ(0, strncmp(hostname, buf.nodename, sizeof(buf.nodename)));
Derek Xued94e7f02014-09-25 11:12:01 +0100764 ASSERT_GT(strlen(hostname), 0U);
765
Yongqin Liu2f954ba2014-10-30 16:34:55 +0800766 // Do we correctly detect truncation?
Derek Xued94e7f02014-09-25 11:12:01 +0100767 errno = 0;
768 ASSERT_EQ(-1, gethostname(hostname, strlen(hostname)));
Elliott Hughes95646e62023-09-21 14:11:19 -0700769 ASSERT_ERRNO(ENAMETOOLONG);
Derek Xued94e7f02014-09-25 11:12:01 +0100770}
Yabin Cuib5e581a2014-11-08 14:58:12 -0800771
Christopher Ferris13f26a72016-01-13 13:47:58 -0800772TEST(UNISTD_TEST, pathconf_fpathconf) {
Yabin Cuib5e581a2014-11-08 14:58:12 -0800773 TemporaryFile tf;
Elliott Hughesae0d0c92024-02-21 18:58:24 +0000774 long l;
775
Yabin Cuib5e581a2014-11-08 14:58:12 -0800776 // As a file system's block size is always power of 2, the configure values
777 // for ALLOC and XFER should be power of 2 as well.
Elliott Hughesae0d0c92024-02-21 18:58:24 +0000778 l = pathconf(tf.path, _PC_ALLOC_SIZE_MIN);
779 ASSERT_TRUE(l > 0 && powerof2(l));
780 l = pathconf(tf.path, _PC_REC_MIN_XFER_SIZE);
781 ASSERT_TRUE(l > 0 && powerof2(l));
782 l = pathconf(tf.path, _PC_REC_XFER_ALIGN);
783 ASSERT_TRUE(l > 0 && powerof2(l));
Yabin Cuib5e581a2014-11-08 14:58:12 -0800784
Elliott Hughesae0d0c92024-02-21 18:58:24 +0000785 l = fpathconf(tf.fd, _PC_ALLOC_SIZE_MIN);
786 ASSERT_TRUE(l > 0 && powerof2(l));
787 l = fpathconf(tf.fd, _PC_REC_MIN_XFER_SIZE);
788 ASSERT_TRUE(l > 0 && powerof2(l));
789 l = fpathconf(tf.fd, _PC_REC_XFER_ALIGN);
790 ASSERT_TRUE(l > 0 && powerof2(l));
791
792 // Check that the "I can't answer that, you'll have to try it and see"
793 // cases don't set errno.
794 int names[] = {
795 _PC_ASYNC_IO, _PC_PRIO_IO, _PC_REC_INCR_XFER_SIZE, _PC_REC_MAX_XFER_SIZE, _PC_SYMLINK_MAX,
796 _PC_SYNC_IO, -1};
797 for (size_t i = 0; names[i] != -1; i++) {
798 errno = 0;
799 ASSERT_EQ(-1, pathconf(tf.path, names[i])) << names[i];
800 ASSERT_ERRNO(0) << names[i];
801 ASSERT_EQ(-1, fpathconf(tf.fd, names[i])) << names[i];
802 ASSERT_ERRNO(0) << names[i];
803 }
Yabin Cuib5e581a2014-11-08 14:58:12 -0800804}
Derek Xuebc644762014-09-25 10:55:34 +0100805
Elliott Hughes19d76852017-10-18 13:27:01 -0700806TEST(UNISTD_TEST, _POSIX_constants) {
Yabin Cui1c191942014-11-19 19:49:14 -0800807 // Make a tight verification of _POSIX_* / _POSIX2_* / _XOPEN_* macros, to prevent change by mistake.
808 // Verify according to POSIX.1-2008.
809 EXPECT_EQ(200809L, _POSIX_VERSION);
810
Elliott Hughes19d76852017-10-18 13:27:01 -0700811 EXPECT_EQ(2, _POSIX_AIO_LISTIO_MAX);
812 EXPECT_EQ(1, _POSIX_AIO_MAX);
813 EXPECT_EQ(4096, _POSIX_ARG_MAX);
814 EXPECT_EQ(25, _POSIX_CHILD_MAX);
815 EXPECT_EQ(20000000, _POSIX_CLOCKRES_MIN);
816 EXPECT_EQ(32, _POSIX_DELAYTIMER_MAX);
817 EXPECT_EQ(255, _POSIX_HOST_NAME_MAX);
818 EXPECT_EQ(8, _POSIX_LINK_MAX);
819 EXPECT_EQ(9, _POSIX_LOGIN_NAME_MAX);
820 EXPECT_EQ(255, _POSIX_MAX_CANON);
821 EXPECT_EQ(255, _POSIX_MAX_INPUT);
822 EXPECT_EQ(8, _POSIX_MQ_OPEN_MAX);
823 EXPECT_EQ(32, _POSIX_MQ_PRIO_MAX);
824 EXPECT_EQ(14, _POSIX_NAME_MAX);
825 EXPECT_EQ(8, _POSIX_NGROUPS_MAX);
826 EXPECT_EQ(20, _POSIX_OPEN_MAX);
827 EXPECT_EQ(256, _POSIX_PATH_MAX);
828 EXPECT_EQ(512, _POSIX_PIPE_BUF);
829 EXPECT_EQ(255, _POSIX_RE_DUP_MAX);
830 EXPECT_EQ(8, _POSIX_RTSIG_MAX);
831 EXPECT_EQ(256, _POSIX_SEM_NSEMS_MAX);
832 EXPECT_EQ(32767, _POSIX_SEM_VALUE_MAX);
833 EXPECT_EQ(32, _POSIX_SIGQUEUE_MAX);
834 EXPECT_EQ(32767, _POSIX_SSIZE_MAX);
835 EXPECT_EQ(8, _POSIX_STREAM_MAX);
836#if !defined(__GLIBC__)
837 EXPECT_EQ(4, _POSIX_SS_REPL_MAX);
838#endif
839 EXPECT_EQ(255, _POSIX_SYMLINK_MAX);
840 EXPECT_EQ(8, _POSIX_SYMLOOP_MAX);
841 EXPECT_EQ(4, _POSIX_THREAD_DESTRUCTOR_ITERATIONS);
842 EXPECT_EQ(128, _POSIX_THREAD_KEYS_MAX);
843 EXPECT_EQ(64, _POSIX_THREAD_THREADS_MAX);
844 EXPECT_EQ(32, _POSIX_TIMER_MAX);
845#if !defined(__GLIBC__)
846 EXPECT_EQ(30, _POSIX_TRACE_EVENT_NAME_MAX);
847 EXPECT_EQ(8, _POSIX_TRACE_NAME_MAX);
848 EXPECT_EQ(8, _POSIX_TRACE_SYS_MAX);
849 EXPECT_EQ(32, _POSIX_TRACE_USER_EVENT_MAX);
850#endif
851 EXPECT_EQ(9, _POSIX_TTY_NAME_MAX);
852 EXPECT_EQ(6, _POSIX_TZNAME_MAX);
853 EXPECT_EQ(99, _POSIX2_BC_BASE_MAX);
854 EXPECT_EQ(2048, _POSIX2_BC_DIM_MAX);
855 EXPECT_EQ(99, _POSIX2_BC_SCALE_MAX);
856 EXPECT_EQ(1000, _POSIX2_BC_STRING_MAX);
857 EXPECT_EQ(14, _POSIX2_CHARCLASS_NAME_MAX);
858 EXPECT_EQ(2, _POSIX2_COLL_WEIGHTS_MAX);
859 EXPECT_EQ(32, _POSIX2_EXPR_NEST_MAX);
860 EXPECT_EQ(2048, _POSIX2_LINE_MAX);
861 EXPECT_EQ(255, _POSIX2_RE_DUP_MAX);
862
863 EXPECT_EQ(16, _XOPEN_IOV_MAX);
864#if !defined(__GLIBC__)
865 EXPECT_EQ(255, _XOPEN_NAME_MAX);
866 EXPECT_EQ(1024, _XOPEN_PATH_MAX);
867#endif
868}
869
870TEST(UNISTD_TEST, _POSIX_options) {
Yabin Cui5afae642014-11-25 20:17:27 -0800871 EXPECT_EQ(_POSIX_VERSION, _POSIX_ADVISORY_INFO);
Elliott Hughes73c44a42016-10-19 09:27:02 -0700872 EXPECT_GT(_POSIX_BARRIERS, 0);
873 EXPECT_GT(_POSIX_SPIN_LOCKS, 0);
Yabin Cui1c191942014-11-19 19:49:14 -0800874 EXPECT_NE(_POSIX_CHOWN_RESTRICTED, -1);
875 EXPECT_EQ(_POSIX_VERSION, _POSIX_CLOCK_SELECTION);
Elliott Hughes19d76852017-10-18 13:27:01 -0700876#if !defined(__GLIBC__) // glibc supports ancient kernels.
Elliott Hughes3a8f75d2017-10-05 10:33:18 -0700877 EXPECT_EQ(_POSIX_VERSION, _POSIX_CPUTIME);
Elliott Hughes19d76852017-10-18 13:27:01 -0700878#endif
Yabin Cui1c191942014-11-19 19:49:14 -0800879 EXPECT_EQ(_POSIX_VERSION, _POSIX_FSYNC);
Yabin Cui1c191942014-11-19 19:49:14 -0800880 EXPECT_EQ(_POSIX_VERSION, _POSIX_IPV6);
881 EXPECT_GT(_POSIX_JOB_CONTROL, 0);
Yabin Cui1c191942014-11-19 19:49:14 -0800882 EXPECT_EQ(_POSIX_VERSION, _POSIX_MAPPED_FILES);
Yabin Cui1c191942014-11-19 19:49:14 -0800883 EXPECT_EQ(_POSIX_VERSION, _POSIX_MEMLOCK);
884 EXPECT_EQ(_POSIX_VERSION, _POSIX_MEMLOCK_RANGE);
885 EXPECT_EQ(_POSIX_VERSION, _POSIX_MEMORY_PROTECTION);
Elliott Hughes19d76852017-10-18 13:27:01 -0700886#if !defined(__GLIBC__) // glibc supports ancient kernels.
Elliott Hughes3a8f75d2017-10-05 10:33:18 -0700887 EXPECT_EQ(_POSIX_VERSION, _POSIX_MONOTONIC_CLOCK);
Elliott Hughes19d76852017-10-18 13:27:01 -0700888#endif
Yabin Cui1c191942014-11-19 19:49:14 -0800889 EXPECT_GT(_POSIX_NO_TRUNC, 0);
Colin Cross4c5595c2021-08-16 15:51:59 -0700890#if !defined(ANDROID_HOST_MUSL)
Yabin Cui1c191942014-11-19 19:49:14 -0800891 EXPECT_EQ(_POSIX_VERSION, _POSIX_PRIORITY_SCHEDULING);
Colin Cross7da20342021-07-28 11:18:11 -0700892#endif
Yabin Cui1c191942014-11-19 19:49:14 -0800893 EXPECT_EQ(_POSIX_VERSION, _POSIX_RAW_SOCKETS);
894 EXPECT_EQ(_POSIX_VERSION, _POSIX_READER_WRITER_LOCKS);
Yabin Cui63481602014-12-01 17:41:04 -0800895 EXPECT_EQ(_POSIX_VERSION, _POSIX_REALTIME_SIGNALS);
Yabin Cui1c191942014-11-19 19:49:14 -0800896 EXPECT_GT(_POSIX_REGEXP, 0);
Yabin Cui1c191942014-11-19 19:49:14 -0800897 EXPECT_GT(_POSIX_SAVED_IDS, 0);
898 EXPECT_EQ(_POSIX_VERSION, _POSIX_SEMAPHORES);
Yabin Cui1c191942014-11-19 19:49:14 -0800899 EXPECT_GT(_POSIX_SHELL, 0);
Elliott Hughes14e3ff92017-10-06 16:58:36 -0700900 EXPECT_EQ(_POSIX_VERSION, _POSIX_SPAWN);
Colin Cross4c5595c2021-08-16 15:51:59 -0700901#if !defined(ANDROID_HOST_MUSL)
Elliott Hughes19d76852017-10-18 13:27:01 -0700902 EXPECT_EQ(-1, _POSIX_SPORADIC_SERVER);
Yabin Cui1c191942014-11-19 19:49:14 -0800903 EXPECT_EQ(_POSIX_VERSION, _POSIX_SYNCHRONIZED_IO);
Colin Cross7da20342021-07-28 11:18:11 -0700904#endif
Yabin Cui1c191942014-11-19 19:49:14 -0800905 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREADS);
906 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKADDR);
907 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKSIZE);
Elliott Hughes19d76852017-10-18 13:27:01 -0700908#if !defined(__GLIBC__) // glibc supports ancient kernels.
Elliott Hughes3a8f75d2017-10-05 10:33:18 -0700909 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_CPUTIME);
Elliott Hughes19d76852017-10-18 13:27:01 -0700910#endif
Yabin Cui1c191942014-11-19 19:49:14 -0800911 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PRIORITY_SCHEDULING);
Elliott Hughes468c8082017-05-20 12:47:14 -0700912 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PROCESS_SHARED);
Colin Cross4c5595c2021-08-16 15:51:59 -0700913#if !defined(ANDROID_HOST_MUSL)
Yabin Cui1c191942014-11-19 19:49:14 -0800914 EXPECT_EQ(-1, _POSIX_THREAD_ROBUST_PRIO_PROTECT);
Colin Cross7da20342021-07-28 11:18:11 -0700915#endif
Yabin Cui1c191942014-11-19 19:49:14 -0800916 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_SAFE_FUNCTIONS);
Colin Cross4c5595c2021-08-16 15:51:59 -0700917#if !defined(ANDROID_HOST_MUSL)
Elliott Hughes19d76852017-10-18 13:27:01 -0700918 EXPECT_EQ(-1, _POSIX_THREAD_SPORADIC_SERVER);
Colin Cross7da20342021-07-28 11:18:11 -0700919#endif
Yabin Cui1c191942014-11-19 19:49:14 -0800920 EXPECT_EQ(_POSIX_VERSION, _POSIX_TIMEOUTS);
921 EXPECT_EQ(_POSIX_VERSION, _POSIX_TIMERS);
Colin Cross4c5595c2021-08-16 15:51:59 -0700922#if !defined(ANDROID_HOST_MUSL)
Yabin Cui1c191942014-11-19 19:49:14 -0800923 EXPECT_EQ(-1, _POSIX_TRACE);
924 EXPECT_EQ(-1, _POSIX_TRACE_EVENT_FILTER);
925 EXPECT_EQ(-1, _POSIX_TRACE_INHERIT);
926 EXPECT_EQ(-1, _POSIX_TRACE_LOG);
Yabin Cui1c191942014-11-19 19:49:14 -0800927 EXPECT_EQ(-1, _POSIX_TYPED_MEMORY_OBJECTS);
Colin Cross7da20342021-07-28 11:18:11 -0700928#endif
Yabin Cui1c191942014-11-19 19:49:14 -0800929 EXPECT_NE(-1, _POSIX_VDISABLE);
930
Elliott Hughesa3529352017-07-13 10:20:41 -0700931 EXPECT_EQ(_POSIX_VERSION, _POSIX2_VERSION);
Yabin Cui1c191942014-11-19 19:49:14 -0800932 EXPECT_EQ(_POSIX_VERSION, _POSIX2_C_BIND);
Colin Cross4c5595c2021-08-16 15:51:59 -0700933#if !defined(ANDROID_HOST_MUSL)
Elliott Hughes19d76852017-10-18 13:27:01 -0700934 EXPECT_EQ(_POSIX_VERSION, _POSIX2_CHAR_TERM);
Colin Cross7da20342021-07-28 11:18:11 -0700935#endif
Yabin Cui1c191942014-11-19 19:49:14 -0800936
937 EXPECT_EQ(700, _XOPEN_VERSION);
Elliott Hughes19d76852017-10-18 13:27:01 -0700938 EXPECT_EQ(1, _XOPEN_ENH_I18N);
Colin Cross4c5595c2021-08-16 15:51:59 -0700939#if !defined(ANDROID_HOST_MUSL)
Elliott Hughes19d76852017-10-18 13:27:01 -0700940 EXPECT_EQ(1, _XOPEN_REALTIME);
941 EXPECT_EQ(1, _XOPEN_REALTIME_THREADS);
942 EXPECT_EQ(1, _XOPEN_SHM);
Colin Cross7da20342021-07-28 11:18:11 -0700943#endif
Elliott Hughes19d76852017-10-18 13:27:01 -0700944 EXPECT_EQ(1, _XOPEN_UNIX);
Yabin Cui1c191942014-11-19 19:49:14 -0800945
946#if defined(__BIONIC__)
947 // These tests only pass on bionic, as bionic and glibc has different support on these macros.
Yabin Cui5afae642014-11-25 20:17:27 -0800948 // Macros like _POSIX_ASYNCHRONOUS_IO are not supported on bionic yet.
Yabin Cui1c191942014-11-19 19:49:14 -0800949 EXPECT_EQ(-1, _POSIX_ASYNCHRONOUS_IO);
Yabin Cui1c191942014-11-19 19:49:14 -0800950 EXPECT_EQ(-1, _POSIX_MESSAGE_PASSING);
951 EXPECT_EQ(-1, _POSIX_PRIORITIZED_IO);
Yabin Cui1c191942014-11-19 19:49:14 -0800952 EXPECT_EQ(-1, _POSIX_SHARED_MEMORY_OBJECTS);
Elliott Hughes19d76852017-10-18 13:27:01 -0700953 EXPECT_EQ(-1, _POSIX_THREAD_PRIO_INHERIT);
954 EXPECT_EQ(-1, _POSIX_THREAD_PRIO_PROTECT);
Yabin Cui1c191942014-11-19 19:49:14 -0800955 EXPECT_EQ(-1, _POSIX_THREAD_ROBUST_PRIO_INHERIT);
956
Yabin Cui1c191942014-11-19 19:49:14 -0800957 EXPECT_EQ(-1, _POSIX2_C_DEV);
Elliott Hughes19d76852017-10-18 13:27:01 -0700958 EXPECT_EQ(-1, _POSIX2_FORT_DEV);
959 EXPECT_EQ(-1, _POSIX2_FORT_RUN);
Yabin Cui1c191942014-11-19 19:49:14 -0800960 EXPECT_EQ(-1, _POSIX2_LOCALEDEF);
961 EXPECT_EQ(-1, _POSIX2_SW_DEV);
962 EXPECT_EQ(-1, _POSIX2_UPE);
963
Yabin Cui1c191942014-11-19 19:49:14 -0800964 EXPECT_EQ(-1, _XOPEN_CRYPT);
965 EXPECT_EQ(-1, _XOPEN_LEGACY);
Elliott Hughes19d76852017-10-18 13:27:01 -0700966 EXPECT_EQ(-1, _XOPEN_STREAMS);
Yabin Cui1c191942014-11-19 19:49:14 -0800967#endif // defined(__BIONIC__)
968}
969
Elliott Hughesd6f57302018-04-25 22:13:14 -0700970#define VERIFY_SYSCONF_UNKNOWN(name) \
971 VerifySysconf(name, #name, [](long v){return v == -1 && errno == EINVAL;})
972
973#define VERIFY_SYSCONF_UNSUPPORTED(name) \
974 VerifySysconf(name, #name, [](long v){return v == -1 && errno == 0;})
Yabin Cui1c191942014-11-19 19:49:14 -0800975
976// sysconf() means unlimited when it returns -1 with errno unchanged.
977#define VERIFY_SYSCONF_POSITIVE(name) \
Elliott Hughesd6f57302018-04-25 22:13:14 -0700978 VerifySysconf(name, #name, [](long v){return (v > 0 || v == -1) && errno == 0;})
Yabin Cui1c191942014-11-19 19:49:14 -0800979
980#define VERIFY_SYSCONF_POSIX_VERSION(name) \
Elliott Hughesd6f57302018-04-25 22:13:14 -0700981 VerifySysconf(name, #name, [](long v){return v == _POSIX_VERSION && errno == 0;})
Yabin Cui1c191942014-11-19 19:49:14 -0800982
983static void VerifySysconf(int option, const char *option_name, bool (*verify)(long)) {
984 errno = 0;
985 long ret = sysconf(option);
Elliott Hughesd6f57302018-04-25 22:13:14 -0700986 EXPECT_TRUE(verify(ret)) << "name = " << option_name << ", ret = "
Yabin Cui1c191942014-11-19 19:49:14 -0800987 << ret <<", Error Message: " << strerror(errno);
988}
Derek Xuebc644762014-09-25 10:55:34 +0100989
Christopher Ferris13f26a72016-01-13 13:47:58 -0800990TEST(UNISTD_TEST, sysconf) {
Yabin Cui5afae642014-11-25 20:17:27 -0800991 VERIFY_SYSCONF_POSIX_VERSION(_SC_ADVISORY_INFO);
Yabin Cui1c191942014-11-19 19:49:14 -0800992 VERIFY_SYSCONF_POSITIVE(_SC_ARG_MAX);
Elliott Hughes73c44a42016-10-19 09:27:02 -0700993 VERIFY_SYSCONF_POSIX_VERSION(_SC_BARRIERS);
Yabin Cui1c191942014-11-19 19:49:14 -0800994 VERIFY_SYSCONF_POSITIVE(_SC_BC_BASE_MAX);
995 VERIFY_SYSCONF_POSITIVE(_SC_BC_DIM_MAX);
996 VERIFY_SYSCONF_POSITIVE(_SC_BC_SCALE_MAX);
997 VERIFY_SYSCONF_POSITIVE(_SC_CHILD_MAX);
998 VERIFY_SYSCONF_POSITIVE(_SC_CLK_TCK);
999 VERIFY_SYSCONF_POSITIVE(_SC_COLL_WEIGHTS_MAX);
Yabin Cuid5c65272014-11-26 14:04:26 -08001000 VERIFY_SYSCONF_POSIX_VERSION(_SC_CPUTIME);
Yabin Cui1c191942014-11-19 19:49:14 -08001001 VERIFY_SYSCONF_POSITIVE(_SC_EXPR_NEST_MAX);
1002 VERIFY_SYSCONF_POSITIVE(_SC_LINE_MAX);
Elliott Hughesb3877432024-02-13 16:48:30 -08001003 VerifySysconf(_SC_NGROUPS_MAX, "_SC_NGROUPS_MAX", [](long v){return v >= 0 && v <= NGROUPS_MAX;});
Elliott Hughesaa7ea412025-01-24 11:38:05 -08001004#if defined(__BIONIC__) || defined(_SC_NSIG) // New in POSIX 2024.
1005 EXPECT_EQ(NSIG, sysconf(_SC_NSIG));
1006#endif
Yabin Cui1c191942014-11-19 19:49:14 -08001007 VERIFY_SYSCONF_POSITIVE(_SC_OPEN_MAX);
1008 VERIFY_SYSCONF_POSITIVE(_SC_PASS_MAX);
1009 VERIFY_SYSCONF_POSIX_VERSION(_SC_2_C_BIND);
Elliott Hughes72927252016-07-27 14:05:10 -07001010 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_FORT_DEV);
1011 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_FORT_RUN);
1012 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_UPE);
Elliott Hughes6c135f42017-07-28 16:53:32 -07001013 VERIFY_SYSCONF_POSIX_VERSION(_SC_2_VERSION);
Yabin Cui1c191942014-11-19 19:49:14 -08001014 VERIFY_SYSCONF_POSITIVE(_SC_JOB_CONTROL);
1015 VERIFY_SYSCONF_POSITIVE(_SC_SAVED_IDS);
1016 VERIFY_SYSCONF_POSIX_VERSION(_SC_VERSION);
1017 VERIFY_SYSCONF_POSITIVE(_SC_RE_DUP_MAX);
1018 VERIFY_SYSCONF_POSITIVE(_SC_STREAM_MAX);
1019 VERIFY_SYSCONF_POSITIVE(_SC_TZNAME_MAX);
Elliott Hughesd6f57302018-04-25 22:13:14 -07001020 VerifySysconf(_SC_XOPEN_VERSION, "_SC_XOPEN_VERSION", [](long v){return v == _XOPEN_VERSION && errno == 0;});
Yabin Cui1c191942014-11-19 19:49:14 -08001021 VERIFY_SYSCONF_POSITIVE(_SC_ATEXIT_MAX);
1022 VERIFY_SYSCONF_POSITIVE(_SC_IOV_MAX);
Elliott Hughes82ab4812018-10-09 13:56:06 -07001023 VERIFY_SYSCONF_POSITIVE(_SC_UIO_MAXIOV);
1024 EXPECT_EQ(sysconf(_SC_IOV_MAX), sysconf(_SC_UIO_MAXIOV));
Yabin Cui1c191942014-11-19 19:49:14 -08001025 VERIFY_SYSCONF_POSITIVE(_SC_PAGESIZE);
1026 VERIFY_SYSCONF_POSITIVE(_SC_PAGE_SIZE);
Elliott Hughes189394b2015-07-24 23:22:07 -07001027 VerifySysconf(_SC_PAGE_SIZE, "_SC_PAGE_SIZE",
Elliott Hughesd6f57302018-04-25 22:13:14 -07001028 [](long v){return v == sysconf(_SC_PAGESIZE) && errno == 0 && v == getpagesize();});
Yabin Cui1c191942014-11-19 19:49:14 -08001029 VERIFY_SYSCONF_POSITIVE(_SC_XOPEN_UNIX);
1030 VERIFY_SYSCONF_POSITIVE(_SC_AIO_LISTIO_MAX);
1031 VERIFY_SYSCONF_POSITIVE(_SC_AIO_MAX);
Elliott Hughesd6f57302018-04-25 22:13:14 -07001032 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 -08001033 VERIFY_SYSCONF_POSITIVE(_SC_DELAYTIMER_MAX);
1034 VERIFY_SYSCONF_POSITIVE(_SC_MQ_OPEN_MAX);
1035 VERIFY_SYSCONF_POSITIVE(_SC_MQ_PRIO_MAX);
1036 VERIFY_SYSCONF_POSITIVE(_SC_RTSIG_MAX);
1037 VERIFY_SYSCONF_POSITIVE(_SC_SEM_NSEMS_MAX);
1038 VERIFY_SYSCONF_POSITIVE(_SC_SEM_VALUE_MAX);
Elliott Hughes73c44a42016-10-19 09:27:02 -07001039 VERIFY_SYSCONF_POSIX_VERSION(_SC_SPIN_LOCKS);
Yabin Cui1c191942014-11-19 19:49:14 -08001040 VERIFY_SYSCONF_POSITIVE(_SC_TIMER_MAX);
1041 VERIFY_SYSCONF_POSIX_VERSION(_SC_FSYNC);
1042 VERIFY_SYSCONF_POSIX_VERSION(_SC_MAPPED_FILES);
1043 VERIFY_SYSCONF_POSIX_VERSION(_SC_MEMLOCK);
1044 VERIFY_SYSCONF_POSIX_VERSION(_SC_MEMLOCK_RANGE);
1045 VERIFY_SYSCONF_POSIX_VERSION(_SC_MEMORY_PROTECTION);
1046 VERIFY_SYSCONF_POSIX_VERSION(_SC_PRIORITY_SCHEDULING);
Yabin Cui63481602014-12-01 17:41:04 -08001047 VERIFY_SYSCONF_POSIX_VERSION(_SC_REALTIME_SIGNALS);
Yabin Cui1c191942014-11-19 19:49:14 -08001048 VERIFY_SYSCONF_POSIX_VERSION(_SC_SEMAPHORES);
1049 VERIFY_SYSCONF_POSIX_VERSION(_SC_SYNCHRONIZED_IO);
1050 VERIFY_SYSCONF_POSIX_VERSION(_SC_TIMERS);
1051 VERIFY_SYSCONF_POSITIVE(_SC_GETGR_R_SIZE_MAX);
1052 VERIFY_SYSCONF_POSITIVE(_SC_GETPW_R_SIZE_MAX);
1053 VERIFY_SYSCONF_POSITIVE(_SC_LOGIN_NAME_MAX);
1054 VERIFY_SYSCONF_POSITIVE(_SC_THREAD_DESTRUCTOR_ITERATIONS);
1055 VERIFY_SYSCONF_POSITIVE(_SC_THREAD_KEYS_MAX);
1056 VERIFY_SYSCONF_POSITIVE(_SC_THREAD_STACK_MIN);
1057 VERIFY_SYSCONF_POSITIVE(_SC_THREAD_THREADS_MAX);
1058 VERIFY_SYSCONF_POSITIVE(_SC_TTY_NAME_MAX);
1059 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREADS);
1060 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_ATTR_STACKADDR);
1061 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_ATTR_STACKSIZE);
1062 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_PRIORITY_SCHEDULING);
Elliott Hughes72927252016-07-27 14:05:10 -07001063 VERIFY_SYSCONF_UNSUPPORTED(_SC_THREAD_PRIO_INHERIT);
1064 VERIFY_SYSCONF_UNSUPPORTED(_SC_THREAD_PRIO_PROTECT);
Yabin Cui1c191942014-11-19 19:49:14 -08001065 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_SAFE_FUNCTIONS);
1066 VERIFY_SYSCONF_POSITIVE(_SC_NPROCESSORS_CONF);
1067 VERIFY_SYSCONF_POSITIVE(_SC_NPROCESSORS_ONLN);
1068 VERIFY_SYSCONF_POSITIVE(_SC_PHYS_PAGES);
1069 VERIFY_SYSCONF_POSITIVE(_SC_AVPHYS_PAGES);
1070 VERIFY_SYSCONF_POSIX_VERSION(_SC_MONOTONIC_CLOCK);
Elliott Hughes72927252016-07-27 14:05:10 -07001071 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_PBS);
1072 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_PBS_ACCOUNTING);
1073 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_PBS_CHECKPOINT);
1074 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_PBS_LOCATE);
1075 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_PBS_MESSAGE);
1076 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_PBS_TRACK);
Yabin Cui1c191942014-11-19 19:49:14 -08001077 VERIFY_SYSCONF_POSIX_VERSION(_SC_CLOCK_SELECTION);
1078 VERIFY_SYSCONF_POSITIVE(_SC_HOST_NAME_MAX);
1079 VERIFY_SYSCONF_POSIX_VERSION(_SC_IPV6);
1080 VERIFY_SYSCONF_POSIX_VERSION(_SC_RAW_SOCKETS);
1081 VERIFY_SYSCONF_POSIX_VERSION(_SC_READER_WRITER_LOCKS);
1082 VERIFY_SYSCONF_POSITIVE(_SC_REGEXP);
1083 VERIFY_SYSCONF_POSITIVE(_SC_SHELL);
Elliott Hughes14e3ff92017-10-06 16:58:36 -07001084 VERIFY_SYSCONF_POSIX_VERSION(_SC_SPAWN);
Elliott Hughes19d76852017-10-18 13:27:01 -07001085 VERIFY_SYSCONF_UNSUPPORTED(_SC_SPORADIC_SERVER);
Yabin Cui1c191942014-11-19 19:49:14 -08001086 VERIFY_SYSCONF_POSITIVE(_SC_SYMLOOP_MAX);
1087 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_CPUTIME);
Elliott Hughes468c8082017-05-20 12:47:14 -07001088 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_PROCESS_SHARED);
Elliott Hughes19d76852017-10-18 13:27:01 -07001089 VERIFY_SYSCONF_UNSUPPORTED(_SC_THREAD_SPORADIC_SERVER);
Yabin Cui1c191942014-11-19 19:49:14 -08001090 VERIFY_SYSCONF_POSIX_VERSION(_SC_TIMEOUTS);
Elliott Hughes72927252016-07-27 14:05:10 -07001091 VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE);
1092 VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE_EVENT_FILTER);
1093 VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE_EVENT_NAME_MAX);
1094 VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE_INHERIT);
1095 VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE_LOG);
1096 VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE_NAME_MAX);
1097 VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE_SYS_MAX);
1098 VERIFY_SYSCONF_UNSUPPORTED(_SC_TRACE_USER_EVENT_MAX);
1099 VERIFY_SYSCONF_UNSUPPORTED(_SC_TYPED_MEMORY_OBJECTS);
1100 VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_STREAMS);
Derek Xuebc644762014-09-25 10:55:34 +01001101
Yabin Cui1c191942014-11-19 19:49:14 -08001102#if defined(__LP64__)
Elliott Hughes72927252016-07-27 14:05:10 -07001103 VERIFY_SYSCONF_UNSUPPORTED(_SC_V7_ILP32_OFF32);
1104 VERIFY_SYSCONF_UNSUPPORTED(_SC_V7_ILP32_OFFBIG);
Yabin Cui1c191942014-11-19 19:49:14 -08001105 VERIFY_SYSCONF_POSITIVE(_SC_V7_LP64_OFF64);
1106 VERIFY_SYSCONF_POSITIVE(_SC_V7_LPBIG_OFFBIG);
1107#else
1108 VERIFY_SYSCONF_POSITIVE(_SC_V7_ILP32_OFF32);
1109#if defined(__BIONIC__)
1110 // bionic does not support 64 bits off_t type on 32bit machine.
Elliott Hughes72927252016-07-27 14:05:10 -07001111 VERIFY_SYSCONF_UNSUPPORTED(_SC_V7_ILP32_OFFBIG);
Yabin Cui1c191942014-11-19 19:49:14 -08001112#endif
Elliott Hughes72927252016-07-27 14:05:10 -07001113 VERIFY_SYSCONF_UNSUPPORTED(_SC_V7_LP64_OFF64);
1114 VERIFY_SYSCONF_UNSUPPORTED(_SC_V7_LPBIG_OFFBIG);
Yabin Cui1c191942014-11-19 19:49:14 -08001115#endif
Derek Xuebc644762014-09-25 10:55:34 +01001116
Yabin Cui1c191942014-11-19 19:49:14 -08001117#if defined(__BIONIC__)
1118 // Tests can only run on bionic, as bionic and glibc have different support for these options.
1119 // Below options are not supported on bionic yet.
Elliott Hughes72927252016-07-27 14:05:10 -07001120 VERIFY_SYSCONF_UNSUPPORTED(_SC_ASYNCHRONOUS_IO);
Elliott Hughes72927252016-07-27 14:05:10 -07001121 VERIFY_SYSCONF_UNSUPPORTED(_SC_MESSAGE_PASSING);
1122 VERIFY_SYSCONF_UNSUPPORTED(_SC_PRIORITIZED_IO);
1123 VERIFY_SYSCONF_UNSUPPORTED(_SC_SHARED_MEMORY_OBJECTS);
Elliott Hughes72927252016-07-27 14:05:10 -07001124 VERIFY_SYSCONF_UNSUPPORTED(_SC_THREAD_ROBUST_PRIO_INHERIT);
1125 VERIFY_SYSCONF_UNSUPPORTED(_SC_THREAD_ROBUST_PRIO_PROTECT);
Derek Xuebc644762014-09-25 10:55:34 +01001126
Elliott Hughes72927252016-07-27 14:05:10 -07001127 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_C_DEV);
Elliott Hughes72927252016-07-27 14:05:10 -07001128 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_LOCALEDEF);
1129 VERIFY_SYSCONF_UNSUPPORTED(_SC_2_SW_DEV);
Derek Xuebc644762014-09-25 10:55:34 +01001130
Elliott Hughes72927252016-07-27 14:05:10 -07001131 VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_CRYPT);
Elliott Hughes72927252016-07-27 14:05:10 -07001132 VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_LEGACY);
Elliott Hughes72927252016-07-27 14:05:10 -07001133 VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_UUCP);
Yabin Cui1c191942014-11-19 19:49:14 -08001134#endif // defined(__BIONIC__)
Derek Xuebc644762014-09-25 10:55:34 +01001135}
Elliott Hughesbe52e652015-02-23 18:02:29 -08001136
Christopher Ferris13f26a72016-01-13 13:47:58 -08001137TEST(UNISTD_TEST, get_cpu_count_from_string) {
Yabin Cuicb6f5992015-09-29 16:11:45 -07001138 ASSERT_EQ(0, GetCpuCountFromString(" "));
1139 ASSERT_EQ(1, GetCpuCountFromString("0"));
1140 ASSERT_EQ(40, GetCpuCountFromString("0-39"));
1141 ASSERT_EQ(4, GetCpuCountFromString("0, 1-2, 4\n"));
1142}
1143
Elliott Hughesd771a7c2022-07-28 17:52:46 +00001144TEST(UNISTD_TEST, sysconf_SC_NPROCESSORS_make_sense) {
1145 ASSERT_LE(sysconf(_SC_NPROCESSORS_ONLN), sysconf(_SC_NPROCESSORS_CONF));
1146}
1147
Christopher Ferris13f26a72016-01-13 13:47:58 -08001148TEST(UNISTD_TEST, sysconf_SC_NPROCESSORS_ONLN) {
Elliott Hughes0b2acdf2015-10-02 18:25:19 -07001149 std::string line;
1150 ASSERT_TRUE(android::base::ReadFileToString("/sys/devices/system/cpu/online", &line));
Yabin Cuicb6f5992015-09-29 16:11:45 -07001151 long online_cpus = 0;
Elliott Hughes0b2acdf2015-10-02 18:25:19 -07001152 for (const std::string& s : android::base::Split(line, ",")) {
Yabin Cuicb6f5992015-09-29 16:11:45 -07001153 std::vector<std::string> numbers = android::base::Split(s, "-");
1154 if (numbers.size() == 1u) {
1155 online_cpus++;
1156 } else {
1157 online_cpus += atoi(numbers[1].c_str()) - atoi(numbers[0].c_str()) + 1;
1158 }
1159 }
1160 ASSERT_EQ(online_cpus, sysconf(_SC_NPROCESSORS_ONLN));
1161}
1162
Elliott Hughes38dba2e2016-08-10 15:51:06 -07001163TEST(UNISTD_TEST, sysconf_SC_ARG_MAX) {
Elliott Hughesdb602e82019-11-15 09:04:27 -08001164 // Since Linux 2.6.23, ARG_MAX isn't a constant and depends on RLIMIT_STACK.
Juan Yescas2da31cf2023-12-07 11:49:11 -08001165 // See setup_arg_pages() in the kernel for the gory details:
1166 // https://elixir.bootlin.com/linux/v6.6.4/source/fs/exec.c#L749
Elliott Hughesdb602e82019-11-15 09:04:27 -08001167
1168 // Get our current limit, and set things up so we restore the limit.
1169 rlimit rl;
1170 ASSERT_EQ(0, getrlimit(RLIMIT_STACK, &rl));
1171 uint64_t original_rlim_cur = rl.rlim_cur;
1172 if (rl.rlim_cur == RLIM_INFINITY) {
1173 rl.rlim_cur = 8 * 1024 * 1024; // Bionic reports unlimited stacks as 8MiB.
1174 }
1175 auto guard = android::base::make_scope_guard([&rl, original_rlim_cur]() {
1176 rl.rlim_cur = original_rlim_cur;
1177 ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
1178 });
1179
1180 // _SC_ARG_MAX should be 1/4 the stack size.
1181 EXPECT_EQ(static_cast<long>(rl.rlim_cur / 4), sysconf(_SC_ARG_MAX));
1182
Juan Yescas2da31cf2023-12-07 11:49:11 -08001183 // If you have a really small stack, the kernel still guarantees a stack
1184 // expansion of 128KiB (see setup_arg_pages() in fs/exec.c).
Elliott Hughesdb602e82019-11-15 09:04:27 -08001185 rl.rlim_cur = 1024;
1186 rl.rlim_max = RLIM_INFINITY;
1187 ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
1188
Juan Yescas2da31cf2023-12-07 11:49:11 -08001189 // The stack expansion number is defined in fs/exec.c.
1190 // https://elixir.bootlin.com/linux/v6.6.4/source/fs/exec.c#L845
1191 constexpr long kernel_stack_expansion = 131072;
1192 EXPECT_EQ(kernel_stack_expansion, sysconf(_SC_ARG_MAX));
Elliott Hughesdb602e82019-11-15 09:04:27 -08001193
Juan Yescas2da31cf2023-12-07 11:49:11 -08001194 // If you have a large stack, the kernel will keep the stack
1195 // expansion to 128KiB (see setup_arg_pages() in fs/exec.c).
1196 rl.rlim_cur = 524288;
Elliott Hughesdb602e82019-11-15 09:04:27 -08001197 rl.rlim_max = RLIM_INFINITY;
1198 ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
1199
Juan Yescas2da31cf2023-12-07 11:49:11 -08001200 EXPECT_EQ(kernel_stack_expansion, sysconf(_SC_ARG_MAX));
Elliott Hughes38dba2e2016-08-10 15:51:06 -07001201}
1202
Elliott Hughesd6f57302018-04-25 22:13:14 -07001203TEST(UNISTD_TEST, sysconf_unknown) {
1204 VERIFY_SYSCONF_UNKNOWN(-1);
1205 VERIFY_SYSCONF_UNKNOWN(666);
1206}
1207
Colin Crosscb5d3c12023-09-05 13:51:51 -07001208[[maybe_unused]] static void show_cache(const char* name, long size, long assoc, long line_size) {
Elliott Hughes02df7382023-08-22 15:57:46 -07001209 printf("%s cache size: %ld bytes, line size %ld bytes, ", name, size, line_size);
1210 if (assoc == 0) {
1211 printf("fully");
1212 } else {
1213 printf("%ld-way", assoc);
1214 }
1215 printf(" associative\n");
1216}
1217
1218TEST(UNISTD_TEST, sysconf_cache) {
Colin Crosscb5d3c12023-09-05 13:51:51 -07001219#if defined(ANDROID_HOST_MUSL)
1220 GTEST_SKIP() << "musl does not have _SC_LEVEL?_?CACHE_SIZE";
1221#else
Elliott Hughes02df7382023-08-22 15:57:46 -07001222 // It's not obvious we can _test_ any of these, but we can at least
1223 // show the output for humans to inspect.
1224 show_cache("L1D", sysconf(_SC_LEVEL1_DCACHE_SIZE), sysconf(_SC_LEVEL1_DCACHE_ASSOC), sysconf(_SC_LEVEL1_DCACHE_LINESIZE));
1225 show_cache("L1I", sysconf(_SC_LEVEL1_ICACHE_SIZE), sysconf(_SC_LEVEL1_ICACHE_ASSOC), sysconf(_SC_LEVEL1_ICACHE_LINESIZE));
1226 show_cache("L2", sysconf(_SC_LEVEL2_CACHE_SIZE), sysconf(_SC_LEVEL2_CACHE_ASSOC), sysconf(_SC_LEVEL2_CACHE_LINESIZE));
1227 show_cache("L3", sysconf(_SC_LEVEL3_CACHE_SIZE), sysconf(_SC_LEVEL3_CACHE_ASSOC), sysconf(_SC_LEVEL3_CACHE_LINESIZE));
1228 show_cache("L4", sysconf(_SC_LEVEL4_CACHE_SIZE), sysconf(_SC_LEVEL4_CACHE_ASSOC), sysconf(_SC_LEVEL4_CACHE_LINESIZE));
Colin Crosscb5d3c12023-09-05 13:51:51 -07001229#endif
Elliott Hughes02df7382023-08-22 15:57:46 -07001230}
1231
Christopher Ferris13f26a72016-01-13 13:47:58 -08001232TEST(UNISTD_TEST, dup2_same) {
Elliott Hughesbe52e652015-02-23 18:02:29 -08001233 // POSIX says of dup2:
1234 // If fildes2 is already a valid open file descriptor ...
1235 // [and] fildes is equal to fildes2 ... dup2() shall return
1236 // fildes2 without closing it.
1237 // This isn't true of dup3(2), so we need to manually implement that.
1238
1239 // Equal and valid.
1240 int fd = open("/proc/version", O_RDONLY);
1241 ASSERT_TRUE(fd != -1);
1242 ASSERT_EQ(fd, dup2(fd, fd));
1243 ASSERT_EQ(0, close(fd)); // Check that dup2 didn't close fd.
1244
1245 // Equal, but invalid.
1246 errno = 0;
1247 ASSERT_EQ(-1, dup2(fd, fd));
Elliott Hughes95646e62023-09-21 14:11:19 -07001248 ASSERT_ERRNO(EBADF);
Elliott Hughesbe52e652015-02-23 18:02:29 -08001249}
Elliott Hughes5704c422016-01-25 18:06:24 -08001250
Elliott Hughesa7f12942017-12-15 13:55:53 -08001251TEST(UNISTD_TEST, dup3) {
1252 int fd = open("/proc/version", O_RDONLY);
1253 ASSERT_EQ(666, dup3(fd, 666, 0));
Elliott Hughesf9cfecf2021-02-04 16:58:13 -08001254 ASSERT_FALSE(CloseOnExec(666));
Elliott Hughesa7f12942017-12-15 13:55:53 -08001255 close(666);
1256 ASSERT_EQ(667, dup3(fd, 667, O_CLOEXEC));
Elliott Hughesf9cfecf2021-02-04 16:58:13 -08001257 ASSERT_TRUE(CloseOnExec(667));
Elliott Hughesa7f12942017-12-15 13:55:53 -08001258 close(667);
1259 close(fd);
1260}
1261
Elliott Hughes5704c422016-01-25 18:06:24 -08001262TEST(UNISTD_TEST, lockf_smoke) {
1263 constexpr off64_t file_size = 32*1024LL;
1264
1265 TemporaryFile tf;
1266 ASSERT_EQ(0, ftruncate(tf.fd, file_size));
1267
1268 // Lock everything.
1269 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1270 ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, file_size));
1271
1272 // Try-lock everything, this should succeed too.
1273 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1274 ASSERT_EQ(0, lockf64(tf.fd, F_TLOCK, file_size));
1275
1276 // Check status.
1277 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1278 ASSERT_EQ(0, lockf64(tf.fd, F_TEST, file_size));
1279
1280 // Unlock file.
1281 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1282 ASSERT_EQ(0, lockf64(tf.fd, F_ULOCK, file_size));
1283}
1284
1285TEST(UNISTD_TEST, lockf_zero) {
1286 constexpr off64_t file_size = 32*1024LL;
1287
1288 TemporaryFile tf;
1289 ASSERT_EQ(0, ftruncate(tf.fd, file_size));
1290
1291 // Lock everything by specifying a size of 0 (meaning "to the end, even if it changes").
1292 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1293 ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, 0));
1294
1295 // Check that it's locked.
1296 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1297 ASSERT_EQ(0, lockf64(tf.fd, F_TEST, file_size));
1298
1299 // Move the end.
1300 ASSERT_EQ(0, ftruncate(tf.fd, 2*file_size));
1301
1302 // Check that the new section is locked too.
1303 ASSERT_EQ(file_size, lseek64(tf.fd, file_size, SEEK_SET));
1304 ASSERT_EQ(0, lockf64(tf.fd, F_TEST, 2*file_size));
1305}
1306
1307TEST(UNISTD_TEST, lockf_negative) {
1308 constexpr off64_t file_size = 32*1024LL;
1309
1310 TemporaryFile tf;
1311 ASSERT_EQ(0, ftruncate(tf.fd, file_size));
1312
1313 // Lock everything, but specifying the range in reverse.
1314 ASSERT_EQ(file_size, lseek64(tf.fd, file_size, SEEK_SET));
1315 ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, -file_size));
1316
1317 // Check that it's locked.
1318 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1319 ASSERT_EQ(0, lockf64(tf.fd, F_TEST, file_size));
1320}
1321
1322TEST(UNISTD_TEST, lockf_with_child) {
1323 constexpr off64_t file_size = 32*1024LL;
1324
1325 TemporaryFile tf;
1326 ASSERT_EQ(0, ftruncate(tf.fd, file_size));
1327
1328 // Lock everything.
1329 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1330 ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, file_size));
1331
1332 // Fork a child process
1333 pid_t pid = fork();
1334 ASSERT_NE(-1, pid);
1335 if (pid == 0) {
1336 // Check that the child cannot lock the file.
1337 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1338 ASSERT_EQ(-1, lockf64(tf.fd, F_TLOCK, file_size));
Elliott Hughes95646e62023-09-21 14:11:19 -07001339 ASSERT_ERRNO(EAGAIN);
Elliott Hughes5704c422016-01-25 18:06:24 -08001340 // Check also that it reports itself as locked.
1341 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1342 ASSERT_EQ(-1, lockf64(tf.fd, F_TEST, file_size));
Elliott Hughes95646e62023-09-21 14:11:19 -07001343 ASSERT_ERRNO(EACCES);
Elliott Hughes5704c422016-01-25 18:06:24 -08001344 _exit(0);
1345 }
Elliott Hughes33697a02016-01-26 13:04:57 -08001346 AssertChildExited(pid, 0);
Elliott Hughes5704c422016-01-25 18:06:24 -08001347}
1348
1349TEST(UNISTD_TEST, lockf_partial_with_child) {
1350 constexpr off64_t file_size = 32*1024LL;
1351
1352 TemporaryFile tf;
1353 ASSERT_EQ(0, ftruncate(tf.fd, file_size));
1354
1355 // Lock the first half of the file.
1356 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1357 ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, file_size/2));
1358
1359 // Fork a child process.
1360 pid_t pid = fork();
1361 ASSERT_NE(-1, pid);
1362 if (pid == 0) {
1363 // Check that the child can lock the other half.
1364 ASSERT_EQ(file_size/2, lseek64(tf.fd, file_size/2, SEEK_SET));
1365 ASSERT_EQ(0, lockf64(tf.fd, F_TLOCK, file_size/2));
1366 // Check that the child cannot lock the first half.
1367 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1368 ASSERT_EQ(-1, lockf64(tf.fd, F_TEST, file_size/2));
Elliott Hughes95646e62023-09-21 14:11:19 -07001369 ASSERT_ERRNO(EACCES);
Elliott Hughes5704c422016-01-25 18:06:24 -08001370 // Check also that it reports itself as locked.
1371 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET));
1372 ASSERT_EQ(-1, lockf64(tf.fd, F_TEST, file_size/2));
Elliott Hughes95646e62023-09-21 14:11:19 -07001373 ASSERT_ERRNO(EACCES);
Elliott Hughes5704c422016-01-25 18:06:24 -08001374 _exit(0);
1375 }
Elliott Hughes33697a02016-01-26 13:04:57 -08001376 AssertChildExited(pid, 0);
Elliott Hughes5704c422016-01-25 18:06:24 -08001377
1378 // The second half was locked by the child, but the lock disappeared
1379 // when the process exited, so check it can be locked now.
1380 ASSERT_EQ(file_size/2, lseek64(tf.fd, file_size/2, SEEK_SET));
1381 ASSERT_EQ(0, lockf64(tf.fd, F_TLOCK, file_size/2));
1382}
Greg Hackmanne2faf072016-03-03 08:37:53 -08001383
1384TEST(UNISTD_TEST, getdomainname) {
1385 struct utsname u;
1386 ASSERT_EQ(0, uname(&u));
1387
1388 char buf[sizeof(u.domainname)];
1389 ASSERT_EQ(0, getdomainname(buf, sizeof(buf)));
1390 EXPECT_STREQ(u.domainname, buf);
1391
1392#if defined(__BIONIC__)
1393 // bionic and glibc have different behaviors when len is too small
1394 ASSERT_EQ(-1, getdomainname(buf, strlen(u.domainname)));
Elliott Hughes95646e62023-09-21 14:11:19 -07001395 EXPECT_ERRNO(EINVAL);
Greg Hackmanne2faf072016-03-03 08:37:53 -08001396#endif
1397}
1398
1399TEST(UNISTD_TEST, setdomainname) {
Christopher Ferris2a391882024-12-19 13:44:35 -08001400 __user_cap_header_struct header = {.version = _LINUX_CAPABILITY_VERSION_3};
Greg Hackmanne2faf072016-03-03 08:37:53 -08001401
1402 __user_cap_data_struct old_caps[_LINUX_CAPABILITY_U32S_3];
1403 ASSERT_EQ(0, capget(&header, &old_caps[0]));
1404
1405 auto admin_idx = CAP_TO_INDEX(CAP_SYS_ADMIN);
1406 auto admin_mask = CAP_TO_MASK(CAP_SYS_ADMIN);
1407 bool has_admin = old_caps[admin_idx].effective & admin_mask;
1408 if (has_admin) {
1409 __user_cap_data_struct new_caps[_LINUX_CAPABILITY_U32S_3];
1410 memcpy(new_caps, old_caps, sizeof(new_caps));
1411 new_caps[admin_idx].effective &= ~admin_mask;
1412
1413 ASSERT_EQ(0, capset(&header, &new_caps[0])) << "failed to drop admin privileges";
1414 }
1415
1416 const char* name = "newdomainname";
1417 ASSERT_EQ(-1, setdomainname(name, strlen(name)));
Elliott Hughes95646e62023-09-21 14:11:19 -07001418 ASSERT_ERRNO(EPERM);
Greg Hackmanne2faf072016-03-03 08:37:53 -08001419
1420 if (has_admin) {
1421 ASSERT_EQ(0, capset(&header, &old_caps[0])) << "failed to restore admin privileges";
1422 }
1423}
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001424
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001425TEST(UNISTD_TEST, execve_failure) {
1426 ExecTestHelper eth;
1427 errno = 0;
1428 ASSERT_EQ(-1, execve("/", eth.GetArgs(), eth.GetEnv()));
Elliott Hughes95646e62023-09-21 14:11:19 -07001429 ASSERT_ERRNO(EACCES);
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001430}
1431
Pirama Arumuga Nainar8035caa2020-06-09 12:48:10 -07001432static void append_llvm_cov_env_var(std::string& env_str) {
1433 if (getenv("LLVM_PROFILE_FILE") != nullptr)
1434 env_str.append("__LLVM_PROFILE_RT_INIT_ONCE=__LLVM_PROFILE_RT_INIT_ONCE\n");
1435}
1436
Elliott Hughes3c115902016-08-24 19:27:04 -07001437TEST(UNISTD_TEST, execve_args) {
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001438 // int execve(const char* path, char* argv[], char* envp[]);
1439
1440 // Test basic argument passing.
1441 ExecTestHelper eth;
1442 eth.SetArgs({"echo", "hello", "world", nullptr});
1443 eth.Run([&]() { execve(BIN_DIR "echo", eth.GetArgs(), eth.GetEnv()); }, 0, "hello world\n");
1444
1445 // Test environment variable setting too.
1446 eth.SetArgs({"printenv", nullptr});
1447 eth.SetEnv({"A=B", nullptr});
Pirama Arumuga Nainar8035caa2020-06-09 12:48:10 -07001448
1449 std::string expected_output("A=B\n");
1450 append_llvm_cov_env_var(expected_output);
1451
1452 eth.Run([&]() { execve(BIN_DIR "printenv", eth.GetArgs(), eth.GetEnv()); }, 0,
1453 expected_output.c_str());
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001454}
1455
1456TEST(UNISTD_TEST, execl_failure) {
1457 errno = 0;
1458 ASSERT_EQ(-1, execl("/", "/", nullptr));
Elliott Hughes95646e62023-09-21 14:11:19 -07001459 ASSERT_ERRNO(EACCES);
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001460}
1461
1462TEST(UNISTD_TEST, execl) {
1463 ExecTestHelper eth;
1464 // int execl(const char* path, const char* arg, ...);
1465 eth.Run([&]() { execl(BIN_DIR "echo", "echo", "hello", "world", nullptr); }, 0, "hello world\n");
1466}
1467
1468TEST(UNISTD_TEST, execle_failure) {
1469 ExecTestHelper eth;
1470 errno = 0;
1471 ASSERT_EQ(-1, execle("/", "/", nullptr, eth.GetEnv()));
Elliott Hughes95646e62023-09-21 14:11:19 -07001472 ASSERT_ERRNO(EACCES);
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001473}
1474
1475TEST(UNISTD_TEST, execle) {
1476 ExecTestHelper eth;
1477 eth.SetEnv({"A=B", nullptr});
Pirama Arumuga Nainar8035caa2020-06-09 12:48:10 -07001478
1479 std::string expected_output("A=B\n");
1480 append_llvm_cov_env_var(expected_output);
1481
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001482 // int execle(const char* path, const char* arg, ..., char* envp[]);
Pirama Arumuga Nainar8035caa2020-06-09 12:48:10 -07001483 eth.Run([&]() { execle(BIN_DIR "printenv", "printenv", nullptr, eth.GetEnv()); }, 0,
1484 expected_output.c_str());
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001485}
1486
1487TEST(UNISTD_TEST, execv_failure) {
1488 ExecTestHelper eth;
1489 errno = 0;
1490 ASSERT_EQ(-1, execv("/", eth.GetArgs()));
Elliott Hughes95646e62023-09-21 14:11:19 -07001491 ASSERT_ERRNO(EACCES);
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001492}
1493
1494TEST(UNISTD_TEST, execv) {
1495 ExecTestHelper eth;
1496 eth.SetArgs({"echo", "hello", "world", nullptr});
1497 // int execv(const char* path, char* argv[]);
1498 eth.Run([&]() { execv(BIN_DIR "echo", eth.GetArgs()); }, 0, "hello world\n");
1499}
1500
1501TEST(UNISTD_TEST, execlp_failure) {
1502 errno = 0;
1503 ASSERT_EQ(-1, execlp("/", "/", nullptr));
Elliott Hughes95646e62023-09-21 14:11:19 -07001504 ASSERT_ERRNO(EACCES);
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001505}
1506
1507TEST(UNISTD_TEST, execlp) {
1508 ExecTestHelper eth;
1509 // int execlp(const char* file, const char* arg, ...);
1510 eth.Run([&]() { execlp("echo", "echo", "hello", "world", nullptr); }, 0, "hello world\n");
1511}
1512
1513TEST(UNISTD_TEST, execvp_failure) {
1514 ExecTestHelper eth;
Elliott Hughes3c115902016-08-24 19:27:04 -07001515 eth.SetArgs({nullptr});
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001516 errno = 0;
1517 ASSERT_EQ(-1, execvp("/", eth.GetArgs()));
Elliott Hughes95646e62023-09-21 14:11:19 -07001518 ASSERT_ERRNO(EACCES);
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001519}
1520
1521TEST(UNISTD_TEST, execvp) {
1522 ExecTestHelper eth;
1523 eth.SetArgs({"echo", "hello", "world", nullptr});
1524 // int execvp(const char* file, char* argv[]);
1525 eth.Run([&]() { execvp("echo", eth.GetArgs()); }, 0, "hello world\n");
1526}
1527
1528TEST(UNISTD_TEST, execvpe_failure) {
1529 ExecTestHelper eth;
1530 errno = 0;
1531 ASSERT_EQ(-1, execvpe("this-does-not-exist", eth.GetArgs(), eth.GetEnv()));
Elliott Hughes5965bf02016-12-01 17:12:49 -08001532 // Running in CTS we might not even be able to search all directories in $PATH.
Elliott Hughes95646e62023-09-21 14:11:19 -07001533 ASSERT_TRUE(errno == ENOENT || errno == EACCES) << strerror(errno);
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001534}
1535
1536TEST(UNISTD_TEST, execvpe) {
1537 // int execvpe(const char* file, char* argv[], char* envp[]);
1538
1539 // Test basic argument passing.
1540 ExecTestHelper eth;
1541 eth.SetArgs({"echo", "hello", "world", nullptr});
1542 eth.Run([&]() { execvpe("echo", eth.GetArgs(), eth.GetEnv()); }, 0, "hello world\n");
1543
1544 // Test environment variable setting too.
1545 eth.SetArgs({"printenv", nullptr});
1546 eth.SetEnv({"A=B", nullptr});
Pirama Arumuga Nainar8035caa2020-06-09 12:48:10 -07001547
1548 std::string expected_output("A=B\n");
1549 append_llvm_cov_env_var(expected_output);
1550
1551 eth.Run([&]() { execvpe("printenv", eth.GetArgs(), eth.GetEnv()); }, 0, expected_output.c_str());
Elliott Hughes1b40aaf2016-08-18 10:11:36 -07001552}
Elliott Hughes3c115902016-08-24 19:27:04 -07001553
1554TEST(UNISTD_TEST, execvpe_ENOEXEC) {
1555 // Create a shell script with #!.
1556 TemporaryFile tf;
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001557 ASSERT_TRUE(android::base::WriteStringToFile("#!" BIN_DIR "sh\necho script\n", tf.path));
Elliott Hughes3c115902016-08-24 19:27:04 -07001558
1559 // Set $PATH so we can find it.
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001560 setenv("PATH", dirname(tf.path), 1);
Elliott Hughes3c115902016-08-24 19:27:04 -07001561
1562 ExecTestHelper eth;
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001563 eth.SetArgs({basename(tf.path), nullptr});
Elliott Hughes3c115902016-08-24 19:27:04 -07001564
1565 // It's not inherently executable.
1566 errno = 0;
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001567 ASSERT_EQ(-1, execvpe(basename(tf.path), eth.GetArgs(), eth.GetEnv()));
Elliott Hughes95646e62023-09-21 14:11:19 -07001568 ASSERT_ERRNO(EACCES);
Elliott Hughes3c115902016-08-24 19:27:04 -07001569
Elliott Hughes5965bf02016-12-01 17:12:49 -08001570 // Make it executable (and keep it writable because we're going to rewrite it below).
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001571 ASSERT_EQ(0, chmod(tf.path, 0777));
Elliott Hughes3c115902016-08-24 19:27:04 -07001572
1573 // TemporaryFile will have a writable fd, so we can test ETXTBSY while we're here...
1574 errno = 0;
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001575 ASSERT_EQ(-1, execvpe(basename(tf.path), eth.GetArgs(), eth.GetEnv()));
Elliott Hughes95646e62023-09-21 14:11:19 -07001576 ASSERT_ERRNO(ETXTBSY);
Elliott Hughes3c115902016-08-24 19:27:04 -07001577
1578 // 1. The simplest test: the kernel should handle this.
1579 ASSERT_EQ(0, close(tf.fd));
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001580 eth.Run([&]() { execvpe(basename(tf.path), eth.GetArgs(), eth.GetEnv()); }, 0, "script\n");
Elliott Hughes3c115902016-08-24 19:27:04 -07001581
1582 // 2. Try again without a #!. We should have to handle this ourselves.
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001583 ASSERT_TRUE(android::base::WriteStringToFile("echo script\n", tf.path));
1584 eth.Run([&]() { execvpe(basename(tf.path), eth.GetArgs(), eth.GetEnv()); }, 0, "script\n");
Elliott Hughes3c115902016-08-24 19:27:04 -07001585
1586 // 3. Again without a #!, but also with a leading '/', since that's a special case in the
1587 // implementation.
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -08001588 eth.Run([&]() { execvpe(tf.path, eth.GetArgs(), eth.GetEnv()); }, 0, "script\n");
Elliott Hughes3c115902016-08-24 19:27:04 -07001589}
Elliott Hughes63615062016-08-25 17:40:27 -07001590
1591TEST(UNISTD_TEST, execvp_libcore_test_55017) {
1592 ExecTestHelper eth;
1593 eth.SetArgs({"/system/bin/does-not-exist", nullptr});
1594
1595 errno = 0;
1596 ASSERT_EQ(-1, execvp("/system/bin/does-not-exist", eth.GetArgs()));
Elliott Hughes95646e62023-09-21 14:11:19 -07001597 ASSERT_ERRNO(ENOENT);
Elliott Hughes63615062016-08-25 17:40:27 -07001598}
Elliott Hughes30a36272017-02-22 17:31:41 -08001599
1600TEST(UNISTD_TEST, exec_argv0_null) {
Elliott Hughesbb1cc5a2022-04-01 11:12:36 -07001601 // http://b/33276926 and http://b/227498625.
1602 //
1603 // With old kernels, bionic will see the null pointer and use "<unknown>" but
1604 // with new (5.18+) kernels, the kernel will already have substituted the
1605 // empty string, so we don't make any assertion here about what (if anything)
1606 // comes before the first ':'.
1607 //
1608 // If this ever causes trouble, we could change bionic to replace _either_ the
1609 // null pointer or the empty string. We could also use the actual name from
1610 // readlink() on /proc/self/exe if we ever had reason to disallow programs
1611 // from trying to hide like this.
Elliott Hughes30a36272017-02-22 17:31:41 -08001612 char* args[] = {nullptr};
1613 char* envs[] = {nullptr};
1614 ASSERT_EXIT(execve("/system/bin/run-as", args, envs), testing::ExitedWithCode(1),
Elliott Hughesbb1cc5a2022-04-01 11:12:36 -07001615 ": usage: run-as");
Elliott Hughes30a36272017-02-22 17:31:41 -08001616}
Elliott Hughes06bd5862017-07-28 16:27:49 -07001617
Elliott Hughes4d215aa2017-10-18 15:54:56 -07001618TEST(UNISTD_TEST, fexecve_failure) {
1619 ExecTestHelper eth;
1620 errno = 0;
1621 int fd = open("/", O_RDONLY);
1622 ASSERT_NE(-1, fd);
1623 ASSERT_EQ(-1, fexecve(fd, eth.GetArgs(), eth.GetEnv()));
Elliott Hughes95646e62023-09-21 14:11:19 -07001624 ASSERT_ERRNO(EACCES);
Elliott Hughes4d215aa2017-10-18 15:54:56 -07001625 close(fd);
1626}
1627
1628TEST(UNISTD_TEST, fexecve_bad_fd) {
1629 ExecTestHelper eth;
1630 errno = 0;
1631 ASSERT_EQ(-1, fexecve(-1, eth.GetArgs(), eth.GetEnv()));
Elliott Hughes95646e62023-09-21 14:11:19 -07001632 ASSERT_ERRNO(EBADF);
Elliott Hughes4d215aa2017-10-18 15:54:56 -07001633}
1634
1635TEST(UNISTD_TEST, fexecve_args) {
1636 // Test basic argument passing.
1637 int echo_fd = open(BIN_DIR "echo", O_RDONLY | O_CLOEXEC);
1638 ASSERT_NE(-1, echo_fd);
1639 ExecTestHelper eth;
1640 eth.SetArgs({"echo", "hello", "world", nullptr});
1641 eth.Run([&]() { fexecve(echo_fd, eth.GetArgs(), eth.GetEnv()); }, 0, "hello world\n");
1642 close(echo_fd);
1643
1644 // Test environment variable setting too.
1645 int printenv_fd = open(BIN_DIR "printenv", O_RDONLY | O_CLOEXEC);
1646 ASSERT_NE(-1, printenv_fd);
1647 eth.SetArgs({"printenv", nullptr});
1648 eth.SetEnv({"A=B", nullptr});
Pirama Arumuga Nainar8035caa2020-06-09 12:48:10 -07001649
1650 std::string expected_output("A=B\n");
1651 append_llvm_cov_env_var(expected_output);
1652
1653 eth.Run([&]() { fexecve(printenv_fd, eth.GetArgs(), eth.GetEnv()); }, 0, expected_output.c_str());
Elliott Hughes4d215aa2017-10-18 15:54:56 -07001654 close(printenv_fd);
1655}
1656
Elliott Hughes06bd5862017-07-28 16:27:49 -07001657TEST(UNISTD_TEST, getlogin_r) {
1658 char buf[LOGIN_NAME_MAX] = {};
1659 EXPECT_EQ(ERANGE, getlogin_r(buf, 0));
1660 EXPECT_EQ(0, getlogin_r(buf, sizeof(buf)));
1661 EXPECT_STREQ(getlogin(), buf);
1662}
Elliott Hughesfa386e02017-10-18 13:34:32 -07001663
1664TEST(UNISTD_TEST, swab) {
1665 // POSIX: "The swab() function shall copy nbytes bytes, which are pointed to by src,
1666 // to the object pointed to by dest, exchanging adjacent bytes."
1667 char buf[BUFSIZ];
1668 memset(buf, 'x', sizeof(buf));
1669 swab("ehll oowlr\0d", buf, 12);
1670 ASSERT_STREQ("hello world", buf);
1671}
1672
1673TEST(UNISTD_TEST, swab_odd_byte_count) {
1674 // POSIX: "If nbytes is odd, swab() copies and exchanges nbytes-1 bytes and the disposition
1675 // of the last byte is unspecified."
1676 // ...but it seems unreasonable to not just leave the last byte alone.
1677 char buf[BUFSIZ];
1678 memset(buf, 'x', sizeof(buf));
1679 swab("012345", buf, 3);
1680 ASSERT_EQ('1', buf[0]);
1681 ASSERT_EQ('0', buf[1]);
1682 ASSERT_EQ('x', buf[2]);
1683}
1684
1685TEST(UNISTD_TEST, swab_overlap) {
1686 // POSIX: "If copying takes place between objects that overlap, the behavior is undefined."
1687 // ...but it seems unreasonable to not just do the right thing.
1688 char buf[] = "012345";
1689 swab(buf, buf, 4);
1690 ASSERT_EQ('1', buf[0]);
1691 ASSERT_EQ('0', buf[1]);
1692 ASSERT_EQ('3', buf[2]);
1693 ASSERT_EQ('2', buf[3]);
1694 ASSERT_EQ('4', buf[4]);
1695 ASSERT_EQ('5', buf[5]);
1696 ASSERT_EQ(0, buf[6]);
1697}
1698
1699TEST(UNISTD_TEST, swab_negative_byte_count) {
1700 // POSIX: "If nbytes is negative, swab() does nothing."
1701 char buf[BUFSIZ];
1702 memset(buf, 'x', sizeof(buf));
1703 swab("hello", buf, -1);
1704 ASSERT_EQ('x', buf[0]);
1705}
Elliott Hughesca3f8e42019-10-28 15:59:38 -07001706
1707TEST(UNISTD_TEST, usleep) {
1708 auto t0 = std::chrono::steady_clock::now();
1709 ASSERT_EQ(0, usleep(5000));
1710 auto t1 = std::chrono::steady_clock::now();
1711 ASSERT_GE(t1-t0, 5000us);
1712}
1713
1714TEST(UNISTD_TEST, sleep) {
1715 auto t0 = std::chrono::steady_clock::now();
1716 ASSERT_EQ(0U, sleep(1));
1717 auto t1 = std::chrono::steady_clock::now();
1718 ASSERT_GE(t1-t0, 1s);
1719}
Maciej Żenczykowskib65e1052022-01-21 11:19:55 -08001720
1721TEST(UNISTD_TEST, close_range) {
1722#if defined(__GLIBC__)
1723 GTEST_SKIP() << "glibc too old";
Colin Cross1b8ebea2022-05-23 16:07:22 -07001724#elif defined(ANDROID_HOST_MUSL)
1725 GTEST_SKIP() << "musl does not have close_range";
Maciej Żenczykowskib65e1052022-01-21 11:19:55 -08001726#else // __GLIBC__
1727 int fd = open("/proc/version", O_RDONLY);
1728 ASSERT_GE(fd, 0);
1729
Elliott Hughes4ae4be92023-09-22 17:15:25 -07001730 int rc = close_range(fd, fd, 0);
1731 if (rc == -1 && errno == ENOSYS) GTEST_SKIP() << "no close_range() in this kernel";
1732 ASSERT_EQ(0, rc) << strerror(errno);
1733
1734 // Check the fd is actually closed.
1735 ASSERT_EQ(close(fd), -1);
1736 ASSERT_ERRNO(EBADF);
Maciej Żenczykowskib65e1052022-01-21 11:19:55 -08001737#endif // __GLIBC__
1738}
zijunzhaoc2e412e2022-04-22 18:08:09 +00001739
1740TEST(UNISTD_TEST, copy_file_range) {
1741#if defined(__GLIBC__)
1742 GTEST_SKIP() << "glibc too old";
1743#else // __GLIBC__
1744 TemporaryFile tf;
1745 ASSERT_TRUE(android::base::WriteStringToFd("hello world", tf.fd));
1746 ASSERT_EQ(0, lseek(tf.fd, SEEK_SET, 0));
1747 TemporaryFile tf2;
1748 ASSERT_EQ(11, copy_file_range(tf.fd, NULL, tf2.fd, NULL, 11, 0));
1749 ASSERT_EQ(0, lseek(tf2.fd, SEEK_SET, 0));
1750 std::string content;
1751 ASSERT_TRUE(android::base::ReadFdToString(tf2.fd, &content));
1752 ASSERT_EQ("hello world", content);
1753#endif // __GLIBC__
Colin Cross1b8ebea2022-05-23 16:07:22 -07001754}
Tamas Petz36927f52025-05-13 12:12:43 +02001755
1756#if defined(__aarch64__)
1757
1758static bool expect_sme_off_after_fork{true};
1759
1760static void fork_process() {
1761 const pid_t pid = fork();
1762 ASSERT_NE(-1, pid);
1763
1764 if (pid == 0) {
1765 if (expect_sme_off_after_fork) {
1766 EXPECT_FALSE(sme_is_za_on());
1767 EXPECT_EQ(sme_tpidr2_el0(), 0UL);
1768 } else {
1769 EXPECT_TRUE(sme_is_za_on());
1770 EXPECT_NE(sme_tpidr2_el0(), 0UL);
1771 }
1772
1773 exit(::testing::Test::HasFailure() ? 1 : 0);
1774 } else {
1775 int status;
1776 ASSERT_EQ(pid, waitpid(pid, &status, 0));
1777 ASSERT_TRUE(WIFEXITED(status));
1778 ASSERT_EQ(0, WEXITSTATUS(status));
1779 }
1780}
1781
1782TEST(UNISTD_TEST, fork_with_sme_off) {
1783 if (!sme_is_enabled()) {
1784 GTEST_SKIP() << "FEAT_SME is not enabled on the device.";
1785 }
1786
1787 __arm_za_disable();
1788 expect_sme_off_after_fork = true;
1789 fork_process();
1790 sme_state_cleanup();
1791}
1792
1793TEST(UNISTD_TEST, fork_with_sme_dormant_state) {
1794 if (!sme_is_enabled()) {
1795 GTEST_SKIP() << "FEAT_SME is not enabled on the device.";
1796 }
1797
1798 __arm_za_disable();
1799 expect_sme_off_after_fork = false;
1800 sme_dormant_caller(&fork_process);
1801 sme_state_cleanup();
1802}
1803
1804#endif // defined(__aarch64__)