diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2021-06-19 12:01:48 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2021-06-19 12:01:48 +0000 |
commit | 9063677c3726d766de3c5fc3a2cd3feabd840d08 (patch) | |
tree | 8f6ec66173bb45a55a65c8449f382c2c16b3b13a /brillo/files/file_util.cc | |
parent | 9e260fa59a43bc04701216c51053922d445fefd8 (diff) | |
parent | 6901182adc9a85d7f514df4d68605a179c195f75 (diff) | |
download | libbrillo-c8fb7718ed046a13722df2c09e11b77a85e8535f.tar.gz |
Snap for 7474514 from 6901182adc9a85d7f514df4d68605a179c195f75 to mainline-media-releaseandroid-mainline-12.0.0_r89android-mainline-12.0.0_r74android-mainline-12.0.0_r62android-mainline-12.0.0_r46android-mainline-12.0.0_r29android-mainline-12.0.0_r12android-mainline-12.0.0_r119android-mainline-12.0.0_r104android12-mainline-media-release
Change-Id: I1756a28b97a568bbb2c02438730597bb2aa59efe
Diffstat (limited to 'brillo/files/file_util.cc')
-rw-r--r-- | brillo/files/file_util.cc | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/brillo/files/file_util.cc b/brillo/files/file_util.cc new file mode 100644 index 0000000..c642d14 --- /dev/null +++ b/brillo/files/file_util.cc @@ -0,0 +1,112 @@ +// Copyright 2019 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "brillo/files/file_util.h" + +#include <fcntl.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <utility> + +#include <base/files/file_util.h> +#include <base/logging.h> +#include <base/strings/stringprintf.h> +#include <brillo/syslog_logging.h> + +namespace brillo { + +namespace { + +enum class FSObjectType { + RegularFile = 0, + Directory, +}; + +SafeFD::SafeFDResult OpenOrRemake(SafeFD* parent, + const std::string& name, + FSObjectType type, + int permissions, + uid_t uid, + gid_t gid, + int flags) { + SafeFD::Error err = IsValidFilename(name); + if (SafeFD::IsError(err)) { + return std::make_pair(SafeFD(), err); + } + + SafeFD::SafeFDResult (SafeFD::*maker)(const base::FilePath&, mode_t, uid_t, + gid_t, int); + if (type == FSObjectType::Directory) { + maker = &SafeFD::MakeDir; + } else { + maker = &SafeFD::MakeFile; + } + + SafeFD child; + std::tie(child, err) = + (parent->*maker)(base::FilePath(name), permissions, uid, gid, flags); + if (child.is_valid()) { + return std::make_pair(std::move(child), err); + } + + // Rmdir should be used on directories. However, kWrongType indicates when + // a directory was expected and a non-directory was found or when a + // directory was found but not expected, so XOR was used. + if ((type == FSObjectType::Directory) ^ (err == SafeFD::Error::kWrongType)) { + err = parent->Rmdir(name, true /*recursive*/); + } else { + err = parent->Unlink(name); + } + if (SafeFD::IsError(err)) { + PLOG(ERROR) << "Failed to clean up \"" << name << "\""; + return std::make_pair(SafeFD(), err); + } + + std::tie(child, err) = + (parent->*maker)(base::FilePath(name), permissions, uid, gid, flags); + return std::make_pair(std::move(child), err); +} + +} // namespace + +SafeFD::Error IsValidFilename(const std::string& filename) { + if (filename == "." || filename == ".." || + filename.find("/") != std::string::npos) { + return SafeFD::Error::kBadArgument; + } + return SafeFD::Error::kNoError; +} + +base::FilePath GetFDPath(int fd) { + const base::FilePath proc_fd(base::StringPrintf("/proc/self/fd/%d", fd)); + base::FilePath resolved; + if (!base::ReadSymbolicLink(proc_fd, &resolved)) { + LOG(ERROR) << "Failed to read " << proc_fd.value(); + return base::FilePath(); + } + return resolved; +} + +SafeFD::SafeFDResult OpenOrRemakeDir(SafeFD* parent, + const std::string& name, + int permissions, + uid_t uid, + gid_t gid, + int flags) { + return OpenOrRemake(parent, name, FSObjectType::Directory, permissions, uid, + gid, flags); +} + +SafeFD::SafeFDResult OpenOrRemakeFile(SafeFD* parent, + const std::string& name, + int permissions, + uid_t uid, + gid_t gid, + int flags) { + return OpenOrRemake(parent, name, FSObjectType::RegularFile, permissions, uid, + gid, flags); +} + +} // namespace brillo |