unistd_test.cpp revision 738b0cc5e95a9a650e9621603f4dd8dd16b07568
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 <stdint.h> 24#include <unistd.h> 25#include <sys/types.h> 26#include <sys/wait.h> 27 28TEST(unistd, sysconf_SC_MONOTONIC_CLOCK) { 29 ASSERT_GT(sysconf(_SC_MONOTONIC_CLOCK), 0); 30} 31 32static void* get_brk() { 33 return sbrk(0); 34} 35 36static void* page_align(uintptr_t addr) { 37 uintptr_t mask = sysconf(_SC_PAGE_SIZE) - 1; 38 return reinterpret_cast<void*>((addr + mask) & ~mask); 39} 40 41TEST(unistd, brk) { 42 void* initial_break = get_brk(); 43 44 // The kernel aligns the break to a page. 45 void* new_break = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(initial_break) + 1); 46 ASSERT_EQ(0, brk(new_break)); 47 ASSERT_GE(get_brk(), new_break); 48 49 new_break = page_align(reinterpret_cast<uintptr_t>(initial_break) + sysconf(_SC_PAGE_SIZE)); 50 ASSERT_EQ(0, brk(new_break)); 51 ASSERT_EQ(get_brk(), new_break); 52} 53 54TEST(unistd, brk_ENOMEM) { 55 ASSERT_EQ(-1, brk(reinterpret_cast<void*>(-1))); 56 ASSERT_EQ(ENOMEM, errno); 57} 58 59#if defined(__GLIBC__) 60#define SBRK_MIN INTPTR_MIN 61#define SBRK_MAX INTPTR_MAX 62#else 63#define SBRK_MIN PTRDIFF_MIN 64#define SBRK_MAX PTRDIFF_MAX 65#endif 66 67TEST(unistd, sbrk_ENOMEM) { 68#if defined(__BIONIC__) && !defined(__LP64__) 69 // There is no way to guarantee that all overflow conditions can be tested 70 // without manipulating the underlying values of the current break. 71 extern void* __bionic_brk; 72 73 class ScopedBrk { 74 public: 75 ScopedBrk() : saved_brk_(__bionic_brk) {} 76 virtual ~ScopedBrk() { __bionic_brk = saved_brk_; } 77 78 private: 79 void* saved_brk_; 80 }; 81 82 ScopedBrk scope_brk; 83 84 // Set the current break to a point that will cause an overflow. 85 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) + 2); 86 87 // Can't increase by so much that we'd overflow. 88 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MAX)); 89 ASSERT_EQ(ENOMEM, errno); 90 91 // Set the current break to a point that will cause an overflow. 92 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX)); 93 94 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN)); 95 ASSERT_EQ(ENOMEM, errno); 96 97 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) - 1); 98 99 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN + 1)); 100 ASSERT_EQ(ENOMEM, errno); 101#else 102 class ScopedBrk { 103 public: 104 ScopedBrk() : saved_brk_(get_brk()) {} 105 virtual ~ScopedBrk() { brk(saved_brk_); } 106 107 private: 108 void* saved_brk_; 109 }; 110 111 ScopedBrk scope_brk; 112 113 uintptr_t cur_brk = reinterpret_cast<uintptr_t>(get_brk()); 114 if (cur_brk < static_cast<uintptr_t>(-(SBRK_MIN+1))) { 115 // Do the overflow test for a max negative increment. 116 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MIN)); 117#if defined(__BIONIC__) 118 // GLIBC does not set errno in overflow case. 119 ASSERT_EQ(ENOMEM, errno); 120#endif 121 } 122 123 uintptr_t overflow_brk = static_cast<uintptr_t>(SBRK_MAX) + 2; 124 if (cur_brk < overflow_brk) { 125 // Try and move the value to PTRDIFF_MAX + 2. 126 cur_brk = reinterpret_cast<uintptr_t>(sbrk(overflow_brk)); 127 } 128 if (cur_brk >= overflow_brk) { 129 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MAX)); 130#if defined(__BIONIC__) 131 // GLIBC does not set errno in overflow case. 132 ASSERT_EQ(ENOMEM, errno); 133#endif 134 } 135#endif 136} 137 138TEST(unistd, truncate) { 139 TemporaryFile tf; 140 ASSERT_EQ(0, close(tf.fd)); 141 ASSERT_EQ(0, truncate(tf.filename, 123)); 142 143 struct stat sb; 144 ASSERT_EQ(0, stat(tf.filename, &sb)); 145 ASSERT_EQ(123, sb.st_size); 146} 147 148TEST(unistd, truncate64) { 149 TemporaryFile tf; 150 ASSERT_EQ(0, close(tf.fd)); 151 ASSERT_EQ(0, truncate64(tf.filename, 123)); 152 153 struct stat sb; 154 ASSERT_EQ(0, stat(tf.filename, &sb)); 155 ASSERT_EQ(123, sb.st_size); 156} 157 158TEST(unistd, ftruncate) { 159 TemporaryFile tf; 160 ASSERT_EQ(0, ftruncate(tf.fd, 123)); 161 ASSERT_EQ(0, close(tf.fd)); 162 163 struct stat sb; 164 ASSERT_EQ(0, stat(tf.filename, &sb)); 165 ASSERT_EQ(123, sb.st_size); 166} 167 168TEST(unistd, ftruncate64) { 169 TemporaryFile tf; 170 ASSERT_EQ(0, ftruncate64(tf.fd, 123)); 171 ASSERT_EQ(0, close(tf.fd)); 172 173 struct stat sb; 174 ASSERT_EQ(0, stat(tf.filename, &sb)); 175 ASSERT_EQ(123, sb.st_size); 176} 177 178static bool g_pause_test_flag = false; 179static void PauseTestSignalHandler(int) { 180 g_pause_test_flag = true; 181} 182 183TEST(unistd, pause) { 184 ScopedSignalHandler handler(SIGALRM, PauseTestSignalHandler); 185 186 alarm(1); 187 ASSERT_FALSE(g_pause_test_flag); 188 ASSERT_EQ(-1, pause()); 189 ASSERT_TRUE(g_pause_test_flag); 190} 191 192TEST(unistd, read) { 193 int fd = open("/proc/version", O_RDONLY); 194 ASSERT_TRUE(fd != -1); 195 196 char buf[5]; 197 ASSERT_EQ(5, read(fd, buf, 5)); 198 ASSERT_EQ(buf[0], 'L'); 199 ASSERT_EQ(buf[1], 'i'); 200 ASSERT_EQ(buf[2], 'n'); 201 ASSERT_EQ(buf[3], 'u'); 202 ASSERT_EQ(buf[4], 'x'); 203 close(fd); 204} 205 206TEST(unistd, read_EBADF) { 207 // read returns ssize_t which is 64-bits on LP64, so it's worth explicitly checking that 208 // our syscall stubs correctly return a 64-bit -1. 209 char buf[1]; 210 ASSERT_EQ(-1, read(-1, buf, sizeof(buf))); 211 ASSERT_EQ(EBADF, errno); 212} 213 214TEST(unistd, alarm) { 215 ASSERT_EQ(0U, alarm(0)); 216} 217 218TEST(unistd, _exit) { 219 int pid = fork(); 220 ASSERT_NE(-1, pid) << strerror(errno); 221 222 if (pid == 0) { 223 _exit(99); 224 } 225 226 int status; 227 ASSERT_EQ(pid, waitpid(pid, &status, 0)); 228 ASSERT_TRUE(WIFEXITED(status)); 229 ASSERT_EQ(99, WEXITSTATUS(status)); 230} 231 232TEST(unistd, getenv_unsetenv) { 233 ASSERT_EQ(0, setenv("test-variable", "hello", 1)); 234 ASSERT_STREQ("hello", getenv("test-variable")); 235 ASSERT_EQ(0, unsetenv("test-variable")); 236 ASSERT_TRUE(getenv("test-variable") == NULL); 237} 238 239TEST(unistd, unsetenv_EINVAL) { 240 EXPECT_EQ(-1, unsetenv(NULL)); 241 EXPECT_EQ(EINVAL, errno); 242 EXPECT_EQ(-1, unsetenv("")); 243 EXPECT_EQ(EINVAL, errno); 244 EXPECT_EQ(-1, unsetenv("a=b")); 245 EXPECT_EQ(EINVAL, errno); 246} 247 248TEST(unistd, setenv_EINVAL) { 249 EXPECT_EQ(-1, setenv(NULL, "value", 0)); 250 EXPECT_EQ(EINVAL, errno); 251 EXPECT_EQ(-1, setenv(NULL, "value", 1)); 252 EXPECT_EQ(EINVAL, errno); 253 EXPECT_EQ(-1, setenv("", "value", 0)); 254 EXPECT_EQ(EINVAL, errno); 255 EXPECT_EQ(-1, setenv("", "value", 1)); 256 EXPECT_EQ(EINVAL, errno); 257 EXPECT_EQ(-1, setenv("a=b", "value", 0)); 258 EXPECT_EQ(EINVAL, errno); 259 EXPECT_EQ(-1, setenv("a=b", "value", 1)); 260 EXPECT_EQ(EINVAL, errno); 261} 262 263TEST(unistd, setenv) { 264 ASSERT_EQ(0, unsetenv("test-variable")); 265 266 char a[] = "a"; 267 char b[] = "b"; 268 char c[] = "c"; 269 270 // New value. 271 EXPECT_EQ(0, setenv("test-variable", a, 0)); 272 EXPECT_STREQ(a, getenv("test-variable")); 273 274 // Existing value, no overwrite. 275 EXPECT_EQ(0, setenv("test-variable", b, 0)); 276 EXPECT_STREQ(a, getenv("test-variable")); 277 278 // Existing value, overwrite. 279 EXPECT_EQ(0, setenv("test-variable", c, 1)); 280 EXPECT_STREQ(c, getenv("test-variable")); 281 // But the arrays backing the values are unchanged. 282 EXPECT_EQ('a', a[0]); 283 EXPECT_EQ('b', b[0]); 284 EXPECT_EQ('c', c[0]); 285 286 ASSERT_EQ(0, unsetenv("test-variable")); 287} 288 289TEST(unistd, putenv) { 290 ASSERT_EQ(0, unsetenv("a")); 291 292 char* s1 = strdup("a=b"); 293 ASSERT_EQ(0, putenv(s1)); 294 295 ASSERT_STREQ("b", getenv("a")); 296 s1[2] = 'c'; 297 ASSERT_STREQ("c", getenv("a")); 298 299 char* s2 = strdup("a=b"); 300 ASSERT_EQ(0, putenv(s2)); 301 302 ASSERT_STREQ("b", getenv("a")); 303 ASSERT_EQ('c', s1[2]); 304 305 ASSERT_EQ(0, unsetenv("a")); 306 free(s1); 307 free(s2); 308} 309 310TEST(unistd, clearenv) { 311 extern char** environ; 312 313 // Guarantee that environ is not initially empty... 314 ASSERT_EQ(0, setenv("test-variable", "a", 1)); 315 316 // Stash a copy. 317 std::vector<char*> old_environ; 318 for (size_t i = 0; environ[i] != NULL; ++i) { 319 old_environ.push_back(strdup(environ[i])); 320 } 321 322 ASSERT_EQ(0, clearenv()); 323 324 EXPECT_TRUE(environ == NULL || environ[0] == NULL); 325 EXPECT_EQ(NULL, getenv("test-variable")); 326 EXPECT_EQ(0, setenv("test-variable", "post-clear", 1)); 327 EXPECT_STREQ("post-clear", getenv("test-variable")); 328 329 // Put the old environment back. 330 for (size_t i = 0; i < old_environ.size(); ++i) { 331 EXPECT_EQ(0, putenv(old_environ[i])); 332 } 333 334 // Check it wasn't overwritten. 335 EXPECT_STREQ("a", getenv("test-variable")); 336 337 EXPECT_EQ(0, unsetenv("test-variable")); 338} 339 340static void TestFsyncFunction(int (*fn)(int)) { 341 int fd; 342 343 // Can't sync an invalid fd. 344 errno = 0; 345 EXPECT_EQ(-1, fn(-1)); 346 EXPECT_EQ(EBADF, errno); 347 348 // It doesn't matter whether you've opened a file for write or not. 349 TemporaryFile tf; 350 ASSERT_NE(-1, tf.fd); 351 352 EXPECT_EQ(0, fn(tf.fd)); 353 354 ASSERT_NE(-1, fd = open(tf.filename, O_RDONLY)); 355 EXPECT_EQ(0, fn(fd)); 356 close(fd); 357 358 ASSERT_NE(-1, fd = open(tf.filename, O_RDWR)); 359 EXPECT_EQ(0, fn(fd)); 360 close(fd); 361 362 // The fd can even be a directory. 363 ASSERT_NE(-1, fd = open("/", O_RDONLY)); 364 EXPECT_EQ(0, fn(fd)); 365 close(fd); 366 367 // But some file systems may choose to be fussy... 368 errno = 0; 369 ASSERT_NE(-1, fd = open("/proc/version", O_RDONLY)); 370 EXPECT_EQ(-1, fn(fd)); 371 EXPECT_EQ(EINVAL, errno); 372 close(fd); 373} 374 375TEST(unistd, fdatasync) { 376 TestFsyncFunction(fdatasync); 377} 378 379TEST(unistd, fsync) { 380 TestFsyncFunction(fsync); 381} 382