1774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes/*
2774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * Copyright (C) 2012 The Android Open Source Project
3774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes *
4774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
5774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * you may not use this file except in compliance with the License.
6774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * You may obtain a copy of the License at
7774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes *
8774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
9774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes *
10774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * Unless required by applicable law or agreed to in writing, software
11774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
12774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * See the License for the specific language governing permissions and
14774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * limitations under the License.
15774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes */
16774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes
17774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes#include <gtest/gtest.h>
18fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle#include "TemporaryFile.h"
19774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes
20b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes#include <errno.h>
21f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes#include <libgen.h>
22f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes#include <limits.h>
23877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes#include <pthread.h>
24b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes#include <stdint.h>
25774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes#include <stdlib.h>
26fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle#include <fcntl.h>
2740488560c17e41c0980b3a08ef54ec38bb572a41Elliott Hughes#include <sys/types.h>
2840488560c17e41c0980b3a08ef54ec38bb572a41Elliott Hughes#include <sys/wait.h>
29774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes
30774c7f54ff375d71106283d42779b0cc5f238f87Elliott HughesTEST(stdlib, drand48) {
31774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  srand48(0x01020304);
32774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_DOUBLE_EQ(0.65619299195623526, drand48());
33774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_DOUBLE_EQ(0.18522597229772941, drand48());
34774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_DOUBLE_EQ(0.42015087072844537, drand48());
35774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_DOUBLE_EQ(0.061637783047395089, drand48());
36774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes}
37774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes
38a0beeeabbc8735bc830544cbbb1d920122b8d958Elliott HughesTEST(stdlib, lrand48) {
39774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  srand48(0x01020304);
40774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(1409163720, lrand48());
41774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(397769746, lrand48());
42774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(902267124, lrand48());
43774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(132366131, lrand48());
44a0beeeabbc8735bc830544cbbb1d920122b8d958Elliott Hughes}
45774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes
46a0beeeabbc8735bc830544cbbb1d920122b8d958Elliott HughesTEST(stdlib, random) {
47774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  srandom(0x01020304);
48a0beeeabbc8735bc830544cbbb1d920122b8d958Elliott Hughes  EXPECT_EQ(55436735, random());
49a0beeeabbc8735bc830544cbbb1d920122b8d958Elliott Hughes  EXPECT_EQ(1399865117, random());
50a0beeeabbc8735bc830544cbbb1d920122b8d958Elliott Hughes  EXPECT_EQ(2032643283, random());
51a0beeeabbc8735bc830544cbbb1d920122b8d958Elliott Hughes  EXPECT_EQ(571329216, random());
52a0beeeabbc8735bc830544cbbb1d920122b8d958Elliott Hughes}
53774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes
54a0beeeabbc8735bc830544cbbb1d920122b8d958Elliott HughesTEST(stdlib, rand) {
55774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  srand(0x01020304);
56a0beeeabbc8735bc830544cbbb1d920122b8d958Elliott Hughes  EXPECT_EQ(55436735, rand());
57a0beeeabbc8735bc830544cbbb1d920122b8d958Elliott Hughes  EXPECT_EQ(1399865117, rand());
58a0beeeabbc8735bc830544cbbb1d920122b8d958Elliott Hughes  EXPECT_EQ(2032643283, rand());
59a0beeeabbc8735bc830544cbbb1d920122b8d958Elliott Hughes  EXPECT_EQ(571329216, rand());
60774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes}
61774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes
62774c7f54ff375d71106283d42779b0cc5f238f87Elliott HughesTEST(stdlib, mrand48) {
63774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  srand48(0x01020304);
64774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(-1476639856, mrand48());
65774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(795539493, mrand48());
66774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(1804534249, mrand48());
67774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(264732262, mrand48());
68774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes}
69b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes
70b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott HughesTEST(stdlib, posix_memalign) {
71b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes  void* p;
72b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes
73b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes  ASSERT_EQ(0, posix_memalign(&p, 512, 128));
74b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(p) % 512);
75b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes  free(p);
76b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes
77b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes  // Can't align to a non-power of 2.
78b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes  ASSERT_EQ(EINVAL, posix_memalign(&p, 81, 128));
79b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes}
80f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes
81f0777843c03deb26b1f78c8edd17c557041696e9Elliott HughesTEST(stdlib, realpath__NULL_filename) {
82f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  errno = 0;
83f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  char* p = realpath(NULL, NULL);
84f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_TRUE(p == NULL);
85f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_EQ(EINVAL, errno);
86f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes}
87f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes
88f0777843c03deb26b1f78c8edd17c557041696e9Elliott HughesTEST(stdlib, realpath__empty_filename) {
89f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  errno = 0;
90f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  char* p = realpath("", NULL);
91f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_TRUE(p == NULL);
92f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_EQ(ENOENT, errno);
93f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes}
94f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes
95f0777843c03deb26b1f78c8edd17c557041696e9Elliott HughesTEST(stdlib, realpath__ENOENT) {
96f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  errno = 0;
97f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  char* p = realpath("/this/directory/path/almost/certainly/does/not/exist", NULL);
98f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_TRUE(p == NULL);
99f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_EQ(ENOENT, errno);
100f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes}
101f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes
102f0777843c03deb26b1f78c8edd17c557041696e9Elliott HughesTEST(stdlib, realpath) {
103f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  // Get the name of this executable.
104f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  char executable_path[PATH_MAX];
105f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  int rc = readlink("/proc/self/exe", executable_path, sizeof(executable_path));
106f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_NE(rc, -1);
107f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  executable_path[rc] = '\0';
108f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes
109f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  char buf[PATH_MAX + 1];
110f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  char* p = realpath("/proc/self/exe", buf);
111f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_STREQ(executable_path, p);
112f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes
113f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  p = realpath("/proc/self/exe", NULL);
114f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_STREQ(executable_path, p);
115f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  free(p);
116f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes}
1170b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes
1180b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott HughesTEST(stdlib, qsort) {
1190b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  struct s {
1200b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes    char name[16];
1210b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes    static int comparator(const void* lhs, const void* rhs) {
1220b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes      return strcmp(reinterpret_cast<const s*>(lhs)->name, reinterpret_cast<const s*>(rhs)->name);
1230b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes    }
1240b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  };
1250b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  s entries[3];
1260b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  strcpy(entries[0].name, "charlie");
1270b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  strcpy(entries[1].name, "bravo");
1280b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  strcpy(entries[2].name, "alpha");
1290b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes
1300b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  qsort(entries, 3, sizeof(s), s::comparator);
1310b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  ASSERT_STREQ("alpha", entries[0].name);
1320b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  ASSERT_STREQ("bravo", entries[1].name);
1330b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  ASSERT_STREQ("charlie", entries[2].name);
1340b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes
1350b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  qsort(entries, 3, sizeof(s), s::comparator);
1360b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  ASSERT_STREQ("alpha", entries[0].name);
1370b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  ASSERT_STREQ("bravo", entries[1].name);
1380b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  ASSERT_STREQ("charlie", entries[2].name);
1390b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes}
140877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
141877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughesstatic void* TestBug57421_child(void* arg) {
142877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  pthread_t main_thread = reinterpret_cast<pthread_t>(arg);
143877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  pthread_join(main_thread, NULL);
144877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  char* value = getenv("ENVIRONMENT_VARIABLE");
145877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  if (value == NULL) {
146877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes    setenv("ENVIRONMENT_VARIABLE", "value", 1);
147877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  }
148877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  return NULL;
149877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes}
150877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
151877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughesstatic void TestBug57421_main() {
152877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  pthread_t t;
153877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  ASSERT_EQ(0, pthread_create(&t, NULL, TestBug57421_child, reinterpret_cast<void*>(pthread_self())));
154877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  pthread_exit(NULL);
155877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes}
156877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
157877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes// Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to
158877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes// run this test (which exits normally) in its own process.
159877ec6d90418ff1d6597147d355a2229fdffae7eElliott HughesTEST(stdlib_DeathTest, getenv_after_main_thread_exits) {
160877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  // https://code.google.com/p/android/issues/detail?id=57421
161877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
162877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  ASSERT_EXIT(TestBug57421_main(), ::testing::ExitedWithCode(0), "");
163877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes}
164fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle
165fe317a3775e16d466bb884a8e054fd77f7087bb3Calin JuravleTEST(stdlib, mkstemp) {
166fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle  TemporaryFile tf;
167fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle  struct stat sb;
168fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle  ASSERT_EQ(0, fstat(tf.fd, &sb));
169fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle}
170fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle
171fe317a3775e16d466bb884a8e054fd77f7087bb3Calin JuravleTEST(stdlib, mkstemp64) {
172fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle  GenericTemporaryFile<mkstemp64> tf;
173fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle  struct stat64 sb;
174fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle  ASSERT_EQ(0, fstat64(tf.fd, &sb));
175fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle  ASSERT_EQ(O_LARGEFILE, fcntl(tf.fd, F_GETFL) & O_LARGEFILE);
176fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle}
1773cdf5739cd34757943a5fff9d26efeb8da04cb09Elliott Hughes
1783cdf5739cd34757943a5fff9d26efeb8da04cb09Elliott HughesTEST(stdlib, system) {
1793cdf5739cd34757943a5fff9d26efeb8da04cb09Elliott Hughes  int status;
1803cdf5739cd34757943a5fff9d26efeb8da04cb09Elliott Hughes
1813cdf5739cd34757943a5fff9d26efeb8da04cb09Elliott Hughes  status = system("exit 0");
1823cdf5739cd34757943a5fff9d26efeb8da04cb09Elliott Hughes  ASSERT_TRUE(WIFEXITED(status));
1833cdf5739cd34757943a5fff9d26efeb8da04cb09Elliott Hughes  ASSERT_EQ(0, WEXITSTATUS(status));
1843cdf5739cd34757943a5fff9d26efeb8da04cb09Elliott Hughes
1853cdf5739cd34757943a5fff9d26efeb8da04cb09Elliott Hughes  status = system("exit 1");
1863cdf5739cd34757943a5fff9d26efeb8da04cb09Elliott Hughes  ASSERT_TRUE(WIFEXITED(status));
1873cdf5739cd34757943a5fff9d26efeb8da04cb09Elliott Hughes  ASSERT_EQ(1, WEXITSTATUS(status));
1883cdf5739cd34757943a5fff9d26efeb8da04cb09Elliott Hughes}
1895a8173860d65182af022be88fed0c5d8d5dcb69dElliott Hughes
1905a8173860d65182af022be88fed0c5d8d5dcb69dElliott HughesTEST(stdlib, atof) {
191f171b34cf045115b82ccb89b57feb56d3cad472bChristopher Ferris  ASSERT_DOUBLE_EQ(1.23, atof("1.23"));
1925a8173860d65182af022be88fed0c5d8d5dcb69dElliott Hughes}
1935a8173860d65182af022be88fed0c5d8d5dcb69dElliott Hughes
1945a8173860d65182af022be88fed0c5d8d5dcb69dElliott HughesTEST(stdlib, strtod) {
195f171b34cf045115b82ccb89b57feb56d3cad472bChristopher Ferris  ASSERT_DOUBLE_EQ(1.23, strtod("1.23", NULL));
1965a8173860d65182af022be88fed0c5d8d5dcb69dElliott Hughes}
1975a8173860d65182af022be88fed0c5d8d5dcb69dElliott Hughes
1985a8173860d65182af022be88fed0c5d8d5dcb69dElliott HughesTEST(stdlib, strtof) {
199f171b34cf045115b82ccb89b57feb56d3cad472bChristopher Ferris  ASSERT_FLOAT_EQ(1.23, strtof("1.23", NULL));
2005a8173860d65182af022be88fed0c5d8d5dcb69dElliott Hughes}
2015a8173860d65182af022be88fed0c5d8d5dcb69dElliott Hughes
2025a8173860d65182af022be88fed0c5d8d5dcb69dElliott HughesTEST(stdlib, strtold) {
203f171b34cf045115b82ccb89b57feb56d3cad472bChristopher Ferris  ASSERT_DOUBLE_EQ(1.23, strtold("1.23", NULL));
2045a8173860d65182af022be88fed0c5d8d5dcb69dElliott Hughes}
2059f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes
206b8425c549a0bfe08b01b5906b95603d8523c1b16Dan AlbertTEST(stdlib, quick_exit) {
207b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  pid_t pid = fork();
208b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  ASSERT_NE(-1, pid) << strerror(errno);
209b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert
210b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  if (pid == 0) {
211b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert    quick_exit(99);
212b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  }
213b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert
214b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  int status;
215b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  ASSERT_EQ(pid, waitpid(pid, &status, 0));
216b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  ASSERT_TRUE(WIFEXITED(status));
217b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  ASSERT_EQ(99, WEXITSTATUS(status));
218b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert}
219b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert
220b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albertstatic int quick_exit_status = 0;
221b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert
222b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albertstatic void quick_exit_1(void) {
223b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  ASSERT_EQ(quick_exit_status, 0);
224b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  quick_exit_status = 1;
225b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert}
226b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert
227b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albertstatic void quick_exit_2(void) {
228b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  ASSERT_EQ(quick_exit_status, 1);
229b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert}
230b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert
231b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albertstatic void not_run(void) {
232b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  FAIL();
233b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert}
234b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert
235b8425c549a0bfe08b01b5906b95603d8523c1b16Dan AlbertTEST(stdlib, at_quick_exit) {
236b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  pid_t pid = fork();
237b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  ASSERT_NE(-1, pid) << strerror(errno);
238b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert
239b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  if (pid == 0) {
240b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert    ASSERT_EQ(at_quick_exit(quick_exit_2), 0);
241b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert    ASSERT_EQ(at_quick_exit(quick_exit_1), 0);
242b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert    atexit(not_run);
243b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert    quick_exit(99);
244b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  }
245b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert
246b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  int status;
247b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  ASSERT_EQ(pid, waitpid(pid, &status, 0));
248b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  ASSERT_TRUE(WIFEXITED(status));
249b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert  ASSERT_EQ(99, WEXITSTATUS(status));
250b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert}
251b8425c549a0bfe08b01b5906b95603d8523c1b16Dan Albert
2529f525644df99cb2f7f81a23ca23840f0a8f82275Elliott HughesTEST(unistd, _Exit) {
2539f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  int pid = fork();
2549f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  ASSERT_NE(-1, pid) << strerror(errno);
2559f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes
2569f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  if (pid == 0) {
2579f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes    _Exit(99);
2589f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  }
2599f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes
2609f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  int status;
2619f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  ASSERT_EQ(pid, waitpid(pid, &status, 0));
2629f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  ASSERT_TRUE(WIFEXITED(status));
2639f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  ASSERT_EQ(99, WEXITSTATUS(status));
2649f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes}
2652ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes
2662ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott HughesTEST(stdlib, pty_smoke) {
2672ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  // getpt returns a pty with O_RDWR|O_NOCTTY.
2682ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  int fd = getpt();
2692ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_NE(-1, fd);
2702ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes
2712ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  // grantpt is a no-op.
2722ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(0, grantpt(fd));
2732ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes
2742ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  // ptsname_r should start "/dev/pts/".
2752ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  char name_r[128];
2762ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(0, ptsname_r(fd, name_r, sizeof(name_r)));
2772ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  name_r[9] = 0;
2782ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_STREQ("/dev/pts/", name_r);
2792ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes
2802ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  close(fd);
2812ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes}
2822ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes
2832ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott HughesTEST(stdlib, posix_openpt) {
2842ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  int fd = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC);
2852ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_NE(-1, fd);
2862ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  close(fd);
2872ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes}
2882ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes
2892ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott HughesTEST(stdlib, ptsname_r_ENOTTY) {
2902ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  errno = 0;
2912ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  char buf[128];
2922ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(ENOTTY, ptsname_r(STDOUT_FILENO, buf, sizeof(buf)));
2932ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(ENOTTY, errno);
2942ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes}
2952ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes
2962ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott HughesTEST(stdlib, ptsname_r_EINVAL) {
2972ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  int fd = getpt();
2982ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_NE(-1, fd);
2992ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  errno = 0;
3002ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  char* buf = NULL;
3012ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(EINVAL, ptsname_r(fd, buf, 128));
3022ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(EINVAL, errno);
3032ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  close(fd);
3042ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes}
3052ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes
3062ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott HughesTEST(stdlib, ptsname_r_ERANGE) {
3072ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  int fd = getpt();
3082ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_NE(-1, fd);
3092ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  errno = 0;
3102ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  char buf[1];
3112ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(ERANGE, ptsname_r(fd, buf, sizeof(buf)));
3122ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(ERANGE, errno);
3132ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  close(fd);
3142ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes}
3152ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes
3162ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott HughesTEST(stdlib, ttyname_r) {
3172ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  int fd = getpt();
3182ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_NE(-1, fd);
3192ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes
3202ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  // ttyname_r returns "/dev/ptmx" for a pty.
3212ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  char name_r[128];
3222ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(0, ttyname_r(fd, name_r, sizeof(name_r)));
3232ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_STREQ("/dev/ptmx", name_r);
3242ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes
3252ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  close(fd);
3262ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes}
3272ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes
3282ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott HughesTEST(stdlib, ttyname_r_ENOTTY) {
3292ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  int fd = open("/dev/null", O_WRONLY);
3302ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  errno = 0;
3312ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  char buf[128];
3322ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(ENOTTY, ttyname_r(fd, buf, sizeof(buf)));
3332ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(ENOTTY, errno);
3342ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  close(fd);
3352ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes}
3362ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes
3372ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott HughesTEST(stdlib, ttyname_r_EINVAL) {
3382ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  int fd = getpt();
3392ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_NE(-1, fd);
3402ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  errno = 0;
3412ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  char* buf = NULL;
3422ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(EINVAL, ttyname_r(fd, buf, 128));
3432ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(EINVAL, errno);
3442ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  close(fd);
3452ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes}
3462ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes
3472ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott HughesTEST(stdlib, ttyname_r_ERANGE) {
3482ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  int fd = getpt();
3492ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_NE(-1, fd);
3502ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  errno = 0;
3512ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  char buf[1];
3522ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(ERANGE, ttyname_r(fd, buf, sizeof(buf)));
3532ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(ERANGE, errno);
3542ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  close(fd);
3552ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes}
3562ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes
3572ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott HughesTEST(stdlib, unlockpt_ENOTTY) {
3582ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  int fd = open("/dev/null", O_WRONLY);
3592ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  errno = 0;
3602ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(-1, unlockpt(fd));
3612ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  ASSERT_EQ(ENOTTY, errno);
3622ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes  close(fd);
3632ea0a58e01c1ed6db1da9dd0314ee053f5a32026Elliott Hughes}
364