1
2 /*
3 * Copyright (C) 2018 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include <vintf/FileSystem.h>
19
20 #include <dirent.h>
21
22 #include <android-base/file.h>
23
24 namespace android {
25 namespace vintf {
26 namespace details {
27
fetch(const std::string & path,std::string * fetched,std::string * error) const28 status_t FileSystemImpl::fetch(const std::string& path, std::string* fetched,
29 std::string* error) const {
30 if (!android::base::ReadFileToString(path, fetched, true /* follow_symlinks */)) {
31 int saved_errno = errno;
32 if (error) {
33 *error = "Cannot read " + path + ": " + strerror(saved_errno);
34 }
35 return saved_errno == 0 ? UNKNOWN_ERROR : -saved_errno;
36 }
37 return OK;
38 }
39
listFiles(const std::string & path,std::vector<std::string> * out,std::string * error) const40 status_t FileSystemImpl::listFiles(const std::string& path, std::vector<std::string>* out,
41 std::string* error) const {
42 std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir);
43 if (!dir) {
44 int saved_errno = errno;
45 if (error) {
46 *error = "Cannot open " + path + ": " + strerror(saved_errno);
47 }
48 return saved_errno == 0 ? UNKNOWN_ERROR : -saved_errno;
49 }
50
51 dirent* dp;
52 while (errno = 0, dp = readdir(dir.get()), dp != nullptr) {
53 if (dp->d_type != DT_DIR) {
54 out->push_back(dp->d_name);
55 }
56 }
57 int saved_errno = errno;
58 if (saved_errno != 0) {
59 if (error) {
60 *error = "Failed while reading directory " + path + ": " + strerror(saved_errno);
61 }
62 }
63 return -saved_errno;
64 }
65
fetch(const std::string &,std::string *,std::string *) const66 status_t FileSystemNoOp::fetch(const std::string&, std::string*, std::string*) const {
67 return NAME_NOT_FOUND;
68 }
69
listFiles(const std::string &,std::vector<std::string> *,std::string *) const70 status_t FileSystemNoOp::listFiles(const std::string&, std::vector<std::string>*,
71 std::string*) const {
72 return NAME_NOT_FOUND;
73 }
74
FileSystemUnderPath(const std::string & rootdir)75 FileSystemUnderPath::FileSystemUnderPath(const std::string& rootdir) {
76 mRootDir = rootdir;
77 if (!mRootDir.empty() && mRootDir.back() != '/') {
78 mRootDir.push_back('/');
79 }
80 }
81
fetch(const std::string & path,std::string * fetched,std::string * error) const82 status_t FileSystemUnderPath::fetch(const std::string& path, std::string* fetched,
83 std::string* error) const {
84 return mImpl.fetch(mRootDir + path, fetched, error);
85 }
86
listFiles(const std::string & path,std::vector<std::string> * out,std::string * error) const87 status_t FileSystemUnderPath::listFiles(const std::string& path, std::vector<std::string>* out,
88 std::string* error) const {
89 return mImpl.listFiles(mRootDir + path, out, error);
90 }
91
getRootDir() const92 const std::string& FileSystemUnderPath::getRootDir() const {
93 return mRootDir;
94 }
95
96 } // namespace details
97 } // namespace vintf
98 } // namespace android
99