unistd_test.cpp revision b5e581abfe28de8ed6c8c8af1c265bb4e36f97bb
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <gtest/gtest.h> 18#include "BionicDeathTest.h" 19#include "ScopedSignalHandler.h" 20#include "TemporaryFile.h" 21 22#include <errno.h> 23#include <fcntl.h> 24#include <limits.h> 25#include <stdint.h> 26#include <sys/param.h> 27#include <sys/syscall.h> 28#include <sys/types.h> 29#include <sys/utsname.h> 30#include <sys/wait.h> 31#include <unistd.h> 32 33 34TEST(unistd, sysconf_SC_MONOTONIC_CLOCK) { 35 ASSERT_GT(sysconf(_SC_MONOTONIC_CLOCK), 0); 36} 37 38static void* get_brk() { 39 return sbrk(0); 40} 41 42static void* page_align(uintptr_t addr) { 43 uintptr_t mask = sysconf(_SC_PAGE_SIZE) - 1; 44 return reinterpret_cast<void*>((addr + mask) & ~mask); 45} 46 47TEST(unistd, brk) { 48 void* initial_break = get_brk(); 49 50 // The kernel aligns the break to a page. 51 void* new_break = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(initial_break) + 1); 52 ASSERT_EQ(0, brk(new_break)); 53 ASSERT_GE(get_brk(), new_break); 54 55 new_break = page_align(reinterpret_cast<uintptr_t>(initial_break) + sysconf(_SC_PAGE_SIZE)); 56 ASSERT_EQ(0, brk(new_break)); 57 ASSERT_EQ(get_brk(), new_break); 58} 59 60TEST(unistd, brk_ENOMEM) { 61 ASSERT_EQ(-1, brk(reinterpret_cast<void*>(-1))); 62 ASSERT_EQ(ENOMEM, errno); 63} 64 65#if defined(__GLIBC__) 66#define SBRK_MIN INTPTR_MIN 67#define SBRK_MAX INTPTR_MAX 68#else 69#define SBRK_MIN PTRDIFF_MIN 70#define SBRK_MAX PTRDIFF_MAX 71#endif 72 73TEST(unistd, sbrk_ENOMEM) { 74#if defined(__BIONIC__) && !defined(__LP64__) 75 // There is no way to guarantee that all overflow conditions can be tested 76 // without manipulating the underlying values of the current break. 77 extern void* __bionic_brk; 78 79 class ScopedBrk { 80 public: 81 ScopedBrk() : saved_brk_(__bionic_brk) {} 82 virtual ~ScopedBrk() { __bionic_brk = saved_brk_; } 83 84 private: 85 void* saved_brk_; 86 }; 87 88 ScopedBrk scope_brk; 89 90 // Set the current break to a point that will cause an overflow. 91 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) + 2); 92 93 // Can't increase by so much that we'd overflow. 94 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MAX)); 95 ASSERT_EQ(ENOMEM, errno); 96 97 // Set the current break to a point that will cause an overflow. 98 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX)); 99 100 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN)); 101 ASSERT_EQ(ENOMEM, errno); 102 103 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) - 1); 104 105 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN + 1)); 106 ASSERT_EQ(ENOMEM, errno); 107#else 108 class ScopedBrk { 109 public: 110 ScopedBrk() : saved_brk_(get_brk()) {} 111 virtual ~ScopedBrk() { brk(saved_brk_); } 112 113 private: 114 void* saved_brk_; 115 }; 116 117 ScopedBrk scope_brk; 118 119 uintptr_t cur_brk = reinterpret_cast<uintptr_t>(get_brk()); 120 if (cur_brk < static_cast<uintptr_t>(-(SBRK_MIN+1))) { 121 // Do the overflow test for a max negative increment. 122 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MIN)); 123#if defined(__BIONIC__) 124 // GLIBC does not set errno in overflow case. 125 ASSERT_EQ(ENOMEM, errno); 126#endif 127 } 128 129 uintptr_t overflow_brk = static_cast<uintptr_t>(SBRK_MAX) + 2; 130 if (cur_brk < overflow_brk) { 131 // Try and move the value to PTRDIFF_MAX + 2. 132 cur_brk = reinterpret_cast<uintptr_t>(sbrk(overflow_brk)); 133 } 134 if (cur_brk >= overflow_brk) { 135 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MAX)); 136#if defined(__BIONIC__) 137 // GLIBC does not set errno in overflow case. 138 ASSERT_EQ(ENOMEM, errno); 139#endif 140 } 141#endif 142} 143 144TEST(unistd, truncate) { 145 TemporaryFile tf; 146 ASSERT_EQ(0, close(tf.fd)); 147 ASSERT_EQ(0, truncate(tf.filename, 123)); 148 149 struct stat sb; 150 ASSERT_EQ(0, stat(tf.filename, &sb)); 151 ASSERT_EQ(123, sb.st_size); 152} 153 154TEST(unistd, truncate64) { 155 TemporaryFile tf; 156 ASSERT_EQ(0, close(tf.fd)); 157 ASSERT_EQ(0, truncate64(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, ftruncate) { 165 TemporaryFile tf; 166 ASSERT_EQ(0, ftruncate(tf.fd, 123)); 167 ASSERT_EQ(0, close(tf.fd)); 168 169 struct stat sb; 170 ASSERT_EQ(0, stat(tf.filename, &sb)); 171 ASSERT_EQ(123, sb.st_size); 172} 173 174TEST(unistd, ftruncate64) { 175 TemporaryFile tf; 176 ASSERT_EQ(0, ftruncate64(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 184static bool g_pause_test_flag = false; 185static void PauseTestSignalHandler(int) { 186 g_pause_test_flag = true; 187} 188 189TEST(unistd, pause) { 190 ScopedSignalHandler handler(SIGALRM, PauseTestSignalHandler); 191 192 alarm(1); 193 ASSERT_FALSE(g_pause_test_flag); 194 ASSERT_EQ(-1, pause()); 195 ASSERT_TRUE(g_pause_test_flag); 196} 197 198TEST(unistd, read) { 199 int fd = open("/proc/version", O_RDONLY); 200 ASSERT_TRUE(fd != -1); 201 202 char buf[5]; 203 ASSERT_EQ(5, read(fd, buf, 5)); 204 ASSERT_EQ(buf[0], 'L'); 205 ASSERT_EQ(buf[1], 'i'); 206 ASSERT_EQ(buf[2], 'n'); 207 ASSERT_EQ(buf[3], 'u'); 208 ASSERT_EQ(buf[4], 'x'); 209 close(fd); 210} 211 212TEST(unistd, read_EBADF) { 213 // read returns ssize_t which is 64-bits on LP64, so it's worth explicitly checking that 214 // our syscall stubs correctly return a 64-bit -1. 215 char buf[1]; 216 ASSERT_EQ(-1, read(-1, buf, sizeof(buf))); 217 ASSERT_EQ(EBADF, errno); 218} 219 220TEST(unistd, syscall_long) { 221 // Check that syscall(3) correctly returns long results. 222 // https://code.google.com/p/android/issues/detail?id=73952 223 // We assume that the break is > 4GiB, but this is potentially flaky. 224 uintptr_t p = reinterpret_cast<uintptr_t>(sbrk(0)); 225 ASSERT_EQ(p, static_cast<uintptr_t>(syscall(__NR_brk, 0))); 226} 227 228TEST(unistd, alarm) { 229 ASSERT_EQ(0U, alarm(0)); 230} 231 232TEST(unistd, _exit) { 233 int pid = fork(); 234 ASSERT_NE(-1, pid) << strerror(errno); 235 236 if (pid == 0) { 237 _exit(99); 238 } 239 240 int status; 241 ASSERT_EQ(pid, waitpid(pid, &status, 0)); 242 ASSERT_TRUE(WIFEXITED(status)); 243 ASSERT_EQ(99, WEXITSTATUS(status)); 244} 245 246TEST(unistd, getenv_unsetenv) { 247 ASSERT_EQ(0, setenv("test-variable", "hello", 1)); 248 ASSERT_STREQ("hello", getenv("test-variable")); 249 ASSERT_EQ(0, unsetenv("test-variable")); 250 ASSERT_TRUE(getenv("test-variable") == NULL); 251} 252 253TEST(unistd, unsetenv_EINVAL) { 254 EXPECT_EQ(-1, unsetenv(NULL)); 255 EXPECT_EQ(EINVAL, errno); 256 EXPECT_EQ(-1, unsetenv("")); 257 EXPECT_EQ(EINVAL, errno); 258 EXPECT_EQ(-1, unsetenv("a=b")); 259 EXPECT_EQ(EINVAL, errno); 260} 261 262TEST(unistd, setenv_EINVAL) { 263 EXPECT_EQ(-1, setenv(NULL, "value", 0)); 264 EXPECT_EQ(EINVAL, errno); 265 EXPECT_EQ(-1, setenv(NULL, "value", 1)); 266 EXPECT_EQ(EINVAL, errno); 267 EXPECT_EQ(-1, setenv("", "value", 0)); 268 EXPECT_EQ(EINVAL, errno); 269 EXPECT_EQ(-1, setenv("", "value", 1)); 270 EXPECT_EQ(EINVAL, errno); 271 EXPECT_EQ(-1, setenv("a=b", "value", 0)); 272 EXPECT_EQ(EINVAL, errno); 273 EXPECT_EQ(-1, setenv("a=b", "value", 1)); 274 EXPECT_EQ(EINVAL, errno); 275} 276 277TEST(unistd, setenv) { 278 ASSERT_EQ(0, unsetenv("test-variable")); 279 280 char a[] = "a"; 281 char b[] = "b"; 282 char c[] = "c"; 283 284 // New value. 285 EXPECT_EQ(0, setenv("test-variable", a, 0)); 286 EXPECT_STREQ(a, getenv("test-variable")); 287 288 // Existing value, no overwrite. 289 EXPECT_EQ(0, setenv("test-variable", b, 0)); 290 EXPECT_STREQ(a, getenv("test-variable")); 291 292 // Existing value, overwrite. 293 EXPECT_EQ(0, setenv("test-variable", c, 1)); 294 EXPECT_STREQ(c, getenv("test-variable")); 295 // But the arrays backing the values are unchanged. 296 EXPECT_EQ('a', a[0]); 297 EXPECT_EQ('b', b[0]); 298 EXPECT_EQ('c', c[0]); 299 300 ASSERT_EQ(0, unsetenv("test-variable")); 301} 302 303TEST(unistd, putenv) { 304 ASSERT_EQ(0, unsetenv("a")); 305 306 char* s1 = strdup("a=b"); 307 ASSERT_EQ(0, putenv(s1)); 308 309 ASSERT_STREQ("b", getenv("a")); 310 s1[2] = 'c'; 311 ASSERT_STREQ("c", getenv("a")); 312 313 char* s2 = strdup("a=b"); 314 ASSERT_EQ(0, putenv(s2)); 315 316 ASSERT_STREQ("b", getenv("a")); 317 ASSERT_EQ('c', s1[2]); 318 319 ASSERT_EQ(0, unsetenv("a")); 320 free(s1); 321 free(s2); 322} 323 324TEST(unistd, clearenv) { 325 extern char** environ; 326 327 // Guarantee that environ is not initially empty... 328 ASSERT_EQ(0, setenv("test-variable", "a", 1)); 329 330 // Stash a copy. 331 std::vector<char*> old_environ; 332 for (size_t i = 0; environ[i] != NULL; ++i) { 333 old_environ.push_back(strdup(environ[i])); 334 } 335 336 ASSERT_EQ(0, clearenv()); 337 338 EXPECT_TRUE(environ == NULL || environ[0] == NULL); 339 EXPECT_EQ(NULL, getenv("test-variable")); 340 EXPECT_EQ(0, setenv("test-variable", "post-clear", 1)); 341 EXPECT_STREQ("post-clear", getenv("test-variable")); 342 343 // Put the old environment back. 344 for (size_t i = 0; i < old_environ.size(); ++i) { 345 EXPECT_EQ(0, putenv(old_environ[i])); 346 } 347 348 // Check it wasn't overwritten. 349 EXPECT_STREQ("a", getenv("test-variable")); 350 351 EXPECT_EQ(0, unsetenv("test-variable")); 352} 353 354static void TestFsyncFunction(int (*fn)(int)) { 355 int fd; 356 357 // Can't sync an invalid fd. 358 errno = 0; 359 EXPECT_EQ(-1, fn(-1)); 360 EXPECT_EQ(EBADF, errno); 361 362 // It doesn't matter whether you've opened a file for write or not. 363 TemporaryFile tf; 364 ASSERT_NE(-1, tf.fd); 365 366 EXPECT_EQ(0, fn(tf.fd)); 367 368 ASSERT_NE(-1, fd = open(tf.filename, O_RDONLY)); 369 EXPECT_EQ(0, fn(fd)); 370 close(fd); 371 372 ASSERT_NE(-1, fd = open(tf.filename, O_RDWR)); 373 EXPECT_EQ(0, fn(fd)); 374 close(fd); 375 376 // The fd can even be a directory. 377 ASSERT_NE(-1, fd = open("/", O_RDONLY)); 378 EXPECT_EQ(0, fn(fd)); 379 close(fd); 380 381 // But some file systems may choose to be fussy... 382 errno = 0; 383 ASSERT_NE(-1, fd = open("/proc/version", O_RDONLY)); 384 EXPECT_EQ(-1, fn(fd)); 385 EXPECT_EQ(EINVAL, errno); 386 close(fd); 387} 388 389TEST(unistd, fdatasync) { 390 TestFsyncFunction(fdatasync); 391} 392 393TEST(unistd, fsync) { 394 TestFsyncFunction(fsync); 395} 396 397static void AssertGetPidCorrect() { 398 // The loop is just to make manual testing/debugging with strace easier. 399 pid_t getpid_syscall_result = syscall(__NR_getpid); 400 for (size_t i = 0; i < 128; ++i) { 401 ASSERT_EQ(getpid_syscall_result, getpid()); 402 } 403} 404 405TEST(unistd, getpid_caching_and_fork) { 406 pid_t parent_pid = getpid(); 407 ASSERT_EQ(syscall(__NR_getpid), parent_pid); 408 409 pid_t fork_result = fork(); 410 ASSERT_NE(fork_result, -1); 411 if (fork_result == 0) { 412 // We're the child. 413 AssertGetPidCorrect(); 414 ASSERT_EQ(parent_pid, getppid()); 415 _exit(123); 416 } else { 417 // We're the parent. 418 ASSERT_EQ(parent_pid, getpid()); 419 420 int status; 421 ASSERT_EQ(fork_result, waitpid(fork_result, &status, 0)); 422 ASSERT_TRUE(WIFEXITED(status)); 423 ASSERT_EQ(123, WEXITSTATUS(status)); 424 } 425} 426 427static int GetPidCachingCloneStartRoutine(void*) { 428 AssertGetPidCorrect(); 429 return 123; 430} 431 432TEST(unistd, getpid_caching_and_clone) { 433 pid_t parent_pid = getpid(); 434 ASSERT_EQ(syscall(__NR_getpid), parent_pid); 435 436 void* child_stack[1024]; 437 int clone_result = clone(GetPidCachingCloneStartRoutine, &child_stack[1024], CLONE_NEWNS | SIGCHLD, NULL); 438 if (clone_result == -1 && errno == EPERM && getuid() != 0) { 439 GTEST_LOG_(INFO) << "This test only works if you have permission to CLONE_NEWNS; try running as root.\n"; 440 return; 441 } 442 ASSERT_NE(clone_result, -1); 443 444 ASSERT_EQ(parent_pid, getpid()); 445 446 int status; 447 ASSERT_EQ(clone_result, waitpid(clone_result, &status, 0)); 448 ASSERT_TRUE(WIFEXITED(status)); 449 ASSERT_EQ(123, WEXITSTATUS(status)); 450} 451 452static void* GetPidCachingPthreadStartRoutine(void*) { 453 AssertGetPidCorrect(); 454 return NULL; 455} 456 457TEST(unistd, getpid_caching_and_pthread_create) { 458 pid_t parent_pid = getpid(); 459 460 pthread_t t; 461 ASSERT_EQ(0, pthread_create(&t, NULL, GetPidCachingPthreadStartRoutine, NULL)); 462 463 ASSERT_EQ(parent_pid, getpid()); 464 465 void* result; 466 ASSERT_EQ(0, pthread_join(t, &result)); 467 ASSERT_EQ(NULL, result); 468} 469 470class unistd_DeathTest : public BionicDeathTest {}; 471 472TEST_F(unistd_DeathTest, abort) { 473 ASSERT_EXIT(abort(), testing::KilledBySignal(SIGABRT), ""); 474} 475 476TEST(unistd, sethostname) { 477 // The permissions check happens before the argument check, so this will 478 // fail for a different reason if you're running as root than if you're 479 // not, but it'll fail either way. Checking that we have the symbol is about 480 // all we can do for sethostname(2). 481 ASSERT_EQ(-1, sethostname("", -1)); 482} 483 484TEST(unistd, gethostname) { 485 char hostname[HOST_NAME_MAX + 1]; 486 memset(hostname, 0, sizeof(hostname)); 487 488 // Can we get the hostname with a big buffer? 489 ASSERT_EQ(0, gethostname(hostname, HOST_NAME_MAX)); 490 491 // Can we get the hostname with a right-sized buffer? 492 errno = 0; 493 ASSERT_EQ(0, gethostname(hostname, strlen(hostname) + 1)); 494 495 // Does uname(2) agree? 496 utsname buf; 497 ASSERT_EQ(0, uname(&buf)); 498 ASSERT_EQ(0, strncmp(hostname, buf.nodename, SYS_NMLN)); 499 ASSERT_GT(strlen(hostname), 0U); 500 501 // Do we correctly detect truncation? 502 errno = 0; 503 ASSERT_EQ(-1, gethostname(hostname, strlen(hostname))); 504 ASSERT_EQ(ENAMETOOLONG, errno); 505} 506 507TEST(unistd, pathconf_fpathconf) { 508 TemporaryFile tf; 509 long rc = 0L; 510 // As a file system's block size is always power of 2, the configure values 511 // for ALLOC and XFER should be power of 2 as well. 512 rc = pathconf(tf.filename, _PC_ALLOC_SIZE_MIN); 513 ASSERT_TRUE(rc > 0 && powerof2(rc)); 514 rc = pathconf(tf.filename, _PC_REC_MIN_XFER_SIZE); 515 ASSERT_TRUE(rc > 0 && powerof2(rc)); 516 rc = pathconf(tf.filename, _PC_REC_XFER_ALIGN); 517 ASSERT_TRUE(rc > 0 && powerof2(rc)); 518 519 rc = fpathconf(tf.fd, _PC_ALLOC_SIZE_MIN); 520 ASSERT_TRUE(rc > 0 && powerof2(rc)); 521 rc = fpathconf(tf.fd, _PC_REC_MIN_XFER_SIZE); 522 ASSERT_TRUE(rc > 0 && powerof2(rc)); 523 rc = fpathconf(tf.fd, _PC_REC_XFER_ALIGN); 524 ASSERT_TRUE(rc > 0 && powerof2(rc)); 525} 526