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 28 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 40 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 66 status_t FileSystemNoOp::fetch(const std::string&, std::string*, std::string*) const { 67 return NAME_NOT_FOUND; 68 } 69 70 status_t FileSystemNoOp::listFiles(const std::string&, std::vector<std::string>*, 71 std::string*) const { 72 return NAME_NOT_FOUND; 73 } 74 75 FileSystemUnderPath::FileSystemUnderPath(const std::string& rootdir) { 76 mRootDir = rootdir; 77 if (!mRootDir.empty() && mRootDir.back() != '/') { 78 mRootDir.push_back('/'); 79 } 80 } 81 82 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 87 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 92 const std::string& FileSystemUnderPath::getRootDir() const { 93 return mRootDir; 94 } 95 96 } // namespace details 97 } // namespace vintf 98 } // namespace android 99