1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <gtest/gtest.h> 18 19#include "BionicDeathTest.h" 20#include "ScopedSignalHandler.h" 21#include "TemporaryFile.h" 22#include "utils.h" 23 24#include <errno.h> 25#include <fcntl.h> 26#include <limits.h> 27#include <stdint.h> 28#include <sys/param.h> 29#include <sys/syscall.h> 30#include <sys/types.h> 31#include <sys/utsname.h> 32#include <sys/wait.h> 33#include <unistd.h> 34 35#include <android-base/file.h> 36#include <android-base/strings.h> 37 38#include "private/get_cpu_count_from_string.h" 39 40#if defined(NOFORTIFY) 41#define UNISTD_TEST unistd_nofortify 42#define UNISTD_DEATHTEST unistd_nofortify_DeathTest 43#else 44#define UNISTD_TEST unistd 45#define UNISTD_DEATHTEST unistd_DeathTest 46#endif 47 48static void* get_brk() { 49 return sbrk(0); 50} 51 52static void* page_align(uintptr_t addr) { 53 uintptr_t mask = sysconf(_SC_PAGE_SIZE) - 1; 54 return reinterpret_cast<void*>((addr + mask) & ~mask); 55} 56 57TEST(UNISTD_TEST, brk) { 58 void* initial_break = get_brk(); 59 60 // The kernel aligns the break to a page. 61 void* new_break = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(initial_break) + 1); 62 ASSERT_EQ(0, brk(new_break)); 63 ASSERT_GE(get_brk(), new_break); 64 65 new_break = page_align(reinterpret_cast<uintptr_t>(initial_break) + sysconf(_SC_PAGE_SIZE)); 66 ASSERT_EQ(0, brk(new_break)); 67 ASSERT_EQ(get_brk(), new_break); 68} 69 70TEST(UNISTD_TEST, brk_ENOMEM) { 71 ASSERT_EQ(-1, brk(reinterpret_cast<void*>(-1))); 72 ASSERT_EQ(ENOMEM, errno); 73} 74 75#if defined(__GLIBC__) 76#define SBRK_MIN INTPTR_MIN 77#define SBRK_MAX INTPTR_MAX 78#else 79#define SBRK_MIN PTRDIFF_MIN 80#define SBRK_MAX PTRDIFF_MAX 81#endif 82 83TEST(UNISTD_TEST, sbrk_ENOMEM) { 84#if defined(__BIONIC__) && !defined(__LP64__) 85 // There is no way to guarantee that all overflow conditions can be tested 86 // without manipulating the underlying values of the current break. 87 extern void* __bionic_brk; 88 89 class ScopedBrk { 90 public: 91 ScopedBrk() : saved_brk_(__bionic_brk) {} 92 virtual ~ScopedBrk() { __bionic_brk = saved_brk_; } 93 94 private: 95 void* saved_brk_; 96 }; 97 98 ScopedBrk scope_brk; 99 100 // Set the current break to a point that will cause an overflow. 101 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) + 2); 102 103 // Can't increase by so much that we'd overflow. 104 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MAX)); 105 ASSERT_EQ(ENOMEM, errno); 106 107 // Set the current break to a point that will cause an overflow. 108 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX)); 109 110 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN)); 111 ASSERT_EQ(ENOMEM, errno); 112 113 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) - 1); 114 115 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN + 1)); 116 ASSERT_EQ(ENOMEM, errno); 117#else 118 class ScopedBrk { 119 public: 120 ScopedBrk() : saved_brk_(get_brk()) {} 121 virtual ~ScopedBrk() { brk(saved_brk_); } 122 123 private: 124 void* saved_brk_; 125 }; 126 127 ScopedBrk scope_brk; 128 129 uintptr_t cur_brk = reinterpret_cast<uintptr_t>(get_brk()); 130 if (cur_brk < static_cast<uintptr_t>(-(SBRK_MIN+1))) { 131 // Do the overflow test for a max negative increment. 132 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MIN)); 133#if defined(__BIONIC__) 134 // GLIBC does not set errno in overflow case. 135 ASSERT_EQ(ENOMEM, errno); 136#endif 137 } 138 139 uintptr_t overflow_brk = static_cast<uintptr_t>(SBRK_MAX) + 2; 140 if (cur_brk < overflow_brk) { 141 // Try and move the value to PTRDIFF_MAX + 2. 142 cur_brk = reinterpret_cast<uintptr_t>(sbrk(overflow_brk)); 143 } 144 if (cur_brk >= overflow_brk) { 145 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MAX)); 146#if defined(__BIONIC__) 147 // GLIBC does not set errno in overflow case. 148 ASSERT_EQ(ENOMEM, errno); 149#endif 150 } 151#endif 152} 153 154TEST(UNISTD_TEST, truncate) { 155 TemporaryFile tf; 156 ASSERT_EQ(0, close(tf.fd)); 157 ASSERT_EQ(0, truncate(tf.filename, 123)); 158 159 struct stat sb; 160 ASSERT_EQ(0, stat(tf.filename, &sb)); 161 ASSERT_EQ(123, sb.st_size); 162} 163 164TEST(UNISTD_TEST, truncate64) { 165 TemporaryFile tf; 166 ASSERT_EQ(0, close(tf.fd)); 167 ASSERT_EQ(0, truncate64(tf.filename, 123)); 168 169 struct stat sb; 170 ASSERT_EQ(0, stat(tf.filename, &sb)); 171 ASSERT_EQ(123, sb.st_size); 172} 173 174TEST(UNISTD_TEST, ftruncate) { 175 TemporaryFile tf; 176 ASSERT_EQ(0, ftruncate(tf.fd, 123)); 177 ASSERT_EQ(0, close(tf.fd)); 178 179 struct stat sb; 180 ASSERT_EQ(0, stat(tf.filename, &sb)); 181 ASSERT_EQ(123, sb.st_size); 182} 183 184TEST(UNISTD_TEST, ftruncate64) { 185 TemporaryFile tf; 186 ASSERT_EQ(0, ftruncate64(tf.fd, 123)); 187 ASSERT_EQ(0, close(tf.fd)); 188 189 struct stat sb; 190 ASSERT_EQ(0, stat(tf.filename, &sb)); 191 ASSERT_EQ(123, sb.st_size); 192} 193 194TEST(UNISTD_TEST, ftruncate_negative) { 195 TemporaryFile tf; 196 errno = 0; 197 ASSERT_EQ(-1, ftruncate(tf.fd, -123)); 198 ASSERT_EQ(EINVAL, errno); 199} 200 201static bool g_pause_test_flag = false; 202static void PauseTestSignalHandler(int) { 203 g_pause_test_flag = true; 204} 205 206TEST(UNISTD_TEST, pause) { 207 ScopedSignalHandler handler(SIGALRM, PauseTestSignalHandler); 208 209 alarm(1); 210 ASSERT_FALSE(g_pause_test_flag); 211 ASSERT_EQ(-1, pause()); 212 ASSERT_TRUE(g_pause_test_flag); 213} 214 215TEST(UNISTD_TEST, read) { 216 int fd = open("/proc/version", O_RDONLY); 217 ASSERT_TRUE(fd != -1); 218 219 char buf[5]; 220 ASSERT_EQ(5, read(fd, buf, 5)); 221 ASSERT_EQ(buf[0], 'L'); 222 ASSERT_EQ(buf[1], 'i'); 223 ASSERT_EQ(buf[2], 'n'); 224 ASSERT_EQ(buf[3], 'u'); 225 ASSERT_EQ(buf[4], 'x'); 226 close(fd); 227} 228 229TEST(UNISTD_TEST, read_EBADF) { 230 // read returns ssize_t which is 64-bits on LP64, so it's worth explicitly checking that 231 // our syscall stubs correctly return a 64-bit -1. 232 char buf[1]; 233 ASSERT_EQ(-1, read(-1, buf, sizeof(buf))); 234 ASSERT_EQ(EBADF, errno); 235} 236 237TEST(UNISTD_TEST, syscall_long) { 238 // Check that syscall(3) correctly returns long results. 239 // https://code.google.com/p/android/issues/detail?id=73952 240 // We assume that the break is > 4GiB, but this is potentially flaky. 241 uintptr_t p = reinterpret_cast<uintptr_t>(sbrk(0)); 242 ASSERT_EQ(p, static_cast<uintptr_t>(syscall(__NR_brk, 0))); 243} 244 245TEST(UNISTD_TEST, alarm) { 246 ASSERT_EQ(0U, alarm(0)); 247} 248 249TEST(UNISTD_TEST, _exit) { 250 pid_t pid = fork(); 251 ASSERT_NE(-1, pid) << strerror(errno); 252 253 if (pid == 0) { 254 _exit(99); 255 } 256 257 AssertChildExited(pid, 99); 258} 259 260TEST(UNISTD_TEST, getenv_unsetenv) { 261 ASSERT_EQ(0, setenv("test-variable", "hello", 1)); 262 ASSERT_STREQ("hello", getenv("test-variable")); 263 ASSERT_EQ(0, unsetenv("test-variable")); 264 ASSERT_TRUE(getenv("test-variable") == NULL); 265} 266 267TEST(UNISTD_TEST, unsetenv_EINVAL) { 268 EXPECT_EQ(-1, unsetenv("")); 269 EXPECT_EQ(EINVAL, errno); 270 EXPECT_EQ(-1, unsetenv("a=b")); 271 EXPECT_EQ(EINVAL, errno); 272} 273 274TEST(UNISTD_TEST, setenv_EINVAL) { 275 EXPECT_EQ(-1, setenv(NULL, "value", 0)); 276 EXPECT_EQ(EINVAL, errno); 277 EXPECT_EQ(-1, setenv(NULL, "value", 1)); 278 EXPECT_EQ(EINVAL, errno); 279 EXPECT_EQ(-1, setenv("", "value", 0)); 280 EXPECT_EQ(EINVAL, errno); 281 EXPECT_EQ(-1, setenv("", "value", 1)); 282 EXPECT_EQ(EINVAL, errno); 283 EXPECT_EQ(-1, setenv("a=b", "value", 0)); 284 EXPECT_EQ(EINVAL, errno); 285 EXPECT_EQ(-1, setenv("a=b", "value", 1)); 286 EXPECT_EQ(EINVAL, errno); 287} 288 289TEST(UNISTD_TEST, setenv) { 290 ASSERT_EQ(0, unsetenv("test-variable")); 291 292 char a[] = "a"; 293 char b[] = "b"; 294 char c[] = "c"; 295 296 // New value. 297 EXPECT_EQ(0, setenv("test-variable", a, 0)); 298 EXPECT_STREQ(a, getenv("test-variable")); 299 300 // Existing value, no overwrite. 301 EXPECT_EQ(0, setenv("test-variable", b, 0)); 302 EXPECT_STREQ(a, getenv("test-variable")); 303 304 // Existing value, overwrite. 305 EXPECT_EQ(0, setenv("test-variable", c, 1)); 306 EXPECT_STREQ(c, getenv("test-variable")); 307 // But the arrays backing the values are unchanged. 308 EXPECT_EQ('a', a[0]); 309 EXPECT_EQ('b', b[0]); 310 EXPECT_EQ('c', c[0]); 311 312 ASSERT_EQ(0, unsetenv("test-variable")); 313} 314 315TEST(UNISTD_TEST, putenv) { 316 ASSERT_EQ(0, unsetenv("a")); 317 318 char* s1 = strdup("a=b"); 319 ASSERT_EQ(0, putenv(s1)); 320 321 ASSERT_STREQ("b", getenv("a")); 322 s1[2] = 'c'; 323 ASSERT_STREQ("c", getenv("a")); 324 325 char* s2 = strdup("a=b"); 326 ASSERT_EQ(0, putenv(s2)); 327 328 ASSERT_STREQ("b", getenv("a")); 329 ASSERT_EQ('c', s1[2]); 330 331 ASSERT_EQ(0, unsetenv("a")); 332 free(s1); 333 free(s2); 334} 335 336TEST(UNISTD_TEST, clearenv) { 337 extern char** environ; 338 339 // Guarantee that environ is not initially empty... 340 ASSERT_EQ(0, setenv("test-variable", "a", 1)); 341 342 // Stash a copy. 343 std::vector<char*> old_environ; 344 for (size_t i = 0; environ[i] != NULL; ++i) { 345 old_environ.push_back(strdup(environ[i])); 346 } 347 348 ASSERT_EQ(0, clearenv()); 349 350 EXPECT_TRUE(environ == NULL || environ[0] == NULL); 351 EXPECT_EQ(NULL, getenv("test-variable")); 352 EXPECT_EQ(0, setenv("test-variable", "post-clear", 1)); 353 EXPECT_STREQ("post-clear", getenv("test-variable")); 354 355 // Put the old environment back. 356 for (size_t i = 0; i < old_environ.size(); ++i) { 357 EXPECT_EQ(0, putenv(old_environ[i])); 358 } 359 360 // Check it wasn't overwritten. 361 EXPECT_STREQ("a", getenv("test-variable")); 362 363 EXPECT_EQ(0, unsetenv("test-variable")); 364} 365 366static void TestFsyncFunction(int (*fn)(int)) { 367 int fd; 368 369 // Can't sync an invalid fd. 370 errno = 0; 371 EXPECT_EQ(-1, fn(-1)); 372 EXPECT_EQ(EBADF, errno); 373 374 // It doesn't matter whether you've opened a file for write or not. 375 TemporaryFile tf; 376 ASSERT_NE(-1, tf.fd); 377 378 EXPECT_EQ(0, fn(tf.fd)); 379 380 ASSERT_NE(-1, fd = open(tf.filename, O_RDONLY)); 381 EXPECT_EQ(0, fn(fd)); 382 close(fd); 383 384 ASSERT_NE(-1, fd = open(tf.filename, O_RDWR)); 385 EXPECT_EQ(0, fn(fd)); 386 close(fd); 387 388 // The fd can even be a directory. 389 ASSERT_NE(-1, fd = open("/data/local/tmp", O_RDONLY)); 390 EXPECT_EQ(0, fn(fd)); 391 close(fd); 392 393 // But some file systems may choose to be fussy... 394 errno = 0; 395 ASSERT_NE(-1, fd = open("/proc/version", O_RDONLY)); 396 EXPECT_EQ(-1, fn(fd)); 397 EXPECT_EQ(EINVAL, errno); 398 close(fd); 399} 400 401TEST(UNISTD_TEST, fdatasync) { 402 TestFsyncFunction(fdatasync); 403} 404 405TEST(UNISTD_TEST, fsync) { 406 TestFsyncFunction(fsync); 407} 408 409static void AssertGetPidCorrect() { 410 // The loop is just to make manual testing/debugging with strace easier. 411 pid_t getpid_syscall_result = syscall(__NR_getpid); 412 for (size_t i = 0; i < 128; ++i) { 413 ASSERT_EQ(getpid_syscall_result, getpid()); 414 } 415} 416 417static void TestGetPidCachingWithFork(int (*fork_fn)()) { 418 pid_t parent_pid = getpid(); 419 ASSERT_EQ(syscall(__NR_getpid), parent_pid); 420 421 pid_t fork_result = fork_fn(); 422 ASSERT_NE(fork_result, -1); 423 if (fork_result == 0) { 424 // We're the child. 425 AssertGetPidCorrect(); 426 ASSERT_EQ(parent_pid, getppid()); 427 _exit(123); 428 } else { 429 // We're the parent. 430 ASSERT_EQ(parent_pid, getpid()); 431 AssertChildExited(fork_result, 123); 432 } 433} 434 435TEST(UNISTD_TEST, getpid_caching_and_fork) { 436 TestGetPidCachingWithFork(fork); 437} 438 439TEST(UNISTD_TEST, getpid_caching_and_vfork) { 440 TestGetPidCachingWithFork(vfork); 441} 442 443static int GetPidCachingCloneStartRoutine(void*) { 444 AssertGetPidCorrect(); 445 return 123; 446} 447 448TEST(UNISTD_TEST, getpid_caching_and_clone) { 449 pid_t parent_pid = getpid(); 450 ASSERT_EQ(syscall(__NR_getpid), parent_pid); 451 452 void* child_stack[1024]; 453 int clone_result = clone(GetPidCachingCloneStartRoutine, &child_stack[1024], CLONE_NEWNS | SIGCHLD, NULL); 454 if (clone_result == -1 && errno == EPERM && getuid() != 0) { 455 GTEST_LOG_(INFO) << "This test only works if you have permission to CLONE_NEWNS; try running as root.\n"; 456 return; 457 } 458 ASSERT_NE(clone_result, -1); 459 460 ASSERT_EQ(parent_pid, getpid()); 461 462 AssertChildExited(clone_result, 123); 463} 464 465static void* GetPidCachingPthreadStartRoutine(void*) { 466 AssertGetPidCorrect(); 467 return NULL; 468} 469 470TEST(UNISTD_TEST, getpid_caching_and_pthread_create) { 471 pid_t parent_pid = getpid(); 472 473 pthread_t t; 474 ASSERT_EQ(0, pthread_create(&t, NULL, GetPidCachingPthreadStartRoutine, NULL)); 475 476 ASSERT_EQ(parent_pid, getpid()); 477 478 void* result; 479 ASSERT_EQ(0, pthread_join(t, &result)); 480 ASSERT_EQ(NULL, result); 481} 482 483class UNISTD_DEATHTEST : public BionicDeathTest {}; 484 485TEST_F(UNISTD_DEATHTEST, abort) { 486 ASSERT_EXIT(abort(), testing::KilledBySignal(SIGABRT), ""); 487} 488 489TEST(UNISTD_TEST, sethostname) { 490 // The permissions check happens before the argument check, so this will 491 // fail for a different reason if you're running as root than if you're 492 // not, but it'll fail either way. Checking that we have the symbol is about 493 // all we can do for sethostname(2). 494 ASSERT_EQ(-1, sethostname("", -1)); 495} 496 497TEST(UNISTD_TEST, gethostname) { 498 char hostname[HOST_NAME_MAX + 1]; 499 memset(hostname, 0, sizeof(hostname)); 500 501 // Can we get the hostname with a big buffer? 502 ASSERT_EQ(0, gethostname(hostname, HOST_NAME_MAX)); 503 504 // Can we get the hostname with a right-sized buffer? 505 errno = 0; 506 ASSERT_EQ(0, gethostname(hostname, strlen(hostname) + 1)); 507 508 // Does uname(2) agree? 509 utsname buf; 510 ASSERT_EQ(0, uname(&buf)); 511 ASSERT_EQ(0, strncmp(hostname, buf.nodename, SYS_NMLN)); 512 ASSERT_GT(strlen(hostname), 0U); 513 514 // Do we correctly detect truncation? 515 errno = 0; 516 ASSERT_EQ(-1, gethostname(hostname, strlen(hostname))); 517 ASSERT_EQ(ENAMETOOLONG, errno); 518} 519 520TEST(UNISTD_TEST, pathconf_fpathconf) { 521 TemporaryFile tf; 522 long rc = 0L; 523 // As a file system's block size is always power of 2, the configure values 524 // for ALLOC and XFER should be power of 2 as well. 525 rc = pathconf(tf.filename, _PC_ALLOC_SIZE_MIN); 526 ASSERT_TRUE(rc > 0 && powerof2(rc)); 527 rc = pathconf(tf.filename, _PC_REC_MIN_XFER_SIZE); 528 ASSERT_TRUE(rc > 0 && powerof2(rc)); 529 rc = pathconf(tf.filename, _PC_REC_XFER_ALIGN); 530 ASSERT_TRUE(rc > 0 && powerof2(rc)); 531 532 rc = fpathconf(tf.fd, _PC_ALLOC_SIZE_MIN); 533 ASSERT_TRUE(rc > 0 && powerof2(rc)); 534 rc = fpathconf(tf.fd, _PC_REC_MIN_XFER_SIZE); 535 ASSERT_TRUE(rc > 0 && powerof2(rc)); 536 rc = fpathconf(tf.fd, _PC_REC_XFER_ALIGN); 537 ASSERT_TRUE(rc > 0 && powerof2(rc)); 538} 539 540 541TEST(UNISTD_TEST, _POSIX_macros_smoke) { 542 // Make a tight verification of _POSIX_* / _POSIX2_* / _XOPEN_* macros, to prevent change by mistake. 543 // Verify according to POSIX.1-2008. 544 EXPECT_EQ(200809L, _POSIX_VERSION); 545 546 EXPECT_EQ(_POSIX_VERSION, _POSIX_ADVISORY_INFO); 547 EXPECT_GT(_POSIX_AIO_LISTIO_MAX, 0); 548 EXPECT_GT(_POSIX_AIO_MAX, 0); 549 EXPECT_GT(_POSIX_ARG_MAX, 0); 550 EXPECT_GT(_POSIX_CHILD_MAX, 0); 551 EXPECT_NE(_POSIX_CHOWN_RESTRICTED, -1); 552 EXPECT_EQ(_POSIX_VERSION, _POSIX_CLOCK_SELECTION); 553 EXPECT_EQ(0, _POSIX_CPUTIME); // Use sysconf to detect support at runtime. 554 EXPECT_GT(_POSIX_DELAYTIMER_MAX, 0); 555 EXPECT_EQ(_POSIX_VERSION, _POSIX_FSYNC); 556 EXPECT_GT(_POSIX_HOST_NAME_MAX, 0); 557 EXPECT_EQ(_POSIX_VERSION, _POSIX_IPV6); 558 EXPECT_GT(_POSIX_JOB_CONTROL, 0); 559 EXPECT_GT(_POSIX_LINK_MAX, 0); 560 EXPECT_GT(_POSIX_LOGIN_NAME_MAX, 0); 561 EXPECT_EQ(_POSIX_VERSION, _POSIX_MAPPED_FILES); 562 EXPECT_GT(_POSIX_MAX_CANON, 0); 563 EXPECT_GT(_POSIX_MAX_INPUT, 0); 564 EXPECT_EQ(_POSIX_VERSION, _POSIX_MEMLOCK); 565 EXPECT_EQ(_POSIX_VERSION, _POSIX_MEMLOCK_RANGE); 566 EXPECT_EQ(_POSIX_VERSION, _POSIX_MEMORY_PROTECTION); 567 EXPECT_EQ(0, _POSIX_MONOTONIC_CLOCK); 568 EXPECT_GT(_POSIX_MQ_OPEN_MAX, 0); 569 EXPECT_GT(_POSIX_MQ_PRIO_MAX, 0); 570 EXPECT_GT(_POSIX_NAME_MAX, 0); 571 EXPECT_GT(_POSIX_NGROUPS_MAX, 0); 572 EXPECT_GT(_POSIX_NO_TRUNC, 0); 573 EXPECT_GT(_POSIX_OPEN_MAX, 0); 574 EXPECT_GT(_POSIX_PATH_MAX, 0); 575 EXPECT_GT(_POSIX_PIPE_BUF, 0); 576 EXPECT_EQ(_POSIX_VERSION, _POSIX_PRIORITY_SCHEDULING); 577 EXPECT_EQ(_POSIX_VERSION, _POSIX_RAW_SOCKETS); 578 EXPECT_EQ(_POSIX_VERSION, _POSIX_READER_WRITER_LOCKS); 579 EXPECT_EQ(_POSIX_VERSION, _POSIX_REALTIME_SIGNALS); 580 EXPECT_GT(_POSIX_REGEXP, 0); 581 EXPECT_GT(_POSIX_RE_DUP_MAX, 0); 582 EXPECT_GT(_POSIX_SAVED_IDS, 0); 583 EXPECT_EQ(_POSIX_VERSION, _POSIX_SEMAPHORES); 584 EXPECT_GT(_POSIX_SEM_NSEMS_MAX, 0); 585 EXPECT_GT(_POSIX_SEM_VALUE_MAX, 0); 586 EXPECT_GT(_POSIX_SHELL, 0); 587 EXPECT_GT(_POSIX_SIGQUEUE_MAX, 0); 588 EXPECT_EQ(-1, _POSIX_SPORADIC_SERVER); 589 EXPECT_GT(_POSIX_SSIZE_MAX, 0); 590 EXPECT_GT(_POSIX_STREAM_MAX, 0); 591 EXPECT_GT(_POSIX_SYMLINK_MAX, 0); 592 EXPECT_GT(_POSIX_SYMLOOP_MAX, 0); 593 EXPECT_EQ(_POSIX_VERSION, _POSIX_SYNCHRONIZED_IO); 594 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREADS); 595 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKADDR); 596 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKSIZE); 597 EXPECT_EQ(0, _POSIX_THREAD_CPUTIME); // Use sysconf to detect support at runtime. 598 EXPECT_GT(_POSIX_THREAD_DESTRUCTOR_ITERATIONS, 0); 599 EXPECT_EQ(_POSIX_THREAD_KEYS_MAX, 128); 600 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PRIORITY_SCHEDULING); 601 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PRIO_INHERIT); 602 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PRIO_PROTECT); 603 EXPECT_EQ(-1, _POSIX_THREAD_ROBUST_PRIO_PROTECT); 604 EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_SAFE_FUNCTIONS); 605 EXPECT_EQ(-1, _POSIX_THREAD_SPORADIC_SERVER); 606 EXPECT_GT(_POSIX_THREAD_THREADS_MAX, 0); 607 EXPECT_EQ(_POSIX_VERSION, _POSIX_TIMEOUTS); 608 EXPECT_EQ(_POSIX_VERSION, _POSIX_TIMERS); 609 EXPECT_GT(_POSIX_TIMER_MAX, 0); 610 EXPECT_EQ(-1, _POSIX_TRACE); 611 EXPECT_EQ(-1, _POSIX_TRACE_EVENT_FILTER); 612 EXPECT_EQ(-1, _POSIX_TRACE_INHERIT); 613 EXPECT_EQ(-1, _POSIX_TRACE_LOG); 614 EXPECT_GT(_POSIX_TTY_NAME_MAX, 0); 615 EXPECT_EQ(-1, _POSIX_TYPED_MEMORY_OBJECTS); 616 EXPECT_GT(_POSIX_TZNAME_MAX, 0); 617 EXPECT_NE(-1, _POSIX_VDISABLE); 618 619 EXPECT_GT(_POSIX2_BC_BASE_MAX, 0); 620 EXPECT_GT(_POSIX2_BC_DIM_MAX, 0); 621 EXPECT_GT(_POSIX2_BC_SCALE_MAX, 0); 622 EXPECT_GT(_POSIX2_BC_STRING_MAX, 0); 623 EXPECT_GT(_POSIX2_CHARCLASS_NAME_MAX, 0); 624 EXPECT_GT(_POSIX2_COLL_WEIGHTS_MAX, 0); 625 EXPECT_EQ(_POSIX_VERSION, _POSIX2_C_BIND); 626 EXPECT_GT(_POSIX2_EXPR_NEST_MAX, 0); 627 EXPECT_GT(_POSIX2_LINE_MAX, 0); 628 EXPECT_GT(_POSIX2_RE_DUP_MAX, 0); 629 630 EXPECT_EQ(700, _XOPEN_VERSION); 631 EXPECT_GT(_XOPEN_IOV_MAX, 0); 632 EXPECT_GT(_XOPEN_UNIX, 0); 633 634#if defined(__BIONIC__) 635 // These tests only pass on bionic, as bionic and glibc has different support on these macros. 636 // Macros like _POSIX_ASYNCHRONOUS_IO are not supported on bionic yet. 637 EXPECT_EQ(-1, _POSIX_ASYNCHRONOUS_IO); 638 EXPECT_EQ(-1, _POSIX_BARRIERS); 639 EXPECT_EQ(-1, _POSIX_MESSAGE_PASSING); 640 EXPECT_EQ(-1, _POSIX_PRIORITIZED_IO); 641 EXPECT_EQ(-1, _POSIX_SHARED_MEMORY_OBJECTS); 642 EXPECT_EQ(-1, _POSIX_SPAWN); 643 EXPECT_EQ(-1, _POSIX_SPIN_LOCKS); 644 EXPECT_EQ(-1, _POSIX_THREAD_PROCESS_SHARED); 645 EXPECT_EQ(-1, _POSIX_THREAD_ROBUST_PRIO_INHERIT); 646 647 EXPECT_EQ(-1, _POSIX2_VERSION); 648 EXPECT_EQ(-1, _POSIX2_CHAR_TERM); 649 EXPECT_EQ(-1, _POSIX2_C_DEV); 650 EXPECT_EQ(-1, _POSIX2_LOCALEDEF); 651 EXPECT_EQ(-1, _POSIX2_SW_DEV); 652 EXPECT_EQ(-1, _POSIX2_UPE); 653 654 EXPECT_EQ(-1, _XOPEN_ENH_I18N); 655 EXPECT_EQ(-1, _XOPEN_CRYPT); 656 EXPECT_EQ(-1, _XOPEN_LEGACY); 657 EXPECT_EQ(-1, _XOPEN_REALTIME); 658 EXPECT_EQ(-1, _XOPEN_REALTIME_THREADS); 659 EXPECT_EQ(-1, _XOPEN_SHM); 660 661#endif // defined(__BIONIC__) 662} 663 664#define VERIFY_SYSCONF_NOT_SUPPORT(name) VerifySysconf(name, #name, [](long v){return v == -1;}) 665 666// sysconf() means unlimited when it returns -1 with errno unchanged. 667#define VERIFY_SYSCONF_POSITIVE(name) \ 668 VerifySysconf(name, #name, [](long v){return (v > 0 || v == -1);}) 669 670#define VERIFY_SYSCONF_POSIX_VERSION(name) \ 671 VerifySysconf(name, #name, [](long v){return v == _POSIX_VERSION;}) 672 673static void VerifySysconf(int option, const char *option_name, bool (*verify)(long)) { 674 errno = 0; 675 long ret = sysconf(option); 676 EXPECT_TRUE(0 == errno && verify(ret)) << "name = " << option_name << ", ret = " 677 << ret <<", Error Message: " << strerror(errno); 678} 679 680TEST(UNISTD_TEST, sysconf) { 681 VERIFY_SYSCONF_POSIX_VERSION(_SC_ADVISORY_INFO); 682 VERIFY_SYSCONF_POSITIVE(_SC_ARG_MAX); 683 VERIFY_SYSCONF_POSITIVE(_SC_BC_BASE_MAX); 684 VERIFY_SYSCONF_POSITIVE(_SC_BC_DIM_MAX); 685 VERIFY_SYSCONF_POSITIVE(_SC_BC_SCALE_MAX); 686 VERIFY_SYSCONF_POSITIVE(_SC_CHILD_MAX); 687 VERIFY_SYSCONF_POSITIVE(_SC_CLK_TCK); 688 VERIFY_SYSCONF_POSITIVE(_SC_COLL_WEIGHTS_MAX); 689 VERIFY_SYSCONF_POSIX_VERSION(_SC_CPUTIME); 690 VERIFY_SYSCONF_POSITIVE(_SC_EXPR_NEST_MAX); 691 VERIFY_SYSCONF_POSITIVE(_SC_LINE_MAX); 692 VERIFY_SYSCONF_POSITIVE(_SC_NGROUPS_MAX); 693 VERIFY_SYSCONF_POSITIVE(_SC_OPEN_MAX); 694 VERIFY_SYSCONF_POSITIVE(_SC_PASS_MAX); 695 VERIFY_SYSCONF_POSIX_VERSION(_SC_2_C_BIND); 696 VERIFY_SYSCONF_NOT_SUPPORT(_SC_2_FORT_DEV); 697 VERIFY_SYSCONF_NOT_SUPPORT(_SC_2_FORT_RUN); 698 VERIFY_SYSCONF_NOT_SUPPORT(_SC_2_UPE); 699 VERIFY_SYSCONF_POSITIVE(_SC_JOB_CONTROL); 700 VERIFY_SYSCONF_POSITIVE(_SC_SAVED_IDS); 701 VERIFY_SYSCONF_POSIX_VERSION(_SC_VERSION); 702 VERIFY_SYSCONF_POSITIVE(_SC_RE_DUP_MAX); 703 VERIFY_SYSCONF_POSITIVE(_SC_STREAM_MAX); 704 VERIFY_SYSCONF_POSITIVE(_SC_TZNAME_MAX); 705 VerifySysconf(_SC_XOPEN_VERSION, "_SC_XOPEN_VERSION", [](long v){return v == _XOPEN_VERSION;}); 706 VERIFY_SYSCONF_POSITIVE(_SC_ATEXIT_MAX); 707 VERIFY_SYSCONF_POSITIVE(_SC_IOV_MAX); 708 VERIFY_SYSCONF_POSITIVE(_SC_PAGESIZE); 709 VERIFY_SYSCONF_POSITIVE(_SC_PAGE_SIZE); 710 VerifySysconf(_SC_PAGE_SIZE, "_SC_PAGE_SIZE", 711 [](long v){return v == sysconf(_SC_PAGESIZE) && v == getpagesize();}); 712 VERIFY_SYSCONF_POSITIVE(_SC_XOPEN_UNIX); 713 VERIFY_SYSCONF_POSITIVE(_SC_AIO_LISTIO_MAX); 714 VERIFY_SYSCONF_POSITIVE(_SC_AIO_MAX); 715 VerifySysconf(_SC_AIO_PRIO_DELTA_MAX, "_SC_AIO_PRIO_DELTA_MAX", [](long v){return v >= 0;}); 716 VERIFY_SYSCONF_POSITIVE(_SC_DELAYTIMER_MAX); 717 VERIFY_SYSCONF_POSITIVE(_SC_MQ_OPEN_MAX); 718 VERIFY_SYSCONF_POSITIVE(_SC_MQ_PRIO_MAX); 719 VERIFY_SYSCONF_POSITIVE(_SC_RTSIG_MAX); 720 VERIFY_SYSCONF_POSITIVE(_SC_SEM_NSEMS_MAX); 721 VERIFY_SYSCONF_POSITIVE(_SC_SEM_VALUE_MAX); 722 VERIFY_SYSCONF_POSITIVE(_SC_TIMER_MAX); 723 VERIFY_SYSCONF_POSIX_VERSION(_SC_FSYNC); 724 VERIFY_SYSCONF_POSIX_VERSION(_SC_MAPPED_FILES); 725 VERIFY_SYSCONF_POSIX_VERSION(_SC_MEMLOCK); 726 VERIFY_SYSCONF_POSIX_VERSION(_SC_MEMLOCK_RANGE); 727 VERIFY_SYSCONF_POSIX_VERSION(_SC_MEMORY_PROTECTION); 728 VERIFY_SYSCONF_POSIX_VERSION(_SC_PRIORITY_SCHEDULING); 729 VERIFY_SYSCONF_POSIX_VERSION(_SC_REALTIME_SIGNALS); 730 VERIFY_SYSCONF_POSIX_VERSION(_SC_SEMAPHORES); 731 VERIFY_SYSCONF_POSIX_VERSION(_SC_SYNCHRONIZED_IO); 732 VERIFY_SYSCONF_POSIX_VERSION(_SC_TIMERS); 733 VERIFY_SYSCONF_POSITIVE(_SC_GETGR_R_SIZE_MAX); 734 VERIFY_SYSCONF_POSITIVE(_SC_GETPW_R_SIZE_MAX); 735 VERIFY_SYSCONF_POSITIVE(_SC_LOGIN_NAME_MAX); 736 VERIFY_SYSCONF_POSITIVE(_SC_THREAD_DESTRUCTOR_ITERATIONS); 737 VERIFY_SYSCONF_POSITIVE(_SC_THREAD_KEYS_MAX); 738 VERIFY_SYSCONF_POSITIVE(_SC_THREAD_STACK_MIN); 739 VERIFY_SYSCONF_POSITIVE(_SC_THREAD_THREADS_MAX); 740 VERIFY_SYSCONF_POSITIVE(_SC_TTY_NAME_MAX); 741 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREADS); 742 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_ATTR_STACKADDR); 743 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_ATTR_STACKSIZE); 744 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_PRIORITY_SCHEDULING); 745 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_PRIO_INHERIT); 746 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_PRIO_PROTECT); 747 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_SAFE_FUNCTIONS); 748 VERIFY_SYSCONF_POSITIVE(_SC_NPROCESSORS_CONF); 749 VERIFY_SYSCONF_POSITIVE(_SC_NPROCESSORS_ONLN); 750 VERIFY_SYSCONF_POSITIVE(_SC_PHYS_PAGES); 751 VERIFY_SYSCONF_POSITIVE(_SC_AVPHYS_PAGES); 752 VERIFY_SYSCONF_POSIX_VERSION(_SC_MONOTONIC_CLOCK); 753 VERIFY_SYSCONF_NOT_SUPPORT(_SC_2_PBS); 754 VERIFY_SYSCONF_NOT_SUPPORT(_SC_2_PBS_ACCOUNTING); 755 VERIFY_SYSCONF_NOT_SUPPORT(_SC_2_PBS_CHECKPOINT); 756 VERIFY_SYSCONF_NOT_SUPPORT(_SC_2_PBS_LOCATE); 757 VERIFY_SYSCONF_NOT_SUPPORT(_SC_2_PBS_MESSAGE); 758 VERIFY_SYSCONF_NOT_SUPPORT(_SC_2_PBS_TRACK); 759 VERIFY_SYSCONF_POSIX_VERSION(_SC_CLOCK_SELECTION); 760 VERIFY_SYSCONF_POSITIVE(_SC_HOST_NAME_MAX); 761 VERIFY_SYSCONF_POSIX_VERSION(_SC_IPV6); 762 VERIFY_SYSCONF_POSIX_VERSION(_SC_RAW_SOCKETS); 763 VERIFY_SYSCONF_POSIX_VERSION(_SC_READER_WRITER_LOCKS); 764 VERIFY_SYSCONF_POSITIVE(_SC_REGEXP); 765 VERIFY_SYSCONF_POSITIVE(_SC_SHELL); 766 VERIFY_SYSCONF_NOT_SUPPORT(_SC_SPORADIC_SERVER); 767 VERIFY_SYSCONF_POSITIVE(_SC_SYMLOOP_MAX); 768 VERIFY_SYSCONF_POSIX_VERSION(_SC_THREAD_CPUTIME); 769 VERIFY_SYSCONF_NOT_SUPPORT(_SC_THREAD_SPORADIC_SERVER); 770 VERIFY_SYSCONF_POSIX_VERSION(_SC_TIMEOUTS); 771 VERIFY_SYSCONF_NOT_SUPPORT(_SC_TRACE); 772 VERIFY_SYSCONF_NOT_SUPPORT(_SC_TRACE_EVENT_FILTER); 773 VERIFY_SYSCONF_NOT_SUPPORT(_SC_TRACE_EVENT_NAME_MAX); 774 VERIFY_SYSCONF_NOT_SUPPORT(_SC_TRACE_INHERIT); 775 VERIFY_SYSCONF_NOT_SUPPORT(_SC_TRACE_LOG); 776 VERIFY_SYSCONF_NOT_SUPPORT(_SC_TRACE_NAME_MAX); 777 VERIFY_SYSCONF_NOT_SUPPORT(_SC_TRACE_SYS_MAX); 778 VERIFY_SYSCONF_NOT_SUPPORT(_SC_TRACE_USER_EVENT_MAX); 779 VERIFY_SYSCONF_NOT_SUPPORT(_SC_TYPED_MEMORY_OBJECTS); 780 VERIFY_SYSCONF_NOT_SUPPORT(_SC_XOPEN_STREAMS); 781 782#if defined(__LP64__) 783 VERIFY_SYSCONF_NOT_SUPPORT(_SC_V7_ILP32_OFF32); 784 VERIFY_SYSCONF_NOT_SUPPORT(_SC_V7_ILP32_OFFBIG); 785 VERIFY_SYSCONF_POSITIVE(_SC_V7_LP64_OFF64); 786 VERIFY_SYSCONF_POSITIVE(_SC_V7_LPBIG_OFFBIG); 787#else 788 VERIFY_SYSCONF_POSITIVE(_SC_V7_ILP32_OFF32); 789#if defined(__BIONIC__) 790 // bionic does not support 64 bits off_t type on 32bit machine. 791 VERIFY_SYSCONF_NOT_SUPPORT(_SC_V7_ILP32_OFFBIG); 792#endif 793 VERIFY_SYSCONF_NOT_SUPPORT(_SC_V7_LP64_OFF64); 794 VERIFY_SYSCONF_NOT_SUPPORT(_SC_V7_LPBIG_OFFBIG); 795#endif 796 797#if defined(__BIONIC__) 798 // Tests can only run on bionic, as bionic and glibc have different support for these options. 799 // Below options are not supported on bionic yet. 800 VERIFY_SYSCONF_NOT_SUPPORT(_SC_ASYNCHRONOUS_IO); 801 VERIFY_SYSCONF_NOT_SUPPORT(_SC_BARRIERS); 802 VERIFY_SYSCONF_NOT_SUPPORT(_SC_MESSAGE_PASSING); 803 VERIFY_SYSCONF_NOT_SUPPORT(_SC_PRIORITIZED_IO); 804 VERIFY_SYSCONF_NOT_SUPPORT(_SC_SHARED_MEMORY_OBJECTS); 805 VERIFY_SYSCONF_NOT_SUPPORT(_SC_SPAWN); 806 VERIFY_SYSCONF_NOT_SUPPORT(_SC_SPIN_LOCKS); 807 VERIFY_SYSCONF_NOT_SUPPORT(_SC_THREAD_PROCESS_SHARED); 808 VERIFY_SYSCONF_NOT_SUPPORT(_SC_THREAD_ROBUST_PRIO_INHERIT); 809 VERIFY_SYSCONF_NOT_SUPPORT(_SC_THREAD_ROBUST_PRIO_PROTECT); 810 811 VERIFY_SYSCONF_NOT_SUPPORT(_SC_2_C_DEV); 812 VERIFY_SYSCONF_NOT_SUPPORT(_SC_2_CHAR_TERM); 813 VERIFY_SYSCONF_NOT_SUPPORT(_SC_2_LOCALEDEF); 814 VERIFY_SYSCONF_NOT_SUPPORT(_SC_2_SW_DEV); 815 VERIFY_SYSCONF_NOT_SUPPORT(_SC_2_VERSION); 816 817 VERIFY_SYSCONF_NOT_SUPPORT(_SC_XOPEN_CRYPT); 818 VERIFY_SYSCONF_NOT_SUPPORT(_SC_XOPEN_ENH_I18N); 819 VERIFY_SYSCONF_NOT_SUPPORT(_SC_XOPEN_LEGACY); 820 VERIFY_SYSCONF_NOT_SUPPORT(_SC_XOPEN_REALTIME); 821 VERIFY_SYSCONF_NOT_SUPPORT(_SC_XOPEN_REALTIME_THREADS); 822 VERIFY_SYSCONF_NOT_SUPPORT(_SC_XOPEN_SHM); 823 VERIFY_SYSCONF_NOT_SUPPORT(_SC_XOPEN_UUCP); 824#endif // defined(__BIONIC__) 825} 826 827TEST(UNISTD_TEST, get_cpu_count_from_string) { 828 ASSERT_EQ(0, GetCpuCountFromString(" ")); 829 ASSERT_EQ(1, GetCpuCountFromString("0")); 830 ASSERT_EQ(40, GetCpuCountFromString("0-39")); 831 ASSERT_EQ(4, GetCpuCountFromString("0, 1-2, 4\n")); 832} 833 834TEST(UNISTD_TEST, sysconf_SC_NPROCESSORS_ONLN) { 835 std::string line; 836 ASSERT_TRUE(android::base::ReadFileToString("/sys/devices/system/cpu/online", &line)); 837 long online_cpus = 0; 838 for (const std::string& s : android::base::Split(line, ",")) { 839 std::vector<std::string> numbers = android::base::Split(s, "-"); 840 if (numbers.size() == 1u) { 841 online_cpus++; 842 } else { 843 online_cpus += atoi(numbers[1].c_str()) - atoi(numbers[0].c_str()) + 1; 844 } 845 } 846 ASSERT_EQ(online_cpus, sysconf(_SC_NPROCESSORS_ONLN)); 847} 848 849TEST(UNISTD_TEST, dup2_same) { 850 // POSIX says of dup2: 851 // If fildes2 is already a valid open file descriptor ... 852 // [and] fildes is equal to fildes2 ... dup2() shall return 853 // fildes2 without closing it. 854 // This isn't true of dup3(2), so we need to manually implement that. 855 856 // Equal and valid. 857 int fd = open("/proc/version", O_RDONLY); 858 ASSERT_TRUE(fd != -1); 859 ASSERT_EQ(fd, dup2(fd, fd)); 860 ASSERT_EQ(0, close(fd)); // Check that dup2 didn't close fd. 861 862 // Equal, but invalid. 863 errno = 0; 864 ASSERT_EQ(-1, dup2(fd, fd)); 865 ASSERT_EQ(EBADF, errno); 866} 867 868TEST(UNISTD_TEST, lockf_smoke) { 869 constexpr off64_t file_size = 32*1024LL; 870 871 TemporaryFile tf; 872 ASSERT_EQ(0, ftruncate(tf.fd, file_size)); 873 874 // Lock everything. 875 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET)); 876 ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, file_size)); 877 878 // Try-lock everything, this should succeed too. 879 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET)); 880 ASSERT_EQ(0, lockf64(tf.fd, F_TLOCK, file_size)); 881 882 // Check status. 883 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET)); 884 ASSERT_EQ(0, lockf64(tf.fd, F_TEST, file_size)); 885 886 // Unlock file. 887 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET)); 888 ASSERT_EQ(0, lockf64(tf.fd, F_ULOCK, file_size)); 889} 890 891TEST(UNISTD_TEST, lockf_zero) { 892 constexpr off64_t file_size = 32*1024LL; 893 894 TemporaryFile tf; 895 ASSERT_EQ(0, ftruncate(tf.fd, file_size)); 896 897 // Lock everything by specifying a size of 0 (meaning "to the end, even if it changes"). 898 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET)); 899 ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, 0)); 900 901 // Check that it's locked. 902 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET)); 903 ASSERT_EQ(0, lockf64(tf.fd, F_TEST, file_size)); 904 905 // Move the end. 906 ASSERT_EQ(0, ftruncate(tf.fd, 2*file_size)); 907 908 // Check that the new section is locked too. 909 ASSERT_EQ(file_size, lseek64(tf.fd, file_size, SEEK_SET)); 910 ASSERT_EQ(0, lockf64(tf.fd, F_TEST, 2*file_size)); 911} 912 913TEST(UNISTD_TEST, lockf_negative) { 914 constexpr off64_t file_size = 32*1024LL; 915 916 TemporaryFile tf; 917 ASSERT_EQ(0, ftruncate(tf.fd, file_size)); 918 919 // Lock everything, but specifying the range in reverse. 920 ASSERT_EQ(file_size, lseek64(tf.fd, file_size, SEEK_SET)); 921 ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, -file_size)); 922 923 // Check that it's locked. 924 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET)); 925 ASSERT_EQ(0, lockf64(tf.fd, F_TEST, file_size)); 926} 927 928TEST(UNISTD_TEST, lockf_with_child) { 929 constexpr off64_t file_size = 32*1024LL; 930 931 TemporaryFile tf; 932 ASSERT_EQ(0, ftruncate(tf.fd, file_size)); 933 934 // Lock everything. 935 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET)); 936 ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, file_size)); 937 938 // Fork a child process 939 pid_t pid = fork(); 940 ASSERT_NE(-1, pid); 941 if (pid == 0) { 942 // Check that the child cannot lock the file. 943 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET)); 944 ASSERT_EQ(-1, lockf64(tf.fd, F_TLOCK, file_size)); 945 ASSERT_EQ(EAGAIN, errno); 946 // Check also that it reports itself as locked. 947 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET)); 948 ASSERT_EQ(-1, lockf64(tf.fd, F_TEST, file_size)); 949 ASSERT_EQ(EACCES, errno); 950 _exit(0); 951 } 952 AssertChildExited(pid, 0); 953} 954 955TEST(UNISTD_TEST, lockf_partial_with_child) { 956 constexpr off64_t file_size = 32*1024LL; 957 958 TemporaryFile tf; 959 ASSERT_EQ(0, ftruncate(tf.fd, file_size)); 960 961 // Lock the first half of the file. 962 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET)); 963 ASSERT_EQ(0, lockf64(tf.fd, F_LOCK, file_size/2)); 964 965 // Fork a child process. 966 pid_t pid = fork(); 967 ASSERT_NE(-1, pid); 968 if (pid == 0) { 969 // Check that the child can lock the other half. 970 ASSERT_EQ(file_size/2, lseek64(tf.fd, file_size/2, SEEK_SET)); 971 ASSERT_EQ(0, lockf64(tf.fd, F_TLOCK, file_size/2)); 972 // Check that the child cannot lock the first half. 973 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET)); 974 ASSERT_EQ(-1, lockf64(tf.fd, F_TEST, file_size/2)); 975 ASSERT_EQ(EACCES, errno); 976 // Check also that it reports itself as locked. 977 ASSERT_EQ(0, lseek64(tf.fd, 0, SEEK_SET)); 978 ASSERT_EQ(-1, lockf64(tf.fd, F_TEST, file_size/2)); 979 ASSERT_EQ(EACCES, errno); 980 _exit(0); 981 } 982 AssertChildExited(pid, 0); 983 984 // The second half was locked by the child, but the lock disappeared 985 // when the process exited, so check it can be locked now. 986 ASSERT_EQ(file_size/2, lseek64(tf.fd, file_size/2, SEEK_SET)); 987 ASSERT_EQ(0, lockf64(tf.fd, F_TLOCK, file_size/2)); 988} 989