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
modifiedTime(const std::string & path,int64_t * mtime,std::string * error) const66 status_t FileSystemImpl::modifiedTime(const std::string& path, int64_t* mtime,
67 std::string* error) const {
68 struct stat stat_buf;
69 if (stat(path.c_str(), &stat_buf) != 0) {
70 int saved_errno = errno;
71 if (error) {
72 *error = "Cannot open " + path + ": " + strerror(saved_errno);
73 }
74 return saved_errno == 0 ? UNKNOWN_ERROR : -saved_errno;
75 }
76 *mtime = stat_buf.st_mtime;
77 return OK;
78 }
79
fetch(const std::string &,std::string *,std::string *) const80 status_t FileSystemNoOp::fetch(const std::string&, std::string*, std::string*) const {
81 return NAME_NOT_FOUND;
82 }
83
listFiles(const std::string &,std::vector<std::string> *,std::string *) const84 status_t FileSystemNoOp::listFiles(const std::string&, std::vector<std::string>*,
85 std::string*) const {
86 return NAME_NOT_FOUND;
87 }
88
modifiedTime(const std::string &,int64_t *,std::string *) const89 status_t FileSystemNoOp::modifiedTime(const std::string&, int64_t*, std::string*) const {
90 return NAME_NOT_FOUND;
91 }
92
FileSystemUnderPath(const std::string & rootdir)93 FileSystemUnderPath::FileSystemUnderPath(const std::string& rootdir) {
94 mRootDir = rootdir;
95 if (!mRootDir.empty() && mRootDir.back() != '/') {
96 mRootDir.push_back('/');
97 }
98 }
99
fetch(const std::string & path,std::string * fetched,std::string * error) const100 status_t FileSystemUnderPath::fetch(const std::string& path, std::string* fetched,
101 std::string* error) const {
102 return mImpl.fetch(mRootDir + path, fetched, error);
103 }
104
listFiles(const std::string & path,std::vector<std::string> * out,std::string * error) const105 status_t FileSystemUnderPath::listFiles(const std::string& path, std::vector<std::string>* out,
106 std::string* error) const {
107 return mImpl.listFiles(mRootDir + path, out, error);
108 }
109
modifiedTime(const std::string & path,int64_t * mtime,std::string * error) const110 status_t FileSystemUnderPath::modifiedTime(const std::string& path, int64_t* mtime,
111 std::string* error) const {
112 return mImpl.modifiedTime(mRootDir + path, mtime, error);
113 }
114
getRootDir() const115 const std::string& FileSystemUnderPath::getRootDir() const {
116 return mRootDir;
117 }
118
119 } // namespace details
120 } // namespace vintf
121 } // namespace android
122