1*8f0ba417SAndroid Build Coastguard Worker /*
2*8f0ba417SAndroid Build Coastguard Worker * Copyright (C) 2013 The Android Open Source Project
3*8f0ba417SAndroid Build Coastguard Worker *
4*8f0ba417SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*8f0ba417SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*8f0ba417SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*8f0ba417SAndroid Build Coastguard Worker *
8*8f0ba417SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*8f0ba417SAndroid Build Coastguard Worker *
10*8f0ba417SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*8f0ba417SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*8f0ba417SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8f0ba417SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*8f0ba417SAndroid Build Coastguard Worker * limitations under the License.
15*8f0ba417SAndroid Build Coastguard Worker */
16*8f0ba417SAndroid Build Coastguard Worker
17*8f0ba417SAndroid Build Coastguard Worker #include "android-base/file.h"
18*8f0ba417SAndroid Build Coastguard Worker
19*8f0ba417SAndroid Build Coastguard Worker #include "android-base/utf8.h"
20*8f0ba417SAndroid Build Coastguard Worker
21*8f0ba417SAndroid Build Coastguard Worker #include <gtest/gtest.h>
22*8f0ba417SAndroid Build Coastguard Worker
23*8f0ba417SAndroid Build Coastguard Worker #include <errno.h>
24*8f0ba417SAndroid Build Coastguard Worker #include <fcntl.h>
25*8f0ba417SAndroid Build Coastguard Worker #include <unistd.h>
26*8f0ba417SAndroid Build Coastguard Worker #include <wchar.h>
27*8f0ba417SAndroid Build Coastguard Worker
28*8f0ba417SAndroid Build Coastguard Worker #include <string>
29*8f0ba417SAndroid Build Coastguard Worker
30*8f0ba417SAndroid Build Coastguard Worker #if !defined(_WIN32)
31*8f0ba417SAndroid Build Coastguard Worker #include <pwd.h>
32*8f0ba417SAndroid Build Coastguard Worker #else
33*8f0ba417SAndroid Build Coastguard Worker #include <windows.h>
34*8f0ba417SAndroid Build Coastguard Worker #endif
35*8f0ba417SAndroid Build Coastguard Worker
36*8f0ba417SAndroid Build Coastguard Worker #include "android-base/logging.h" // and must be after windows.h for ERROR
37*8f0ba417SAndroid Build Coastguard Worker
TEST(file,ReadFileToString_ENOENT)38*8f0ba417SAndroid Build Coastguard Worker TEST(file, ReadFileToString_ENOENT) {
39*8f0ba417SAndroid Build Coastguard Worker std::string s("hello");
40*8f0ba417SAndroid Build Coastguard Worker errno = 0;
41*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(android::base::ReadFileToString("/proc/does-not-exist", &s));
42*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(ENOENT, errno);
43*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("", s); // s was cleared.
44*8f0ba417SAndroid Build Coastguard Worker }
45*8f0ba417SAndroid Build Coastguard Worker
TEST(file,ReadFileToString_WriteStringToFile)46*8f0ba417SAndroid Build Coastguard Worker TEST(file, ReadFileToString_WriteStringToFile) {
47*8f0ba417SAndroid Build Coastguard Worker TemporaryFile tf;
48*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE(tf.fd, -1) << tf.path;
49*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteStringToFile("abc", tf.path))
50*8f0ba417SAndroid Build Coastguard Worker << strerror(errno);
51*8f0ba417SAndroid Build Coastguard Worker std::string s;
52*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFileToString(tf.path, &s))
53*8f0ba417SAndroid Build Coastguard Worker << strerror(errno);
54*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("abc", s);
55*8f0ba417SAndroid Build Coastguard Worker }
56*8f0ba417SAndroid Build Coastguard Worker
57*8f0ba417SAndroid Build Coastguard Worker // symlinks require elevated privileges on Windows.
58*8f0ba417SAndroid Build Coastguard Worker #if !defined(_WIN32)
TEST(file,ReadFileToString_WriteStringToFile_symlink)59*8f0ba417SAndroid Build Coastguard Worker TEST(file, ReadFileToString_WriteStringToFile_symlink) {
60*8f0ba417SAndroid Build Coastguard Worker TemporaryFile target, link;
61*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(0, unlink(link.path));
62*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(0, symlink(target.path, link.path));
63*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(android::base::WriteStringToFile("foo", link.path, false));
64*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(ELOOP, errno);
65*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteStringToFile("foo", link.path, true));
66*8f0ba417SAndroid Build Coastguard Worker
67*8f0ba417SAndroid Build Coastguard Worker std::string s;
68*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(android::base::ReadFileToString(link.path, &s));
69*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(ELOOP, errno);
70*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFileToString(link.path, &s, true));
71*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ("foo", s);
72*8f0ba417SAndroid Build Coastguard Worker }
73*8f0ba417SAndroid Build Coastguard Worker #endif
74*8f0ba417SAndroid Build Coastguard Worker
75*8f0ba417SAndroid Build Coastguard Worker // WriteStringToFile2 is explicitly for setting Unix permissions, which make no
76*8f0ba417SAndroid Build Coastguard Worker // sense on Windows.
77*8f0ba417SAndroid Build Coastguard Worker #if !defined(_WIN32)
TEST(file,WriteStringToFile2)78*8f0ba417SAndroid Build Coastguard Worker TEST(file, WriteStringToFile2) {
79*8f0ba417SAndroid Build Coastguard Worker TemporaryFile tf;
80*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE(tf.fd, -1) << tf.path;
81*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteStringToFile("abc", tf.path, 0660,
82*8f0ba417SAndroid Build Coastguard Worker getuid(), getgid()))
83*8f0ba417SAndroid Build Coastguard Worker << strerror(errno);
84*8f0ba417SAndroid Build Coastguard Worker struct stat sb;
85*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(0, stat(tf.path, &sb));
86*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(0660U, static_cast<unsigned int>(sb.st_mode & ~S_IFMT));
87*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(getuid(), sb.st_uid);
88*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(getgid(), sb.st_gid);
89*8f0ba417SAndroid Build Coastguard Worker std::string s;
90*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFileToString(tf.path, &s))
91*8f0ba417SAndroid Build Coastguard Worker << strerror(errno);
92*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("abc", s);
93*8f0ba417SAndroid Build Coastguard Worker }
94*8f0ba417SAndroid Build Coastguard Worker #endif
95*8f0ba417SAndroid Build Coastguard Worker
96*8f0ba417SAndroid Build Coastguard Worker #if defined(_WIN32)
TEST(file,NonUnicodeCharsWindows)97*8f0ba417SAndroid Build Coastguard Worker TEST(file, NonUnicodeCharsWindows) {
98*8f0ba417SAndroid Build Coastguard Worker constexpr auto kMaxEnvVariableValueSize = 32767;
99*8f0ba417SAndroid Build Coastguard Worker std::wstring old_tmp;
100*8f0ba417SAndroid Build Coastguard Worker old_tmp.resize(kMaxEnvVariableValueSize);
101*8f0ba417SAndroid Build Coastguard Worker old_tmp.resize(GetEnvironmentVariableW(L"TMP", old_tmp.data(), old_tmp.size()));
102*8f0ba417SAndroid Build Coastguard Worker if (old_tmp.empty()) {
103*8f0ba417SAndroid Build Coastguard Worker // Can't continue with empty TMP folder.
104*8f0ba417SAndroid Build Coastguard Worker return;
105*8f0ba417SAndroid Build Coastguard Worker }
106*8f0ba417SAndroid Build Coastguard Worker
107*8f0ba417SAndroid Build Coastguard Worker std::wstring new_tmp = old_tmp;
108*8f0ba417SAndroid Build Coastguard Worker if (new_tmp.back() != L'\\') {
109*8f0ba417SAndroid Build Coastguard Worker new_tmp.push_back(L'\\');
110*8f0ba417SAndroid Build Coastguard Worker }
111*8f0ba417SAndroid Build Coastguard Worker
112*8f0ba417SAndroid Build Coastguard Worker {
113*8f0ba417SAndroid Build Coastguard Worker auto path(new_tmp + L"锦绣成都\\");
114*8f0ba417SAndroid Build Coastguard Worker _wmkdir(path.c_str());
115*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(SetEnvironmentVariableW(L"TMP", path.c_str()));
116*8f0ba417SAndroid Build Coastguard Worker
117*8f0ba417SAndroid Build Coastguard Worker TemporaryFile tf;
118*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE(tf.fd, -1) << tf.path;
119*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteStringToFd("abc", tf.fd));
120*8f0ba417SAndroid Build Coastguard Worker
121*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)) << strerror(errno);
122*8f0ba417SAndroid Build Coastguard Worker
123*8f0ba417SAndroid Build Coastguard Worker std::string s;
124*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)) << strerror(errno);
125*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("abc", s);
126*8f0ba417SAndroid Build Coastguard Worker }
127*8f0ba417SAndroid Build Coastguard Worker {
128*8f0ba417SAndroid Build Coastguard Worker auto path(new_tmp + L"директория с длинным именем\\");
129*8f0ba417SAndroid Build Coastguard Worker _wmkdir(path.c_str());
130*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(SetEnvironmentVariableW(L"TMP", path.c_str()));
131*8f0ba417SAndroid Build Coastguard Worker
132*8f0ba417SAndroid Build Coastguard Worker TemporaryFile tf;
133*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE(tf.fd, -1) << tf.path;
134*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteStringToFd("abc", tf.fd));
135*8f0ba417SAndroid Build Coastguard Worker
136*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)) << strerror(errno);
137*8f0ba417SAndroid Build Coastguard Worker
138*8f0ba417SAndroid Build Coastguard Worker std::string s;
139*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)) << strerror(errno);
140*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("abc", s);
141*8f0ba417SAndroid Build Coastguard Worker }
142*8f0ba417SAndroid Build Coastguard Worker {
143*8f0ba417SAndroid Build Coastguard Worker auto path(new_tmp + L"äüöß weiß\\");
144*8f0ba417SAndroid Build Coastguard Worker _wmkdir(path.c_str());
145*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(SetEnvironmentVariableW(L"TMP", path.c_str()));
146*8f0ba417SAndroid Build Coastguard Worker
147*8f0ba417SAndroid Build Coastguard Worker TemporaryFile tf;
148*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE(tf.fd, -1) << tf.path;
149*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteStringToFd("abc", tf.fd));
150*8f0ba417SAndroid Build Coastguard Worker
151*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)) << strerror(errno);
152*8f0ba417SAndroid Build Coastguard Worker
153*8f0ba417SAndroid Build Coastguard Worker std::string s;
154*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)) << strerror(errno);
155*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("abc", s);
156*8f0ba417SAndroid Build Coastguard Worker }
157*8f0ba417SAndroid Build Coastguard Worker
158*8f0ba417SAndroid Build Coastguard Worker SetEnvironmentVariableW(L"TMP", old_tmp.c_str());
159*8f0ba417SAndroid Build Coastguard Worker }
160*8f0ba417SAndroid Build Coastguard Worker
TEST(file,RootDirectoryWindows)161*8f0ba417SAndroid Build Coastguard Worker TEST(file, RootDirectoryWindows) {
162*8f0ba417SAndroid Build Coastguard Worker constexpr auto kMaxEnvVariableValueSize = 32767;
163*8f0ba417SAndroid Build Coastguard Worker std::wstring old_tmp;
164*8f0ba417SAndroid Build Coastguard Worker bool tmp_is_empty = false;
165*8f0ba417SAndroid Build Coastguard Worker old_tmp.resize(kMaxEnvVariableValueSize);
166*8f0ba417SAndroid Build Coastguard Worker old_tmp.resize(GetEnvironmentVariableW(L"TMP", old_tmp.data(), old_tmp.size()));
167*8f0ba417SAndroid Build Coastguard Worker if (old_tmp.empty()) {
168*8f0ba417SAndroid Build Coastguard Worker tmp_is_empty = (GetLastError() == ERROR_ENVVAR_NOT_FOUND);
169*8f0ba417SAndroid Build Coastguard Worker }
170*8f0ba417SAndroid Build Coastguard Worker SetEnvironmentVariableW(L"TMP", L"C:");
171*8f0ba417SAndroid Build Coastguard Worker
172*8f0ba417SAndroid Build Coastguard Worker TemporaryFile tf;
173*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE(tf.fd, -1) << tf.path;
174*8f0ba417SAndroid Build Coastguard Worker
175*8f0ba417SAndroid Build Coastguard Worker SetEnvironmentVariableW(L"TMP", tmp_is_empty ? nullptr : old_tmp.c_str());
176*8f0ba417SAndroid Build Coastguard Worker }
177*8f0ba417SAndroid Build Coastguard Worker #endif
178*8f0ba417SAndroid Build Coastguard Worker
TEST(file,WriteStringToFd_StringLiteral)179*8f0ba417SAndroid Build Coastguard Worker TEST(file, WriteStringToFd_StringLiteral) {
180*8f0ba417SAndroid Build Coastguard Worker TemporaryFile tf;
181*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE(tf.fd, -1) << tf.path;
182*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteStringToFd("abc", tf.fd));
183*8f0ba417SAndroid Build Coastguard Worker
184*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)) << strerror(errno);
185*8f0ba417SAndroid Build Coastguard Worker
186*8f0ba417SAndroid Build Coastguard Worker std::string s;
187*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)) << strerror(errno);
188*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("abc", s);
189*8f0ba417SAndroid Build Coastguard Worker }
190*8f0ba417SAndroid Build Coastguard Worker
TEST(file,WriteStringToFd_String)191*8f0ba417SAndroid Build Coastguard Worker TEST(file, WriteStringToFd_String) {
192*8f0ba417SAndroid Build Coastguard Worker std::string testStr = "def";
193*8f0ba417SAndroid Build Coastguard Worker TemporaryFile tf;
194*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE(tf.fd, -1) << tf.path;
195*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteStringToFd(testStr, tf.fd));
196*8f0ba417SAndroid Build Coastguard Worker
197*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)) << strerror(errno);
198*8f0ba417SAndroid Build Coastguard Worker
199*8f0ba417SAndroid Build Coastguard Worker std::string s;
200*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)) << strerror(errno);
201*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(testStr, s);
202*8f0ba417SAndroid Build Coastguard Worker }
203*8f0ba417SAndroid Build Coastguard Worker
TEST(file,WriteStringToFd_StringView)204*8f0ba417SAndroid Build Coastguard Worker TEST(file, WriteStringToFd_StringView) {
205*8f0ba417SAndroid Build Coastguard Worker std::string_view testStrView = "ghi";
206*8f0ba417SAndroid Build Coastguard Worker TemporaryFile tf;
207*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE(tf.fd, -1) << tf.path;
208*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteStringToFd(testStrView, tf.fd));
209*8f0ba417SAndroid Build Coastguard Worker
210*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)) << strerror(errno);
211*8f0ba417SAndroid Build Coastguard Worker
212*8f0ba417SAndroid Build Coastguard Worker std::string s;
213*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFdToString(tf.fd, &s)) << strerror(errno);
214*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(testStrView, s);
215*8f0ba417SAndroid Build Coastguard Worker }
216*8f0ba417SAndroid Build Coastguard Worker
TEST(file,WriteFully)217*8f0ba417SAndroid Build Coastguard Worker TEST(file, WriteFully) {
218*8f0ba417SAndroid Build Coastguard Worker TemporaryFile tf;
219*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE(tf.fd, -1) << tf.path;
220*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteFully(tf.fd, "abc", 3));
221*8f0ba417SAndroid Build Coastguard Worker
222*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)) << strerror(errno);
223*8f0ba417SAndroid Build Coastguard Worker
224*8f0ba417SAndroid Build Coastguard Worker std::string s;
225*8f0ba417SAndroid Build Coastguard Worker s.resize(3);
226*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFully(tf.fd, &s[0], s.size()))
227*8f0ba417SAndroid Build Coastguard Worker << strerror(errno);
228*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("abc", s);
229*8f0ba417SAndroid Build Coastguard Worker
230*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET)) << strerror(errno);
231*8f0ba417SAndroid Build Coastguard Worker
232*8f0ba417SAndroid Build Coastguard Worker s.resize(1024);
233*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(android::base::ReadFully(tf.fd, &s[0], s.size()));
234*8f0ba417SAndroid Build Coastguard Worker }
235*8f0ba417SAndroid Build Coastguard Worker
TEST(file,RemoveFileIfExists)236*8f0ba417SAndroid Build Coastguard Worker TEST(file, RemoveFileIfExists) {
237*8f0ba417SAndroid Build Coastguard Worker TemporaryFile tf;
238*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE(tf.fd, -1) << tf.path;
239*8f0ba417SAndroid Build Coastguard Worker close(tf.fd);
240*8f0ba417SAndroid Build Coastguard Worker tf.fd = -1;
241*8f0ba417SAndroid Build Coastguard Worker std::string err;
242*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::RemoveFileIfExists(tf.path, &err)) << err;
243*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::RemoveFileIfExists(tf.path));
244*8f0ba417SAndroid Build Coastguard Worker TemporaryDir td;
245*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(android::base::RemoveFileIfExists(td.path));
246*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(android::base::RemoveFileIfExists(td.path, &err));
247*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ("is not a regular file or symbolic link", err);
248*8f0ba417SAndroid Build Coastguard Worker }
249*8f0ba417SAndroid Build Coastguard Worker
TEST(file,RemoveFileIfExists_ENOTDIR)250*8f0ba417SAndroid Build Coastguard Worker TEST(file, RemoveFileIfExists_ENOTDIR) {
251*8f0ba417SAndroid Build Coastguard Worker TemporaryFile tf;
252*8f0ba417SAndroid Build Coastguard Worker close(tf.fd);
253*8f0ba417SAndroid Build Coastguard Worker tf.fd = -1;
254*8f0ba417SAndroid Build Coastguard Worker std::string err{"xxx"};
255*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::RemoveFileIfExists(std::string{tf.path} + "/abc", &err));
256*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ("xxx", err);
257*8f0ba417SAndroid Build Coastguard Worker }
258*8f0ba417SAndroid Build Coastguard Worker
259*8f0ba417SAndroid Build Coastguard Worker #if !defined(_WIN32)
TEST(file,RemoveFileIfExists_EACCES)260*8f0ba417SAndroid Build Coastguard Worker TEST(file, RemoveFileIfExists_EACCES) {
261*8f0ba417SAndroid Build Coastguard Worker // EACCES -- one of the directories in the path has no search permission
262*8f0ba417SAndroid Build Coastguard Worker // root can bypass permission restrictions, so drop root.
263*8f0ba417SAndroid Build Coastguard Worker if (getuid() == 0) {
264*8f0ba417SAndroid Build Coastguard Worker passwd* shell = getpwnam("shell");
265*8f0ba417SAndroid Build Coastguard Worker setgid(shell->pw_gid);
266*8f0ba417SAndroid Build Coastguard Worker setuid(shell->pw_uid);
267*8f0ba417SAndroid Build Coastguard Worker }
268*8f0ba417SAndroid Build Coastguard Worker
269*8f0ba417SAndroid Build Coastguard Worker TemporaryDir td;
270*8f0ba417SAndroid Build Coastguard Worker TemporaryFile tf(td.path);
271*8f0ba417SAndroid Build Coastguard Worker close(tf.fd);
272*8f0ba417SAndroid Build Coastguard Worker tf.fd = -1;
273*8f0ba417SAndroid Build Coastguard Worker std::string err{"xxx"};
274*8f0ba417SAndroid Build Coastguard Worker // Remove dir's search permission.
275*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(chmod(td.path, S_IRUSR | S_IWUSR) == 0);
276*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(android::base::RemoveFileIfExists(tf.path, &err));
277*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ("Permission denied", err);
278*8f0ba417SAndroid Build Coastguard Worker // Set dir's search permission again.
279*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(chmod(td.path, S_IRWXU) == 0);
280*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::RemoveFileIfExists(tf.path, &err));
281*8f0ba417SAndroid Build Coastguard Worker }
282*8f0ba417SAndroid Build Coastguard Worker #endif
283*8f0ba417SAndroid Build Coastguard Worker
TEST(file,Readlink)284*8f0ba417SAndroid Build Coastguard Worker TEST(file, Readlink) {
285*8f0ba417SAndroid Build Coastguard Worker #if !defined(_WIN32)
286*8f0ba417SAndroid Build Coastguard Worker // Linux doesn't allow empty symbolic links.
287*8f0ba417SAndroid Build Coastguard Worker std::string min("x");
288*8f0ba417SAndroid Build Coastguard Worker // ext2 and ext4 both have PAGE_SIZE limits.
289*8f0ba417SAndroid Build Coastguard Worker // If file encryption is enabled, there's extra overhead to store the
290*8f0ba417SAndroid Build Coastguard Worker // size of the encrypted symlink target. There's also an off-by-one
291*8f0ba417SAndroid Build Coastguard Worker // in current kernels (and marlin/sailfish where we're seeing this
292*8f0ba417SAndroid Build Coastguard Worker // failure are still on 3.18, far from current). http://b/33306057.
293*8f0ba417SAndroid Build Coastguard Worker std::string max(static_cast<size_t>(4096 - 2 - 1 - 1), 'x');
294*8f0ba417SAndroid Build Coastguard Worker
295*8f0ba417SAndroid Build Coastguard Worker TemporaryDir td;
296*8f0ba417SAndroid Build Coastguard Worker std::string min_path{std::string(td.path) + "/" + "min"};
297*8f0ba417SAndroid Build Coastguard Worker std::string max_path{std::string(td.path) + "/" + "max"};
298*8f0ba417SAndroid Build Coastguard Worker
299*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(0, symlink(min.c_str(), min_path.c_str()));
300*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(0, symlink(max.c_str(), max_path.c_str()));
301*8f0ba417SAndroid Build Coastguard Worker
302*8f0ba417SAndroid Build Coastguard Worker std::string result;
303*8f0ba417SAndroid Build Coastguard Worker
304*8f0ba417SAndroid Build Coastguard Worker result = "wrong";
305*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::Readlink(min_path, &result));
306*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(min, result);
307*8f0ba417SAndroid Build Coastguard Worker
308*8f0ba417SAndroid Build Coastguard Worker result = "wrong";
309*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::Readlink(max_path, &result));
310*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(max, result);
311*8f0ba417SAndroid Build Coastguard Worker #endif
312*8f0ba417SAndroid Build Coastguard Worker }
313*8f0ba417SAndroid Build Coastguard Worker
TEST(file,Realpath)314*8f0ba417SAndroid Build Coastguard Worker TEST(file, Realpath) {
315*8f0ba417SAndroid Build Coastguard Worker #if !defined(_WIN32)
316*8f0ba417SAndroid Build Coastguard Worker TemporaryDir td;
317*8f0ba417SAndroid Build Coastguard Worker std::string basename = android::base::Basename(td.path);
318*8f0ba417SAndroid Build Coastguard Worker std::string dir_name = android::base::Dirname(td.path);
319*8f0ba417SAndroid Build Coastguard Worker std::string base_dir_name = android::base::Basename(dir_name);
320*8f0ba417SAndroid Build Coastguard Worker
321*8f0ba417SAndroid Build Coastguard Worker {
322*8f0ba417SAndroid Build Coastguard Worker std::string path = dir_name + "/../" + base_dir_name + "/" + basename;
323*8f0ba417SAndroid Build Coastguard Worker std::string result;
324*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::Realpath(path, &result));
325*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(td.path, result);
326*8f0ba417SAndroid Build Coastguard Worker }
327*8f0ba417SAndroid Build Coastguard Worker
328*8f0ba417SAndroid Build Coastguard Worker {
329*8f0ba417SAndroid Build Coastguard Worker std::string path = std::string(td.path) + "/..";
330*8f0ba417SAndroid Build Coastguard Worker std::string result;
331*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::Realpath(path, &result));
332*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(dir_name, result);
333*8f0ba417SAndroid Build Coastguard Worker }
334*8f0ba417SAndroid Build Coastguard Worker
335*8f0ba417SAndroid Build Coastguard Worker {
336*8f0ba417SAndroid Build Coastguard Worker errno = 0;
337*8f0ba417SAndroid Build Coastguard Worker std::string path = std::string(td.path) + "/foo.noent";
338*8f0ba417SAndroid Build Coastguard Worker std::string result = "wrong";
339*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(!android::base::Realpath(path, &result));
340*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(result.empty());
341*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(ENOENT, errno);
342*8f0ba417SAndroid Build Coastguard Worker }
343*8f0ba417SAndroid Build Coastguard Worker #endif
344*8f0ba417SAndroid Build Coastguard Worker }
345*8f0ba417SAndroid Build Coastguard Worker
TEST(file,GetExecutableDirectory)346*8f0ba417SAndroid Build Coastguard Worker TEST(file, GetExecutableDirectory) {
347*8f0ba417SAndroid Build Coastguard Worker std::string path = android::base::GetExecutableDirectory();
348*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE("", path);
349*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE(android::base::GetExecutablePath(), path);
350*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ('/', path[0]);
351*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE('/', path[path.size() - 1]);
352*8f0ba417SAndroid Build Coastguard Worker }
353*8f0ba417SAndroid Build Coastguard Worker
TEST(file,GetExecutablePath)354*8f0ba417SAndroid Build Coastguard Worker TEST(file, GetExecutablePath) {
355*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE("", android::base::GetExecutablePath());
356*8f0ba417SAndroid Build Coastguard Worker }
357*8f0ba417SAndroid Build Coastguard Worker
TEST(file,Basename)358*8f0ba417SAndroid Build Coastguard Worker TEST(file, Basename) {
359*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("sh", android::base::Basename("/system/bin/sh"));
360*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("sh", android::base::Basename("sh"));
361*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("sh", android::base::Basename("/system/bin/sh/"));
362*8f0ba417SAndroid Build Coastguard Worker
363*8f0ba417SAndroid Build Coastguard Worker // Since we've copy & pasted bionic's implementation, copy & paste the tests.
364*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(".", android::base::Basename(""));
365*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("lib", android::base::Basename("/usr/lib"));
366*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("usr", android::base::Basename("/usr/"));
367*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("usr", android::base::Basename("usr"));
368*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("/", android::base::Basename("/"));
369*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(".", android::base::Basename("."));
370*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("..", android::base::Basename(".."));
371*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("/", android::base::Basename("///"));
372*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("lib", android::base::Basename("//usr//lib//"));
373*8f0ba417SAndroid Build Coastguard Worker }
374*8f0ba417SAndroid Build Coastguard Worker
TEST(file,Dirname)375*8f0ba417SAndroid Build Coastguard Worker TEST(file, Dirname) {
376*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("/system/bin", android::base::Dirname("/system/bin/sh"));
377*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(".", android::base::Dirname("sh"));
378*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("/system/bin", android::base::Dirname("/system/bin/sh/"));
379*8f0ba417SAndroid Build Coastguard Worker
380*8f0ba417SAndroid Build Coastguard Worker // Since we've copy & pasted bionic's implementation, copy & paste the tests.
381*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(".", android::base::Dirname(""));
382*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("/usr", android::base::Dirname("/usr/lib"));
383*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("/", android::base::Dirname("/usr/"));
384*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(".", android::base::Dirname("usr"));
385*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(".", android::base::Dirname("."));
386*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(".", android::base::Dirname(".."));
387*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ("/", android::base::Dirname("/"));
388*8f0ba417SAndroid Build Coastguard Worker }
389*8f0ba417SAndroid Build Coastguard Worker
TEST(file,ReadFileToString_capacity)390*8f0ba417SAndroid Build Coastguard Worker TEST(file, ReadFileToString_capacity) {
391*8f0ba417SAndroid Build Coastguard Worker TemporaryFile tf;
392*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE(tf.fd, -1) << tf.path;
393*8f0ba417SAndroid Build Coastguard Worker
394*8f0ba417SAndroid Build Coastguard Worker // For a huge file, the overhead should still be small.
395*8f0ba417SAndroid Build Coastguard Worker std::string s;
396*8f0ba417SAndroid Build Coastguard Worker size_t size = 16 * 1024 * 1024;
397*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteStringToFile(std::string(size, 'x'), tf.path));
398*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFileToString(tf.path, &s));
399*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(size, s.size());
400*8f0ba417SAndroid Build Coastguard Worker EXPECT_LT(s.capacity(), size + 16);
401*8f0ba417SAndroid Build Coastguard Worker
402*8f0ba417SAndroid Build Coastguard Worker // Even for weird badly-aligned sizes.
403*8f0ba417SAndroid Build Coastguard Worker size += 12345;
404*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteStringToFile(std::string(size, 'x'), tf.path));
405*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFileToString(tf.path, &s));
406*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(size, s.size());
407*8f0ba417SAndroid Build Coastguard Worker EXPECT_LT(s.capacity(), size + 16);
408*8f0ba417SAndroid Build Coastguard Worker
409*8f0ba417SAndroid Build Coastguard Worker // We'll shrink an enormous string if you read a small file into it.
410*8f0ba417SAndroid Build Coastguard Worker size = 64;
411*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteStringToFile(std::string(size, 'x'), tf.path));
412*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFileToString(tf.path, &s));
413*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(size, s.size());
414*8f0ba417SAndroid Build Coastguard Worker EXPECT_LT(s.capacity(), size + 16);
415*8f0ba417SAndroid Build Coastguard Worker }
416*8f0ba417SAndroid Build Coastguard Worker
TEST(file,ReadFileToString_capacity_0)417*8f0ba417SAndroid Build Coastguard Worker TEST(file, ReadFileToString_capacity_0) {
418*8f0ba417SAndroid Build Coastguard Worker TemporaryFile tf;
419*8f0ba417SAndroid Build Coastguard Worker ASSERT_NE(tf.fd, -1) << tf.path;
420*8f0ba417SAndroid Build Coastguard Worker
421*8f0ba417SAndroid Build Coastguard Worker // Because /proc reports its files as zero-length, we don't actually trust
422*8f0ba417SAndroid Build Coastguard Worker // any file that claims to be zero-length. Rather than add increasingly
423*8f0ba417SAndroid Build Coastguard Worker // complex heuristics for shrinking the passed-in string in that case, we
424*8f0ba417SAndroid Build Coastguard Worker // currently leave it alone.
425*8f0ba417SAndroid Build Coastguard Worker std::string s;
426*8f0ba417SAndroid Build Coastguard Worker size_t initial_capacity = s.capacity();
427*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WriteStringToFile("", tf.path));
428*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFileToString(tf.path, &s));
429*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(0U, s.size());
430*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(initial_capacity, s.capacity());
431*8f0ba417SAndroid Build Coastguard Worker }
432