unistd_test.cpp revision cbf6df0459f05e180d1c50b3f5b36cdd483193c6
1a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes/*
2a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * Copyright (C) 2012 The Android Open Source Project
3a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes *
4a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
5a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * you may not use this file except in compliance with the License.
6a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * You may obtain a copy of the License at
7a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes *
8a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
9a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes *
10a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * Unless required by applicable law or agreed to in writing, software
11a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
12a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * See the License for the specific language governing permissions and
14a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes * limitations under the License.
15a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes */
16a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes
17a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes#include <gtest/gtest.h>
1813613137bc4266656bffce464e525eb9ae6371f0Christopher Ferris#include "ScopedSignalHandler.h"
19b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes#include "TemporaryFile.h"
20a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes
21915fefb62e1beed3da26fe299a8141645733a925Elliott Hughes#include <errno.h>
223d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross#include <fcntl.h>
23428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes#include <stdint.h>
24a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes#include <unistd.h>
25764a99361130dceda62bbc4f8780bbf395dbc424Elliott Hughes#include <sys/types.h>
26764a99361130dceda62bbc4f8780bbf395dbc424Elliott Hughes#include <sys/wait.h>
27a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes
28a55f63083fb16b2595f517a3260083e5f8cddd02Elliott HughesTEST(unistd, sysconf_SC_MONOTONIC_CLOCK) {
29a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes  ASSERT_GT(sysconf(_SC_MONOTONIC_CLOCK), 0);
30a55f63083fb16b2595f517a3260083e5f8cddd02Elliott Hughes}
31428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes
32428f5567be25b8090e3dd72e2d3d337c305b514eElliott HughesTEST(unistd, sbrk) {
33428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes  void* initial_break = sbrk(0);
34428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes
35428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes  void* new_break = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(initial_break) + 2000);
36428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes  ASSERT_EQ(0, brk(new_break));
37428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes
38428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes  void* final_break = sbrk(0);
39428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes  ASSERT_EQ(final_break, new_break);
40428f5567be25b8090e3dd72e2d3d337c305b514eElliott Hughes}
41b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
42b4f7616fd618875768b8fffc122b58bdb84a9969Elliott HughesTEST(unistd, truncate) {
43b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  TemporaryFile tf;
44b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, close(tf.fd));
45b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, truncate(tf.filename, 123));
46b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
47b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  struct stat sb;
48b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, stat(tf.filename, &sb));
49b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(123, sb.st_size);
50b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes}
51b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
52b4f7616fd618875768b8fffc122b58bdb84a9969Elliott HughesTEST(unistd, truncate64) {
53b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  TemporaryFile tf;
54b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, close(tf.fd));
55b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, truncate64(tf.filename, 123));
56b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
57b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  struct stat sb;
58b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, stat(tf.filename, &sb));
59b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(123, sb.st_size);
60b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes}
61b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
62b4f7616fd618875768b8fffc122b58bdb84a9969Elliott HughesTEST(unistd, ftruncate) {
63b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  TemporaryFile tf;
64b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, ftruncate(tf.fd, 123));
65b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, close(tf.fd));
66b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
67b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  struct stat sb;
68b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, stat(tf.filename, &sb));
69b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(123, sb.st_size);
70b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes}
71b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
72b4f7616fd618875768b8fffc122b58bdb84a9969Elliott HughesTEST(unistd, ftruncate64) {
73b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  TemporaryFile tf;
74b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, ftruncate64(tf.fd, 123));
75b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, close(tf.fd));
76b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes
77b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  struct stat sb;
78b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(0, stat(tf.filename, &sb));
79b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes  ASSERT_EQ(123, sb.st_size);
80b4f7616fd618875768b8fffc122b58bdb84a9969Elliott Hughes}
8111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
8211952073af22568bba0b661f7a9d4402c443a888Elliott Hughesstatic bool gPauseTestFlag = false;
8311952073af22568bba0b661f7a9d4402c443a888Elliott Hughesstatic void PauseTestSignalHandler(int) {
8411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  gPauseTestFlag = true;
8511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes}
8611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes
8711952073af22568bba0b661f7a9d4402c443a888Elliott HughesTEST(unistd, pause) {
8813613137bc4266656bffce464e525eb9ae6371f0Christopher Ferris  ScopedSignalHandler handler(SIGALRM, PauseTestSignalHandler);
8913613137bc4266656bffce464e525eb9ae6371f0Christopher Ferris
9011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  alarm(1);
9111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  ASSERT_FALSE(gPauseTestFlag);
9211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  ASSERT_EQ(-1, pause());
9311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes  ASSERT_TRUE(gPauseTestFlag);
9411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes}
953d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross
963d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin CrossTEST(unistd, read) {
973d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  int fd = open("/proc/version", O_RDONLY);
983d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_TRUE(fd != -1);
993d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross
1003d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  char buf[5];
1013d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_EQ(5, read(fd, buf, 5));
1023d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_EQ(buf[0], 'L');
1033d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_EQ(buf[1], 'i');
1043d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_EQ(buf[2], 'n');
1053d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_EQ(buf[3], 'u');
1063d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_EQ(buf[4], 'x');
1073d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  close(fd);
1083d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross}
1093d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross
1103d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin CrossTEST(unistd, read_EBADF) {
1113d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  // read returns ssize_t which is 64-bits on LP64, so it's worth explicitly checking that
1123d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  // our syscall stubs correctly return a 64-bit -1.
1133d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  char buf[1];
1143d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_EQ(-1, read(-1, buf, sizeof(buf)));
1153d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross  ASSERT_EQ(EBADF, errno);
1163d19a8319b9c27af8aa5cfbf495da0fe7fa62d3eColin Cross}
117aedb00d04eb7f0b20b6abde702ba94a46577ca68Elliott Hughes
118aedb00d04eb7f0b20b6abde702ba94a46577ca68Elliott HughesTEST(unistd, alarm) {
119aedb00d04eb7f0b20b6abde702ba94a46577ca68Elliott Hughes  ASSERT_EQ(0U, alarm(0));
120aedb00d04eb7f0b20b6abde702ba94a46577ca68Elliott Hughes}
1219f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes
1229f525644df99cb2f7f81a23ca23840f0a8f82275Elliott HughesTEST(unistd, _exit) {
1239f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  int pid = fork();
1249f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  ASSERT_NE(-1, pid) << strerror(errno);
1259f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes
1269f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  if (pid == 0) {
1279f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes    _exit(99);
1289f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  }
1299f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes
1309f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  int status;
1319f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  ASSERT_EQ(pid, waitpid(pid, &status, 0));
1329f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  ASSERT_TRUE(WIFEXITED(status));
1339f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes  ASSERT_EQ(99, WEXITSTATUS(status));
1349f525644df99cb2f7f81a23ca23840f0a8f82275Elliott Hughes}
135cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
136cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, getenv_unsetenv) {
137cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, setenv("test-variable", "hello", 1));
138cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_STREQ("hello", getenv("test-variable"));
139cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, unsetenv("test-variable"));
140cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_TRUE(getenv("test-variable") == NULL);
141cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov}
142cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
143cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, unsetenv_EINVAL) {
144cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, unsetenv(NULL));
145cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
146cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, unsetenv(""));
147cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
148cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, unsetenv("a=b"));
149cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
150cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov}
151cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
152cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, setenv_EINVAL) {
153cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, setenv(NULL, "value", 0));
154cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
155cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, setenv(NULL, "value", 1));
156cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
157cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, setenv("", "value", 0));
158cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
159cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, setenv("", "value", 1));
160cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
161cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, setenv("a=b", "value", 0));
162cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
163cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(-1, setenv("a=b", "value", 1));
164cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(EINVAL, errno);
165cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov}
166cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
167cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, setenv) {
168cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, unsetenv("test-variable"));
169cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
170cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  char a[] = "a";
171cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  char b[] = "b";
172cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  char c[] = "c";
173cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
174cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  // New value.
175cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(0, setenv("test-variable", a, 0));
176cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_STREQ(a, getenv("test-variable"));
177cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
178cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  // Existing value, no overwrite.
179cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(0, setenv("test-variable", b, 0));
180cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_STREQ(a, getenv("test-variable"));
181cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
182cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  // Existing value, overwrite.
183cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(0, setenv("test-variable", c, 1));
184cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_STREQ(c, getenv("test-variable"));
185cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  // But the arrays backing the values are unchanged.
186cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ('a', a[0]);
187cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ('b', b[0]);
188cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ('c', c[0]);
189cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
190cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, unsetenv("test-variable"));
191cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov}
192cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
193cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, putenv) {
194cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, unsetenv("a"));
195cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
196cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  char* s1 = strdup("a=b");
197cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, putenv(s1));
198cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
199cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_STREQ("b", getenv("a"));
200cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  s1[2] = 'c';
201cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_STREQ("c", getenv("a"));
202cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
203cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  char* s2 = strdup("a=b");
204cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, putenv(s2));
205cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
206cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_STREQ("b", getenv("a"));
207cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ('c', s1[2]);
208cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
209cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, unsetenv("a"));
210cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  free(s1);
211cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  free(s2);
212cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov}
213cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
214cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy KraynovTEST(unistd, clearenv) {
215cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  extern char** environ;
216cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
217cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  // Guarantee that environ is not initially empty...
218cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, setenv("test-variable", "a", 1));
219cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
220cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  // Stash a copy.
221cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  std::vector<char*> old_environ;
222cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  for (size_t i = 0; environ[i] != NULL; ++i) {
223cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov    old_environ.push_back(strdup(environ[i]));
224cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  }
225cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
226cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  ASSERT_EQ(0, clearenv());
227cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
228cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_TRUE(environ == NULL || environ[0] == NULL);
229cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(NULL, getenv("test-variable"));
230cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(0, setenv("test-variable", "post-clear", 1));
231cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_STREQ("post-clear", getenv("test-variable"));
232cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
233cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  // Put the old environment back.
234cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  for (size_t i = 0; i < old_environ.size(); ++i) {
235cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov    EXPECT_EQ(0, putenv(old_environ[i]));
236cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  }
237cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
238cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  // Check it wasn't overwritten.
239cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_STREQ("a", getenv("test-variable"));
240cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov
241cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov  EXPECT_EQ(0, unsetenv("test-variable"));
242cbf6df0459f05e180d1c50b3f5b36cdd483193c6Grigoriy Kraynov}
243