blob: ff4cb71eed20903bf8cc92f41b8deae914999323 [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
Elliott Hughesb16b7222013-02-04 13:18:00 -080017#include <errno.h>
Elliott Hughes7f0849f2016-08-26 16:17:17 -070018#include <fcntl.h>
Elliott Hughesf0777842013-03-01 16:59:46 -080019#include <libgen.h>
20#include <limits.h>
Elliott Hughes7f0849f2016-08-26 16:17:17 -070021#include <math.h>
Elliott Hughes877ec6d2013-11-15 17:40:18 -080022#include <pthread.h>
Elliott Hughesb16b7222013-02-04 13:18:00 -080023#include <stdint.h>
Elliott Hughes774c7f52012-10-01 13:11:03 -070024#include <stdlib.h>
Elliott Hughes40488562014-03-12 13:50:38 -070025#include <sys/types.h>
26#include <sys/wait.h>
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -080027#include <unistd.h>
Elliott Hughes774c7f52012-10-01 13:11:03 -070028
Elliott Hughes1921dce2017-12-19 10:27:27 -080029#include <limits>
Elliott Hughesf61a06e2017-12-19 16:11:37 -080030#include <string>
Elliott Hughes1921dce2017-12-19 10:27:27 -080031
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -080032#include <android-base/macros.h>
33#include <gtest/gtest.h>
34
35#include "BionicDeathTest.h"
36#include "math_data_test.h"
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -080037#include "utils.h"
38
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -080039template <typename T = int (*)(char*)>
40class GenericTemporaryFile {
41 public:
42 explicit GenericTemporaryFile(T mk_fn = mkstemp) : mk_fn_(mk_fn) {
43 // Since we might be running on the host or the target, and if we're
44 // running on the host we might be running under bionic or glibc,
45 // let's just try both possible temporary directories and take the
46 // first one that works.
47 init("/data/local/tmp");
48 if (fd == -1) {
49 init("/tmp");
50 }
51 }
52
53 ~GenericTemporaryFile() {
54 close(fd);
55 unlink(path);
56 }
57
58 int fd;
59 char path[1024];
60
61 private:
62 T mk_fn_;
63
64 void init(const char* tmp_dir) {
65 snprintf(path, sizeof(path), "%s/TemporaryFile-XXXXXX", tmp_dir);
66 fd = mk_fn_(path);
67 }
68
69 DISALLOW_COPY_AND_ASSIGN(GenericTemporaryFile);
70};
71
72typedef GenericTemporaryFile<> MyTemporaryFile;
73
Elliott Hughes274afe82014-11-06 12:40:08 -080074// The random number generator tests all set the seed, get four values, reset the seed and check
75// that they get the first two values repeated, and then reset the seed and check two more values
76// to rule out the possibility that we're just going round a cycle of four values.
77// TODO: factor this out.
78
Elliott Hughes774c7f52012-10-01 13:11:03 -070079TEST(stdlib, drand48) {
80 srand48(0x01020304);
81 EXPECT_DOUBLE_EQ(0.65619299195623526, drand48());
82 EXPECT_DOUBLE_EQ(0.18522597229772941, drand48());
83 EXPECT_DOUBLE_EQ(0.42015087072844537, drand48());
84 EXPECT_DOUBLE_EQ(0.061637783047395089, drand48());
Elliott Hughes274afe82014-11-06 12:40:08 -080085 srand48(0x01020304);
86 EXPECT_DOUBLE_EQ(0.65619299195623526, drand48());
87 EXPECT_DOUBLE_EQ(0.18522597229772941, drand48());
88 srand48(0x01020304);
89 EXPECT_DOUBLE_EQ(0.65619299195623526, drand48());
90 EXPECT_DOUBLE_EQ(0.18522597229772941, drand48());
91}
92
93TEST(stdlib, erand48) {
94 const unsigned short seed[3] = { 0x330e, 0xabcd, 0x1234 };
95 unsigned short xsubi[3];
96 memcpy(xsubi, seed, sizeof(seed));
97 EXPECT_DOUBLE_EQ(0.39646477376027534, erand48(xsubi));
98 EXPECT_DOUBLE_EQ(0.84048536941142515, erand48(xsubi));
99 EXPECT_DOUBLE_EQ(0.35333609724524351, erand48(xsubi));
100 EXPECT_DOUBLE_EQ(0.44658343479654405, erand48(xsubi));
101 memcpy(xsubi, seed, sizeof(seed));
102 EXPECT_DOUBLE_EQ(0.39646477376027534, erand48(xsubi));
103 EXPECT_DOUBLE_EQ(0.84048536941142515, erand48(xsubi));
104 memcpy(xsubi, seed, sizeof(seed));
105 EXPECT_DOUBLE_EQ(0.39646477376027534, erand48(xsubi));
106 EXPECT_DOUBLE_EQ(0.84048536941142515, erand48(xsubi));
107}
108
109TEST(stdlib, lcong48) {
110 unsigned short p[7] = { 0x0102, 0x0304, 0x0506, 0x0708, 0x090a, 0x0b0c, 0x0d0e };
111 lcong48(p);
112 EXPECT_EQ(1531389981, lrand48());
113 EXPECT_EQ(1598801533, lrand48());
114 EXPECT_EQ(2080534853, lrand48());
115 EXPECT_EQ(1102488897, lrand48());
116 lcong48(p);
117 EXPECT_EQ(1531389981, lrand48());
118 EXPECT_EQ(1598801533, lrand48());
119 lcong48(p);
120 EXPECT_EQ(1531389981, lrand48());
121 EXPECT_EQ(1598801533, lrand48());
Elliott Hughes774c7f52012-10-01 13:11:03 -0700122}
123
Elliott Hughesa0beeea2014-06-12 11:48:04 -0700124TEST(stdlib, lrand48) {
Elliott Hughes774c7f52012-10-01 13:11:03 -0700125 srand48(0x01020304);
126 EXPECT_EQ(1409163720, lrand48());
127 EXPECT_EQ(397769746, lrand48());
128 EXPECT_EQ(902267124, lrand48());
129 EXPECT_EQ(132366131, lrand48());
Elliott Hughes274afe82014-11-06 12:40:08 -0800130 srand48(0x01020304);
131 EXPECT_EQ(1409163720, lrand48());
132 EXPECT_EQ(397769746, lrand48());
133 srand48(0x01020304);
134 EXPECT_EQ(1409163720, lrand48());
135 EXPECT_EQ(397769746, lrand48());
Elliott Hughesa0beeea2014-06-12 11:48:04 -0700136}
Elliott Hughes774c7f52012-10-01 13:11:03 -0700137
Elliott Hughesa0beeea2014-06-12 11:48:04 -0700138TEST(stdlib, random) {
Elliott Hughes774c7f52012-10-01 13:11:03 -0700139 srandom(0x01020304);
Elliott Hughesa0beeea2014-06-12 11:48:04 -0700140 EXPECT_EQ(55436735, random());
141 EXPECT_EQ(1399865117, random());
142 EXPECT_EQ(2032643283, random());
143 EXPECT_EQ(571329216, random());
Elliott Hughes274afe82014-11-06 12:40:08 -0800144 srandom(0x01020304);
145 EXPECT_EQ(55436735, random());
146 EXPECT_EQ(1399865117, random());
147 srandom(0x01020304);
148 EXPECT_EQ(55436735, random());
149 EXPECT_EQ(1399865117, random());
Elliott Hughesa0beeea2014-06-12 11:48:04 -0700150}
Elliott Hughes774c7f52012-10-01 13:11:03 -0700151
Elliott Hughesa0beeea2014-06-12 11:48:04 -0700152TEST(stdlib, rand) {
Elliott Hughes774c7f52012-10-01 13:11:03 -0700153 srand(0x01020304);
Elliott Hughesa0beeea2014-06-12 11:48:04 -0700154 EXPECT_EQ(55436735, rand());
155 EXPECT_EQ(1399865117, rand());
156 EXPECT_EQ(2032643283, rand());
157 EXPECT_EQ(571329216, rand());
Elliott Hughes274afe82014-11-06 12:40:08 -0800158 srand(0x01020304);
159 EXPECT_EQ(55436735, rand());
160 EXPECT_EQ(1399865117, rand());
161 srand(0x01020304);
162 EXPECT_EQ(55436735, rand());
163 EXPECT_EQ(1399865117, rand());
Elliott Hughes774c7f52012-10-01 13:11:03 -0700164}
165
166TEST(stdlib, mrand48) {
167 srand48(0x01020304);
168 EXPECT_EQ(-1476639856, mrand48());
169 EXPECT_EQ(795539493, mrand48());
170 EXPECT_EQ(1804534249, mrand48());
171 EXPECT_EQ(264732262, mrand48());
Elliott Hughes274afe82014-11-06 12:40:08 -0800172 srand48(0x01020304);
173 EXPECT_EQ(-1476639856, mrand48());
174 EXPECT_EQ(795539493, mrand48());
175 srand48(0x01020304);
176 EXPECT_EQ(-1476639856, mrand48());
177 EXPECT_EQ(795539493, mrand48());
Elliott Hughes774c7f52012-10-01 13:11:03 -0700178}
Elliott Hughesb16b7222013-02-04 13:18:00 -0800179
Aleksandra Tsvetkova608b4512015-02-27 15:01:59 +0300180TEST(stdlib, jrand48_distribution) {
181 const int iterations = 4096;
182 const int pivot_low = 1536;
183 const int pivot_high = 2560;
184
185 unsigned short xsubi[3];
186 int bits[32] = {};
187
188 for (int iter = 0; iter < iterations; ++iter) {
189 long rand_val = jrand48(xsubi);
190 for (int bit = 0; bit < 32; ++bit) {
191 bits[bit] += (static_cast<unsigned long>(rand_val) >> bit) & 0x01;
192 }
193 }
194
195 // Check that bit probability is uniform
196 for (int bit = 0; bit < 32; ++bit) {
197 EXPECT_TRUE((pivot_low <= bits[bit]) && (bits[bit] <= pivot_high));
198 }
199}
200
201TEST(stdlib, mrand48_distribution) {
202 const int iterations = 4096;
203 const int pivot_low = 1536;
204 const int pivot_high = 2560;
205
206 int bits[32] = {};
207
208 for (int iter = 0; iter < iterations; ++iter) {
209 long rand_val = mrand48();
210 for (int bit = 0; bit < 32; ++bit) {
211 bits[bit] += (static_cast<unsigned long>(rand_val) >> bit) & 0x01;
212 }
213 }
214
215 // Check that bit probability is uniform
216 for (int bit = 0; bit < 32; ++bit) {
217 EXPECT_TRUE((pivot_low <= bits[bit]) && (bits[bit] <= pivot_high));
218 }
219}
220
Christopher Ferris3a32d952017-06-15 13:30:44 -0700221TEST(stdlib, posix_memalign_sweep) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800222 SKIP_WITH_HWASAN;
Christopher Ferris3a32d952017-06-15 13:30:44 -0700223 void* ptr;
Elliott Hughesb16b7222013-02-04 13:18:00 -0800224
Christopher Ferris3a32d952017-06-15 13:30:44 -0700225 // These should all fail.
226 for (size_t align = 0; align < sizeof(long); align++) {
227 ASSERT_EQ(EINVAL, posix_memalign(&ptr, align, 256))
228 << "Unexpected value at align " << align;
229 }
Elliott Hughesb16b7222013-02-04 13:18:00 -0800230
Christopher Ferris3a32d952017-06-15 13:30:44 -0700231 // Verify powers of 2 up to 2048 allocate, and verify that all other
232 // alignment values between the powers of 2 fail.
233 size_t last_align = sizeof(long);
234 for (size_t align = sizeof(long); align <= 2048; align <<= 1) {
235 // Try all of the non power of 2 values from the last until this value.
236 for (size_t fail_align = last_align + 1; fail_align < align; fail_align++) {
237 ASSERT_EQ(EINVAL, posix_memalign(&ptr, fail_align, 256))
238 << "Unexpected success at align " << fail_align;
239 }
240 ASSERT_EQ(0, posix_memalign(&ptr, align, 256))
241 << "Unexpected failure at align " << align;
242 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) & (align - 1))
243 << "Did not return a valid aligned ptr " << ptr << " expected alignment " << align;
244 free(ptr);
245 last_align = align;
246 }
247}
248
249TEST(stdlib, posix_memalign_various_sizes) {
250 std::vector<size_t> sizes{1, 4, 8, 256, 1024, 65000, 128000, 256000, 1000000};
251 for (auto size : sizes) {
252 void* ptr;
253 ASSERT_EQ(0, posix_memalign(&ptr, 16, 1))
254 << "posix_memalign failed at size " << size;
255 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) & 0xf)
256 << "Pointer not aligned at size " << size << " ptr " << ptr;
257 free(ptr);
258 }
259}
260
261TEST(stdlib, posix_memalign_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800262 SKIP_WITH_HWASAN;
Christopher Ferris3a32d952017-06-15 13:30:44 -0700263 void* ptr;
264 ASSERT_NE(0, posix_memalign(&ptr, 16, SIZE_MAX));
Elliott Hughesb16b7222013-02-04 13:18:00 -0800265}
Elliott Hughesf0777842013-03-01 16:59:46 -0800266
Christopher Ferriscae21a92018-02-05 18:14:55 -0800267TEST(stdlib, aligned_alloc_sweep) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800268 SKIP_WITH_HWASAN;
Christopher Ferriscae21a92018-02-05 18:14:55 -0800269 // Verify powers of 2 up to 2048 allocate, and verify that all other
270 // alignment values between the powers of 2 fail.
271 size_t last_align = 1;
272 for (size_t align = 1; align <= 2048; align <<= 1) {
273 // Try all of the non power of 2 values from the last until this value.
274 for (size_t fail_align = last_align + 1; fail_align < align; fail_align++) {
Christopher Ferrisa22f5d52019-03-01 16:40:59 -0800275 ASSERT_TRUE(aligned_alloc(fail_align, fail_align) == nullptr)
Christopher Ferriscae21a92018-02-05 18:14:55 -0800276 << "Unexpected success at align " << fail_align;
277 ASSERT_EQ(EINVAL, errno) << "Unexpected errno at align " << fail_align;
278 }
Christopher Ferrisa22f5d52019-03-01 16:40:59 -0800279 void* ptr = aligned_alloc(align, 2 * align);
Christopher Ferriscae21a92018-02-05 18:14:55 -0800280 ASSERT_TRUE(ptr != nullptr) << "Unexpected failure at align " << align;
281 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) & (align - 1))
282 << "Did not return a valid aligned ptr " << ptr << " expected alignment " << align;
283 free(ptr);
284 last_align = align;
285 }
Christopher Ferriscae21a92018-02-05 18:14:55 -0800286}
287
288TEST(stdlib, aligned_alloc_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800289 SKIP_WITH_HWASAN;
Christopher Ferriscae21a92018-02-05 18:14:55 -0800290 ASSERT_TRUE(aligned_alloc(16, SIZE_MAX) == nullptr);
Christopher Ferriscae21a92018-02-05 18:14:55 -0800291}
292
293TEST(stdlib, aligned_alloc_size_not_multiple_of_alignment) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800294 SKIP_WITH_HWASAN;
Christopher Ferrisa22f5d52019-03-01 16:40:59 -0800295
296 ASSERT_TRUE(aligned_alloc(2048, 1) == nullptr);
297 ASSERT_TRUE(aligned_alloc(4, 3) == nullptr);
298 ASSERT_TRUE(aligned_alloc(4, 7) == nullptr);
299 ASSERT_TRUE(aligned_alloc(16, 8) == nullptr);
Christopher Ferriscae21a92018-02-05 18:14:55 -0800300}
301
Elliott Hughesf0777842013-03-01 16:59:46 -0800302TEST(stdlib, realpath__NULL_filename) {
303 errno = 0;
George Burgess IV95bd4882017-08-14 14:48:55 -0700304 // Work around the compile-time error generated by FORTIFY here.
Yi Kong32bc0fc2018-08-02 17:31:13 -0700305 const char* path = nullptr;
306 char* p = realpath(path, nullptr);
307 ASSERT_TRUE(p == nullptr);
Elliott Hughesf0777842013-03-01 16:59:46 -0800308 ASSERT_EQ(EINVAL, errno);
309}
310
311TEST(stdlib, realpath__empty_filename) {
312 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700313 char* p = realpath("", nullptr);
314 ASSERT_TRUE(p == nullptr);
Elliott Hughesf0777842013-03-01 16:59:46 -0800315 ASSERT_EQ(ENOENT, errno);
316}
317
318TEST(stdlib, realpath__ENOENT) {
319 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700320 char* p = realpath("/this/directory/path/almost/certainly/does/not/exist", nullptr);
321 ASSERT_TRUE(p == nullptr);
Elliott Hughesf0777842013-03-01 16:59:46 -0800322 ASSERT_EQ(ENOENT, errno);
323}
324
Elliott Hughes31e072f2014-09-30 16:15:42 -0700325TEST(stdlib, realpath__component_after_non_directory) {
326 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700327 char* p = realpath("/dev/null/.", nullptr);
328 ASSERT_TRUE(p == nullptr);
Elliott Hughes31e072f2014-09-30 16:15:42 -0700329 ASSERT_EQ(ENOTDIR, errno);
330
331 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700332 p = realpath("/dev/null/..", nullptr);
333 ASSERT_TRUE(p == nullptr);
Elliott Hughes31e072f2014-09-30 16:15:42 -0700334 ASSERT_EQ(ENOTDIR, errno);
335}
336
Elliott Hughesf0777842013-03-01 16:59:46 -0800337TEST(stdlib, realpath) {
338 // Get the name of this executable.
339 char executable_path[PATH_MAX];
340 int rc = readlink("/proc/self/exe", executable_path, sizeof(executable_path));
341 ASSERT_NE(rc, -1);
342 executable_path[rc] = '\0';
343
344 char buf[PATH_MAX + 1];
345 char* p = realpath("/proc/self/exe", buf);
346 ASSERT_STREQ(executable_path, p);
347
Yi Kong32bc0fc2018-08-02 17:31:13 -0700348 p = realpath("/proc/self/exe", nullptr);
Elliott Hughesf0777842013-03-01 16:59:46 -0800349 ASSERT_STREQ(executable_path, p);
350 free(p);
351}
Elliott Hughes0b25f632013-04-11 18:08:34 -0700352
353TEST(stdlib, qsort) {
354 struct s {
355 char name[16];
356 static int comparator(const void* lhs, const void* rhs) {
357 return strcmp(reinterpret_cast<const s*>(lhs)->name, reinterpret_cast<const s*>(rhs)->name);
358 }
359 };
360 s entries[3];
361 strcpy(entries[0].name, "charlie");
362 strcpy(entries[1].name, "bravo");
363 strcpy(entries[2].name, "alpha");
364
365 qsort(entries, 3, sizeof(s), s::comparator);
366 ASSERT_STREQ("alpha", entries[0].name);
367 ASSERT_STREQ("bravo", entries[1].name);
368 ASSERT_STREQ("charlie", entries[2].name);
369
370 qsort(entries, 3, sizeof(s), s::comparator);
371 ASSERT_STREQ("alpha", entries[0].name);
372 ASSERT_STREQ("bravo", entries[1].name);
373 ASSERT_STREQ("charlie", entries[2].name);
374}
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800375
376static void* TestBug57421_child(void* arg) {
377 pthread_t main_thread = reinterpret_cast<pthread_t>(arg);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700378 pthread_join(main_thread, nullptr);
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800379 char* value = getenv("ENVIRONMENT_VARIABLE");
Yi Kong32bc0fc2018-08-02 17:31:13 -0700380 if (value == nullptr) {
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800381 setenv("ENVIRONMENT_VARIABLE", "value", 1);
382 }
Yi Kong32bc0fc2018-08-02 17:31:13 -0700383 return nullptr;
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800384}
385
386static void TestBug57421_main() {
387 pthread_t t;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700388 ASSERT_EQ(0, pthread_create(&t, nullptr, TestBug57421_child, reinterpret_cast<void*>(pthread_self())));
389 pthread_exit(nullptr);
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800390}
391
392// Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to
393// run this test (which exits normally) in its own process.
Yabin Cui9df70402014-11-05 18:01:01 -0800394
395class stdlib_DeathTest : public BionicDeathTest {};
396
397TEST_F(stdlib_DeathTest, getenv_after_main_thread_exits) {
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800398 // https://code.google.com/p/android/issues/detail?id=57421
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800399 ASSERT_EXIT(TestBug57421_main(), ::testing::ExitedWithCode(0), "");
400}
Calin Juravlefe317a32014-02-21 15:11:03 +0000401
Elliott Hughes31165ed2014-09-23 17:34:29 -0700402TEST(stdlib, mkostemp64) {
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800403 MyTemporaryFile tf([](char* path) { return mkostemp64(path, O_CLOEXEC); });
Elliott Hughesa7f12942017-12-15 13:55:53 -0800404 AssertCloseOnExec(tf.fd, true);
Elliott Hughes31165ed2014-09-23 17:34:29 -0700405}
406
407TEST(stdlib, mkostemp) {
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800408 MyTemporaryFile tf([](char* path) { return mkostemp(path, O_CLOEXEC); });
Elliott Hughesa7f12942017-12-15 13:55:53 -0800409 AssertCloseOnExec(tf.fd, true);
Elliott Hughes31165ed2014-09-23 17:34:29 -0700410}
411
412TEST(stdlib, mkstemp64) {
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800413 MyTemporaryFile tf(mkstemp64);
Elliott Hughes31165ed2014-09-23 17:34:29 -0700414 struct stat64 sb;
415 ASSERT_EQ(0, fstat64(tf.fd, &sb));
416 ASSERT_EQ(O_LARGEFILE, fcntl(tf.fd, F_GETFL) & O_LARGEFILE);
417}
418
Calin Juravlefe317a32014-02-21 15:11:03 +0000419TEST(stdlib, mkstemp) {
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800420 MyTemporaryFile tf(mkstemp);
Calin Juravlefe317a32014-02-21 15:11:03 +0000421 struct stat sb;
422 ASSERT_EQ(0, fstat(tf.fd, &sb));
423}
424
Elliott Hughes3cdf5732014-03-11 12:54:44 -0700425TEST(stdlib, system) {
426 int status;
427
428 status = system("exit 0");
429 ASSERT_TRUE(WIFEXITED(status));
430 ASSERT_EQ(0, WEXITSTATUS(status));
431
432 status = system("exit 1");
433 ASSERT_TRUE(WIFEXITED(status));
434 ASSERT_EQ(1, WEXITSTATUS(status));
435}
Elliott Hughes5a817382014-03-12 16:12:57 -0700436
437TEST(stdlib, atof) {
Christopher Ferrisf171b342014-03-17 16:40:26 -0700438 ASSERT_DOUBLE_EQ(1.23, atof("1.23"));
Elliott Hughes5a817382014-03-12 16:12:57 -0700439}
440
Elliott Hughes7f0849f2016-08-26 16:17:17 -0700441template <typename T>
442static void CheckStrToFloat(T fn(const char* s, char** end)) {
443 FpUlpEq<0, T> pred;
444
445 EXPECT_PRED_FORMAT2(pred, 9.0, fn("9.0", nullptr));
446 EXPECT_PRED_FORMAT2(pred, 9.0, fn("0.9e1", nullptr));
447 EXPECT_PRED_FORMAT2(pred, 9.0, fn("0x1.2p3", nullptr));
448
Dan Albertf6346552016-12-02 12:02:03 -0800449 const char* s = " \t\v\f\r\n9.0";
450 char* p;
451 EXPECT_PRED_FORMAT2(pred, 9.0, fn(s, &p));
452 EXPECT_EQ(s + strlen(s), p);
453
Elliott Hughes7f0849f2016-08-26 16:17:17 -0700454 EXPECT_TRUE(isnan(fn("+nan", nullptr)));
455 EXPECT_TRUE(isnan(fn("nan", nullptr)));
456 EXPECT_TRUE(isnan(fn("-nan", nullptr)));
457
458 EXPECT_TRUE(isnan(fn("+nan(0xff)", nullptr)));
459 EXPECT_TRUE(isnan(fn("nan(0xff)", nullptr)));
460 EXPECT_TRUE(isnan(fn("-nan(0xff)", nullptr)));
461
Elliott Hughes7f0849f2016-08-26 16:17:17 -0700462 EXPECT_TRUE(isnan(fn("+nanny", &p)));
463 EXPECT_STREQ("ny", p);
464 EXPECT_TRUE(isnan(fn("nanny", &p)));
465 EXPECT_STREQ("ny", p);
466 EXPECT_TRUE(isnan(fn("-nanny", &p)));
467 EXPECT_STREQ("ny", p);
468
469 EXPECT_EQ(0, fn("muppet", &p));
470 EXPECT_STREQ("muppet", p);
471 EXPECT_EQ(0, fn(" muppet", &p));
472 EXPECT_STREQ(" muppet", p);
473
474 EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("+inf", nullptr));
475 EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("inf", nullptr));
476 EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn("-inf", nullptr));
477
478 EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("+infinity", nullptr));
479 EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("infinity", nullptr));
480 EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn("-infinity", nullptr));
481
482 EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("+infinitude", &p));
483 EXPECT_STREQ("initude", p);
484 EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("infinitude", &p));
485 EXPECT_STREQ("initude", p);
486 EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn("-infinitude", &p));
487 EXPECT_STREQ("initude", p);
488
489 // Check case-insensitivity.
490 EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("InFiNiTy", nullptr));
491 EXPECT_TRUE(isnan(fn("NaN", nullptr)));
492}
493
Elliott Hughes5a817382014-03-12 16:12:57 -0700494TEST(stdlib, strtod) {
Elliott Hughes7f0849f2016-08-26 16:17:17 -0700495 CheckStrToFloat(strtod);
Elliott Hughes5a817382014-03-12 16:12:57 -0700496}
497
498TEST(stdlib, strtof) {
Elliott Hughes7f0849f2016-08-26 16:17:17 -0700499 CheckStrToFloat(strtof);
Elliott Hughes5a817382014-03-12 16:12:57 -0700500}
501
502TEST(stdlib, strtold) {
Elliott Hughes7f0849f2016-08-26 16:17:17 -0700503 CheckStrToFloat(strtold);
Elliott Hughes5a817382014-03-12 16:12:57 -0700504}
Elliott Hughes9f525642014-04-08 17:14:01 -0700505
Elliott Hughes89aaaff2014-10-28 17:54:23 -0700506TEST(stdlib, strtof_2206701) {
Yi Kong32bc0fc2018-08-02 17:31:13 -0700507 ASSERT_EQ(0.0f, strtof("7.0064923216240853546186479164495e-46", nullptr));
508 ASSERT_EQ(1.4e-45f, strtof("7.0064923216240853546186479164496e-46", nullptr));
Elliott Hughes89aaaff2014-10-28 17:54:23 -0700509}
510
511TEST(stdlib, strtod_largest_subnormal) {
512 // This value has been known to cause javac and java to infinite loop.
513 // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
Yi Kong32bc0fc2018-08-02 17:31:13 -0700514 ASSERT_EQ(2.2250738585072014e-308, strtod("2.2250738585072012e-308", nullptr));
515 ASSERT_EQ(2.2250738585072014e-308, strtod("0.00022250738585072012e-304", nullptr));
516 ASSERT_EQ(2.2250738585072014e-308, strtod("00000002.2250738585072012e-308", nullptr));
517 ASSERT_EQ(2.2250738585072014e-308, strtod("2.225073858507201200000e-308", nullptr));
518 ASSERT_EQ(2.2250738585072014e-308, strtod("2.2250738585072012e-00308", nullptr));
519 ASSERT_EQ(2.2250738585072014e-308, strtod("2.22507385850720129978001e-308", nullptr));
520 ASSERT_EQ(-2.2250738585072014e-308, strtod("-2.2250738585072012e-308", nullptr));
Elliott Hughes89aaaff2014-10-28 17:54:23 -0700521}
522
Dan Albertb8425c52014-04-29 17:49:06 -0700523TEST(stdlib, quick_exit) {
524 pid_t pid = fork();
525 ASSERT_NE(-1, pid) << strerror(errno);
526
527 if (pid == 0) {
528 quick_exit(99);
529 }
530
Elliott Hughes33697a02016-01-26 13:04:57 -0800531 AssertChildExited(pid, 99);
Dan Albertb8425c52014-04-29 17:49:06 -0700532}
533
534static int quick_exit_status = 0;
535
536static void quick_exit_1(void) {
537 ASSERT_EQ(quick_exit_status, 0);
538 quick_exit_status = 1;
539}
540
541static void quick_exit_2(void) {
542 ASSERT_EQ(quick_exit_status, 1);
543}
544
545static void not_run(void) {
546 FAIL();
547}
548
549TEST(stdlib, at_quick_exit) {
550 pid_t pid = fork();
551 ASSERT_NE(-1, pid) << strerror(errno);
552
553 if (pid == 0) {
554 ASSERT_EQ(at_quick_exit(quick_exit_2), 0);
555 ASSERT_EQ(at_quick_exit(quick_exit_1), 0);
556 atexit(not_run);
557 quick_exit(99);
558 }
559
Elliott Hughes33697a02016-01-26 13:04:57 -0800560 AssertChildExited(pid, 99);
Dan Albertb8425c52014-04-29 17:49:06 -0700561}
562
Elliott Hughes9f525642014-04-08 17:14:01 -0700563TEST(unistd, _Exit) {
Elliott Hughes33697a02016-01-26 13:04:57 -0800564 pid_t pid = fork();
Elliott Hughes9f525642014-04-08 17:14:01 -0700565 ASSERT_NE(-1, pid) << strerror(errno);
566
567 if (pid == 0) {
568 _Exit(99);
569 }
570
Elliott Hughes33697a02016-01-26 13:04:57 -0800571 AssertChildExited(pid, 99);
Elliott Hughes9f525642014-04-08 17:14:01 -0700572}
Elliott Hughes49167062014-07-25 17:24:00 -0700573
574TEST(stdlib, pty_smoke) {
575 // getpt returns a pty with O_RDWR|O_NOCTTY.
576 int fd = getpt();
577 ASSERT_NE(-1, fd);
578
579 // grantpt is a no-op.
580 ASSERT_EQ(0, grantpt(fd));
581
582 // ptsname_r should start "/dev/pts/".
583 char name_r[128];
584 ASSERT_EQ(0, ptsname_r(fd, name_r, sizeof(name_r)));
585 name_r[9] = 0;
586 ASSERT_STREQ("/dev/pts/", name_r);
587
588 close(fd);
589}
590
591TEST(stdlib, posix_openpt) {
592 int fd = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC);
593 ASSERT_NE(-1, fd);
594 close(fd);
595}
596
597TEST(stdlib, ptsname_r_ENOTTY) {
598 errno = 0;
599 char buf[128];
600 ASSERT_EQ(ENOTTY, ptsname_r(STDOUT_FILENO, buf, sizeof(buf)));
601 ASSERT_EQ(ENOTTY, errno);
602}
603
604TEST(stdlib, ptsname_r_EINVAL) {
605 int fd = getpt();
606 ASSERT_NE(-1, fd);
607 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700608 char* buf = nullptr;
Elliott Hughes49167062014-07-25 17:24:00 -0700609 ASSERT_EQ(EINVAL, ptsname_r(fd, buf, 128));
610 ASSERT_EQ(EINVAL, errno);
611 close(fd);
612}
613
614TEST(stdlib, ptsname_r_ERANGE) {
615 int fd = getpt();
616 ASSERT_NE(-1, fd);
617 errno = 0;
618 char buf[1];
619 ASSERT_EQ(ERANGE, ptsname_r(fd, buf, sizeof(buf)));
620 ASSERT_EQ(ERANGE, errno);
621 close(fd);
622}
623
Elliott Hughes728cde52017-11-08 21:53:50 -0800624TEST(stdlib, ttyname) {
625 int fd = getpt();
626 ASSERT_NE(-1, fd);
627
628 // ttyname returns "/dev/ptmx" for a pty.
629 ASSERT_STREQ("/dev/ptmx", ttyname(fd));
630
631 close(fd);
632}
633
Elliott Hughes49167062014-07-25 17:24:00 -0700634TEST(stdlib, ttyname_r) {
635 int fd = getpt();
636 ASSERT_NE(-1, fd);
637
638 // ttyname_r returns "/dev/ptmx" for a pty.
639 char name_r[128];
640 ASSERT_EQ(0, ttyname_r(fd, name_r, sizeof(name_r)));
641 ASSERT_STREQ("/dev/ptmx", name_r);
642
643 close(fd);
644}
645
646TEST(stdlib, ttyname_r_ENOTTY) {
647 int fd = open("/dev/null", O_WRONLY);
648 errno = 0;
649 char buf[128];
650 ASSERT_EQ(ENOTTY, ttyname_r(fd, buf, sizeof(buf)));
651 ASSERT_EQ(ENOTTY, errno);
652 close(fd);
653}
654
655TEST(stdlib, ttyname_r_EINVAL) {
656 int fd = getpt();
657 ASSERT_NE(-1, fd);
658 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700659 char* buf = nullptr;
Elliott Hughes49167062014-07-25 17:24:00 -0700660 ASSERT_EQ(EINVAL, ttyname_r(fd, buf, 128));
661 ASSERT_EQ(EINVAL, errno);
662 close(fd);
663}
664
665TEST(stdlib, ttyname_r_ERANGE) {
666 int fd = getpt();
667 ASSERT_NE(-1, fd);
668 errno = 0;
669 char buf[1];
670 ASSERT_EQ(ERANGE, ttyname_r(fd, buf, sizeof(buf)));
671 ASSERT_EQ(ERANGE, errno);
672 close(fd);
673}
674
675TEST(stdlib, unlockpt_ENOTTY) {
676 int fd = open("/dev/null", O_WRONLY);
677 errno = 0;
678 ASSERT_EQ(-1, unlockpt(fd));
679 ASSERT_EQ(ENOTTY, errno);
680 close(fd);
681}
Elliott Hughesb05ec5a2014-09-23 14:53:10 -0700682
Elliott Hughesdf143f82016-04-04 17:34:04 -0700683TEST(stdlib, getsubopt) {
684 char* const tokens[] = {
685 const_cast<char*>("a"),
686 const_cast<char*>("b"),
687 const_cast<char*>("foo"),
688 nullptr
689 };
690 std::string input = "a,b,foo=bar,a,unknown";
691 char* subopts = &input[0];
692 char* value = nullptr;
693
694 ASSERT_EQ(0, getsubopt(&subopts, tokens, &value));
695 ASSERT_EQ(nullptr, value);
696 ASSERT_EQ(1, getsubopt(&subopts, tokens, &value));
697 ASSERT_EQ(nullptr, value);
698 ASSERT_EQ(2, getsubopt(&subopts, tokens, &value));
699 ASSERT_STREQ("bar", value);
700 ASSERT_EQ(0, getsubopt(&subopts, tokens, &value));
701 ASSERT_EQ(nullptr, value);
702
703 ASSERT_EQ(-1, getsubopt(&subopts, tokens, &value));
704}
Elliott Hughes6f6f9052016-04-28 14:54:52 -0700705
706TEST(stdlib, mblen) {
707 // "If s is a null pointer, mblen() shall return a non-zero or 0 value, if character encodings,
708 // respectively, do or do not have state-dependent encodings." We're always UTF-8.
709 EXPECT_EQ(0, mblen(nullptr, 1));
710
711 ASSERT_STREQ("C.UTF-8", setlocale(LC_ALL, "C.UTF-8"));
712
713 // 1-byte UTF-8.
714 EXPECT_EQ(1, mblen("abcdef", 6));
715 // 2-byte UTF-8.
716 EXPECT_EQ(2, mblen("\xc2\xa2" "cdef", 6));
717 // 3-byte UTF-8.
718 EXPECT_EQ(3, mblen("\xe2\x82\xac" "def", 6));
719 // 4-byte UTF-8.
720 EXPECT_EQ(4, mblen("\xf0\xa4\xad\xa2" "ef", 6));
721
722 // Illegal over-long sequence.
723 ASSERT_EQ(-1, mblen("\xf0\x82\x82\xac" "ef", 6));
724
725 // "mblen() shall ... return 0 (if s points to the null byte)".
726 EXPECT_EQ(0, mblen("", 1));
727}
Elliott Hughesf826a372017-07-13 09:35:15 -0700728
729template <typename T>
730static void CheckStrToInt(T fn(const char* s, char** end, int base)) {
731 char* end_p;
732
733 // Negative base => invalid.
734 errno = 0;
735 ASSERT_EQ(T(0), fn("123", &end_p, -1));
736 ASSERT_EQ(EINVAL, errno);
737
738 // Base 1 => invalid (base 0 means "please guess").
739 errno = 0;
740 ASSERT_EQ(T(0), fn("123", &end_p, 1));
741 ASSERT_EQ(EINVAL, errno);
742
743 // Base > 36 => invalid.
744 errno = 0;
745 ASSERT_EQ(T(0), fn("123", &end_p, 37));
746 ASSERT_EQ(EINVAL, errno);
747
748 // If we see "0x" *not* followed by a hex digit, we shouldn't swallow the 'x'.
749 ASSERT_EQ(T(0), fn("0xy", &end_p, 16));
750 ASSERT_EQ('x', *end_p);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800751
752 if (std::numeric_limits<T>::is_signed) {
753 // Minimum (such as -128).
Elliott Hughesf61a06e2017-12-19 16:11:37 -0800754 std::string min{std::to_string(std::numeric_limits<T>::min())};
Elliott Hughescb239bd2017-12-20 17:37:11 -0800755 end_p = nullptr;
756 errno = 0;
Elliott Hughes1921dce2017-12-19 10:27:27 -0800757 ASSERT_EQ(std::numeric_limits<T>::min(), fn(min.c_str(), &end_p, 0));
Elliott Hughescb239bd2017-12-20 17:37:11 -0800758 ASSERT_EQ(0, errno);
759 ASSERT_EQ('\0', *end_p);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800760 // Too negative (such as -129).
761 min.back() = (min.back() + 1);
Elliott Hughescb239bd2017-12-20 17:37:11 -0800762 end_p = nullptr;
Elliott Hughes1921dce2017-12-19 10:27:27 -0800763 errno = 0;
764 ASSERT_EQ(std::numeric_limits<T>::min(), fn(min.c_str(), &end_p, 0));
765 ASSERT_EQ(ERANGE, errno);
Elliott Hughescb239bd2017-12-20 17:37:11 -0800766 ASSERT_EQ('\0', *end_p);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800767 }
768
769 // Maximum (such as 127).
Elliott Hughesf61a06e2017-12-19 16:11:37 -0800770 std::string max{std::to_string(std::numeric_limits<T>::max())};
Elliott Hughescb239bd2017-12-20 17:37:11 -0800771 end_p = nullptr;
772 errno = 0;
Elliott Hughes1921dce2017-12-19 10:27:27 -0800773 ASSERT_EQ(std::numeric_limits<T>::max(), fn(max.c_str(), &end_p, 0));
Elliott Hughescb239bd2017-12-20 17:37:11 -0800774 ASSERT_EQ(0, errno);
775 ASSERT_EQ('\0', *end_p);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800776 // Too positive (such as 128).
777 max.back() = (max.back() + 1);
Elliott Hughescb239bd2017-12-20 17:37:11 -0800778 end_p = nullptr;
Elliott Hughes1921dce2017-12-19 10:27:27 -0800779 errno = 0;
780 ASSERT_EQ(std::numeric_limits<T>::max(), fn(max.c_str(), &end_p, 0));
781 ASSERT_EQ(ERANGE, errno);
Elliott Hughescb239bd2017-12-20 17:37:11 -0800782 ASSERT_EQ('\0', *end_p);
783
784 // In case of overflow, strto* leaves us pointing past the end of the number,
785 // not at the digit that overflowed.
786 end_p = nullptr;
787 errno = 0;
788 ASSERT_EQ(std::numeric_limits<T>::max(),
789 fn("99999999999999999999999999999999999999999999999999999abc", &end_p, 0));
790 ASSERT_EQ(ERANGE, errno);
791 ASSERT_STREQ("abc", end_p);
792 if (std::numeric_limits<T>::is_signed) {
793 end_p = nullptr;
794 errno = 0;
795 ASSERT_EQ(std::numeric_limits<T>::min(),
796 fn("-99999999999999999999999999999999999999999999999999999abc", &end_p, 0));
797 ASSERT_EQ(ERANGE, errno);
798 ASSERT_STREQ("abc", end_p);
799 }
Elliott Hughesf826a372017-07-13 09:35:15 -0700800}
801
802TEST(stdlib, strtol_smoke) {
803 CheckStrToInt(strtol);
804}
805
806TEST(stdlib, strtoll_smoke) {
807 CheckStrToInt(strtoll);
808}
809
810TEST(stdlib, strtoul_smoke) {
811 CheckStrToInt(strtoul);
812}
813
814TEST(stdlib, strtoull_smoke) {
815 CheckStrToInt(strtoull);
816}
817
818TEST(stdlib, strtoimax_smoke) {
819 CheckStrToInt(strtoimax);
820}
821
822TEST(stdlib, strtoumax_smoke) {
823 CheckStrToInt(strtoumax);
824}
Elliott Hughes00d8a8b2017-09-07 16:42:13 -0700825
826TEST(stdlib, abs) {
827 ASSERT_EQ(INT_MAX, abs(-INT_MAX));
828 ASSERT_EQ(INT_MAX, abs(INT_MAX));
829}
830
831TEST(stdlib, labs) {
832 ASSERT_EQ(LONG_MAX, labs(-LONG_MAX));
833 ASSERT_EQ(LONG_MAX, labs(LONG_MAX));
834}
835
836TEST(stdlib, llabs) {
837 ASSERT_EQ(LLONG_MAX, llabs(-LLONG_MAX));
838 ASSERT_EQ(LLONG_MAX, llabs(LLONG_MAX));
839}
Elliott Hughes2d0b28b2018-10-23 11:23:00 -0700840
841TEST(stdlib, getloadavg) {
842 double load[3];
843
844 // The second argument should have been size_t.
845 ASSERT_EQ(-1, getloadavg(load, -1));
846 ASSERT_EQ(-1, getloadavg(load, INT_MIN));
847
848 // Zero is a no-op.
849 ASSERT_EQ(0, getloadavg(load, 0));
850
851 // The Linux kernel doesn't support more than 3 (but you can ask for fewer).
852 ASSERT_EQ(1, getloadavg(load, 1));
853 ASSERT_EQ(2, getloadavg(load, 2));
854 ASSERT_EQ(3, getloadavg(load, 3));
855 ASSERT_EQ(3, getloadavg(load, 4));
856 ASSERT_EQ(3, getloadavg(load, INT_MAX));
857
858 // Read /proc/loadavg and check that it's "close enough".
Elliott Hughes2d0b28b2018-10-23 11:23:00 -0700859 double expected[3];
860 std::unique_ptr<FILE, decltype(&fclose)> fp{fopen("/proc/loadavg", "re"), fclose};
861 ASSERT_EQ(3, fscanf(fp.get(), "%lf %lf %lf", &expected[0], &expected[1], &expected[2]));
Elliott Hughes72a54a42018-12-18 14:47:25 -0800862 load[0] = load[1] = load[2] = nan("");
Elliott Hughes2d0b28b2018-10-23 11:23:00 -0700863 ASSERT_EQ(3, getloadavg(load, 3));
864
Elliott Hughes72a54a42018-12-18 14:47:25 -0800865 // Check that getloadavg(3) at least overwrote the NaNs.
Elliott Hughes2d0b28b2018-10-23 11:23:00 -0700866 ASSERT_FALSE(isnan(load[0]));
Elliott Hughes72a54a42018-12-18 14:47:25 -0800867 ASSERT_FALSE(isnan(load[1]));
868 ASSERT_FALSE(isnan(load[2]));
869 // And that the difference between /proc/loadavg and getloadavg(3) is "small".
870 ASSERT_TRUE(fabs(expected[0] - load[0]) < 0.5) << expected[0] << ' ' << load[0];
871 ASSERT_TRUE(fabs(expected[1] - load[1]) < 0.5) << expected[1] << ' ' << load[1];
872 ASSERT_TRUE(fabs(expected[2] - load[2]) < 0.5) << expected[2] << ' ' << load[2];
Elliott Hughes2d0b28b2018-10-23 11:23:00 -0700873}