Home | History | Annotate | Download | only in tests
      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 "ScopedSignalHandler.h"
     19 #include "TemporaryFile.h"
     20 
     21 #include <errno.h>
     22 #include <fcntl.h>
     23 #include <limits.h>
     24 #include <stdint.h>
     25 #include <unistd.h>
     26 #include <sys/syscall.h>
     27 #include <sys/types.h>
     28 #include <sys/wait.h>
     29 
     30 TEST(unistd, sysconf_SC_MONOTONIC_CLOCK) {
     31   ASSERT_GT(sysconf(_SC_MONOTONIC_CLOCK), 0);
     32 }
     33 
     34 static void* get_brk() {
     35   return sbrk(0);
     36 }
     37 
     38 static void* page_align(uintptr_t addr) {
     39   uintptr_t mask = sysconf(_SC_PAGE_SIZE) - 1;
     40   return reinterpret_cast<void*>((addr + mask) & ~mask);
     41 }
     42 
     43 TEST(unistd, brk) {
     44   void* initial_break = get_brk();
     45 
     46   // The kernel aligns the break to a page.
     47   void* new_break = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(initial_break) + 1);
     48   ASSERT_EQ(0, brk(new_break));
     49   ASSERT_GE(get_brk(), new_break);
     50 
     51   new_break = page_align(reinterpret_cast<uintptr_t>(initial_break) + sysconf(_SC_PAGE_SIZE));
     52   ASSERT_EQ(0, brk(new_break));
     53   ASSERT_EQ(get_brk(), new_break);
     54 }
     55 
     56 TEST(unistd, brk_ENOMEM) {
     57   ASSERT_EQ(-1, brk(reinterpret_cast<void*>(-1)));
     58   ASSERT_EQ(ENOMEM, errno);
     59 }
     60 
     61 #if defined(__GLIBC__)
     62 #define SBRK_MIN INTPTR_MIN
     63 #define SBRK_MAX INTPTR_MAX
     64 #else
     65 #define SBRK_MIN PTRDIFF_MIN
     66 #define SBRK_MAX PTRDIFF_MAX
     67 #endif
     68 
     69 TEST(unistd, sbrk_ENOMEM) {
     70 #if defined(__BIONIC__) && !defined(__LP64__)
     71   // There is no way to guarantee that all overflow conditions can be tested
     72   // without manipulating the underlying values of the current break.
     73   extern void* __bionic_brk;
     74 
     75   class ScopedBrk {
     76   public:
     77     ScopedBrk() : saved_brk_(__bionic_brk) {}
     78     virtual ~ScopedBrk() { __bionic_brk = saved_brk_; }
     79 
     80   private:
     81     void* saved_brk_;
     82   };
     83 
     84   ScopedBrk scope_brk;
     85 
     86   // Set the current break to a point that will cause an overflow.
     87   __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) + 2);
     88 
     89   // Can't increase by so much that we'd overflow.
     90   ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MAX));
     91   ASSERT_EQ(ENOMEM, errno);
     92 
     93   // Set the current break to a point that will cause an overflow.
     94   __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX));
     95 
     96   ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN));
     97   ASSERT_EQ(ENOMEM, errno);
     98 
     99   __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) - 1);
    100 
    101   ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN + 1));
    102   ASSERT_EQ(ENOMEM, errno);
    103 #else
    104   class ScopedBrk {
    105   public:
    106     ScopedBrk() : saved_brk_(get_brk()) {}
    107     virtual ~ScopedBrk() { brk(saved_brk_); }
    108 
    109   private:
    110     void* saved_brk_;
    111   };
    112 
    113   ScopedBrk scope_brk;
    114 
    115   uintptr_t cur_brk = reinterpret_cast<uintptr_t>(get_brk());
    116   if (cur_brk < static_cast<uintptr_t>(-(SBRK_MIN+1))) {
    117     // Do the overflow test for a max negative increment.
    118     ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MIN));
    119 #if defined(__BIONIC__)
    120     // GLIBC does not set errno in overflow case.
    121     ASSERT_EQ(ENOMEM, errno);
    122 #endif
    123   }
    124 
    125   uintptr_t overflow_brk = static_cast<uintptr_t>(SBRK_MAX) + 2;
    126   if (cur_brk < overflow_brk) {
    127     // Try and move the value to PTRDIFF_MAX + 2.
    128     cur_brk = reinterpret_cast<uintptr_t>(sbrk(overflow_brk));
    129   }
    130   if (cur_brk >= overflow_brk) {
    131     ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MAX));
    132 #if defined(__BIONIC__)
    133     // GLIBC does not set errno in overflow case.
    134     ASSERT_EQ(ENOMEM, errno);
    135 #endif
    136   }
    137 #endif
    138 }
    139 
    140 TEST(unistd, truncate) {
    141   TemporaryFile tf;
    142   ASSERT_EQ(0, close(tf.fd));
    143   ASSERT_EQ(0, truncate(tf.filename, 123));
    144 
    145   struct stat sb;
    146   ASSERT_EQ(0, stat(tf.filename, &sb));
    147   ASSERT_EQ(123, sb.st_size);
    148 }
    149 
    150 TEST(unistd, truncate64) {
    151   TemporaryFile tf;
    152   ASSERT_EQ(0, close(tf.fd));
    153   ASSERT_EQ(0, truncate64(tf.filename, 123));
    154 
    155   struct stat sb;
    156   ASSERT_EQ(0, stat(tf.filename, &sb));
    157   ASSERT_EQ(123, sb.st_size);
    158 }
    159 
    160 TEST(unistd, ftruncate) {
    161   TemporaryFile tf;
    162   ASSERT_EQ(0, ftruncate(tf.fd, 123));
    163   ASSERT_EQ(0, close(tf.fd));
    164 
    165   struct stat sb;
    166   ASSERT_EQ(0, stat(tf.filename, &sb));
    167   ASSERT_EQ(123, sb.st_size);
    168 }
    169 
    170 TEST(unistd, ftruncate64) {
    171   TemporaryFile tf;
    172   ASSERT_EQ(0, ftruncate64(tf.fd, 123));
    173   ASSERT_EQ(0, close(tf.fd));
    174 
    175   struct stat sb;
    176   ASSERT_EQ(0, stat(tf.filename, &sb));
    177   ASSERT_EQ(123, sb.st_size);
    178 }
    179 
    180 static bool g_pause_test_flag = false;
    181 static void PauseTestSignalHandler(int) {
    182   g_pause_test_flag = true;
    183 }
    184 
    185 TEST(unistd, pause) {
    186   ScopedSignalHandler handler(SIGALRM, PauseTestSignalHandler);
    187 
    188   alarm(1);
    189   ASSERT_FALSE(g_pause_test_flag);
    190   ASSERT_EQ(-1, pause());
    191   ASSERT_TRUE(g_pause_test_flag);
    192 }
    193 
    194 TEST(unistd, read) {
    195   int fd = open("/proc/version", O_RDONLY);
    196   ASSERT_TRUE(fd != -1);
    197 
    198   char buf[5];
    199   ASSERT_EQ(5, read(fd, buf, 5));
    200   ASSERT_EQ(buf[0], 'L');
    201   ASSERT_EQ(buf[1], 'i');
    202   ASSERT_EQ(buf[2], 'n');
    203   ASSERT_EQ(buf[3], 'u');
    204   ASSERT_EQ(buf[4], 'x');
    205   close(fd);
    206 }
    207 
    208 TEST(unistd, read_EBADF) {
    209   // read returns ssize_t which is 64-bits on LP64, so it's worth explicitly checking that
    210   // our syscall stubs correctly return a 64-bit -1.
    211   char buf[1];
    212   ASSERT_EQ(-1, read(-1, buf, sizeof(buf)));
    213   ASSERT_EQ(EBADF, errno);
    214 }
    215 
    216 TEST(unistd, syscall_long) {
    217   // Check that syscall(3) correctly returns long results.
    218   // https://code.google.com/p/android/issues/detail?id=73952
    219   // We assume that the break is > 4GiB, but this is potentially flaky.
    220   uintptr_t p = reinterpret_cast<uintptr_t>(sbrk(0));
    221   ASSERT_EQ(p, static_cast<uintptr_t>(syscall(__NR_brk, 0)));
    222 }
    223 
    224 TEST(unistd, alarm) {
    225   ASSERT_EQ(0U, alarm(0));
    226 }
    227 
    228 TEST(unistd, _exit) {
    229   int pid = fork();
    230   ASSERT_NE(-1, pid) << strerror(errno);
    231 
    232   if (pid == 0) {
    233     _exit(99);
    234   }
    235 
    236   int status;
    237   ASSERT_EQ(pid, waitpid(pid, &status, 0));
    238   ASSERT_TRUE(WIFEXITED(status));
    239   ASSERT_EQ(99, WEXITSTATUS(status));
    240 }
    241 
    242 TEST(unistd, getenv_unsetenv) {
    243   ASSERT_EQ(0, setenv("test-variable", "hello", 1));
    244   ASSERT_STREQ("hello", getenv("test-variable"));
    245   ASSERT_EQ(0, unsetenv("test-variable"));
    246   ASSERT_TRUE(getenv("test-variable") == NULL);
    247 }
    248 
    249 TEST(unistd, unsetenv_EINVAL) {
    250   EXPECT_EQ(-1, unsetenv(NULL));
    251   EXPECT_EQ(EINVAL, errno);
    252   EXPECT_EQ(-1, unsetenv(""));
    253   EXPECT_EQ(EINVAL, errno);
    254   EXPECT_EQ(-1, unsetenv("a=b"));
    255   EXPECT_EQ(EINVAL, errno);
    256 }
    257 
    258 TEST(unistd, setenv_EINVAL) {
    259   EXPECT_EQ(-1, setenv(NULL, "value", 0));
    260   EXPECT_EQ(EINVAL, errno);
    261   EXPECT_EQ(-1, setenv(NULL, "value", 1));
    262   EXPECT_EQ(EINVAL, errno);
    263   EXPECT_EQ(-1, setenv("", "value", 0));
    264   EXPECT_EQ(EINVAL, errno);
    265   EXPECT_EQ(-1, setenv("", "value", 1));
    266   EXPECT_EQ(EINVAL, errno);
    267   EXPECT_EQ(-1, setenv("a=b", "value", 0));
    268   EXPECT_EQ(EINVAL, errno);
    269   EXPECT_EQ(-1, setenv("a=b", "value", 1));
    270   EXPECT_EQ(EINVAL, errno);
    271 }
    272 
    273 TEST(unistd, setenv) {
    274   ASSERT_EQ(0, unsetenv("test-variable"));
    275 
    276   char a[] = "a";
    277   char b[] = "b";
    278   char c[] = "c";
    279 
    280   // New value.
    281   EXPECT_EQ(0, setenv("test-variable", a, 0));
    282   EXPECT_STREQ(a, getenv("test-variable"));
    283 
    284   // Existing value, no overwrite.
    285   EXPECT_EQ(0, setenv("test-variable", b, 0));
    286   EXPECT_STREQ(a, getenv("test-variable"));
    287 
    288   // Existing value, overwrite.
    289   EXPECT_EQ(0, setenv("test-variable", c, 1));
    290   EXPECT_STREQ(c, getenv("test-variable"));
    291   // But the arrays backing the values are unchanged.
    292   EXPECT_EQ('a', a[0]);
    293   EXPECT_EQ('b', b[0]);
    294   EXPECT_EQ('c', c[0]);
    295 
    296   ASSERT_EQ(0, unsetenv("test-variable"));
    297 }
    298 
    299 TEST(unistd, putenv) {
    300   ASSERT_EQ(0, unsetenv("a"));
    301 
    302   char* s1 = strdup("a=b");
    303   ASSERT_EQ(0, putenv(s1));
    304 
    305   ASSERT_STREQ("b", getenv("a"));
    306   s1[2] = 'c';
    307   ASSERT_STREQ("c", getenv("a"));
    308 
    309   char* s2 = strdup("a=b");
    310   ASSERT_EQ(0, putenv(s2));
    311 
    312   ASSERT_STREQ("b", getenv("a"));
    313   ASSERT_EQ('c', s1[2]);
    314 
    315   ASSERT_EQ(0, unsetenv("a"));
    316   free(s1);
    317   free(s2);
    318 }
    319 
    320 TEST(unistd, clearenv) {
    321   extern char** environ;
    322 
    323   // Guarantee that environ is not initially empty...
    324   ASSERT_EQ(0, setenv("test-variable", "a", 1));
    325 
    326   // Stash a copy.
    327   std::vector<char*> old_environ;
    328   for (size_t i = 0; environ[i] != NULL; ++i) {
    329     old_environ.push_back(strdup(environ[i]));
    330   }
    331 
    332   ASSERT_EQ(0, clearenv());
    333 
    334   EXPECT_TRUE(environ == NULL || environ[0] == NULL);
    335   EXPECT_EQ(NULL, getenv("test-variable"));
    336   EXPECT_EQ(0, setenv("test-variable", "post-clear", 1));
    337   EXPECT_STREQ("post-clear", getenv("test-variable"));
    338 
    339   // Put the old environment back.
    340   for (size_t i = 0; i < old_environ.size(); ++i) {
    341     EXPECT_EQ(0, putenv(old_environ[i]));
    342   }
    343 
    344   // Check it wasn't overwritten.
    345   EXPECT_STREQ("a", getenv("test-variable"));
    346 
    347   EXPECT_EQ(0, unsetenv("test-variable"));
    348 }
    349 
    350 static void TestFsyncFunction(int (*fn)(int)) {
    351   int fd;
    352 
    353   // Can't sync an invalid fd.
    354   errno = 0;
    355   EXPECT_EQ(-1, fn(-1));
    356   EXPECT_EQ(EBADF, errno);
    357 
    358   // It doesn't matter whether you've opened a file for write or not.
    359   TemporaryFile tf;
    360   ASSERT_NE(-1, tf.fd);
    361 
    362   EXPECT_EQ(0, fn(tf.fd));
    363 
    364   ASSERT_NE(-1, fd = open(tf.filename, O_RDONLY));
    365   EXPECT_EQ(0, fn(fd));
    366   close(fd);
    367 
    368   ASSERT_NE(-1, fd = open(tf.filename, O_RDWR));
    369   EXPECT_EQ(0, fn(fd));
    370   close(fd);
    371 
    372   // The fd can even be a directory.
    373   ASSERT_NE(-1, fd = open("/", O_RDONLY));
    374   EXPECT_EQ(0, fn(fd));
    375   close(fd);
    376 
    377   // But some file systems may choose to be fussy...
    378   errno = 0;
    379   ASSERT_NE(-1, fd = open("/proc/version", O_RDONLY));
    380   EXPECT_EQ(-1, fn(fd));
    381   EXPECT_EQ(EINVAL, errno);
    382   close(fd);
    383 }
    384 
    385 TEST(unistd, fdatasync) {
    386   TestFsyncFunction(fdatasync);
    387 }
    388 
    389 TEST(unistd, fsync) {
    390   TestFsyncFunction(fsync);
    391 }
    392 
    393 static void AssertGetPidCorrect() {
    394   // The loop is just to make manual testing/debugging with strace easier.
    395   pid_t getpid_syscall_result = syscall(__NR_getpid);
    396   for (size_t i = 0; i < 128; ++i) {
    397     ASSERT_EQ(getpid_syscall_result, getpid());
    398   }
    399 }
    400 
    401 TEST(unistd, getpid_caching_and_fork) {
    402   pid_t parent_pid = getpid();
    403   ASSERT_EQ(syscall(__NR_getpid), parent_pid);
    404 
    405   pid_t fork_result = fork();
    406   ASSERT_NE(fork_result, -1);
    407   if (fork_result == 0) {
    408     // We're the child.
    409     AssertGetPidCorrect();
    410     ASSERT_EQ(parent_pid, getppid());
    411     _exit(123);
    412   } else {
    413     // We're the parent.
    414     ASSERT_EQ(parent_pid, getpid());
    415 
    416     int status;
    417     ASSERT_EQ(fork_result, waitpid(fork_result, &status, 0));
    418     ASSERT_TRUE(WIFEXITED(status));
    419     ASSERT_EQ(123, WEXITSTATUS(status));
    420   }
    421 }
    422 
    423 static int GetPidCachingCloneStartRoutine(void*) {
    424   AssertGetPidCorrect();
    425   return 123;
    426 }
    427 
    428 TEST(unistd, getpid_caching_and_clone) {
    429   pid_t parent_pid = getpid();
    430   ASSERT_EQ(syscall(__NR_getpid), parent_pid);
    431 
    432   void* child_stack[1024];
    433   int clone_result = clone(GetPidCachingCloneStartRoutine, &child_stack[1024], CLONE_NEWNS | SIGCHLD, NULL);
    434   if (clone_result == -1 && errno == EPERM && getuid() != 0) {
    435     GTEST_LOG_(INFO) << "This test only works if you have permission to CLONE_NEWNS; try running as root.\n";
    436     return;
    437   }
    438   ASSERT_NE(clone_result, -1);
    439 
    440   ASSERT_EQ(parent_pid, getpid());
    441 
    442   int status;
    443   ASSERT_EQ(clone_result, waitpid(clone_result, &status, 0));
    444   ASSERT_TRUE(WIFEXITED(status));
    445   ASSERT_EQ(123, WEXITSTATUS(status));
    446 }
    447 
    448 static void* GetPidCachingPthreadStartRoutine(void*) {
    449   AssertGetPidCorrect();
    450   return NULL;
    451 }
    452 
    453 TEST(unistd, getpid_caching_and_pthread_create) {
    454   pid_t parent_pid = getpid();
    455 
    456   pthread_t t;
    457   ASSERT_EQ(0, pthread_create(&t, NULL, GetPidCachingPthreadStartRoutine, NULL));
    458 
    459   ASSERT_EQ(parent_pid, getpid());
    460 
    461   void* result;
    462   ASSERT_EQ(0, pthread_join(t, &result));
    463   ASSERT_EQ(NULL, result);
    464 }
    465