• 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 <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  
TEST(stdlib,drand48)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  
TEST(stdlib,erand48)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  
TEST(stdlib,lcong48)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  
TEST(stdlib,lrand48)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  
TEST(stdlib,random)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  
TEST(stdlib,rand)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  
TEST(stdlib,mrand48)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  
TEST(stdlib,posix_memalign_sweep)141  TEST(stdlib, posix_memalign_sweep) {
142    void* ptr;
143  
144    // These should all fail.
145    for (size_t align = 0; align < sizeof(long); align++) {
146      ASSERT_EQ(EINVAL, posix_memalign(&ptr, align, 256))
147          << "Unexpected value at align " << align;
148    }
149  
150    // Verify powers of 2 up to 2048 allocate, and verify that all other
151    // alignment values between the powers of 2 fail.
152    size_t last_align = sizeof(long);
153    for (size_t align = sizeof(long); align <= 2048; align <<= 1) {
154      // Try all of the non power of 2 values from the last until this value.
155      for (size_t fail_align = last_align + 1; fail_align < align; fail_align++) {
156        ASSERT_EQ(EINVAL, posix_memalign(&ptr, fail_align, 256))
157            << "Unexpected success at align " << fail_align;
158      }
159      ASSERT_EQ(0, posix_memalign(&ptr, align, 256))
160          << "Unexpected failure at align " << align;
161      ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) & (align - 1))
162          << "Did not return a valid aligned ptr " << ptr << " expected alignment " << align;
163      free(ptr);
164      last_align = align;
165    }
166  }
167  
TEST(stdlib,posix_memalign_various_sizes)168  TEST(stdlib, posix_memalign_various_sizes) {
169    std::vector<size_t> sizes{1, 4, 8, 256, 1024, 65000, 128000, 256000, 1000000};
170    for (auto size : sizes) {
171      void* ptr;
172      ASSERT_EQ(0, posix_memalign(&ptr, 16, 1))
173          << "posix_memalign failed at size " << size;
174      ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) & 0xf)
175          << "Pointer not aligned at size " << size << " ptr " << ptr;
176      free(ptr);
177    }
178  }
179  
TEST(stdlib,posix_memalign_overflow)180  TEST(stdlib, posix_memalign_overflow) {
181    void* ptr;
182    ASSERT_NE(0, posix_memalign(&ptr, 16, SIZE_MAX));
183  }
184  
TEST(stdlib,realpath__NULL_filename)185  TEST(stdlib, realpath__NULL_filename) {
186    errno = 0;
187    char* p = realpath(NULL, NULL);
188    ASSERT_TRUE(p == NULL);
189    ASSERT_EQ(EINVAL, errno);
190  }
191  
TEST(stdlib,realpath__empty_filename)192  TEST(stdlib, realpath__empty_filename) {
193    errno = 0;
194    char* p = realpath("", NULL);
195    ASSERT_TRUE(p == NULL);
196    ASSERT_EQ(ENOENT, errno);
197  }
198  
TEST(stdlib,realpath__ENOENT)199  TEST(stdlib, realpath__ENOENT) {
200    errno = 0;
201    char* p = realpath("/this/directory/path/almost/certainly/does/not/exist", NULL);
202    ASSERT_TRUE(p == NULL);
203    ASSERT_EQ(ENOENT, errno);
204  }
205  
TEST(stdlib,realpath__component_after_non_directory)206  TEST(stdlib, realpath__component_after_non_directory) {
207    errno = 0;
208    char* p = realpath("/dev/null/.", NULL);
209    ASSERT_TRUE(p == NULL);
210    ASSERT_EQ(ENOTDIR, errno);
211  
212    errno = 0;
213    p = realpath("/dev/null/..", NULL);
214    ASSERT_TRUE(p == NULL);
215    ASSERT_EQ(ENOTDIR, errno);
216  }
217  
TEST(stdlib,realpath)218  TEST(stdlib, realpath) {
219    // Get the name of this executable.
220    char executable_path[PATH_MAX];
221    int rc = readlink("/proc/self/exe", executable_path, sizeof(executable_path));
222    ASSERT_NE(rc, -1);
223    executable_path[rc] = '\0';
224  
225    char buf[PATH_MAX + 1];
226    char* p = realpath("/proc/self/exe", buf);
227    ASSERT_STREQ(executable_path, p);
228  
229    p = realpath("/proc/self/exe", NULL);
230    ASSERT_STREQ(executable_path, p);
231    free(p);
232  }
233  
TEST(stdlib,qsort)234  TEST(stdlib, qsort) {
235    struct s {
236      char name[16];
237      static int comparator(const void* lhs, const void* rhs) {
238        return strcmp(reinterpret_cast<const s*>(lhs)->name, reinterpret_cast<const s*>(rhs)->name);
239      }
240    };
241    s entries[3];
242    strcpy(entries[0].name, "charlie");
243    strcpy(entries[1].name, "bravo");
244    strcpy(entries[2].name, "alpha");
245  
246    qsort(entries, 3, sizeof(s), s::comparator);
247    ASSERT_STREQ("alpha", entries[0].name);
248    ASSERT_STREQ("bravo", entries[1].name);
249    ASSERT_STREQ("charlie", entries[2].name);
250  
251    qsort(entries, 3, sizeof(s), s::comparator);
252    ASSERT_STREQ("alpha", entries[0].name);
253    ASSERT_STREQ("bravo", entries[1].name);
254    ASSERT_STREQ("charlie", entries[2].name);
255  }
256  
TestBug57421_child(void * arg)257  static void* TestBug57421_child(void* arg) {
258    pthread_t main_thread = reinterpret_cast<pthread_t>(arg);
259    pthread_join(main_thread, NULL);
260    char* value = getenv("ENVIRONMENT_VARIABLE");
261    if (value == NULL) {
262      setenv("ENVIRONMENT_VARIABLE", "value", 1);
263    }
264    return NULL;
265  }
266  
TestBug57421_main()267  static void TestBug57421_main() {
268    pthread_t t;
269    ASSERT_EQ(0, pthread_create(&t, NULL, TestBug57421_child, reinterpret_cast<void*>(pthread_self())));
270    pthread_exit(NULL);
271  }
272  
273  // Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to
274  // run this test (which exits normally) in its own process.
275  
276  class stdlib_DeathTest : public BionicDeathTest {};
277  
TEST_F(stdlib_DeathTest,getenv_after_main_thread_exits)278  TEST_F(stdlib_DeathTest, getenv_after_main_thread_exits) {
279    // https://code.google.com/p/android/issues/detail?id=57421
280    ASSERT_EXIT(TestBug57421_main(), ::testing::ExitedWithCode(0), "");
281  }
282  
TEST(stdlib,mkostemp64)283  TEST(stdlib, mkostemp64) {
284    TemporaryFile tf([](char* path) { return mkostemp64(path, O_CLOEXEC); });
285    int flags = fcntl(tf.fd, F_GETFD);
286    ASSERT_TRUE(flags != -1);
287    ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC);
288  }
289  
TEST(stdlib,mkostemp)290  TEST(stdlib, mkostemp) {
291    TemporaryFile tf([](char* path) { return mkostemp(path, O_CLOEXEC); });
292    int flags = fcntl(tf.fd, F_GETFD);
293    ASSERT_TRUE(flags != -1);
294    ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC);
295  }
296  
TEST(stdlib,mkstemp64)297  TEST(stdlib, mkstemp64) {
298    TemporaryFile tf(mkstemp64);
299    struct stat64 sb;
300    ASSERT_EQ(0, fstat64(tf.fd, &sb));
301    ASSERT_EQ(O_LARGEFILE, fcntl(tf.fd, F_GETFL) & O_LARGEFILE);
302  }
303  
TEST(stdlib,mkstemp)304  TEST(stdlib, mkstemp) {
305    TemporaryFile tf;
306    struct stat sb;
307    ASSERT_EQ(0, fstat(tf.fd, &sb));
308  }
309  
TEST(stdlib,system)310  TEST(stdlib, system) {
311    int status;
312  
313    status = system("exit 0");
314    ASSERT_TRUE(WIFEXITED(status));
315    ASSERT_EQ(0, WEXITSTATUS(status));
316  
317    status = system("exit 1");
318    ASSERT_TRUE(WIFEXITED(status));
319    ASSERT_EQ(1, WEXITSTATUS(status));
320  }
321  
TEST(stdlib,atof)322  TEST(stdlib, atof) {
323    ASSERT_DOUBLE_EQ(1.23, atof("1.23"));
324  }
325  
326  template <typename T>
CheckStrToFloat(T fn (const char * s,char ** end))327  static void CheckStrToFloat(T fn(const char* s, char** end)) {
328    FpUlpEq<0, T> pred;
329  
330    EXPECT_PRED_FORMAT2(pred, 9.0, fn("9.0", nullptr));
331    EXPECT_PRED_FORMAT2(pred, 9.0, fn("0.9e1", nullptr));
332    EXPECT_PRED_FORMAT2(pred, 9.0, fn("0x1.2p3", nullptr));
333  
334    const char* s = " \t\v\f\r\n9.0";
335    char* p;
336    EXPECT_PRED_FORMAT2(pred, 9.0, fn(s, &p));
337    EXPECT_EQ(s + strlen(s), p);
338  
339    EXPECT_TRUE(isnan(fn("+nan", nullptr)));
340    EXPECT_TRUE(isnan(fn("nan", nullptr)));
341    EXPECT_TRUE(isnan(fn("-nan", nullptr)));
342  
343    EXPECT_TRUE(isnan(fn("+nan(0xff)", nullptr)));
344    EXPECT_TRUE(isnan(fn("nan(0xff)", nullptr)));
345    EXPECT_TRUE(isnan(fn("-nan(0xff)", nullptr)));
346  
347    EXPECT_TRUE(isnan(fn("+nanny", &p)));
348    EXPECT_STREQ("ny", p);
349    EXPECT_TRUE(isnan(fn("nanny", &p)));
350    EXPECT_STREQ("ny", p);
351    EXPECT_TRUE(isnan(fn("-nanny", &p)));
352    EXPECT_STREQ("ny", p);
353  
354    EXPECT_EQ(0, fn("muppet", &p));
355    EXPECT_STREQ("muppet", p);
356    EXPECT_EQ(0, fn("  muppet", &p));
357    EXPECT_STREQ("  muppet", p);
358  
359    EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("+inf", nullptr));
360    EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("inf", nullptr));
361    EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn("-inf", nullptr));
362  
363    EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("+infinity", nullptr));
364    EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("infinity", nullptr));
365    EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn("-infinity", nullptr));
366  
367    EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("+infinitude", &p));
368    EXPECT_STREQ("initude", p);
369    EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("infinitude", &p));
370    EXPECT_STREQ("initude", p);
371    EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn("-infinitude", &p));
372    EXPECT_STREQ("initude", p);
373  
374    // Check case-insensitivity.
375    EXPECT_EQ(std::numeric_limits<T>::infinity(), fn("InFiNiTy", nullptr));
376    EXPECT_TRUE(isnan(fn("NaN", nullptr)));
377  }
378  
TEST(stdlib,strtod)379  TEST(stdlib, strtod) {
380    CheckStrToFloat(strtod);
381  }
382  
TEST(stdlib,strtof)383  TEST(stdlib, strtof) {
384    CheckStrToFloat(strtof);
385  }
386  
TEST(stdlib,strtold)387  TEST(stdlib, strtold) {
388    CheckStrToFloat(strtold);
389  }
390  
TEST(stdlib,strtof_2206701)391  TEST(stdlib, strtof_2206701) {
392    ASSERT_EQ(0.0f, strtof("7.0064923216240853546186479164495e-46", NULL));
393    ASSERT_EQ(1.4e-45f, strtof("7.0064923216240853546186479164496e-46", NULL));
394  }
395  
TEST(stdlib,strtod_largest_subnormal)396  TEST(stdlib, strtod_largest_subnormal) {
397    // This value has been known to cause javac and java to infinite loop.
398    // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
399    ASSERT_EQ(2.2250738585072014e-308, strtod("2.2250738585072012e-308", NULL));
400    ASSERT_EQ(2.2250738585072014e-308, strtod("0.00022250738585072012e-304", NULL));
401    ASSERT_EQ(2.2250738585072014e-308, strtod("00000002.2250738585072012e-308", NULL));
402    ASSERT_EQ(2.2250738585072014e-308, strtod("2.225073858507201200000e-308", NULL));
403    ASSERT_EQ(2.2250738585072014e-308, strtod("2.2250738585072012e-00308", NULL));
404    ASSERT_EQ(2.2250738585072014e-308, strtod("2.22507385850720129978001e-308", NULL));
405    ASSERT_EQ(-2.2250738585072014e-308, strtod("-2.2250738585072012e-308", NULL));
406  }
407  
TEST(stdlib,quick_exit)408  TEST(stdlib, quick_exit) {
409    pid_t pid = fork();
410    ASSERT_NE(-1, pid) << strerror(errno);
411  
412    if (pid == 0) {
413      quick_exit(99);
414    }
415  
416    AssertChildExited(pid, 99);
417  }
418  
419  static int quick_exit_status = 0;
420  
quick_exit_1(void)421  static void quick_exit_1(void) {
422    ASSERT_EQ(quick_exit_status, 0);
423    quick_exit_status = 1;
424  }
425  
quick_exit_2(void)426  static void quick_exit_2(void) {
427    ASSERT_EQ(quick_exit_status, 1);
428  }
429  
not_run(void)430  static void not_run(void) {
431    FAIL();
432  }
433  
TEST(stdlib,at_quick_exit)434  TEST(stdlib, at_quick_exit) {
435    pid_t pid = fork();
436    ASSERT_NE(-1, pid) << strerror(errno);
437  
438    if (pid == 0) {
439      ASSERT_EQ(at_quick_exit(quick_exit_2), 0);
440      ASSERT_EQ(at_quick_exit(quick_exit_1), 0);
441      atexit(not_run);
442      quick_exit(99);
443    }
444  
445    AssertChildExited(pid, 99);
446  }
447  
TEST(unistd,_Exit)448  TEST(unistd, _Exit) {
449    pid_t pid = fork();
450    ASSERT_NE(-1, pid) << strerror(errno);
451  
452    if (pid == 0) {
453      _Exit(99);
454    }
455  
456    AssertChildExited(pid, 99);
457  }
458  
TEST(stdlib,pty_smoke)459  TEST(stdlib, pty_smoke) {
460    // getpt returns a pty with O_RDWR|O_NOCTTY.
461    int fd = getpt();
462    ASSERT_NE(-1, fd);
463  
464    // grantpt is a no-op.
465    ASSERT_EQ(0, grantpt(fd));
466  
467    // ptsname_r should start "/dev/pts/".
468    char name_r[128];
469    ASSERT_EQ(0, ptsname_r(fd, name_r, sizeof(name_r)));
470    name_r[9] = 0;
471    ASSERT_STREQ("/dev/pts/", name_r);
472  
473    close(fd);
474  }
475  
TEST(stdlib,posix_openpt)476  TEST(stdlib, posix_openpt) {
477    int fd = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC);
478    ASSERT_NE(-1, fd);
479    close(fd);
480  }
481  
TEST(stdlib,ptsname_r_ENOTTY)482  TEST(stdlib, ptsname_r_ENOTTY) {
483    errno = 0;
484    char buf[128];
485    ASSERT_EQ(ENOTTY, ptsname_r(STDOUT_FILENO, buf, sizeof(buf)));
486    ASSERT_EQ(ENOTTY, errno);
487  }
488  
TEST(stdlib,ptsname_r_EINVAL)489  TEST(stdlib, ptsname_r_EINVAL) {
490    int fd = getpt();
491    ASSERT_NE(-1, fd);
492    errno = 0;
493    char* buf = NULL;
494    ASSERT_EQ(EINVAL, ptsname_r(fd, buf, 128));
495    ASSERT_EQ(EINVAL, errno);
496    close(fd);
497  }
498  
TEST(stdlib,ptsname_r_ERANGE)499  TEST(stdlib, ptsname_r_ERANGE) {
500    int fd = getpt();
501    ASSERT_NE(-1, fd);
502    errno = 0;
503    char buf[1];
504    ASSERT_EQ(ERANGE, ptsname_r(fd, buf, sizeof(buf)));
505    ASSERT_EQ(ERANGE, errno);
506    close(fd);
507  }
508  
TEST(stdlib,ttyname_r)509  TEST(stdlib, ttyname_r) {
510    int fd = getpt();
511    ASSERT_NE(-1, fd);
512  
513    // ttyname_r returns "/dev/ptmx" for a pty.
514    char name_r[128];
515    ASSERT_EQ(0, ttyname_r(fd, name_r, sizeof(name_r)));
516    ASSERT_STREQ("/dev/ptmx", name_r);
517  
518    close(fd);
519  }
520  
TEST(stdlib,ttyname_r_ENOTTY)521  TEST(stdlib, ttyname_r_ENOTTY) {
522    int fd = open("/dev/null", O_WRONLY);
523    errno = 0;
524    char buf[128];
525    ASSERT_EQ(ENOTTY, ttyname_r(fd, buf, sizeof(buf)));
526    ASSERT_EQ(ENOTTY, errno);
527    close(fd);
528  }
529  
TEST(stdlib,ttyname_r_EINVAL)530  TEST(stdlib, ttyname_r_EINVAL) {
531    int fd = getpt();
532    ASSERT_NE(-1, fd);
533    errno = 0;
534    char* buf = NULL;
535    ASSERT_EQ(EINVAL, ttyname_r(fd, buf, 128));
536    ASSERT_EQ(EINVAL, errno);
537    close(fd);
538  }
539  
TEST(stdlib,ttyname_r_ERANGE)540  TEST(stdlib, ttyname_r_ERANGE) {
541    int fd = getpt();
542    ASSERT_NE(-1, fd);
543    errno = 0;
544    char buf[1];
545    ASSERT_EQ(ERANGE, ttyname_r(fd, buf, sizeof(buf)));
546    ASSERT_EQ(ERANGE, errno);
547    close(fd);
548  }
549  
TEST(stdlib,unlockpt_ENOTTY)550  TEST(stdlib, unlockpt_ENOTTY) {
551    int fd = open("/dev/null", O_WRONLY);
552    errno = 0;
553    ASSERT_EQ(-1, unlockpt(fd));
554    ASSERT_EQ(ENOTTY, errno);
555    close(fd);
556  }
557  
TEST(stdlib,strtol_EINVAL)558  TEST(stdlib, strtol_EINVAL) {
559    errno = 0;
560    strtol("123", NULL, -1);
561    ASSERT_EQ(EINVAL, errno);
562    errno = 0;
563    strtol("123", NULL, 1);
564    ASSERT_EQ(EINVAL, errno);
565    errno = 0;
566    strtol("123", NULL, 37);
567    ASSERT_EQ(EINVAL, errno);
568  }
569  
TEST(stdlib,strtoll_EINVAL)570  TEST(stdlib, strtoll_EINVAL) {
571    errno = 0;
572    strtoll("123", NULL, -1);
573    ASSERT_EQ(EINVAL, errno);
574    errno = 0;
575    strtoll("123", NULL, 1);
576    ASSERT_EQ(EINVAL, errno);
577    errno = 0;
578    strtoll("123", NULL, 37);
579    ASSERT_EQ(EINVAL, errno);
580  }
581  
TEST(stdlib,strtoul_EINVAL)582  TEST(stdlib, strtoul_EINVAL) {
583    errno = 0;
584    strtoul("123", NULL, -1);
585    ASSERT_EQ(EINVAL, errno);
586    errno = 0;
587    strtoul("123", NULL, 1);
588    ASSERT_EQ(EINVAL, errno);
589    errno = 0;
590    strtoul("123", NULL, 37);
591    ASSERT_EQ(EINVAL, errno);
592  }
593  
TEST(stdlib,strtoull_EINVAL)594  TEST(stdlib, strtoull_EINVAL) {
595    errno = 0;
596    strtoull("123", NULL, -1);
597    ASSERT_EQ(EINVAL, errno);
598    errno = 0;
599    strtoull("123", NULL, 1);
600    ASSERT_EQ(EINVAL, errno);
601    errno = 0;
602    strtoull("123", NULL, 37);
603    ASSERT_EQ(EINVAL, errno);
604  }
605  
TEST(stdlib,getsubopt)606  TEST(stdlib, getsubopt) {
607    char* const tokens[] = {
608      const_cast<char*>("a"),
609      const_cast<char*>("b"),
610      const_cast<char*>("foo"),
611      nullptr
612    };
613    std::string input = "a,b,foo=bar,a,unknown";
614    char* subopts = &input[0];
615    char* value = nullptr;
616  
617    ASSERT_EQ(0, getsubopt(&subopts, tokens, &value));
618    ASSERT_EQ(nullptr, value);
619    ASSERT_EQ(1, getsubopt(&subopts, tokens, &value));
620    ASSERT_EQ(nullptr, value);
621    ASSERT_EQ(2, getsubopt(&subopts, tokens, &value));
622    ASSERT_STREQ("bar", value);
623    ASSERT_EQ(0, getsubopt(&subopts, tokens, &value));
624    ASSERT_EQ(nullptr, value);
625  
626    ASSERT_EQ(-1, getsubopt(&subopts, tokens, &value));
627  }
628  
TEST(stdlib,mblen)629  TEST(stdlib, mblen) {
630    // "If s is a null pointer, mblen() shall return a non-zero or 0 value, if character encodings,
631    // respectively, do or do not have state-dependent encodings." We're always UTF-8.
632    EXPECT_EQ(0, mblen(nullptr, 1));
633  
634    ASSERT_STREQ("C.UTF-8", setlocale(LC_ALL, "C.UTF-8"));
635  
636    // 1-byte UTF-8.
637    EXPECT_EQ(1, mblen("abcdef", 6));
638    // 2-byte UTF-8.
639    EXPECT_EQ(2, mblen("\xc2\xa2" "cdef", 6));
640    // 3-byte UTF-8.
641    EXPECT_EQ(3, mblen("\xe2\x82\xac" "def", 6));
642    // 4-byte UTF-8.
643    EXPECT_EQ(4, mblen("\xf0\xa4\xad\xa2" "ef", 6));
644  
645    // Illegal over-long sequence.
646    ASSERT_EQ(-1, mblen("\xf0\x82\x82\xac" "ef", 6));
647  
648    // "mblen() shall ... return 0 (if s points to the null byte)".
649    EXPECT_EQ(0, mblen("", 1));
650  }
651