blob: 00850f61e6b3e217f52153053c01c88e7f03fb16 [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
Christopher Ferriscae21a92018-02-05 18:14:55 -080039#if defined(__BIONIC__)
40 #define ALIGNED_ALLOC_AVAILABLE 1
41#elif defined(__GLIBC_PREREQ)
42 #if __GLIBC_PREREQ(2, 16)
43 #define ALIGNED_ALLOC_AVAILABLE 1
44 #endif
45#endif
46
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -080047template <typename T = int (*)(char*)>
48class GenericTemporaryFile {
49 public:
50 explicit GenericTemporaryFile(T mk_fn = mkstemp) : mk_fn_(mk_fn) {
51 // Since we might be running on the host or the target, and if we're
52 // running on the host we might be running under bionic or glibc,
53 // let's just try both possible temporary directories and take the
54 // first one that works.
55 init("/data/local/tmp");
56 if (fd == -1) {
57 init("/tmp");
58 }
59 }
60
61 ~GenericTemporaryFile() {
62 close(fd);
63 unlink(path);
64 }
65
66 int fd;
67 char path[1024];
68
69 private:
70 T mk_fn_;
71
72 void init(const char* tmp_dir) {
73 snprintf(path, sizeof(path), "%s/TemporaryFile-XXXXXX", tmp_dir);
74 fd = mk_fn_(path);
75 }
76
77 DISALLOW_COPY_AND_ASSIGN(GenericTemporaryFile);
78};
79
80typedef GenericTemporaryFile<> MyTemporaryFile;
81
Elliott Hughes274afe82014-11-06 12:40:08 -080082// The random number generator tests all set the seed, get four values, reset the seed and check
83// that they get the first two values repeated, and then reset the seed and check two more values
84// to rule out the possibility that we're just going round a cycle of four values.
85// TODO: factor this out.
86
Elliott Hughes774c7f52012-10-01 13:11:03 -070087TEST(stdlib, drand48) {
88 srand48(0x01020304);
89 EXPECT_DOUBLE_EQ(0.65619299195623526, drand48());
90 EXPECT_DOUBLE_EQ(0.18522597229772941, drand48());
91 EXPECT_DOUBLE_EQ(0.42015087072844537, drand48());
92 EXPECT_DOUBLE_EQ(0.061637783047395089, drand48());
Elliott Hughes274afe82014-11-06 12:40:08 -080093 srand48(0x01020304);
94 EXPECT_DOUBLE_EQ(0.65619299195623526, drand48());
95 EXPECT_DOUBLE_EQ(0.18522597229772941, drand48());
96 srand48(0x01020304);
97 EXPECT_DOUBLE_EQ(0.65619299195623526, drand48());
98 EXPECT_DOUBLE_EQ(0.18522597229772941, drand48());
99}
100
101TEST(stdlib, erand48) {
102 const unsigned short seed[3] = { 0x330e, 0xabcd, 0x1234 };
103 unsigned short xsubi[3];
104 memcpy(xsubi, seed, sizeof(seed));
105 EXPECT_DOUBLE_EQ(0.39646477376027534, erand48(xsubi));
106 EXPECT_DOUBLE_EQ(0.84048536941142515, erand48(xsubi));
107 EXPECT_DOUBLE_EQ(0.35333609724524351, erand48(xsubi));
108 EXPECT_DOUBLE_EQ(0.44658343479654405, erand48(xsubi));
109 memcpy(xsubi, seed, sizeof(seed));
110 EXPECT_DOUBLE_EQ(0.39646477376027534, erand48(xsubi));
111 EXPECT_DOUBLE_EQ(0.84048536941142515, erand48(xsubi));
112 memcpy(xsubi, seed, sizeof(seed));
113 EXPECT_DOUBLE_EQ(0.39646477376027534, erand48(xsubi));
114 EXPECT_DOUBLE_EQ(0.84048536941142515, erand48(xsubi));
115}
116
117TEST(stdlib, lcong48) {
118 unsigned short p[7] = { 0x0102, 0x0304, 0x0506, 0x0708, 0x090a, 0x0b0c, 0x0d0e };
119 lcong48(p);
120 EXPECT_EQ(1531389981, lrand48());
121 EXPECT_EQ(1598801533, lrand48());
122 EXPECT_EQ(2080534853, lrand48());
123 EXPECT_EQ(1102488897, lrand48());
124 lcong48(p);
125 EXPECT_EQ(1531389981, lrand48());
126 EXPECT_EQ(1598801533, lrand48());
127 lcong48(p);
128 EXPECT_EQ(1531389981, lrand48());
129 EXPECT_EQ(1598801533, lrand48());
Elliott Hughes774c7f52012-10-01 13:11:03 -0700130}
131
Elliott Hughesa0beeea2014-06-12 11:48:04 -0700132TEST(stdlib, lrand48) {
Elliott Hughes774c7f52012-10-01 13:11:03 -0700133 srand48(0x01020304);
134 EXPECT_EQ(1409163720, lrand48());
135 EXPECT_EQ(397769746, lrand48());
136 EXPECT_EQ(902267124, lrand48());
137 EXPECT_EQ(132366131, lrand48());
Elliott Hughes274afe82014-11-06 12:40:08 -0800138 srand48(0x01020304);
139 EXPECT_EQ(1409163720, lrand48());
140 EXPECT_EQ(397769746, lrand48());
141 srand48(0x01020304);
142 EXPECT_EQ(1409163720, lrand48());
143 EXPECT_EQ(397769746, lrand48());
Elliott Hughesa0beeea2014-06-12 11:48:04 -0700144}
Elliott Hughes774c7f52012-10-01 13:11:03 -0700145
Elliott Hughesa0beeea2014-06-12 11:48:04 -0700146TEST(stdlib, random) {
Elliott Hughes774c7f52012-10-01 13:11:03 -0700147 srandom(0x01020304);
Elliott Hughesa0beeea2014-06-12 11:48:04 -0700148 EXPECT_EQ(55436735, random());
149 EXPECT_EQ(1399865117, random());
150 EXPECT_EQ(2032643283, random());
151 EXPECT_EQ(571329216, random());
Elliott Hughes274afe82014-11-06 12:40:08 -0800152 srandom(0x01020304);
153 EXPECT_EQ(55436735, random());
154 EXPECT_EQ(1399865117, random());
155 srandom(0x01020304);
156 EXPECT_EQ(55436735, random());
157 EXPECT_EQ(1399865117, random());
Elliott Hughesa0beeea2014-06-12 11:48:04 -0700158}
Elliott Hughes774c7f52012-10-01 13:11:03 -0700159
Elliott Hughesa0beeea2014-06-12 11:48:04 -0700160TEST(stdlib, rand) {
Elliott Hughes774c7f52012-10-01 13:11:03 -0700161 srand(0x01020304);
Elliott Hughesa0beeea2014-06-12 11:48:04 -0700162 EXPECT_EQ(55436735, rand());
163 EXPECT_EQ(1399865117, rand());
164 EXPECT_EQ(2032643283, rand());
165 EXPECT_EQ(571329216, rand());
Elliott Hughes274afe82014-11-06 12:40:08 -0800166 srand(0x01020304);
167 EXPECT_EQ(55436735, rand());
168 EXPECT_EQ(1399865117, rand());
169 srand(0x01020304);
170 EXPECT_EQ(55436735, rand());
171 EXPECT_EQ(1399865117, rand());
Elliott Hughes774c7f52012-10-01 13:11:03 -0700172}
173
174TEST(stdlib, mrand48) {
175 srand48(0x01020304);
176 EXPECT_EQ(-1476639856, mrand48());
177 EXPECT_EQ(795539493, mrand48());
178 EXPECT_EQ(1804534249, mrand48());
179 EXPECT_EQ(264732262, mrand48());
Elliott Hughes274afe82014-11-06 12:40:08 -0800180 srand48(0x01020304);
181 EXPECT_EQ(-1476639856, mrand48());
182 EXPECT_EQ(795539493, mrand48());
183 srand48(0x01020304);
184 EXPECT_EQ(-1476639856, mrand48());
185 EXPECT_EQ(795539493, mrand48());
Elliott Hughes774c7f52012-10-01 13:11:03 -0700186}
Elliott Hughesb16b7222013-02-04 13:18:00 -0800187
Aleksandra Tsvetkova608b4512015-02-27 15:01:59 +0300188TEST(stdlib, jrand48_distribution) {
189 const int iterations = 4096;
190 const int pivot_low = 1536;
191 const int pivot_high = 2560;
192
193 unsigned short xsubi[3];
194 int bits[32] = {};
195
196 for (int iter = 0; iter < iterations; ++iter) {
197 long rand_val = jrand48(xsubi);
198 for (int bit = 0; bit < 32; ++bit) {
199 bits[bit] += (static_cast<unsigned long>(rand_val) >> bit) & 0x01;
200 }
201 }
202
203 // Check that bit probability is uniform
204 for (int bit = 0; bit < 32; ++bit) {
205 EXPECT_TRUE((pivot_low <= bits[bit]) && (bits[bit] <= pivot_high));
206 }
207}
208
209TEST(stdlib, mrand48_distribution) {
210 const int iterations = 4096;
211 const int pivot_low = 1536;
212 const int pivot_high = 2560;
213
214 int bits[32] = {};
215
216 for (int iter = 0; iter < iterations; ++iter) {
217 long rand_val = mrand48();
218 for (int bit = 0; bit < 32; ++bit) {
219 bits[bit] += (static_cast<unsigned long>(rand_val) >> bit) & 0x01;
220 }
221 }
222
223 // Check that bit probability is uniform
224 for (int bit = 0; bit < 32; ++bit) {
225 EXPECT_TRUE((pivot_low <= bits[bit]) && (bits[bit] <= pivot_high));
226 }
227}
228
Christopher Ferris3a32d952017-06-15 13:30:44 -0700229TEST(stdlib, posix_memalign_sweep) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800230 SKIP_WITH_HWASAN;
Christopher Ferris3a32d952017-06-15 13:30:44 -0700231 void* ptr;
Elliott Hughesb16b7222013-02-04 13:18:00 -0800232
Christopher Ferris3a32d952017-06-15 13:30:44 -0700233 // These should all fail.
234 for (size_t align = 0; align < sizeof(long); align++) {
235 ASSERT_EQ(EINVAL, posix_memalign(&ptr, align, 256))
236 << "Unexpected value at align " << align;
237 }
Elliott Hughesb16b7222013-02-04 13:18:00 -0800238
Christopher Ferris3a32d952017-06-15 13:30:44 -0700239 // Verify powers of 2 up to 2048 allocate, and verify that all other
240 // alignment values between the powers of 2 fail.
241 size_t last_align = sizeof(long);
242 for (size_t align = sizeof(long); align <= 2048; align <<= 1) {
243 // Try all of the non power of 2 values from the last until this value.
244 for (size_t fail_align = last_align + 1; fail_align < align; fail_align++) {
245 ASSERT_EQ(EINVAL, posix_memalign(&ptr, fail_align, 256))
246 << "Unexpected success at align " << fail_align;
247 }
248 ASSERT_EQ(0, posix_memalign(&ptr, align, 256))
249 << "Unexpected failure at align " << align;
250 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) & (align - 1))
251 << "Did not return a valid aligned ptr " << ptr << " expected alignment " << align;
252 free(ptr);
253 last_align = align;
254 }
255}
256
257TEST(stdlib, posix_memalign_various_sizes) {
258 std::vector<size_t> sizes{1, 4, 8, 256, 1024, 65000, 128000, 256000, 1000000};
259 for (auto size : sizes) {
260 void* ptr;
261 ASSERT_EQ(0, posix_memalign(&ptr, 16, 1))
262 << "posix_memalign failed at size " << size;
263 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) & 0xf)
264 << "Pointer not aligned at size " << size << " ptr " << ptr;
265 free(ptr);
266 }
267}
268
269TEST(stdlib, posix_memalign_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800270 SKIP_WITH_HWASAN;
Christopher Ferris3a32d952017-06-15 13:30:44 -0700271 void* ptr;
272 ASSERT_NE(0, posix_memalign(&ptr, 16, SIZE_MAX));
Elliott Hughesb16b7222013-02-04 13:18:00 -0800273}
Elliott Hughesf0777842013-03-01 16:59:46 -0800274
Christopher Ferriscae21a92018-02-05 18:14:55 -0800275TEST(stdlib, aligned_alloc_sweep) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800276 SKIP_WITH_HWASAN;
Christopher Ferriscae21a92018-02-05 18:14:55 -0800277#if defined(ALIGNED_ALLOC_AVAILABLE)
278 // Verify powers of 2 up to 2048 allocate, and verify that all other
279 // alignment values between the powers of 2 fail.
280 size_t last_align = 1;
281 for (size_t align = 1; align <= 2048; align <<= 1) {
282 // Try all of the non power of 2 values from the last until this value.
283 for (size_t fail_align = last_align + 1; fail_align < align; fail_align++) {
284 ASSERT_TRUE(aligned_alloc(fail_align, 256) == nullptr)
285 << "Unexpected success at align " << fail_align;
286 ASSERT_EQ(EINVAL, errno) << "Unexpected errno at align " << fail_align;
287 }
288 void* ptr = aligned_alloc(align, 256);
289 ASSERT_TRUE(ptr != nullptr) << "Unexpected failure at align " << align;
290 ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) & (align - 1))
291 << "Did not return a valid aligned ptr " << ptr << " expected alignment " << align;
292 free(ptr);
293 last_align = align;
294 }
295#else
296 GTEST_LOG_(INFO) << "This test requires a C library that has aligned_alloc.\n";
297#endif
298}
299
300TEST(stdlib, aligned_alloc_overflow) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800301 SKIP_WITH_HWASAN;
Christopher Ferriscae21a92018-02-05 18:14:55 -0800302#if defined(ALIGNED_ALLOC_AVAILABLE)
303 ASSERT_TRUE(aligned_alloc(16, SIZE_MAX) == nullptr);
304#else
305 GTEST_LOG_(INFO) << "This test requires a C library that has aligned_alloc.\n";
306#endif
307}
308
309TEST(stdlib, aligned_alloc_size_not_multiple_of_alignment) {
Evgenii Stepanovacd6f4f2018-11-06 16:48:27 -0800310 SKIP_WITH_HWASAN;
Christopher Ferriscae21a92018-02-05 18:14:55 -0800311#if defined(ALIGNED_ALLOC_AVAILABLE)
312 for (size_t size = 1; size <= 2048; size++) {
313 void* ptr = aligned_alloc(2048, size);
314 ASSERT_TRUE(ptr != nullptr) << "Failed at size " << std::to_string(size);
315 free(ptr);
316 }
317#else
318 GTEST_LOG_(INFO) << "This test requires a C library that has aligned_alloc.\n";
319#endif
320}
321
Elliott Hughesf0777842013-03-01 16:59:46 -0800322TEST(stdlib, realpath__NULL_filename) {
323 errno = 0;
George Burgess IV95bd4882017-08-14 14:48:55 -0700324 // Work around the compile-time error generated by FORTIFY here.
Yi Kong32bc0fc2018-08-02 17:31:13 -0700325 const char* path = nullptr;
326 char* p = realpath(path, nullptr);
327 ASSERT_TRUE(p == nullptr);
Elliott Hughesf0777842013-03-01 16:59:46 -0800328 ASSERT_EQ(EINVAL, errno);
329}
330
331TEST(stdlib, realpath__empty_filename) {
332 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700333 char* p = realpath("", nullptr);
334 ASSERT_TRUE(p == nullptr);
Elliott Hughesf0777842013-03-01 16:59:46 -0800335 ASSERT_EQ(ENOENT, errno);
336}
337
338TEST(stdlib, realpath__ENOENT) {
339 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700340 char* p = realpath("/this/directory/path/almost/certainly/does/not/exist", nullptr);
341 ASSERT_TRUE(p == nullptr);
Elliott Hughesf0777842013-03-01 16:59:46 -0800342 ASSERT_EQ(ENOENT, errno);
343}
344
Elliott Hughes31e072f2014-09-30 16:15:42 -0700345TEST(stdlib, realpath__component_after_non_directory) {
346 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700347 char* p = realpath("/dev/null/.", nullptr);
348 ASSERT_TRUE(p == nullptr);
Elliott Hughes31e072f2014-09-30 16:15:42 -0700349 ASSERT_EQ(ENOTDIR, errno);
350
351 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700352 p = realpath("/dev/null/..", nullptr);
353 ASSERT_TRUE(p == nullptr);
Elliott Hughes31e072f2014-09-30 16:15:42 -0700354 ASSERT_EQ(ENOTDIR, errno);
355}
356
Elliott Hughesf0777842013-03-01 16:59:46 -0800357TEST(stdlib, realpath) {
358 // Get the name of this executable.
359 char executable_path[PATH_MAX];
360 int rc = readlink("/proc/self/exe", executable_path, sizeof(executable_path));
361 ASSERT_NE(rc, -1);
362 executable_path[rc] = '\0';
363
364 char buf[PATH_MAX + 1];
365 char* p = realpath("/proc/self/exe", buf);
366 ASSERT_STREQ(executable_path, p);
367
Yi Kong32bc0fc2018-08-02 17:31:13 -0700368 p = realpath("/proc/self/exe", nullptr);
Elliott Hughesf0777842013-03-01 16:59:46 -0800369 ASSERT_STREQ(executable_path, p);
370 free(p);
371}
Elliott Hughes0b25f632013-04-11 18:08:34 -0700372
373TEST(stdlib, qsort) {
374 struct s {
375 char name[16];
376 static int comparator(const void* lhs, const void* rhs) {
377 return strcmp(reinterpret_cast<const s*>(lhs)->name, reinterpret_cast<const s*>(rhs)->name);
378 }
379 };
380 s entries[3];
381 strcpy(entries[0].name, "charlie");
382 strcpy(entries[1].name, "bravo");
383 strcpy(entries[2].name, "alpha");
384
385 qsort(entries, 3, sizeof(s), s::comparator);
386 ASSERT_STREQ("alpha", entries[0].name);
387 ASSERT_STREQ("bravo", entries[1].name);
388 ASSERT_STREQ("charlie", entries[2].name);
389
390 qsort(entries, 3, sizeof(s), s::comparator);
391 ASSERT_STREQ("alpha", entries[0].name);
392 ASSERT_STREQ("bravo", entries[1].name);
393 ASSERT_STREQ("charlie", entries[2].name);
394}
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800395
396static void* TestBug57421_child(void* arg) {
397 pthread_t main_thread = reinterpret_cast<pthread_t>(arg);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700398 pthread_join(main_thread, nullptr);
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800399 char* value = getenv("ENVIRONMENT_VARIABLE");
Yi Kong32bc0fc2018-08-02 17:31:13 -0700400 if (value == nullptr) {
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800401 setenv("ENVIRONMENT_VARIABLE", "value", 1);
402 }
Yi Kong32bc0fc2018-08-02 17:31:13 -0700403 return nullptr;
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800404}
405
406static void TestBug57421_main() {
407 pthread_t t;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700408 ASSERT_EQ(0, pthread_create(&t, nullptr, TestBug57421_child, reinterpret_cast<void*>(pthread_self())));
409 pthread_exit(nullptr);
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800410}
411
412// Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to
413// run this test (which exits normally) in its own process.
Yabin Cui9df70402014-11-05 18:01:01 -0800414
415class stdlib_DeathTest : public BionicDeathTest {};
416
417TEST_F(stdlib_DeathTest, getenv_after_main_thread_exits) {
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800418 // https://code.google.com/p/android/issues/detail?id=57421
Elliott Hughes877ec6d2013-11-15 17:40:18 -0800419 ASSERT_EXIT(TestBug57421_main(), ::testing::ExitedWithCode(0), "");
420}
Calin Juravlefe317a32014-02-21 15:11:03 +0000421
Elliott Hughes31165ed2014-09-23 17:34:29 -0700422TEST(stdlib, mkostemp64) {
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800423 MyTemporaryFile tf([](char* path) { return mkostemp64(path, O_CLOEXEC); });
Elliott Hughesa7f12942017-12-15 13:55:53 -0800424 AssertCloseOnExec(tf.fd, true);
Elliott Hughes31165ed2014-09-23 17:34:29 -0700425}
426
427TEST(stdlib, mkostemp) {
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800428 MyTemporaryFile tf([](char* path) { return mkostemp(path, O_CLOEXEC); });
Elliott Hughesa7f12942017-12-15 13:55:53 -0800429 AssertCloseOnExec(tf.fd, true);
Elliott Hughes31165ed2014-09-23 17:34:29 -0700430}
431
432TEST(stdlib, mkstemp64) {
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800433 MyTemporaryFile tf(mkstemp64);
Elliott Hughes31165ed2014-09-23 17:34:29 -0700434 struct stat64 sb;
435 ASSERT_EQ(0, fstat64(tf.fd, &sb));
436 ASSERT_EQ(O_LARGEFILE, fcntl(tf.fd, F_GETFL) & O_LARGEFILE);
437}
438
Calin Juravlefe317a32014-02-21 15:11:03 +0000439TEST(stdlib, mkstemp) {
Mark Salyzyn68a3bcc2018-11-13 07:35:21 -0800440 MyTemporaryFile tf(mkstemp);
Calin Juravlefe317a32014-02-21 15:11:03 +0000441 struct stat sb;
442 ASSERT_EQ(0, fstat(tf.fd, &sb));
443}
444
Elliott Hughes3cdf5732014-03-11 12:54:44 -0700445TEST(stdlib, system) {
446 int status;
447
448 status = system("exit 0");
449 ASSERT_TRUE(WIFEXITED(status));
450 ASSERT_EQ(0, WEXITSTATUS(status));
451
452 status = system("exit 1");
453 ASSERT_TRUE(WIFEXITED(status));
454 ASSERT_EQ(1, WEXITSTATUS(status));
455}
Elliott Hughes5a817382014-03-12 16:12:57 -0700456
457TEST(stdlib, atof) {
Christopher Ferrisf171b342014-03-17 16:40:26 -0700458 ASSERT_DOUBLE_EQ(1.23, atof("1.23"));
Elliott Hughes5a817382014-03-12 16:12:57 -0700459}
460
Elliott Hughes7f0849f2016-08-26 16:17:17 -0700461template <typename T>
462static void CheckStrToFloat(T fn(const char* s, char** end)) {
463 FpUlpEq<0, T> pred;
464
465 EXPECT_PRED_FORMAT2(pred, 9.0, fn("9.0", nullptr));
466 EXPECT_PRED_FORMAT2(pred, 9.0, fn("0.9e1", nullptr));
467 EXPECT_PRED_FORMAT2(pred, 9.0, fn("0x1.2p3", nullptr));
468
Dan Albertf6346552016-12-02 12:02:03 -0800469 const char* s = " \t\v\f\r\n9.0";
470 char* p;
471 EXPECT_PRED_FORMAT2(pred, 9.0, fn(s, &p));
472 EXPECT_EQ(s + strlen(s), p);
473
Elliott Hughes7f0849f2016-08-26 16:17:17 -0700474 EXPECT_TRUE(isnan(fn("+nan", nullptr)));
475 EXPECT_TRUE(isnan(fn("nan", nullptr)));
476 EXPECT_TRUE(isnan(fn("-nan", nullptr)));
477
478 EXPECT_TRUE(isnan(fn("+nan(0xff)", nullptr)));
479 EXPECT_TRUE(isnan(fn("nan(0xff)", nullptr)));
480 EXPECT_TRUE(isnan(fn("-nan(0xff)", nullptr)));
481
Elliott Hughes7f0849f2016-08-26 16:17:17 -0700482 EXPECT_TRUE(isnan(fn("+nanny", &p)));
483 EXPECT_STREQ("ny", p);
484 EXPECT_TRUE(isnan(fn("nanny", &p)));
485 EXPECT_STREQ("ny", p);
486 EXPECT_TRUE(isnan(fn("-nanny", &p)));
487 EXPECT_STREQ("ny", p);
488
489 EXPECT_EQ(0, fn("muppet", &p));
490 EXPECT_STREQ("muppet", p);
491 EXPECT_EQ(0, fn(" muppet", &p));
492 EXPECT_STREQ(" muppet", p);
493
494 EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("+inf", nullptr));
495 EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("inf", nullptr));
496 EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn("-inf", nullptr));
497
498 EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("+infinity", nullptr));
499 EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("infinity", nullptr));
500 EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn("-infinity", nullptr));
501
502 EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("+infinitude", &p));
503 EXPECT_STREQ("initude", p);
504 EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("infinitude", &p));
505 EXPECT_STREQ("initude", p);
506 EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn("-infinitude", &p));
507 EXPECT_STREQ("initude", p);
508
509 // Check case-insensitivity.
510 EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("InFiNiTy", nullptr));
511 EXPECT_TRUE(isnan(fn("NaN", nullptr)));
512}
513
Elliott Hughes5a817382014-03-12 16:12:57 -0700514TEST(stdlib, strtod) {
Elliott Hughes7f0849f2016-08-26 16:17:17 -0700515 CheckStrToFloat(strtod);
Elliott Hughes5a817382014-03-12 16:12:57 -0700516}
517
518TEST(stdlib, strtof) {
Elliott Hughes7f0849f2016-08-26 16:17:17 -0700519 CheckStrToFloat(strtof);
Elliott Hughes5a817382014-03-12 16:12:57 -0700520}
521
522TEST(stdlib, strtold) {
Elliott Hughes7f0849f2016-08-26 16:17:17 -0700523 CheckStrToFloat(strtold);
Elliott Hughes5a817382014-03-12 16:12:57 -0700524}
Elliott Hughes9f525642014-04-08 17:14:01 -0700525
Elliott Hughes89aaaff2014-10-28 17:54:23 -0700526TEST(stdlib, strtof_2206701) {
Yi Kong32bc0fc2018-08-02 17:31:13 -0700527 ASSERT_EQ(0.0f, strtof("7.0064923216240853546186479164495e-46", nullptr));
528 ASSERT_EQ(1.4e-45f, strtof("7.0064923216240853546186479164496e-46", nullptr));
Elliott Hughes89aaaff2014-10-28 17:54:23 -0700529}
530
531TEST(stdlib, strtod_largest_subnormal) {
532 // This value has been known to cause javac and java to infinite loop.
533 // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
Yi Kong32bc0fc2018-08-02 17:31:13 -0700534 ASSERT_EQ(2.2250738585072014e-308, strtod("2.2250738585072012e-308", nullptr));
535 ASSERT_EQ(2.2250738585072014e-308, strtod("0.00022250738585072012e-304", nullptr));
536 ASSERT_EQ(2.2250738585072014e-308, strtod("00000002.2250738585072012e-308", nullptr));
537 ASSERT_EQ(2.2250738585072014e-308, strtod("2.225073858507201200000e-308", nullptr));
538 ASSERT_EQ(2.2250738585072014e-308, strtod("2.2250738585072012e-00308", nullptr));
539 ASSERT_EQ(2.2250738585072014e-308, strtod("2.22507385850720129978001e-308", nullptr));
540 ASSERT_EQ(-2.2250738585072014e-308, strtod("-2.2250738585072012e-308", nullptr));
Elliott Hughes89aaaff2014-10-28 17:54:23 -0700541}
542
Dan Albertb8425c52014-04-29 17:49:06 -0700543TEST(stdlib, quick_exit) {
544 pid_t pid = fork();
545 ASSERT_NE(-1, pid) << strerror(errno);
546
547 if (pid == 0) {
548 quick_exit(99);
549 }
550
Elliott Hughes33697a02016-01-26 13:04:57 -0800551 AssertChildExited(pid, 99);
Dan Albertb8425c52014-04-29 17:49:06 -0700552}
553
554static int quick_exit_status = 0;
555
556static void quick_exit_1(void) {
557 ASSERT_EQ(quick_exit_status, 0);
558 quick_exit_status = 1;
559}
560
561static void quick_exit_2(void) {
562 ASSERT_EQ(quick_exit_status, 1);
563}
564
565static void not_run(void) {
566 FAIL();
567}
568
569TEST(stdlib, at_quick_exit) {
570 pid_t pid = fork();
571 ASSERT_NE(-1, pid) << strerror(errno);
572
573 if (pid == 0) {
574 ASSERT_EQ(at_quick_exit(quick_exit_2), 0);
575 ASSERT_EQ(at_quick_exit(quick_exit_1), 0);
576 atexit(not_run);
577 quick_exit(99);
578 }
579
Elliott Hughes33697a02016-01-26 13:04:57 -0800580 AssertChildExited(pid, 99);
Dan Albertb8425c52014-04-29 17:49:06 -0700581}
582
Elliott Hughes9f525642014-04-08 17:14:01 -0700583TEST(unistd, _Exit) {
Elliott Hughes33697a02016-01-26 13:04:57 -0800584 pid_t pid = fork();
Elliott Hughes9f525642014-04-08 17:14:01 -0700585 ASSERT_NE(-1, pid) << strerror(errno);
586
587 if (pid == 0) {
588 _Exit(99);
589 }
590
Elliott Hughes33697a02016-01-26 13:04:57 -0800591 AssertChildExited(pid, 99);
Elliott Hughes9f525642014-04-08 17:14:01 -0700592}
Elliott Hughes49167062014-07-25 17:24:00 -0700593
594TEST(stdlib, pty_smoke) {
595 // getpt returns a pty with O_RDWR|O_NOCTTY.
596 int fd = getpt();
597 ASSERT_NE(-1, fd);
598
599 // grantpt is a no-op.
600 ASSERT_EQ(0, grantpt(fd));
601
602 // ptsname_r should start "/dev/pts/".
603 char name_r[128];
604 ASSERT_EQ(0, ptsname_r(fd, name_r, sizeof(name_r)));
605 name_r[9] = 0;
606 ASSERT_STREQ("/dev/pts/", name_r);
607
608 close(fd);
609}
610
611TEST(stdlib, posix_openpt) {
612 int fd = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC);
613 ASSERT_NE(-1, fd);
614 close(fd);
615}
616
617TEST(stdlib, ptsname_r_ENOTTY) {
618 errno = 0;
619 char buf[128];
620 ASSERT_EQ(ENOTTY, ptsname_r(STDOUT_FILENO, buf, sizeof(buf)));
621 ASSERT_EQ(ENOTTY, errno);
622}
623
624TEST(stdlib, ptsname_r_EINVAL) {
625 int fd = getpt();
626 ASSERT_NE(-1, fd);
627 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700628 char* buf = nullptr;
Elliott Hughes49167062014-07-25 17:24:00 -0700629 ASSERT_EQ(EINVAL, ptsname_r(fd, buf, 128));
630 ASSERT_EQ(EINVAL, errno);
631 close(fd);
632}
633
634TEST(stdlib, ptsname_r_ERANGE) {
635 int fd = getpt();
636 ASSERT_NE(-1, fd);
637 errno = 0;
638 char buf[1];
639 ASSERT_EQ(ERANGE, ptsname_r(fd, buf, sizeof(buf)));
640 ASSERT_EQ(ERANGE, errno);
641 close(fd);
642}
643
Elliott Hughes728cde52017-11-08 21:53:50 -0800644TEST(stdlib, ttyname) {
645 int fd = getpt();
646 ASSERT_NE(-1, fd);
647
648 // ttyname returns "/dev/ptmx" for a pty.
649 ASSERT_STREQ("/dev/ptmx", ttyname(fd));
650
651 close(fd);
652}
653
Elliott Hughes49167062014-07-25 17:24:00 -0700654TEST(stdlib, ttyname_r) {
655 int fd = getpt();
656 ASSERT_NE(-1, fd);
657
658 // ttyname_r returns "/dev/ptmx" for a pty.
659 char name_r[128];
660 ASSERT_EQ(0, ttyname_r(fd, name_r, sizeof(name_r)));
661 ASSERT_STREQ("/dev/ptmx", name_r);
662
663 close(fd);
664}
665
666TEST(stdlib, ttyname_r_ENOTTY) {
667 int fd = open("/dev/null", O_WRONLY);
668 errno = 0;
669 char buf[128];
670 ASSERT_EQ(ENOTTY, ttyname_r(fd, buf, sizeof(buf)));
671 ASSERT_EQ(ENOTTY, errno);
672 close(fd);
673}
674
675TEST(stdlib, ttyname_r_EINVAL) {
676 int fd = getpt();
677 ASSERT_NE(-1, fd);
678 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700679 char* buf = nullptr;
Elliott Hughes49167062014-07-25 17:24:00 -0700680 ASSERT_EQ(EINVAL, ttyname_r(fd, buf, 128));
681 ASSERT_EQ(EINVAL, errno);
682 close(fd);
683}
684
685TEST(stdlib, ttyname_r_ERANGE) {
686 int fd = getpt();
687 ASSERT_NE(-1, fd);
688 errno = 0;
689 char buf[1];
690 ASSERT_EQ(ERANGE, ttyname_r(fd, buf, sizeof(buf)));
691 ASSERT_EQ(ERANGE, errno);
692 close(fd);
693}
694
695TEST(stdlib, unlockpt_ENOTTY) {
696 int fd = open("/dev/null", O_WRONLY);
697 errno = 0;
698 ASSERT_EQ(-1, unlockpt(fd));
699 ASSERT_EQ(ENOTTY, errno);
700 close(fd);
701}
Elliott Hughesb05ec5a2014-09-23 14:53:10 -0700702
Elliott Hughesdf143f82016-04-04 17:34:04 -0700703TEST(stdlib, getsubopt) {
704 char* const tokens[] = {
705 const_cast<char*>("a"),
706 const_cast<char*>("b"),
707 const_cast<char*>("foo"),
708 nullptr
709 };
710 std::string input = "a,b,foo=bar,a,unknown";
711 char* subopts = &input[0];
712 char* value = nullptr;
713
714 ASSERT_EQ(0, getsubopt(&subopts, tokens, &value));
715 ASSERT_EQ(nullptr, value);
716 ASSERT_EQ(1, getsubopt(&subopts, tokens, &value));
717 ASSERT_EQ(nullptr, value);
718 ASSERT_EQ(2, getsubopt(&subopts, tokens, &value));
719 ASSERT_STREQ("bar", value);
720 ASSERT_EQ(0, getsubopt(&subopts, tokens, &value));
721 ASSERT_EQ(nullptr, value);
722
723 ASSERT_EQ(-1, getsubopt(&subopts, tokens, &value));
724}
Elliott Hughes6f6f9052016-04-28 14:54:52 -0700725
726TEST(stdlib, mblen) {
727 // "If s is a null pointer, mblen() shall return a non-zero or 0 value, if character encodings,
728 // respectively, do or do not have state-dependent encodings." We're always UTF-8.
729 EXPECT_EQ(0, mblen(nullptr, 1));
730
731 ASSERT_STREQ("C.UTF-8", setlocale(LC_ALL, "C.UTF-8"));
732
733 // 1-byte UTF-8.
734 EXPECT_EQ(1, mblen("abcdef", 6));
735 // 2-byte UTF-8.
736 EXPECT_EQ(2, mblen("\xc2\xa2" "cdef", 6));
737 // 3-byte UTF-8.
738 EXPECT_EQ(3, mblen("\xe2\x82\xac" "def", 6));
739 // 4-byte UTF-8.
740 EXPECT_EQ(4, mblen("\xf0\xa4\xad\xa2" "ef", 6));
741
742 // Illegal over-long sequence.
743 ASSERT_EQ(-1, mblen("\xf0\x82\x82\xac" "ef", 6));
744
745 // "mblen() shall ... return 0 (if s points to the null byte)".
746 EXPECT_EQ(0, mblen("", 1));
747}
Elliott Hughesf826a372017-07-13 09:35:15 -0700748
749template <typename T>
750static void CheckStrToInt(T fn(const char* s, char** end, int base)) {
751 char* end_p;
752
753 // Negative base => invalid.
754 errno = 0;
755 ASSERT_EQ(T(0), fn("123", &end_p, -1));
756 ASSERT_EQ(EINVAL, errno);
757
758 // Base 1 => invalid (base 0 means "please guess").
759 errno = 0;
760 ASSERT_EQ(T(0), fn("123", &end_p, 1));
761 ASSERT_EQ(EINVAL, errno);
762
763 // Base > 36 => invalid.
764 errno = 0;
765 ASSERT_EQ(T(0), fn("123", &end_p, 37));
766 ASSERT_EQ(EINVAL, errno);
767
768 // If we see "0x" *not* followed by a hex digit, we shouldn't swallow the 'x'.
769 ASSERT_EQ(T(0), fn("0xy", &end_p, 16));
770 ASSERT_EQ('x', *end_p);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800771
772 if (std::numeric_limits<T>::is_signed) {
773 // Minimum (such as -128).
Elliott Hughesf61a06e2017-12-19 16:11:37 -0800774 std::string min{std::to_string(std::numeric_limits<T>::min())};
Elliott Hughescb239bd2017-12-20 17:37:11 -0800775 end_p = nullptr;
776 errno = 0;
Elliott Hughes1921dce2017-12-19 10:27:27 -0800777 ASSERT_EQ(std::numeric_limits<T>::min(), fn(min.c_str(), &end_p, 0));
Elliott Hughescb239bd2017-12-20 17:37:11 -0800778 ASSERT_EQ(0, errno);
779 ASSERT_EQ('\0', *end_p);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800780 // Too negative (such as -129).
781 min.back() = (min.back() + 1);
Elliott Hughescb239bd2017-12-20 17:37:11 -0800782 end_p = nullptr;
Elliott Hughes1921dce2017-12-19 10:27:27 -0800783 errno = 0;
784 ASSERT_EQ(std::numeric_limits<T>::min(), fn(min.c_str(), &end_p, 0));
785 ASSERT_EQ(ERANGE, errno);
Elliott Hughescb239bd2017-12-20 17:37:11 -0800786 ASSERT_EQ('\0', *end_p);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800787 }
788
789 // Maximum (such as 127).
Elliott Hughesf61a06e2017-12-19 16:11:37 -0800790 std::string max{std::to_string(std::numeric_limits<T>::max())};
Elliott Hughescb239bd2017-12-20 17:37:11 -0800791 end_p = nullptr;
792 errno = 0;
Elliott Hughes1921dce2017-12-19 10:27:27 -0800793 ASSERT_EQ(std::numeric_limits<T>::max(), fn(max.c_str(), &end_p, 0));
Elliott Hughescb239bd2017-12-20 17:37:11 -0800794 ASSERT_EQ(0, errno);
795 ASSERT_EQ('\0', *end_p);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800796 // Too positive (such as 128).
797 max.back() = (max.back() + 1);
Elliott Hughescb239bd2017-12-20 17:37:11 -0800798 end_p = nullptr;
Elliott Hughes1921dce2017-12-19 10:27:27 -0800799 errno = 0;
800 ASSERT_EQ(std::numeric_limits<T>::max(), fn(max.c_str(), &end_p, 0));
801 ASSERT_EQ(ERANGE, errno);
Elliott Hughescb239bd2017-12-20 17:37:11 -0800802 ASSERT_EQ('\0', *end_p);
803
804 // In case of overflow, strto* leaves us pointing past the end of the number,
805 // not at the digit that overflowed.
806 end_p = nullptr;
807 errno = 0;
808 ASSERT_EQ(std::numeric_limits<T>::max(),
809 fn("99999999999999999999999999999999999999999999999999999abc", &end_p, 0));
810 ASSERT_EQ(ERANGE, errno);
811 ASSERT_STREQ("abc", end_p);
812 if (std::numeric_limits<T>::is_signed) {
813 end_p = nullptr;
814 errno = 0;
815 ASSERT_EQ(std::numeric_limits<T>::min(),
816 fn("-99999999999999999999999999999999999999999999999999999abc", &end_p, 0));
817 ASSERT_EQ(ERANGE, errno);
818 ASSERT_STREQ("abc", end_p);
819 }
Elliott Hughesf826a372017-07-13 09:35:15 -0700820}
821
822TEST(stdlib, strtol_smoke) {
823 CheckStrToInt(strtol);
824}
825
826TEST(stdlib, strtoll_smoke) {
827 CheckStrToInt(strtoll);
828}
829
830TEST(stdlib, strtoul_smoke) {
831 CheckStrToInt(strtoul);
832}
833
834TEST(stdlib, strtoull_smoke) {
835 CheckStrToInt(strtoull);
836}
837
838TEST(stdlib, strtoimax_smoke) {
839 CheckStrToInt(strtoimax);
840}
841
842TEST(stdlib, strtoumax_smoke) {
843 CheckStrToInt(strtoumax);
844}
Elliott Hughes00d8a8b2017-09-07 16:42:13 -0700845
846TEST(stdlib, abs) {
847 ASSERT_EQ(INT_MAX, abs(-INT_MAX));
848 ASSERT_EQ(INT_MAX, abs(INT_MAX));
849}
850
851TEST(stdlib, labs) {
852 ASSERT_EQ(LONG_MAX, labs(-LONG_MAX));
853 ASSERT_EQ(LONG_MAX, labs(LONG_MAX));
854}
855
856TEST(stdlib, llabs) {
857 ASSERT_EQ(LLONG_MAX, llabs(-LLONG_MAX));
858 ASSERT_EQ(LLONG_MAX, llabs(LLONG_MAX));
859}
Elliott Hughes2d0b28b2018-10-23 11:23:00 -0700860
861TEST(stdlib, getloadavg) {
862 double load[3];
863
864 // The second argument should have been size_t.
865 ASSERT_EQ(-1, getloadavg(load, -1));
866 ASSERT_EQ(-1, getloadavg(load, INT_MIN));
867
868 // Zero is a no-op.
869 ASSERT_EQ(0, getloadavg(load, 0));
870
871 // The Linux kernel doesn't support more than 3 (but you can ask for fewer).
872 ASSERT_EQ(1, getloadavg(load, 1));
873 ASSERT_EQ(2, getloadavg(load, 2));
874 ASSERT_EQ(3, getloadavg(load, 3));
875 ASSERT_EQ(3, getloadavg(load, 4));
876 ASSERT_EQ(3, getloadavg(load, INT_MAX));
877
878 // Read /proc/loadavg and check that it's "close enough".
879 load[0] = nan("");
880 double expected[3];
881 std::unique_ptr<FILE, decltype(&fclose)> fp{fopen("/proc/loadavg", "re"), fclose};
882 ASSERT_EQ(3, fscanf(fp.get(), "%lf %lf %lf", &expected[0], &expected[1], &expected[2]));
883 ASSERT_EQ(3, getloadavg(load, 3));
884
885 // It's probably too flaky if we look at the 1-minute average, so we just place a NaN there
886 // and check that it's overwritten with _something_.
887 ASSERT_FALSE(isnan(load[0]));
888 // For the others, rounding to an integer is pessimistic but at least gives us a sanity check.
889 ASSERT_DOUBLE_EQ(rint(expected[1]), rint(load[1]));
890 ASSERT_DOUBLE_EQ(rint(expected[2]), rint(load[2]));
891}