Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <gtest/gtest.h>
     18 
     19 #include "BionicDeathTest.h"
     20 #include "math_data_test.h"
     21 #include "TemporaryFile.h"
     22 #include "utils.h"
     23 
     24 #include <errno.h>
     25 #include <fcntl.h>
     26 #include <libgen.h>
     27 #include <limits.h>
     28 #include <math.h>
     29 #include <pthread.h>
     30 #include <stdint.h>
     31 #include <stdlib.h>
     32 #include <sys/types.h>
     33 #include <sys/wait.h>
     34 
     35 // The random number generator tests all set the seed, get four values, reset the seed and check
     36 // that they get the first two values repeated, and then reset the seed and check two more values
     37 // to rule out the possibility that we're just going round a cycle of four values.
     38 // TODO: factor this out.
     39 
     40 TEST(stdlib, drand48) {
     41   srand48(0x01020304);
     42   EXPECT_DOUBLE_EQ(0.65619299195623526, drand48());
     43   EXPECT_DOUBLE_EQ(0.18522597229772941, drand48());
     44   EXPECT_DOUBLE_EQ(0.42015087072844537, drand48());
     45   EXPECT_DOUBLE_EQ(0.061637783047395089, drand48());
     46   srand48(0x01020304);
     47   EXPECT_DOUBLE_EQ(0.65619299195623526, drand48());
     48   EXPECT_DOUBLE_EQ(0.18522597229772941, drand48());
     49   srand48(0x01020304);
     50   EXPECT_DOUBLE_EQ(0.65619299195623526, drand48());
     51   EXPECT_DOUBLE_EQ(0.18522597229772941, drand48());
     52 }
     53 
     54 TEST(stdlib, erand48) {
     55   const unsigned short seed[3] = { 0x330e, 0xabcd, 0x1234 };
     56   unsigned short xsubi[3];
     57   memcpy(xsubi, seed, sizeof(seed));
     58   EXPECT_DOUBLE_EQ(0.39646477376027534, erand48(xsubi));
     59   EXPECT_DOUBLE_EQ(0.84048536941142515, erand48(xsubi));
     60   EXPECT_DOUBLE_EQ(0.35333609724524351, erand48(xsubi));
     61   EXPECT_DOUBLE_EQ(0.44658343479654405, erand48(xsubi));
     62   memcpy(xsubi, seed, sizeof(seed));
     63   EXPECT_DOUBLE_EQ(0.39646477376027534, erand48(xsubi));
     64   EXPECT_DOUBLE_EQ(0.84048536941142515, erand48(xsubi));
     65   memcpy(xsubi, seed, sizeof(seed));
     66   EXPECT_DOUBLE_EQ(0.39646477376027534, erand48(xsubi));
     67   EXPECT_DOUBLE_EQ(0.84048536941142515, erand48(xsubi));
     68 }
     69 
     70 TEST(stdlib, lcong48) {
     71   unsigned short p[7] = { 0x0102, 0x0304, 0x0506, 0x0708, 0x090a, 0x0b0c, 0x0d0e };
     72   lcong48(p);
     73   EXPECT_EQ(1531389981, lrand48());
     74   EXPECT_EQ(1598801533, lrand48());
     75   EXPECT_EQ(2080534853, lrand48());
     76   EXPECT_EQ(1102488897, lrand48());
     77   lcong48(p);
     78   EXPECT_EQ(1531389981, lrand48());
     79   EXPECT_EQ(1598801533, lrand48());
     80   lcong48(p);
     81   EXPECT_EQ(1531389981, lrand48());
     82   EXPECT_EQ(1598801533, lrand48());
     83 }
     84 
     85 TEST(stdlib, lrand48) {
     86   srand48(0x01020304);
     87   EXPECT_EQ(1409163720, lrand48());
     88   EXPECT_EQ(397769746, lrand48());
     89   EXPECT_EQ(902267124, lrand48());
     90   EXPECT_EQ(132366131, lrand48());
     91   srand48(0x01020304);
     92   EXPECT_EQ(1409163720, lrand48());
     93   EXPECT_EQ(397769746, lrand48());
     94   srand48(0x01020304);
     95   EXPECT_EQ(1409163720, lrand48());
     96   EXPECT_EQ(397769746, lrand48());
     97 }
     98 
     99 TEST(stdlib, random) {
    100   srandom(0x01020304);
    101   EXPECT_EQ(55436735, random());
    102   EXPECT_EQ(1399865117, random());
    103   EXPECT_EQ(2032643283, random());
    104   EXPECT_EQ(571329216, random());
    105   srandom(0x01020304);
    106   EXPECT_EQ(55436735, random());
    107   EXPECT_EQ(1399865117, random());
    108   srandom(0x01020304);
    109   EXPECT_EQ(55436735, random());
    110   EXPECT_EQ(1399865117, random());
    111 }
    112 
    113 TEST(stdlib, rand) {
    114   srand(0x01020304);
    115   EXPECT_EQ(55436735, rand());
    116   EXPECT_EQ(1399865117, rand());
    117   EXPECT_EQ(2032643283, rand());
    118   EXPECT_EQ(571329216, rand());
    119   srand(0x01020304);
    120   EXPECT_EQ(55436735, rand());
    121   EXPECT_EQ(1399865117, rand());
    122   srand(0x01020304);
    123   EXPECT_EQ(55436735, rand());
    124   EXPECT_EQ(1399865117, rand());
    125 }
    126 
    127 TEST(stdlib, mrand48) {
    128   srand48(0x01020304);
    129   EXPECT_EQ(-1476639856, mrand48());
    130   EXPECT_EQ(795539493, mrand48());
    131   EXPECT_EQ(1804534249, mrand48());
    132   EXPECT_EQ(264732262, mrand48());
    133   srand48(0x01020304);
    134   EXPECT_EQ(-1476639856, mrand48());
    135   EXPECT_EQ(795539493, mrand48());
    136   srand48(0x01020304);
    137   EXPECT_EQ(-1476639856, mrand48());
    138   EXPECT_EQ(795539493, mrand48());
    139 }
    140 
    141 TEST(stdlib, posix_memalign) {
    142   void* p;
    143 
    144   ASSERT_EQ(0, posix_memalign(&p, 512, 128));
    145   ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(p) % 512);
    146   free(p);
    147 
    148   // Can't align to a non-power of 2.
    149   ASSERT_EQ(EINVAL, posix_memalign(&p, 81, 128));
    150 }
    151 
    152 TEST(stdlib, realpath__NULL_filename) {
    153   errno = 0;
    154   char* p = realpath(NULL, NULL);
    155   ASSERT_TRUE(p == NULL);
    156   ASSERT_EQ(EINVAL, errno);
    157 }
    158 
    159 TEST(stdlib, realpath__empty_filename) {
    160   errno = 0;
    161   char* p = realpath("", NULL);
    162   ASSERT_TRUE(p == NULL);
    163   ASSERT_EQ(ENOENT, errno);
    164 }
    165 
    166 TEST(stdlib, realpath__ENOENT) {
    167   errno = 0;
    168   char* p = realpath("/this/directory/path/almost/certainly/does/not/exist", NULL);
    169   ASSERT_TRUE(p == NULL);
    170   ASSERT_EQ(ENOENT, errno);
    171 }
    172 
    173 TEST(stdlib, realpath__component_after_non_directory) {
    174   errno = 0;
    175   char* p = realpath("/dev/null/.", NULL);
    176   ASSERT_TRUE(p == NULL);
    177   ASSERT_EQ(ENOTDIR, errno);
    178 
    179   errno = 0;
    180   p = realpath("/dev/null/..", NULL);
    181   ASSERT_TRUE(p == NULL);
    182   ASSERT_EQ(ENOTDIR, errno);
    183 }
    184 
    185 TEST(stdlib, realpath) {
    186   // Get the name of this executable.
    187   char executable_path[PATH_MAX];
    188   int rc = readlink("/proc/self/exe", executable_path, sizeof(executable_path));
    189   ASSERT_NE(rc, -1);
    190   executable_path[rc] = '\0';
    191 
    192   char buf[PATH_MAX + 1];
    193   char* p = realpath("/proc/self/exe", buf);
    194   ASSERT_STREQ(executable_path, p);
    195 
    196   p = realpath("/proc/self/exe", NULL);
    197   ASSERT_STREQ(executable_path, p);
    198   free(p);
    199 }
    200 
    201 TEST(stdlib, qsort) {
    202   struct s {
    203     char name[16];
    204     static int comparator(const void* lhs, const void* rhs) {
    205       return strcmp(reinterpret_cast<const s*>(lhs)->name, reinterpret_cast<const s*>(rhs)->name);
    206     }
    207   };
    208   s entries[3];
    209   strcpy(entries[0].name, "charlie");
    210   strcpy(entries[1].name, "bravo");
    211   strcpy(entries[2].name, "alpha");
    212 
    213   qsort(entries, 3, sizeof(s), s::comparator);
    214   ASSERT_STREQ("alpha", entries[0].name);
    215   ASSERT_STREQ("bravo", entries[1].name);
    216   ASSERT_STREQ("charlie", entries[2].name);
    217 
    218   qsort(entries, 3, sizeof(s), s::comparator);
    219   ASSERT_STREQ("alpha", entries[0].name);
    220   ASSERT_STREQ("bravo", entries[1].name);
    221   ASSERT_STREQ("charlie", entries[2].name);
    222 }
    223 
    224 static void* TestBug57421_child(void* arg) {
    225   pthread_t main_thread = reinterpret_cast<pthread_t>(arg);
    226   pthread_join(main_thread, NULL);
    227   char* value = getenv("ENVIRONMENT_VARIABLE");
    228   if (value == NULL) {
    229     setenv("ENVIRONMENT_VARIABLE", "value", 1);
    230   }
    231   return NULL;
    232 }
    233 
    234 static void TestBug57421_main() {
    235   pthread_t t;
    236   ASSERT_EQ(0, pthread_create(&t, NULL, TestBug57421_child, reinterpret_cast<void*>(pthread_self())));
    237   pthread_exit(NULL);
    238 }
    239 
    240 // Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to
    241 // run this test (which exits normally) in its own process.
    242 
    243 class stdlib_DeathTest : public BionicDeathTest {};
    244 
    245 TEST_F(stdlib_DeathTest, getenv_after_main_thread_exits) {
    246   // https://code.google.com/p/android/issues/detail?id=57421
    247   ASSERT_EXIT(TestBug57421_main(), ::testing::ExitedWithCode(0), "");
    248 }
    249 
    250 TEST(stdlib, mkostemp64) {
    251   TemporaryFile tf([](char* path) { return mkostemp64(path, O_CLOEXEC); });
    252   int flags = fcntl(tf.fd, F_GETFD);
    253   ASSERT_TRUE(flags != -1);
    254   ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC);
    255 }
    256 
    257 TEST(stdlib, mkostemp) {
    258   TemporaryFile tf([](char* path) { return mkostemp(path, O_CLOEXEC); });
    259   int flags = fcntl(tf.fd, F_GETFD);
    260   ASSERT_TRUE(flags != -1);
    261   ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC);
    262 }
    263 
    264 TEST(stdlib, mkstemp64) {
    265   TemporaryFile tf(mkstemp64);
    266   struct stat64 sb;
    267   ASSERT_EQ(0, fstat64(tf.fd, &sb));
    268   ASSERT_EQ(O_LARGEFILE, fcntl(tf.fd, F_GETFL) & O_LARGEFILE);
    269 }
    270 
    271 TEST(stdlib, mkstemp) {
    272   TemporaryFile tf;
    273   struct stat sb;
    274   ASSERT_EQ(0, fstat(tf.fd, &sb));
    275 }
    276 
    277 TEST(stdlib, system) {
    278   int status;
    279 
    280   status = system("exit 0");
    281   ASSERT_TRUE(WIFEXITED(status));
    282   ASSERT_EQ(0, WEXITSTATUS(status));
    283 
    284   status = system("exit 1");
    285   ASSERT_TRUE(WIFEXITED(status));
    286   ASSERT_EQ(1, WEXITSTATUS(status));
    287 }
    288 
    289 TEST(stdlib, atof) {
    290   ASSERT_DOUBLE_EQ(1.23, atof("1.23"));
    291 }
    292 
    293 template <typename T>
    294 static void CheckStrToFloat(T fn(const char* s, char** end)) {
    295   FpUlpEq<0, T> pred;
    296 
    297   EXPECT_PRED_FORMAT2(pred, 9.0, fn("9.0", nullptr));
    298   EXPECT_PRED_FORMAT2(pred, 9.0, fn("0.9e1", nullptr));
    299   EXPECT_PRED_FORMAT2(pred, 9.0, fn("0x1.2p3", nullptr));
    300 
    301   const char* s = " \t\v\f\r\n9.0";
    302   char* p;
    303   EXPECT_PRED_FORMAT2(pred, 9.0, fn(s, &p));
    304   EXPECT_EQ(s + strlen(s), p);
    305 
    306   EXPECT_TRUE(isnan(fn("+nan", nullptr)));
    307   EXPECT_TRUE(isnan(fn("nan", nullptr)));
    308   EXPECT_TRUE(isnan(fn("-nan", nullptr)));
    309 
    310   EXPECT_TRUE(isnan(fn("+nan(0xff)", nullptr)));
    311   EXPECT_TRUE(isnan(fn("nan(0xff)", nullptr)));
    312   EXPECT_TRUE(isnan(fn("-nan(0xff)", nullptr)));
    313 
    314   EXPECT_TRUE(isnan(fn("+nanny", &p)));
    315   EXPECT_STREQ("ny", p);
    316   EXPECT_TRUE(isnan(fn("nanny", &p)));
    317   EXPECT_STREQ("ny", p);
    318   EXPECT_TRUE(isnan(fn("-nanny", &p)));
    319   EXPECT_STREQ("ny", p);
    320 
    321   EXPECT_EQ(0, fn("muppet", &p));
    322   EXPECT_STREQ("muppet", p);
    323   EXPECT_EQ(0, fn("  muppet", &p));
    324   EXPECT_STREQ("  muppet", p);
    325 
    326   EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("+inf", nullptr));
    327   EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("inf", nullptr));
    328   EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn("-inf", nullptr));
    329 
    330   EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("+infinity", nullptr));
    331   EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("infinity", nullptr));
    332   EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn("-infinity", nullptr));
    333 
    334   EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("+infinitude", &p));
    335   EXPECT_STREQ("initude", p);
    336   EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("infinitude", &p));
    337   EXPECT_STREQ("initude", p);
    338   EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn("-infinitude", &p));
    339   EXPECT_STREQ("initude", p);
    340 
    341   // Check case-insensitivity.
    342   EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("InFiNiTy", nullptr));
    343   EXPECT_TRUE(isnan(fn("NaN", nullptr)));
    344 }
    345 
    346 TEST(stdlib, strtod) {
    347   CheckStrToFloat(strtod);
    348 }
    349 
    350 TEST(stdlib, strtof) {
    351   CheckStrToFloat(strtof);
    352 }
    353 
    354 TEST(stdlib, strtold) {
    355   CheckStrToFloat(strtold);
    356 }
    357 
    358 TEST(stdlib, strtof_2206701) {
    359   ASSERT_EQ(0.0f, strtof("7.0064923216240853546186479164495e-46", NULL));
    360   ASSERT_EQ(1.4e-45f, strtof("7.0064923216240853546186479164496e-46", NULL));
    361 }
    362 
    363 TEST(stdlib, strtod_largest_subnormal) {
    364   // This value has been known to cause javac and java to infinite loop.
    365   // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
    366   ASSERT_EQ(2.2250738585072014e-308, strtod("2.2250738585072012e-308", NULL));
    367   ASSERT_EQ(2.2250738585072014e-308, strtod("0.00022250738585072012e-304", NULL));
    368   ASSERT_EQ(2.2250738585072014e-308, strtod("00000002.2250738585072012e-308", NULL));
    369   ASSERT_EQ(2.2250738585072014e-308, strtod("2.225073858507201200000e-308", NULL));
    370   ASSERT_EQ(2.2250738585072014e-308, strtod("2.2250738585072012e-00308", NULL));
    371   ASSERT_EQ(2.2250738585072014e-308, strtod("2.22507385850720129978001e-308", NULL));
    372   ASSERT_EQ(-2.2250738585072014e-308, strtod("-2.2250738585072012e-308", NULL));
    373 }
    374 
    375 TEST(stdlib, quick_exit) {
    376   pid_t pid = fork();
    377   ASSERT_NE(-1, pid) << strerror(errno);
    378 
    379   if (pid == 0) {
    380     quick_exit(99);
    381   }
    382 
    383   AssertChildExited(pid, 99);
    384 }
    385 
    386 static int quick_exit_status = 0;
    387 
    388 static void quick_exit_1(void) {
    389   ASSERT_EQ(quick_exit_status, 0);
    390   quick_exit_status = 1;
    391 }
    392 
    393 static void quick_exit_2(void) {
    394   ASSERT_EQ(quick_exit_status, 1);
    395 }
    396 
    397 static void not_run(void) {
    398   FAIL();
    399 }
    400 
    401 TEST(stdlib, at_quick_exit) {
    402   pid_t pid = fork();
    403   ASSERT_NE(-1, pid) << strerror(errno);
    404 
    405   if (pid == 0) {
    406     ASSERT_EQ(at_quick_exit(quick_exit_2), 0);
    407     ASSERT_EQ(at_quick_exit(quick_exit_1), 0);
    408     atexit(not_run);
    409     quick_exit(99);
    410   }
    411 
    412   AssertChildExited(pid, 99);
    413 }
    414 
    415 TEST(unistd, _Exit) {
    416   pid_t pid = fork();
    417   ASSERT_NE(-1, pid) << strerror(errno);
    418 
    419   if (pid == 0) {
    420     _Exit(99);
    421   }
    422 
    423   AssertChildExited(pid, 99);
    424 }
    425 
    426 TEST(stdlib, pty_smoke) {
    427   // getpt returns a pty with O_RDWR|O_NOCTTY.
    428   int fd = getpt();
    429   ASSERT_NE(-1, fd);
    430 
    431   // grantpt is a no-op.
    432   ASSERT_EQ(0, grantpt(fd));
    433 
    434   // ptsname_r should start "/dev/pts/".
    435   char name_r[128];
    436   ASSERT_EQ(0, ptsname_r(fd, name_r, sizeof(name_r)));
    437   name_r[9] = 0;
    438   ASSERT_STREQ("/dev/pts/", name_r);
    439 
    440   close(fd);
    441 }
    442 
    443 TEST(stdlib, posix_openpt) {
    444   int fd = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC);
    445   ASSERT_NE(-1, fd);
    446   close(fd);
    447 }
    448 
    449 TEST(stdlib, ptsname_r_ENOTTY) {
    450   errno = 0;
    451   char buf[128];
    452   ASSERT_EQ(ENOTTY, ptsname_r(STDOUT_FILENO, buf, sizeof(buf)));
    453   ASSERT_EQ(ENOTTY, errno);
    454 }
    455 
    456 TEST(stdlib, ptsname_r_EINVAL) {
    457   int fd = getpt();
    458   ASSERT_NE(-1, fd);
    459   errno = 0;
    460   char* buf = NULL;
    461   ASSERT_EQ(EINVAL, ptsname_r(fd, buf, 128));
    462   ASSERT_EQ(EINVAL, errno);
    463   close(fd);
    464 }
    465 
    466 TEST(stdlib, ptsname_r_ERANGE) {
    467   int fd = getpt();
    468   ASSERT_NE(-1, fd);
    469   errno = 0;
    470   char buf[1];
    471   ASSERT_EQ(ERANGE, ptsname_r(fd, buf, sizeof(buf)));
    472   ASSERT_EQ(ERANGE, errno);
    473   close(fd);
    474 }
    475 
    476 TEST(stdlib, ttyname_r) {
    477   int fd = getpt();
    478   ASSERT_NE(-1, fd);
    479 
    480   // ttyname_r returns "/dev/ptmx" for a pty.
    481   char name_r[128];
    482   ASSERT_EQ(0, ttyname_r(fd, name_r, sizeof(name_r)));
    483   ASSERT_STREQ("/dev/ptmx", name_r);
    484 
    485   close(fd);
    486 }
    487 
    488 TEST(stdlib, ttyname_r_ENOTTY) {
    489   int fd = open("/dev/null", O_WRONLY);
    490   errno = 0;
    491   char buf[128];
    492   ASSERT_EQ(ENOTTY, ttyname_r(fd, buf, sizeof(buf)));
    493   ASSERT_EQ(ENOTTY, errno);
    494   close(fd);
    495 }
    496 
    497 TEST(stdlib, ttyname_r_EINVAL) {
    498   int fd = getpt();
    499   ASSERT_NE(-1, fd);
    500   errno = 0;
    501   char* buf = NULL;
    502   ASSERT_EQ(EINVAL, ttyname_r(fd, buf, 128));
    503   ASSERT_EQ(EINVAL, errno);
    504   close(fd);
    505 }
    506 
    507 TEST(stdlib, ttyname_r_ERANGE) {
    508   int fd = getpt();
    509   ASSERT_NE(-1, fd);
    510   errno = 0;
    511   char buf[1];
    512   ASSERT_EQ(ERANGE, ttyname_r(fd, buf, sizeof(buf)));
    513   ASSERT_EQ(ERANGE, errno);
    514   close(fd);
    515 }
    516 
    517 TEST(stdlib, unlockpt_ENOTTY) {
    518   int fd = open("/dev/null", O_WRONLY);
    519   errno = 0;
    520   ASSERT_EQ(-1, unlockpt(fd));
    521   ASSERT_EQ(ENOTTY, errno);
    522   close(fd);
    523 }
    524 
    525 TEST(stdlib, strtol_EINVAL) {
    526   errno = 0;
    527   strtol("123", NULL, -1);
    528   ASSERT_EQ(EINVAL, errno);
    529   errno = 0;
    530   strtol("123", NULL, 1);
    531   ASSERT_EQ(EINVAL, errno);
    532   errno = 0;
    533   strtol("123", NULL, 37);
    534   ASSERT_EQ(EINVAL, errno);
    535 }
    536 
    537 TEST(stdlib, strtoll_EINVAL) {
    538   errno = 0;
    539   strtoll("123", NULL, -1);
    540   ASSERT_EQ(EINVAL, errno);
    541   errno = 0;
    542   strtoll("123", NULL, 1);
    543   ASSERT_EQ(EINVAL, errno);
    544   errno = 0;
    545   strtoll("123", NULL, 37);
    546   ASSERT_EQ(EINVAL, errno);
    547 }
    548 
    549 TEST(stdlib, strtoul_EINVAL) {
    550   errno = 0;
    551   strtoul("123", NULL, -1);
    552   ASSERT_EQ(EINVAL, errno);
    553   errno = 0;
    554   strtoul("123", NULL, 1);
    555   ASSERT_EQ(EINVAL, errno);
    556   errno = 0;
    557   strtoul("123", NULL, 37);
    558   ASSERT_EQ(EINVAL, errno);
    559 }
    560 
    561 TEST(stdlib, strtoull_EINVAL) {
    562   errno = 0;
    563   strtoull("123", NULL, -1);
    564   ASSERT_EQ(EINVAL, errno);
    565   errno = 0;
    566   strtoull("123", NULL, 1);
    567   ASSERT_EQ(EINVAL, errno);
    568   errno = 0;
    569   strtoull("123", NULL, 37);
    570   ASSERT_EQ(EINVAL, errno);
    571 }
    572 
    573 TEST(stdlib, getsubopt) {
    574   char* const tokens[] = {
    575     const_cast<char*>("a"),
    576     const_cast<char*>("b"),
    577     const_cast<char*>("foo"),
    578     nullptr
    579   };
    580   std::string input = "a,b,foo=bar,a,unknown";
    581   char* subopts = &input[0];
    582   char* value = nullptr;
    583 
    584   ASSERT_EQ(0, getsubopt(&subopts, tokens, &value));
    585   ASSERT_EQ(nullptr, value);
    586   ASSERT_EQ(1, getsubopt(&subopts, tokens, &value));
    587   ASSERT_EQ(nullptr, value);
    588   ASSERT_EQ(2, getsubopt(&subopts, tokens, &value));
    589   ASSERT_STREQ("bar", value);
    590   ASSERT_EQ(0, getsubopt(&subopts, tokens, &value));
    591   ASSERT_EQ(nullptr, value);
    592 
    593   ASSERT_EQ(-1, getsubopt(&subopts, tokens, &value));
    594 }
    595 
    596 TEST(stdlib, mblen) {
    597   // "If s is a null pointer, mblen() shall return a non-zero or 0 value, if character encodings,
    598   // respectively, do or do not have state-dependent encodings." We're always UTF-8.
    599   EXPECT_EQ(0, mblen(nullptr, 1));
    600 
    601   ASSERT_STREQ("C.UTF-8", setlocale(LC_ALL, "C.UTF-8"));
    602 
    603   // 1-byte UTF-8.
    604   EXPECT_EQ(1, mblen("abcdef", 6));
    605   // 2-byte UTF-8.
    606   EXPECT_EQ(2, mblen("\xc2\xa2" "cdef", 6));
    607   // 3-byte UTF-8.
    608   EXPECT_EQ(3, mblen("\xe2\x82\xac" "def", 6));
    609   // 4-byte UTF-8.
    610   EXPECT_EQ(4, mblen("\xf0\xa4\xad\xa2" "ef", 6));
    611 
    612   // Illegal over-long sequence.
    613   ASSERT_EQ(-1, mblen("\xf0\x82\x82\xac" "ef", 6));
    614 
    615   // "mblen() shall ... return 0 (if s points to the null byte)".
    616   EXPECT_EQ(0, mblen("", 1));
    617 }
    618