blob: 421cd8263d25025141c63a0cbfe1e7cae920da2b [file] [log] [blame]
Elliott Hughes774c7f52012-10-01 13:11:03 -07001/*
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>
Yabin Cui9df70402014-11-05 18:01:01 -080018#include "BionicDeathTest.h"
Calin Juravlefe317a32014-02-21 15:11:03 +000019#include "TemporaryFile.h"
Elliott Hughes774c7f52012-10-01 13:11:03 -070020
Elliott Hughesb16b7222013-02-04 13:18:00 -080021#include <errno.h>
Elliott Hughesf0777842013-03-01 16:59:46 -080022#include <libgen.h>
23#include <limits.h>
Elliott Hughes877ec6d2013-11-15 17:40:18 -080024#include <pthread.h>
Elliott Hughesb16b7222013-02-04 13:18:00 -080025#include <stdint.h>
Elliott Hughes774c7f52012-10-01 13:11:03 -070026#include <stdlib.h>
Calin Juravlefe317a32014-02-21 15:11:03 +000027#include <fcntl.h>
Elliott Hughes40488562014-03-12 13:50:38 -070028#include <sys/types.h>
29#include <sys/wait.h>
Elliott Hughes774c7f52012-10-01 13:11:03 -070030
31TEST(stdlib, drand48) {
32 srand48(0x01020304);
33 EXPECT_DOUBLE_EQ(0.65619299195623526, drand48());
34 EXPECT_DOUBLE_EQ(0.18522597229772941, drand48());
35 EXPECT_DOUBLE_EQ(0.42015087072844537, drand48());
36 EXPECT_DOUBLE_EQ(0.061637783047395089, drand48());
37}
38
Elliott Hughesa0beeea2014-06-12 11:48:04 -070039TEST(stdlib, lrand48) {
Elliott Hughes774c7f52012-10-01 13:11:03 -070040 srand48(0x01020304);
41 EXPECT_EQ(1409163720, lrand48());
42 EXPECT_EQ(397769746, lrand48());
43 EXPECT_EQ(902267124, lrand48());
44 EXPECT_EQ(132366131, lrand48());
Elliott Hughesa0beeea2014-06-12 11:48:04 -070045}
Elliott Hughes774c7f52012-10-01 13:11:03 -070046
Elliott Hughesa0beeea2014-06-12 11:48:04 -070047TEST(stdlib, random) {
Elliott Hughes774c7f52012-10-01 13:11:03 -070048 srandom(0x01020304);
Elliott Hughesa0beeea2014-06-12 11:48:04 -070049 EXPECT_EQ(55436735, random());
50 EXPECT_EQ(1399865117, random());
51 EXPECT_EQ(2032643283, random());
52 EXPECT_EQ(571329216, random());
53}
Elliott Hughes774c7f52012-10-01 13:11:03 -070054
Elliott Hughesa0beeea2014-06-12 11:48:04 -070055TEST(stdlib, rand) {
Elliott Hughes774c7f52012-10-01 13:11:03 -070056 srand(0x01020304);
Elliott Hughesa0beeea2014-06-12 11:48:04 -070057 EXPECT_EQ(55436735, rand());
58 EXPECT_EQ(1399865117, rand());
59 EXPECT_EQ(2032643283, rand());
60 EXPECT_EQ(571329216, rand());
Elliott Hughes774c7f52012-10-01 13:11:03 -070061}
62
63TEST(stdlib, mrand48) {
64 srand48(0x01020304);
65 EXPECT_EQ(-1476639856, mrand48());
66 EXPECT_EQ(795539493, mrand48());
67 EXPECT_EQ(1804534249, mrand48());
68 EXPECT_EQ(264732262, mrand48());
69}
Elliott Hughesb16b7222013-02-04 13:18:00 -080070
71TEST(stdlib, posix_memalign) {
72 void* p;
73
74 ASSERT_EQ(0, posix_memalign(&p, 512, 128));
75 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(p) % 512);
76 free(p);
77
78 // Can't align to a non-power of 2.
79 ASSERT_EQ(EINVAL, posix_memalign(&p, 81, 128));
80}
Elliott Hughesf0777842013-03-01 16:59:46 -080081
82TEST(stdlib, realpath__NULL_filename) {
83 errno = 0;
84 char* p = realpath(NULL, NULL);
85 ASSERT_TRUE(p == NULL);
86 ASSERT_EQ(EINVAL, errno);
87}
88
89TEST(stdlib, realpath__empty_filename) {
90 errno = 0;
91 char* p = realpath("", NULL);
92 ASSERT_TRUE(p == NULL);
93 ASSERT_EQ(ENOENT, errno);
94}
95
96TEST(stdlib, realpath__ENOENT) {
97 errno = 0;
98 char* p = realpath("/this/directory/path/almost/certainly/does/not/exist", NULL);
99 ASSERT_TRUE(p == NULL);
100 ASSERT_EQ(ENOENT, errno);
101}
102
Elliott Hughes31e072f2014-09-30 16:15:42 -0700103TEST(stdlib, realpath__component_after_non_directory) {
104 errno = 0;
105 char* p = realpath("/dev/null/.", NULL);
106 ASSERT_TRUE(p == NULL);
107 ASSERT_EQ(ENOTDIR, errno);
108
109 errno = 0;
110 p = realpath("/dev/null/..", NULL);
111 ASSERT_TRUE(p == NULL);
112 ASSERT_EQ(ENOTDIR, errno);
113}
114
Elliott Hughesf0777842013-03-01 16:59:46 -0800115TEST(stdlib, realpath) {
116 // Get the name of this executable.
117 char executable_path[PATH_MAX];
118 int rc = readlink("/proc/self/exe", executable_path, sizeof(executable_path));
119 ASSERT_NE(rc, -1);
120 executable_path[rc] = '\0';
121
122 char buf[PATH_MAX + 1];
123 char* p = realpath("/proc/self/exe", buf);
124 ASSERT_STREQ(executable_path, p);
125
126 p = realpath("/proc/self/exe", NULL);
127 ASSERT_STREQ(executable_path, p);
128 free(p);
129}
Elliott Hughes0b25f632013-04-11 18:08:34 -0700130
131TEST(stdlib, qsort) {
132 struct s {
133 char name[16];
134 static int comparator(const void* lhs, const void* rhs) {
135 return strcmp(reinterpret_cast<const s*>(lhs)->name, reinterpret_cast<const s*>(rhs)->name);
136 }
137 };
138 s entries[3];
139 strcpy(entries[0].name, "charlie");
140 strcpy(entries[1].name, "bravo");
141 strcpy(entries[2].name, "alpha");
142
143 qsort(entries, 3, sizeof(s), s::comparator);
144 ASSERT_STREQ("alpha", entries[0].name);
145 ASSERT_STREQ("bravo", entries[1].name);
146 ASSERT_STREQ("charlie", entries[2].name);
147
148 qsort(entries, 3, sizeof(s), s::comparator);
149 ASSERT_STREQ("alpha", entries[0].name);
150 ASSERT_STREQ("bravo", entries[1].name);
151 ASSERT_STREQ("charlie", entries[2].name);
152}
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800153
154static void* TestBug57421_child(void* arg) {
155 pthread_t main_thread = reinterpret_cast<pthread_t>(arg);
156 pthread_join(main_thread, NULL);
157 char* value = getenv("ENVIRONMENT_VARIABLE");
158 if (value == NULL) {
159 setenv("ENVIRONMENT_VARIABLE", "value", 1);
160 }
161 return NULL;
162}
163
164static void TestBug57421_main() {
165 pthread_t t;
166 ASSERT_EQ(0, pthread_create(&t, NULL, TestBug57421_child, reinterpret_cast<void*>(pthread_self())));
167 pthread_exit(NULL);
168}
169
170// Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to
171// run this test (which exits normally) in its own process.
Yabin Cui9df70402014-11-05 18:01:01 -0800172
173class stdlib_DeathTest : public BionicDeathTest {};
174
175TEST_F(stdlib_DeathTest, getenv_after_main_thread_exits) {
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800176 // https://code.google.com/p/android/issues/detail?id=57421
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800177 ASSERT_EXIT(TestBug57421_main(), ::testing::ExitedWithCode(0), "");
178}
Calin Juravlefe317a32014-02-21 15:11:03 +0000179
Elliott Hughes31165ed2014-09-23 17:34:29 -0700180TEST(stdlib, mkostemp64) {
181 TemporaryFile tf([](char* path) { return mkostemp64(path, O_CLOEXEC); });
182 int flags = fcntl(tf.fd, F_GETFD);
183 ASSERT_TRUE(flags != -1);
184 ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC);
185}
186
187TEST(stdlib, mkostemp) {
188 TemporaryFile tf([](char* path) { return mkostemp(path, O_CLOEXEC); });
189 int flags = fcntl(tf.fd, F_GETFD);
190 ASSERT_TRUE(flags != -1);
191 ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC);
192}
193
194TEST(stdlib, mkstemp64) {
195 TemporaryFile tf(mkstemp64);
196 struct stat64 sb;
197 ASSERT_EQ(0, fstat64(tf.fd, &sb));
198 ASSERT_EQ(O_LARGEFILE, fcntl(tf.fd, F_GETFL) & O_LARGEFILE);
199}
200
Calin Juravlefe317a32014-02-21 15:11:03 +0000201TEST(stdlib, mkstemp) {
202 TemporaryFile tf;
203 struct stat sb;
204 ASSERT_EQ(0, fstat(tf.fd, &sb));
205}
206
Elliott Hughes3cdf5732014-03-11 12:54:44 -0700207TEST(stdlib, system) {
208 int status;
209
210 status = system("exit 0");
211 ASSERT_TRUE(WIFEXITED(status));
212 ASSERT_EQ(0, WEXITSTATUS(status));
213
214 status = system("exit 1");
215 ASSERT_TRUE(WIFEXITED(status));
216 ASSERT_EQ(1, WEXITSTATUS(status));
217}
Elliott Hughes5a817382014-03-12 16:12:57 -0700218
219TEST(stdlib, atof) {
Christopher Ferrisf171b342014-03-17 16:40:26 -0700220 ASSERT_DOUBLE_EQ(1.23, atof("1.23"));
Elliott Hughes5a817382014-03-12 16:12:57 -0700221}
222
223TEST(stdlib, strtod) {
Christopher Ferrisf171b342014-03-17 16:40:26 -0700224 ASSERT_DOUBLE_EQ(1.23, strtod("1.23", NULL));
Elliott Hughes5a817382014-03-12 16:12:57 -0700225}
226
227TEST(stdlib, strtof) {
Christopher Ferrisf171b342014-03-17 16:40:26 -0700228 ASSERT_FLOAT_EQ(1.23, strtof("1.23", NULL));
Elliott Hughes5a817382014-03-12 16:12:57 -0700229}
230
231TEST(stdlib, strtold) {
Christopher Ferrisf171b342014-03-17 16:40:26 -0700232 ASSERT_DOUBLE_EQ(1.23, strtold("1.23", NULL));
Elliott Hughes5a817382014-03-12 16:12:57 -0700233}
Elliott Hughes9f525642014-04-08 17:14:01 -0700234
Elliott Hughes89aaaff2014-10-28 17:54:23 -0700235TEST(stdlib, strtof_2206701) {
236 ASSERT_EQ(0.0f, strtof("7.0064923216240853546186479164495e-46", NULL));
237 ASSERT_EQ(1.4e-45f, strtof("7.0064923216240853546186479164496e-46", NULL));
238}
239
240TEST(stdlib, strtod_largest_subnormal) {
241 // This value has been known to cause javac and java to infinite loop.
242 // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
243 ASSERT_EQ(2.2250738585072014e-308, strtod("2.2250738585072012e-308", NULL));
244 ASSERT_EQ(2.2250738585072014e-308, strtod("0.00022250738585072012e-304", NULL));
245 ASSERT_EQ(2.2250738585072014e-308, strtod("00000002.2250738585072012e-308", NULL));
246 ASSERT_EQ(2.2250738585072014e-308, strtod("2.225073858507201200000e-308", NULL));
247 ASSERT_EQ(2.2250738585072014e-308, strtod("2.2250738585072012e-00308", NULL));
248 ASSERT_EQ(2.2250738585072014e-308, strtod("2.22507385850720129978001e-308", NULL));
249 ASSERT_EQ(-2.2250738585072014e-308, strtod("-2.2250738585072012e-308", NULL));
250}
251
Dan Albertb8425c52014-04-29 17:49:06 -0700252TEST(stdlib, quick_exit) {
253 pid_t pid = fork();
254 ASSERT_NE(-1, pid) << strerror(errno);
255
256 if (pid == 0) {
257 quick_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
266static int quick_exit_status = 0;
267
268static void quick_exit_1(void) {
269 ASSERT_EQ(quick_exit_status, 0);
270 quick_exit_status = 1;
271}
272
273static void quick_exit_2(void) {
274 ASSERT_EQ(quick_exit_status, 1);
275}
276
277static void not_run(void) {
278 FAIL();
279}
280
281TEST(stdlib, at_quick_exit) {
282 pid_t pid = fork();
283 ASSERT_NE(-1, pid) << strerror(errno);
284
285 if (pid == 0) {
286 ASSERT_EQ(at_quick_exit(quick_exit_2), 0);
287 ASSERT_EQ(at_quick_exit(quick_exit_1), 0);
288 atexit(not_run);
289 quick_exit(99);
290 }
291
292 int status;
293 ASSERT_EQ(pid, waitpid(pid, &status, 0));
294 ASSERT_TRUE(WIFEXITED(status));
295 ASSERT_EQ(99, WEXITSTATUS(status));
296}
297
Elliott Hughes9f525642014-04-08 17:14:01 -0700298TEST(unistd, _Exit) {
299 int pid = fork();
300 ASSERT_NE(-1, pid) << strerror(errno);
301
302 if (pid == 0) {
303 _Exit(99);
304 }
305
306 int status;
307 ASSERT_EQ(pid, waitpid(pid, &status, 0));
308 ASSERT_TRUE(WIFEXITED(status));
309 ASSERT_EQ(99, WEXITSTATUS(status));
310}
Elliott Hughes49167062014-07-25 17:24:00 -0700311
312TEST(stdlib, pty_smoke) {
313 // getpt returns a pty with O_RDWR|O_NOCTTY.
314 int fd = getpt();
315 ASSERT_NE(-1, fd);
316
317 // grantpt is a no-op.
318 ASSERT_EQ(0, grantpt(fd));
319
320 // ptsname_r should start "/dev/pts/".
321 char name_r[128];
322 ASSERT_EQ(0, ptsname_r(fd, name_r, sizeof(name_r)));
323 name_r[9] = 0;
324 ASSERT_STREQ("/dev/pts/", name_r);
325
326 close(fd);
327}
328
329TEST(stdlib, posix_openpt) {
330 int fd = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC);
331 ASSERT_NE(-1, fd);
332 close(fd);
333}
334
335TEST(stdlib, ptsname_r_ENOTTY) {
336 errno = 0;
337 char buf[128];
338 ASSERT_EQ(ENOTTY, ptsname_r(STDOUT_FILENO, buf, sizeof(buf)));
339 ASSERT_EQ(ENOTTY, errno);
340}
341
342TEST(stdlib, ptsname_r_EINVAL) {
343 int fd = getpt();
344 ASSERT_NE(-1, fd);
345 errno = 0;
346 char* buf = NULL;
347 ASSERT_EQ(EINVAL, ptsname_r(fd, buf, 128));
348 ASSERT_EQ(EINVAL, errno);
349 close(fd);
350}
351
352TEST(stdlib, ptsname_r_ERANGE) {
353 int fd = getpt();
354 ASSERT_NE(-1, fd);
355 errno = 0;
356 char buf[1];
357 ASSERT_EQ(ERANGE, ptsname_r(fd, buf, sizeof(buf)));
358 ASSERT_EQ(ERANGE, errno);
359 close(fd);
360}
361
362TEST(stdlib, ttyname_r) {
363 int fd = getpt();
364 ASSERT_NE(-1, fd);
365
366 // ttyname_r returns "/dev/ptmx" for a pty.
367 char name_r[128];
368 ASSERT_EQ(0, ttyname_r(fd, name_r, sizeof(name_r)));
369 ASSERT_STREQ("/dev/ptmx", name_r);
370
371 close(fd);
372}
373
374TEST(stdlib, ttyname_r_ENOTTY) {
375 int fd = open("/dev/null", O_WRONLY);
376 errno = 0;
377 char buf[128];
378 ASSERT_EQ(ENOTTY, ttyname_r(fd, buf, sizeof(buf)));
379 ASSERT_EQ(ENOTTY, errno);
380 close(fd);
381}
382
383TEST(stdlib, ttyname_r_EINVAL) {
384 int fd = getpt();
385 ASSERT_NE(-1, fd);
386 errno = 0;
387 char* buf = NULL;
388 ASSERT_EQ(EINVAL, ttyname_r(fd, buf, 128));
389 ASSERT_EQ(EINVAL, errno);
390 close(fd);
391}
392
393TEST(stdlib, ttyname_r_ERANGE) {
394 int fd = getpt();
395 ASSERT_NE(-1, fd);
396 errno = 0;
397 char buf[1];
398 ASSERT_EQ(ERANGE, ttyname_r(fd, buf, sizeof(buf)));
399 ASSERT_EQ(ERANGE, errno);
400 close(fd);
401}
402
403TEST(stdlib, unlockpt_ENOTTY) {
404 int fd = open("/dev/null", O_WRONLY);
405 errno = 0;
406 ASSERT_EQ(-1, unlockpt(fd));
407 ASSERT_EQ(ENOTTY, errno);
408 close(fd);
409}
Elliott Hughesb05ec5a2014-09-23 14:53:10 -0700410
411TEST(stdlib, strtol_EINVAL) {
412 errno = 0;
413 strtol("123", NULL, -1);
414 ASSERT_EQ(EINVAL, errno);
415 errno = 0;
416 strtol("123", NULL, 1);
417 ASSERT_EQ(EINVAL, errno);
418 errno = 0;
419 strtol("123", NULL, 37);
420 ASSERT_EQ(EINVAL, errno);
421}
422
423TEST(stdlib, strtoll_EINVAL) {
424 errno = 0;
425 strtoll("123", NULL, -1);
426 ASSERT_EQ(EINVAL, errno);
427 errno = 0;
428 strtoll("123", NULL, 1);
429 ASSERT_EQ(EINVAL, errno);
430 errno = 0;
431 strtoll("123", NULL, 37);
432 ASSERT_EQ(EINVAL, errno);
433}
434
435TEST(stdlib, strtoul_EINVAL) {
436 errno = 0;
437 strtoul("123", NULL, -1);
438 ASSERT_EQ(EINVAL, errno);
439 errno = 0;
440 strtoul("123", NULL, 1);
441 ASSERT_EQ(EINVAL, errno);
442 errno = 0;
443 strtoul("123", NULL, 37);
444 ASSERT_EQ(EINVAL, errno);
445}
446
447TEST(stdlib, strtoull_EINVAL) {
448 errno = 0;
449 strtoull("123", NULL, -1);
450 ASSERT_EQ(EINVAL, errno);
451 errno = 0;
452 strtoull("123", NULL, 1);
453 ASSERT_EQ(EINVAL, errno);
454 errno = 0;
455 strtoull("123", NULL, 37);
456 ASSERT_EQ(EINVAL, errno);
457}