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 "TemporaryFile.h" 19 20 #include <errno.h> 21 #include <libgen.h> 22 #include <limits.h> 23 #include <pthread.h> 24 #include <stdint.h> 25 #include <stdlib.h> 26 #include <fcntl.h> 27 #include <sys/types.h> 28 #include <sys/wait.h> 29 30 TEST(stdlib, drand48) { 31 srand48(0x01020304); 32 EXPECT_DOUBLE_EQ(0.65619299195623526, drand48()); 33 EXPECT_DOUBLE_EQ(0.18522597229772941, drand48()); 34 EXPECT_DOUBLE_EQ(0.42015087072844537, drand48()); 35 EXPECT_DOUBLE_EQ(0.061637783047395089, drand48()); 36 } 37 38 TEST(stdlib, lrand48) { 39 srand48(0x01020304); 40 EXPECT_EQ(1409163720, lrand48()); 41 EXPECT_EQ(397769746, lrand48()); 42 EXPECT_EQ(902267124, lrand48()); 43 EXPECT_EQ(132366131, lrand48()); 44 } 45 46 TEST(stdlib, random) { 47 srandom(0x01020304); 48 EXPECT_EQ(55436735, random()); 49 EXPECT_EQ(1399865117, random()); 50 EXPECT_EQ(2032643283, random()); 51 EXPECT_EQ(571329216, random()); 52 } 53 54 TEST(stdlib, rand) { 55 srand(0x01020304); 56 EXPECT_EQ(55436735, rand()); 57 EXPECT_EQ(1399865117, rand()); 58 EXPECT_EQ(2032643283, rand()); 59 EXPECT_EQ(571329216, rand()); 60 } 61 62 TEST(stdlib, mrand48) { 63 srand48(0x01020304); 64 EXPECT_EQ(-1476639856, mrand48()); 65 EXPECT_EQ(795539493, mrand48()); 66 EXPECT_EQ(1804534249, mrand48()); 67 EXPECT_EQ(264732262, mrand48()); 68 } 69 70 TEST(stdlib, posix_memalign) { 71 void* p; 72 73 ASSERT_EQ(0, posix_memalign(&p, 512, 128)); 74 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(p) % 512); 75 free(p); 76 77 // Can't align to a non-power of 2. 78 ASSERT_EQ(EINVAL, posix_memalign(&p, 81, 128)); 79 } 80 81 TEST(stdlib, realpath__NULL_filename) { 82 errno = 0; 83 char* p = realpath(NULL, NULL); 84 ASSERT_TRUE(p == NULL); 85 ASSERT_EQ(EINVAL, errno); 86 } 87 88 TEST(stdlib, realpath__empty_filename) { 89 errno = 0; 90 char* p = realpath("", NULL); 91 ASSERT_TRUE(p == NULL); 92 ASSERT_EQ(ENOENT, errno); 93 } 94 95 TEST(stdlib, realpath__ENOENT) { 96 errno = 0; 97 char* p = realpath("/this/directory/path/almost/certainly/does/not/exist", NULL); 98 ASSERT_TRUE(p == NULL); 99 ASSERT_EQ(ENOENT, errno); 100 } 101 102 TEST(stdlib, realpath) { 103 // Get the name of this executable. 104 char executable_path[PATH_MAX]; 105 int rc = readlink("/proc/self/exe", executable_path, sizeof(executable_path)); 106 ASSERT_NE(rc, -1); 107 executable_path[rc] = '\0'; 108 109 char buf[PATH_MAX + 1]; 110 char* p = realpath("/proc/self/exe", buf); 111 ASSERT_STREQ(executable_path, p); 112 113 p = realpath("/proc/self/exe", NULL); 114 ASSERT_STREQ(executable_path, p); 115 free(p); 116 } 117 118 TEST(stdlib, qsort) { 119 struct s { 120 char name[16]; 121 static int comparator(const void* lhs, const void* rhs) { 122 return strcmp(reinterpret_cast<const s*>(lhs)->name, reinterpret_cast<const s*>(rhs)->name); 123 } 124 }; 125 s entries[3]; 126 strcpy(entries[0].name, "charlie"); 127 strcpy(entries[1].name, "bravo"); 128 strcpy(entries[2].name, "alpha"); 129 130 qsort(entries, 3, sizeof(s), s::comparator); 131 ASSERT_STREQ("alpha", entries[0].name); 132 ASSERT_STREQ("bravo", entries[1].name); 133 ASSERT_STREQ("charlie", entries[2].name); 134 135 qsort(entries, 3, sizeof(s), s::comparator); 136 ASSERT_STREQ("alpha", entries[0].name); 137 ASSERT_STREQ("bravo", entries[1].name); 138 ASSERT_STREQ("charlie", entries[2].name); 139 } 140 141 static void* TestBug57421_child(void* arg) { 142 pthread_t main_thread = reinterpret_cast<pthread_t>(arg); 143 pthread_join(main_thread, NULL); 144 char* value = getenv("ENVIRONMENT_VARIABLE"); 145 if (value == NULL) { 146 setenv("ENVIRONMENT_VARIABLE", "value", 1); 147 } 148 return NULL; 149 } 150 151 static void TestBug57421_main() { 152 pthread_t t; 153 ASSERT_EQ(0, pthread_create(&t, NULL, TestBug57421_child, reinterpret_cast<void*>(pthread_self()))); 154 pthread_exit(NULL); 155 } 156 157 // Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to 158 // run this test (which exits normally) in its own process. 159 TEST(stdlib_DeathTest, getenv_after_main_thread_exits) { 160 // https://code.google.com/p/android/issues/detail?id=57421 161 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; 162 ASSERT_EXIT(TestBug57421_main(), ::testing::ExitedWithCode(0), ""); 163 } 164 165 TEST(stdlib, mkstemp) { 166 TemporaryFile tf; 167 struct stat sb; 168 ASSERT_EQ(0, fstat(tf.fd, &sb)); 169 } 170 171 TEST(stdlib, mkstemp64) { 172 GenericTemporaryFile<mkstemp64> tf; 173 struct stat64 sb; 174 ASSERT_EQ(0, fstat64(tf.fd, &sb)); 175 ASSERT_EQ(O_LARGEFILE, fcntl(tf.fd, F_GETFL) & O_LARGEFILE); 176 } 177 178 TEST(stdlib, system) { 179 int status; 180 181 status = system("exit 0"); 182 ASSERT_TRUE(WIFEXITED(status)); 183 ASSERT_EQ(0, WEXITSTATUS(status)); 184 185 status = system("exit 1"); 186 ASSERT_TRUE(WIFEXITED(status)); 187 ASSERT_EQ(1, WEXITSTATUS(status)); 188 } 189 190 TEST(stdlib, atof) { 191 ASSERT_DOUBLE_EQ(1.23, atof("1.23")); 192 } 193 194 TEST(stdlib, strtod) { 195 ASSERT_DOUBLE_EQ(1.23, strtod("1.23", NULL)); 196 } 197 198 TEST(stdlib, strtof) { 199 ASSERT_FLOAT_EQ(1.23, strtof("1.23", NULL)); 200 } 201 202 TEST(stdlib, strtold) { 203 ASSERT_DOUBLE_EQ(1.23, strtold("1.23", NULL)); 204 } 205 206 TEST(stdlib, quick_exit) { 207 pid_t pid = fork(); 208 ASSERT_NE(-1, pid) << strerror(errno); 209 210 if (pid == 0) { 211 quick_exit(99); 212 } 213 214 int status; 215 ASSERT_EQ(pid, waitpid(pid, &status, 0)); 216 ASSERT_TRUE(WIFEXITED(status)); 217 ASSERT_EQ(99, WEXITSTATUS(status)); 218 } 219 220 static int quick_exit_status = 0; 221 222 static void quick_exit_1(void) { 223 ASSERT_EQ(quick_exit_status, 0); 224 quick_exit_status = 1; 225 } 226 227 static void quick_exit_2(void) { 228 ASSERT_EQ(quick_exit_status, 1); 229 } 230 231 static void not_run(void) { 232 FAIL(); 233 } 234 235 TEST(stdlib, at_quick_exit) { 236 pid_t pid = fork(); 237 ASSERT_NE(-1, pid) << strerror(errno); 238 239 if (pid == 0) { 240 ASSERT_EQ(at_quick_exit(quick_exit_2), 0); 241 ASSERT_EQ(at_quick_exit(quick_exit_1), 0); 242 atexit(not_run); 243 quick_exit(99); 244 } 245 246 int status; 247 ASSERT_EQ(pid, waitpid(pid, &status, 0)); 248 ASSERT_TRUE(WIFEXITED(status)); 249 ASSERT_EQ(99, WEXITSTATUS(status)); 250 } 251 252 TEST(unistd, _Exit) { 253 int pid = fork(); 254 ASSERT_NE(-1, pid) << strerror(errno); 255 256 if (pid == 0) { 257 _Exit(99); 258 } 259 260 int status; 261 ASSERT_EQ(pid, waitpid(pid, &status, 0)); 262 ASSERT_TRUE(WIFEXITED(status)); 263 ASSERT_EQ(99, WEXITSTATUS(status)); 264 } 265 266 TEST(stdlib, pty_smoke) { 267 // getpt returns a pty with O_RDWR|O_NOCTTY. 268 int fd = getpt(); 269 ASSERT_NE(-1, fd); 270 271 // grantpt is a no-op. 272 ASSERT_EQ(0, grantpt(fd)); 273 274 // ptsname_r should start "/dev/pts/". 275 char name_r[128]; 276 ASSERT_EQ(0, ptsname_r(fd, name_r, sizeof(name_r))); 277 name_r[9] = 0; 278 ASSERT_STREQ("/dev/pts/", name_r); 279 280 close(fd); 281 } 282 283 TEST(stdlib, posix_openpt) { 284 int fd = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC); 285 ASSERT_NE(-1, fd); 286 close(fd); 287 } 288 289 TEST(stdlib, ptsname_r_ENOTTY) { 290 errno = 0; 291 char buf[128]; 292 ASSERT_EQ(ENOTTY, ptsname_r(STDOUT_FILENO, buf, sizeof(buf))); 293 ASSERT_EQ(ENOTTY, errno); 294 } 295 296 TEST(stdlib, ptsname_r_EINVAL) { 297 int fd = getpt(); 298 ASSERT_NE(-1, fd); 299 errno = 0; 300 char* buf = NULL; 301 ASSERT_EQ(EINVAL, ptsname_r(fd, buf, 128)); 302 ASSERT_EQ(EINVAL, errno); 303 close(fd); 304 } 305 306 TEST(stdlib, ptsname_r_ERANGE) { 307 int fd = getpt(); 308 ASSERT_NE(-1, fd); 309 errno = 0; 310 char buf[1]; 311 ASSERT_EQ(ERANGE, ptsname_r(fd, buf, sizeof(buf))); 312 ASSERT_EQ(ERANGE, errno); 313 close(fd); 314 } 315 316 TEST(stdlib, ttyname_r) { 317 int fd = getpt(); 318 ASSERT_NE(-1, fd); 319 320 // ttyname_r returns "/dev/ptmx" for a pty. 321 char name_r[128]; 322 ASSERT_EQ(0, ttyname_r(fd, name_r, sizeof(name_r))); 323 ASSERT_STREQ("/dev/ptmx", name_r); 324 325 close(fd); 326 } 327 328 TEST(stdlib, ttyname_r_ENOTTY) { 329 int fd = open("/dev/null", O_WRONLY); 330 errno = 0; 331 char buf[128]; 332 ASSERT_EQ(ENOTTY, ttyname_r(fd, buf, sizeof(buf))); 333 ASSERT_EQ(ENOTTY, errno); 334 close(fd); 335 } 336 337 TEST(stdlib, ttyname_r_EINVAL) { 338 int fd = getpt(); 339 ASSERT_NE(-1, fd); 340 errno = 0; 341 char* buf = NULL; 342 ASSERT_EQ(EINVAL, ttyname_r(fd, buf, 128)); 343 ASSERT_EQ(EINVAL, errno); 344 close(fd); 345 } 346 347 TEST(stdlib, ttyname_r_ERANGE) { 348 int fd = getpt(); 349 ASSERT_NE(-1, fd); 350 errno = 0; 351 char buf[1]; 352 ASSERT_EQ(ERANGE, ttyname_r(fd, buf, sizeof(buf))); 353 ASSERT_EQ(ERANGE, errno); 354 close(fd); 355 } 356 357 TEST(stdlib, unlockpt_ENOTTY) { 358 int fd = open("/dev/null", O_WRONLY); 359 errno = 0; 360 ASSERT_EQ(-1, unlockpt(fd)); 361 ASSERT_EQ(ENOTTY, errno); 362 close(fd); 363 } 364