• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <errno.h>
18 #include <fcntl.h>
19 #include <libgen.h>
20 #include <limits.h>
21 #include <math.h>
22 #include <pthread.h>
23 #include <stdint.h>
24 #include <stdlib.h>
25 #include <sys/types.h>
26 #include <sys/wait.h>
27 #include <unistd.h>
28 
29 #include <limits>
30 #include <string>
31 
32 #include <android-base/macros.h>
33 #include <gtest/gtest.h>
34 
35 #include "BionicDeathTest.h"
36 #include "math_data_test.h"
37 #include "utils.h"
38 
39 template <typename T = int (*)(char*)>
40 class GenericTemporaryFile {
41  public:
GenericTemporaryFile(T mk_fn=mkstemp)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 
~GenericTemporaryFile()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 
init(const char * tmp_dir)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 
72 typedef GenericTemporaryFile<> MyTemporaryFile;
73 
74 // 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 
TEST(stdlib,drand48)79 TEST(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());
85   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 
TEST(stdlib,erand48)93 TEST(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 
TEST(stdlib,lcong48)109 TEST(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());
122 }
123 
TEST(stdlib,lrand48)124 TEST(stdlib, lrand48) {
125   srand48(0x01020304);
126   EXPECT_EQ(1409163720, lrand48());
127   EXPECT_EQ(397769746, lrand48());
128   EXPECT_EQ(902267124, lrand48());
129   EXPECT_EQ(132366131, lrand48());
130   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());
136 }
137 
TEST(stdlib,random)138 TEST(stdlib, random) {
139   srandom(0x01020304);
140   EXPECT_EQ(55436735, random());
141   EXPECT_EQ(1399865117, random());
142   EXPECT_EQ(2032643283, random());
143   EXPECT_EQ(571329216, random());
144   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());
150 }
151 
TEST(stdlib,rand)152 TEST(stdlib, rand) {
153   srand(0x01020304);
154   EXPECT_EQ(55436735, rand());
155   EXPECT_EQ(1399865117, rand());
156   EXPECT_EQ(2032643283, rand());
157   EXPECT_EQ(571329216, rand());
158   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());
164 }
165 
TEST(stdlib,mrand48)166 TEST(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());
172   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());
178 }
179 
TEST(stdlib,jrand48_distribution)180 TEST(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 
TEST(stdlib,mrand48_distribution)201 TEST(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 
TEST(stdlib,posix_memalign_sweep)221 TEST(stdlib, posix_memalign_sweep) {
222   SKIP_WITH_HWASAN;
223   void* ptr;
224 
225   // 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   }
230 
231   // 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 
TEST(stdlib,posix_memalign_various_sizes)249 TEST(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 
TEST(stdlib,posix_memalign_overflow)261 TEST(stdlib, posix_memalign_overflow) {
262   SKIP_WITH_HWASAN;
263   void* ptr;
264   ASSERT_NE(0, posix_memalign(&ptr, 16, SIZE_MAX));
265 }
266 
TEST(stdlib,aligned_alloc_sweep)267 TEST(stdlib, aligned_alloc_sweep) {
268   SKIP_WITH_HWASAN;
269   // 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++) {
275       ASSERT_TRUE(aligned_alloc(fail_align, fail_align) == nullptr)
276           << "Unexpected success at align " << fail_align;
277       ASSERT_EQ(EINVAL, errno) << "Unexpected errno at align " << fail_align;
278     }
279     void* ptr = aligned_alloc(align, 2 * align);
280     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   }
286 }
287 
TEST(stdlib,aligned_alloc_overflow)288 TEST(stdlib, aligned_alloc_overflow) {
289   SKIP_WITH_HWASAN;
290   ASSERT_TRUE(aligned_alloc(16, SIZE_MAX) == nullptr);
291 }
292 
TEST(stdlib,aligned_alloc_size_not_multiple_of_alignment)293 TEST(stdlib, aligned_alloc_size_not_multiple_of_alignment) {
294   SKIP_WITH_HWASAN;
295 
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);
300 }
301 
TEST(stdlib,realpath__NULL_filename)302 TEST(stdlib, realpath__NULL_filename) {
303   errno = 0;
304   // Work around the compile-time error generated by FORTIFY here.
305   const char* path = nullptr;
306   char* p = realpath(path, nullptr);
307   ASSERT_TRUE(p == nullptr);
308   ASSERT_EQ(EINVAL, errno);
309 }
310 
TEST(stdlib,realpath__empty_filename)311 TEST(stdlib, realpath__empty_filename) {
312   errno = 0;
313   char* p = realpath("", nullptr);
314   ASSERT_TRUE(p == nullptr);
315   ASSERT_EQ(ENOENT, errno);
316 }
317 
TEST(stdlib,realpath__ENOENT)318 TEST(stdlib, realpath__ENOENT) {
319   errno = 0;
320   char* p = realpath("/this/directory/path/almost/certainly/does/not/exist", nullptr);
321   ASSERT_TRUE(p == nullptr);
322   ASSERT_EQ(ENOENT, errno);
323 }
324 
TEST(stdlib,realpath__component_after_non_directory)325 TEST(stdlib, realpath__component_after_non_directory) {
326   errno = 0;
327   char* p = realpath("/dev/null/.", nullptr);
328   ASSERT_TRUE(p == nullptr);
329   ASSERT_EQ(ENOTDIR, errno);
330 
331   errno = 0;
332   p = realpath("/dev/null/..", nullptr);
333   ASSERT_TRUE(p == nullptr);
334   ASSERT_EQ(ENOTDIR, errno);
335 }
336 
TEST(stdlib,realpath)337 TEST(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 
348   p = realpath("/proc/self/exe", nullptr);
349   ASSERT_STREQ(executable_path, p);
350   free(p);
351 }
352 
TEST(stdlib,qsort)353 TEST(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 }
375 
TestBug57421_child(void * arg)376 static void* TestBug57421_child(void* arg) {
377   pthread_t main_thread = reinterpret_cast<pthread_t>(arg);
378   pthread_join(main_thread, nullptr);
379   char* value = getenv("ENVIRONMENT_VARIABLE");
380   if (value == nullptr) {
381     setenv("ENVIRONMENT_VARIABLE", "value", 1);
382   }
383   return nullptr;
384 }
385 
TestBug57421_main()386 static void TestBug57421_main() {
387   pthread_t t;
388   ASSERT_EQ(0, pthread_create(&t, nullptr, TestBug57421_child, reinterpret_cast<void*>(pthread_self())));
389   pthread_exit(nullptr);
390 }
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.
394 
395 class stdlib_DeathTest : public BionicDeathTest {};
396 
TEST_F(stdlib_DeathTest,getenv_after_main_thread_exits)397 TEST_F(stdlib_DeathTest, getenv_after_main_thread_exits) {
398   // https://code.google.com/p/android/issues/detail?id=57421
399   ASSERT_EXIT(TestBug57421_main(), ::testing::ExitedWithCode(0), "");
400 }
401 
TEST(stdlib,mkostemp64)402 TEST(stdlib, mkostemp64) {
403   MyTemporaryFile tf([](char* path) { return mkostemp64(path, O_CLOEXEC); });
404   AssertCloseOnExec(tf.fd, true);
405 }
406 
TEST(stdlib,mkostemp)407 TEST(stdlib, mkostemp) {
408   MyTemporaryFile tf([](char* path) { return mkostemp(path, O_CLOEXEC); });
409   AssertCloseOnExec(tf.fd, true);
410 }
411 
TEST(stdlib,mkstemp64)412 TEST(stdlib, mkstemp64) {
413   MyTemporaryFile tf(mkstemp64);
414   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 
TEST(stdlib,mkstemp)419 TEST(stdlib, mkstemp) {
420   MyTemporaryFile tf(mkstemp);
421   struct stat sb;
422   ASSERT_EQ(0, fstat(tf.fd, &sb));
423 }
424 
TEST(stdlib,system)425 TEST(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 }
436 
TEST(stdlib,atof)437 TEST(stdlib, atof) {
438   ASSERT_DOUBLE_EQ(1.23, atof("1.23"));
439 }
440 
441 template <typename T>
CheckStrToFloat(T fn (const char * s,char ** end))442 static 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 
449   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 
454   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 
462   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 
TEST(stdlib,strtod)494 TEST(stdlib, strtod) {
495   CheckStrToFloat(strtod);
496 }
497 
TEST(stdlib,strtof)498 TEST(stdlib, strtof) {
499   CheckStrToFloat(strtof);
500 }
501 
TEST(stdlib,strtold)502 TEST(stdlib, strtold) {
503   CheckStrToFloat(strtold);
504 }
505 
TEST(stdlib,strtof_2206701)506 TEST(stdlib, strtof_2206701) {
507   ASSERT_EQ(0.0f, strtof("7.0064923216240853546186479164495e-46", nullptr));
508   ASSERT_EQ(1.4e-45f, strtof("7.0064923216240853546186479164496e-46", nullptr));
509 }
510 
TEST(stdlib,strtod_largest_subnormal)511 TEST(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/
514   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));
521 }
522 
TEST(stdlib,quick_exit)523 TEST(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 
531   AssertChildExited(pid, 99);
532 }
533 
534 static int quick_exit_status = 0;
535 
quick_exit_1(void)536 static void quick_exit_1(void) {
537   ASSERT_EQ(quick_exit_status, 0);
538   quick_exit_status = 1;
539 }
540 
quick_exit_2(void)541 static void quick_exit_2(void) {
542   ASSERT_EQ(quick_exit_status, 1);
543 }
544 
not_run(void)545 static void not_run(void) {
546   FAIL();
547 }
548 
TEST(stdlib,at_quick_exit)549 TEST(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 
560   AssertChildExited(pid, 99);
561 }
562 
TEST(unistd,_Exit)563 TEST(unistd, _Exit) {
564   pid_t pid = fork();
565   ASSERT_NE(-1, pid) << strerror(errno);
566 
567   if (pid == 0) {
568     _Exit(99);
569   }
570 
571   AssertChildExited(pid, 99);
572 }
573 
TEST(stdlib,pty_smoke)574 TEST(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 
TEST(stdlib,posix_openpt)591 TEST(stdlib, posix_openpt) {
592   int fd = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC);
593   ASSERT_NE(-1, fd);
594   close(fd);
595 }
596 
TEST(stdlib,ptsname_r_ENOTTY)597 TEST(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 
TEST(stdlib,ptsname_r_EINVAL)604 TEST(stdlib, ptsname_r_EINVAL) {
605   int fd = getpt();
606   ASSERT_NE(-1, fd);
607   errno = 0;
608   char* buf = nullptr;
609   ASSERT_EQ(EINVAL, ptsname_r(fd, buf, 128));
610   ASSERT_EQ(EINVAL, errno);
611   close(fd);
612 }
613 
TEST(stdlib,ptsname_r_ERANGE)614 TEST(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 
TEST(stdlib,ttyname)624 TEST(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 
TEST(stdlib,ttyname_r)634 TEST(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 
TEST(stdlib,ttyname_r_ENOTTY)646 TEST(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 
TEST(stdlib,ttyname_r_EINVAL)655 TEST(stdlib, ttyname_r_EINVAL) {
656   int fd = getpt();
657   ASSERT_NE(-1, fd);
658   errno = 0;
659   char* buf = nullptr;
660   ASSERT_EQ(EINVAL, ttyname_r(fd, buf, 128));
661   ASSERT_EQ(EINVAL, errno);
662   close(fd);
663 }
664 
TEST(stdlib,ttyname_r_ERANGE)665 TEST(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 
TEST(stdlib,unlockpt_ENOTTY)675 TEST(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 }
682 
TEST(stdlib,getsubopt)683 TEST(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 }
705 
TEST(stdlib,mblen)706 TEST(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 }
728 
729 template <typename T>
CheckStrToInt(T fn (const char * s,char ** end,int base))730 static 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);
751 
752   if (std::numeric_limits<T>::is_signed) {
753     // Minimum (such as -128).
754     std::string min{std::to_string(std::numeric_limits<T>::min())};
755     end_p = nullptr;
756     errno = 0;
757     ASSERT_EQ(std::numeric_limits<T>::min(), fn(min.c_str(), &end_p, 0));
758     ASSERT_EQ(0, errno);
759     ASSERT_EQ('\0', *end_p);
760     // Too negative (such as -129).
761     min.back() = (min.back() + 1);
762     end_p = nullptr;
763     errno = 0;
764     ASSERT_EQ(std::numeric_limits<T>::min(), fn(min.c_str(), &end_p, 0));
765     ASSERT_EQ(ERANGE, errno);
766     ASSERT_EQ('\0', *end_p);
767   }
768 
769   // Maximum (such as 127).
770   std::string max{std::to_string(std::numeric_limits<T>::max())};
771   end_p = nullptr;
772   errno = 0;
773   ASSERT_EQ(std::numeric_limits<T>::max(), fn(max.c_str(), &end_p, 0));
774   ASSERT_EQ(0, errno);
775   ASSERT_EQ('\0', *end_p);
776   // Too positive (such as 128).
777   max.back() = (max.back() + 1);
778   end_p = nullptr;
779   errno = 0;
780   ASSERT_EQ(std::numeric_limits<T>::max(), fn(max.c_str(), &end_p, 0));
781   ASSERT_EQ(ERANGE, errno);
782   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   }
800 }
801 
TEST(stdlib,strtol_smoke)802 TEST(stdlib, strtol_smoke) {
803   CheckStrToInt(strtol);
804 }
805 
TEST(stdlib,strtoll_smoke)806 TEST(stdlib, strtoll_smoke) {
807   CheckStrToInt(strtoll);
808 }
809 
TEST(stdlib,strtoul_smoke)810 TEST(stdlib, strtoul_smoke) {
811   CheckStrToInt(strtoul);
812 }
813 
TEST(stdlib,strtoull_smoke)814 TEST(stdlib, strtoull_smoke) {
815   CheckStrToInt(strtoull);
816 }
817 
TEST(stdlib,strtoimax_smoke)818 TEST(stdlib, strtoimax_smoke) {
819   CheckStrToInt(strtoimax);
820 }
821 
TEST(stdlib,strtoumax_smoke)822 TEST(stdlib, strtoumax_smoke) {
823   CheckStrToInt(strtoumax);
824 }
825 
TEST(stdlib,abs)826 TEST(stdlib, abs) {
827   ASSERT_EQ(INT_MAX, abs(-INT_MAX));
828   ASSERT_EQ(INT_MAX, abs(INT_MAX));
829 }
830 
TEST(stdlib,labs)831 TEST(stdlib, labs) {
832   ASSERT_EQ(LONG_MAX, labs(-LONG_MAX));
833   ASSERT_EQ(LONG_MAX, labs(LONG_MAX));
834 }
835 
TEST(stdlib,llabs)836 TEST(stdlib, llabs) {
837   ASSERT_EQ(LLONG_MAX, llabs(-LLONG_MAX));
838   ASSERT_EQ(LLONG_MAX, llabs(LLONG_MAX));
839 }
840 
TEST(stdlib,getloadavg)841 TEST(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".
859   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]));
862   load[0] = load[1] = load[2] = nan("");
863   ASSERT_EQ(3, getloadavg(load, 3));
864 
865   // Check that getloadavg(3) at least overwrote the NaNs.
866   ASSERT_FALSE(isnan(load[0]));
867   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];
873 }
874