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 */
17 #include <gtest/gtest.h>
18 #include "ScopedSignalHandler.h"
19 #include "TemporaryFile.h"
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <stdint.h>
24 #include <unistd.h>
25 #include <sys/types.h>
26 #include <sys/wait.h>
28 TEST(unistd, sysconf_SC_MONOTONIC_CLOCK) {
29 ASSERT_GT(sysconf(_SC_MONOTONIC_CLOCK), 0);
30 }
32 static void* get_brk() {
33 return sbrk(0);
34 }
36 static void* page_align(uintptr_t addr) {
37 uintptr_t mask = sysconf(_SC_PAGE_SIZE) - 1;
38 return reinterpret_cast<void*>((addr + mask) & ~mask);
39 }
41 TEST(unistd, brk) {
42 void* initial_break = get_brk();
44 // The kernel aligns the break to a page.
45 void* new_break = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(initial_break) + 1);
46 ASSERT_EQ(0, brk(new_break));
47 ASSERT_GE(get_brk(), new_break);
49 new_break = page_align(reinterpret_cast<uintptr_t>(initial_break) + sysconf(_SC_PAGE_SIZE));
50 ASSERT_EQ(0, brk(new_break));
51 ASSERT_EQ(get_brk(), new_break);
52 }
54 TEST(unistd, brk_ENOMEM) {
55 ASSERT_EQ(-1, brk(reinterpret_cast<void*>(-1)));
56 ASSERT_EQ(ENOMEM, errno);
57 }
59 TEST(unistd, sbrk_ENOMEM) {
60 intptr_t current_brk = reinterpret_cast<intptr_t>(get_brk());
62 // Can't increase by so much that we'd overflow.
63 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MAX));
64 ASSERT_EQ(ENOMEM, errno);
66 // Can't reduce by more than the current break.
67 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(-(current_brk + 1)));
68 ASSERT_EQ(ENOMEM, errno);
70 #if defined(__BIONIC__)
71 // The maximum negative value is an interesting special case that glibc gets wrong.
72 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN));
73 ASSERT_EQ(ENOMEM, errno);
74 #endif
75 }
77 TEST(unistd, truncate) {
78 TemporaryFile tf;
79 ASSERT_EQ(0, close(tf.fd));
80 ASSERT_EQ(0, truncate(tf.filename, 123));
82 struct stat sb;
83 ASSERT_EQ(0, stat(tf.filename, &sb));
84 ASSERT_EQ(123, sb.st_size);
85 }
87 TEST(unistd, truncate64) {
88 TemporaryFile tf;
89 ASSERT_EQ(0, close(tf.fd));
90 ASSERT_EQ(0, truncate64(tf.filename, 123));
92 struct stat sb;
93 ASSERT_EQ(0, stat(tf.filename, &sb));
94 ASSERT_EQ(123, sb.st_size);
95 }
97 TEST(unistd, ftruncate) {
98 TemporaryFile tf;
99 ASSERT_EQ(0, ftruncate(tf.fd, 123));
100 ASSERT_EQ(0, close(tf.fd));
102 struct stat sb;
103 ASSERT_EQ(0, stat(tf.filename, &sb));
104 ASSERT_EQ(123, sb.st_size);
105 }
107 TEST(unistd, ftruncate64) {
108 TemporaryFile tf;
109 ASSERT_EQ(0, ftruncate64(tf.fd, 123));
110 ASSERT_EQ(0, close(tf.fd));
112 struct stat sb;
113 ASSERT_EQ(0, stat(tf.filename, &sb));
114 ASSERT_EQ(123, sb.st_size);
115 }
117 static bool g_pause_test_flag = false;
118 static void PauseTestSignalHandler(int) {
119 g_pause_test_flag = true;
120 }
122 TEST(unistd, pause) {
123 ScopedSignalHandler handler(SIGALRM, PauseTestSignalHandler);
125 alarm(1);
126 ASSERT_FALSE(g_pause_test_flag);
127 ASSERT_EQ(-1, pause());
128 ASSERT_TRUE(g_pause_test_flag);
129 }
131 TEST(unistd, read) {
132 int fd = open("/proc/version", O_RDONLY);
133 ASSERT_TRUE(fd != -1);
135 char buf[5];
136 ASSERT_EQ(5, read(fd, buf, 5));
137 ASSERT_EQ(buf[0], 'L');
138 ASSERT_EQ(buf[1], 'i');
139 ASSERT_EQ(buf[2], 'n');
140 ASSERT_EQ(buf[3], 'u');
141 ASSERT_EQ(buf[4], 'x');
142 close(fd);
143 }
145 TEST(unistd, read_EBADF) {
146 // read returns ssize_t which is 64-bits on LP64, so it's worth explicitly checking that
147 // our syscall stubs correctly return a 64-bit -1.
148 char buf[1];
149 ASSERT_EQ(-1, read(-1, buf, sizeof(buf)));
150 ASSERT_EQ(EBADF, errno);
151 }
153 TEST(unistd, alarm) {
154 ASSERT_EQ(0U, alarm(0));
155 }
157 TEST(unistd, _exit) {
158 int pid = fork();
159 ASSERT_NE(-1, pid) << strerror(errno);
161 if (pid == 0) {
162 _exit(99);
163 }
165 int status;
166 ASSERT_EQ(pid, waitpid(pid, &status, 0));
167 ASSERT_TRUE(WIFEXITED(status));
168 ASSERT_EQ(99, WEXITSTATUS(status));
169 }
171 TEST(unistd, getenv_unsetenv) {
172 ASSERT_EQ(0, setenv("test-variable", "hello", 1));
173 ASSERT_STREQ("hello", getenv("test-variable"));
174 ASSERT_EQ(0, unsetenv("test-variable"));
175 ASSERT_TRUE(getenv("test-variable") == NULL);
176 }
178 TEST(unistd, unsetenv_EINVAL) {
179 EXPECT_EQ(-1, unsetenv(NULL));
180 EXPECT_EQ(EINVAL, errno);
181 EXPECT_EQ(-1, unsetenv(""));
182 EXPECT_EQ(EINVAL, errno);
183 EXPECT_EQ(-1, unsetenv("a=b"));
184 EXPECT_EQ(EINVAL, errno);
185 }
187 TEST(unistd, setenv_EINVAL) {
188 EXPECT_EQ(-1, setenv(NULL, "value", 0));
189 EXPECT_EQ(EINVAL, errno);
190 EXPECT_EQ(-1, setenv(NULL, "value", 1));
191 EXPECT_EQ(EINVAL, errno);
192 EXPECT_EQ(-1, setenv("", "value", 0));
193 EXPECT_EQ(EINVAL, errno);
194 EXPECT_EQ(-1, setenv("", "value", 1));
195 EXPECT_EQ(EINVAL, errno);
196 EXPECT_EQ(-1, setenv("a=b", "value", 0));
197 EXPECT_EQ(EINVAL, errno);
198 EXPECT_EQ(-1, setenv("a=b", "value", 1));
199 EXPECT_EQ(EINVAL, errno);
200 }
202 TEST(unistd, setenv) {
203 ASSERT_EQ(0, unsetenv("test-variable"));
205 char a[] = "a";
206 char b[] = "b";
207 char c[] = "c";
209 // New value.
210 EXPECT_EQ(0, setenv("test-variable", a, 0));
211 EXPECT_STREQ(a, getenv("test-variable"));
213 // Existing value, no overwrite.
214 EXPECT_EQ(0, setenv("test-variable", b, 0));
215 EXPECT_STREQ(a, getenv("test-variable"));
217 // Existing value, overwrite.
218 EXPECT_EQ(0, setenv("test-variable", c, 1));
219 EXPECT_STREQ(c, getenv("test-variable"));
220 // But the arrays backing the values are unchanged.
221 EXPECT_EQ('a', a[0]);
222 EXPECT_EQ('b', b[0]);
223 EXPECT_EQ('c', c[0]);
225 ASSERT_EQ(0, unsetenv("test-variable"));
226 }
228 TEST(unistd, putenv) {
229 ASSERT_EQ(0, unsetenv("a"));
231 char* s1 = strdup("a=b");
232 ASSERT_EQ(0, putenv(s1));
234 ASSERT_STREQ("b", getenv("a"));
235 s1[2] = 'c';
236 ASSERT_STREQ("c", getenv("a"));
238 char* s2 = strdup("a=b");
239 ASSERT_EQ(0, putenv(s2));
241 ASSERT_STREQ("b", getenv("a"));
242 ASSERT_EQ('c', s1[2]);
244 ASSERT_EQ(0, unsetenv("a"));
245 free(s1);
246 free(s2);
247 }
249 TEST(unistd, clearenv) {
250 extern char** environ;
252 // Guarantee that environ is not initially empty...
253 ASSERT_EQ(0, setenv("test-variable", "a", 1));
255 // Stash a copy.
256 std::vector<char*> old_environ;
257 for (size_t i = 0; environ[i] != NULL; ++i) {
258 old_environ.push_back(strdup(environ[i]));
259 }
261 ASSERT_EQ(0, clearenv());
263 EXPECT_TRUE(environ == NULL || environ[0] == NULL);
264 EXPECT_EQ(NULL, getenv("test-variable"));
265 EXPECT_EQ(0, setenv("test-variable", "post-clear", 1));
266 EXPECT_STREQ("post-clear", getenv("test-variable"));
268 // Put the old environment back.
269 for (size_t i = 0; i < old_environ.size(); ++i) {
270 EXPECT_EQ(0, putenv(old_environ[i]));
271 }
273 // Check it wasn't overwritten.
274 EXPECT_STREQ("a", getenv("test-variable"));
276 EXPECT_EQ(0, unsetenv("test-variable"));
277 }
279 static void TestFsyncFunction(int (*fn)(int)) {
280 int fd;
282 // Can't sync an invalid fd.
283 errno = 0;
284 EXPECT_EQ(-1, fn(-1));
285 EXPECT_EQ(EBADF, errno);
287 // It doesn't matter whether you've opened a file for write or not.
288 TemporaryFile tf;
289 ASSERT_NE(-1, tf.fd);
291 EXPECT_EQ(0, fn(tf.fd));
293 ASSERT_NE(-1, fd = open(tf.filename, O_RDONLY));
294 EXPECT_EQ(0, fn(fd));
295 close(fd);
297 ASSERT_NE(-1, fd = open(tf.filename, O_RDWR));
298 EXPECT_EQ(0, fn(fd));
299 close(fd);
301 // The fd can even be a directory.
302 ASSERT_NE(-1, fd = open("/", O_RDONLY));
303 EXPECT_EQ(0, fn(fd));
304 close(fd);
306 // But some file systems may choose to be fussy...
307 errno = 0;
308 ASSERT_NE(-1, fd = open("/proc/version", O_RDONLY));
309 EXPECT_EQ(-1, fn(fd));
310 EXPECT_EQ(EINVAL, errno);
311 close(fd);
312 }
314 TEST(unistd, fdatasync) {
315 TestFsyncFunction(fdatasync);
316 }
318 TEST(unistd, fsync) {
319 TestFsyncFunction(fsync);
320 }