diff --git a/base/cvd/cuttlefish/common/libs/utils/BUILD.bazel b/base/cvd/cuttlefish/common/libs/utils/BUILD.bazel index 4eb9d268201..ea1ccd3ca0d 100644 --- a/base/cvd/cuttlefish/common/libs/utils/BUILD.bazel +++ b/base/cvd/cuttlefish/common/libs/utils/BUILD.bazel @@ -115,7 +115,6 @@ cf_cc_library( deps = [ ":environment", "//cuttlefish/common/libs/fs", - "//cuttlefish/common/libs/utils:contains", "//cuttlefish/common/libs/utils:in_sandbox", "//cuttlefish/common/libs/utils:users", "//cuttlefish/posix:rename", @@ -130,23 +129,11 @@ cf_cc_library( ], ) -cf_cc_library( - name = "files_test_helper", - testonly = 1, - srcs = ["files_test_helper.cpp"], - hdrs = ["files_test_helper.h"], - deps = [ - "//cuttlefish/common/libs/utils:files", - "@googletest//:gtest", - ], -) - cf_cc_test( name = "files_test", srcs = ["files_test.cpp"], deps = [ "//cuttlefish/common/libs/utils:files", - "//cuttlefish/common/libs/utils:files_test_helper", "//cuttlefish/result", "//cuttlefish/result:result_matchers", "//libbase", diff --git a/base/cvd/cuttlefish/common/libs/utils/files.cpp b/base/cvd/cuttlefish/common/libs/utils/files.cpp index 5d5f44c0464..86b1c7b6b60 100644 --- a/base/cvd/cuttlefish/common/libs/utils/files.cpp +++ b/base/cvd/cuttlefish/common/libs/utils/files.cpp @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include @@ -57,14 +56,12 @@ #include "absl/strings/str_split.h" #include "absl/log/check.h" #include "absl/log/log.h" -#include "absl/strings/match.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_join.h" #include "fmt/format.h" #include "cuttlefish/common/libs/fs/shared_buf.h" #include "cuttlefish/common/libs/fs/shared_fd.h" -#include "cuttlefish/common/libs/utils/contains.h" #include "cuttlefish/common/libs/utils/environment.h" #include "cuttlefish/common/libs/utils/in_sandbox.h" #include "cuttlefish/common/libs/utils/users.h" @@ -340,10 +337,6 @@ Result RecursivelyRemoveDirectory(const std::string& path) { return {}; } -namespace { - -} // namespace - bool Copy(const std::string& from, const std::string& to) { SharedFD fd_from = SharedFD::Open(from, O_RDONLY); SharedFD fd_to = SharedFD::Open(to, O_WRONLY | O_CREAT | O_TRUNC, 0644); @@ -638,83 +631,6 @@ Result WalkDirectory(const std::string& dir, return {}; } -namespace { - -std::vector FoldPath(std::vector elements, - std::string token) { - static constexpr std::array kIgnored = {".", "..", ""}; - if (token == ".." && !elements.empty()) { - elements.pop_back(); - } else if (!Contains(kIgnored, token)) { - elements.emplace_back(token); - } - return elements; -} - -Result> CalculatePrefix( - const InputPathForm& path_info) { - const auto& path = path_info.path_to_convert; - std::string working_dir; - if (path_info.current_working_dir) { - working_dir = *path_info.current_working_dir; - } else { - working_dir = CurrentDirectory(); - } - std::vector prefix; - if (path == "~" || absl::StartsWith(path, "~/")) { - const auto home_dir = - path_info.home_dir.value_or(CF_EXPECT(SystemWideUserHome())); - prefix = absl::StrSplit(home_dir, '/', absl::SkipEmpty()); - } else if (!absl::StartsWith(path, "/")) { - prefix = absl::StrSplit(working_dir, '/', absl::SkipEmpty()); - } - return prefix; -} - -} // namespace - -Result EmulateAbsolutePath(const InputPathForm& path_info) { - const auto& path = path_info.path_to_convert; - std::string working_dir; - if (path_info.current_working_dir) { - working_dir = *path_info.current_working_dir; - } else { - working_dir = CurrentDirectory(); - } - CF_EXPECT(absl::StartsWith(working_dir, "/"), - "Current working directory should be given in an absolute path."); - - if (path.empty()) { - LOG(ERROR) << "The requested path to convert an absolute path is empty."; - return ""; - } - - auto prefix = CF_EXPECT(CalculatePrefix(path_info)); - std::vector components; - components.insert(components.end(), prefix.begin(), prefix.end()); - std::vector tokens = absl::StrSplit(path, '/', absl::SkipEmpty()); - // remove first ~ - if (!tokens.empty() && tokens[0] == "~") { - tokens.erase(tokens.begin()); - } - components.insert(components.end(), tokens.begin(), tokens.end()); - - std::string combined = absl::StrJoin(components, "/"); - CF_EXPECTF(!Contains(components, "~"), - "~ is not allowed in the middle of the path: {}", combined); - - auto processed_tokens = std::accumulate(components.begin(), components.end(), - std::vector{}, FoldPath); - - const auto processed_path = "/" + absl::StrJoin(processed_tokens, "/"); - - if (path_info.follow_symlink && FileExists(processed_path)) { - return CF_EXPECTF(RealPath(processed_path), - "Failed to effectively conduct readpath -f {}", processed_path); - } - return processed_path; -} - std::vector Path(const std::string& env_name) { // TODO: Assumes a SUS system. Elsewhere we may need to change the delimiter. // https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html diff --git a/base/cvd/cuttlefish/common/libs/utils/files.h b/base/cvd/cuttlefish/common/libs/utils/files.h index 2427522a34f..083e4678172 100644 --- a/base/cvd/cuttlefish/common/libs/utils/files.h +++ b/base/cvd/cuttlefish/common/libs/utils/files.h @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -106,33 +105,6 @@ using WalkDirectoryCallback = std::function(const std::string&)>; Result WalkDirectory(const std::string& dir, const WalkDirectoryCallback& callback); -// parameter to EmulateAbsolutePath -struct InputPathForm { - /** If nullopt, uses the process' current working dir - * But if there is no preceding .. or ., this field is not used. - */ - std::optional current_working_dir; - /** If nullopt, use SystemWideUserHome() - * But, if there's no preceding ~, this field is not used. - */ - std::optional home_dir; - std::string path_to_convert; - bool follow_symlink; -}; - -/** - * Returns emulated absolute path with a different process'/thread's - * context. - * - * This is useful when daemon(0, 0)-started server process wants to - * figure out a relative path that came from its client. - * - * The call mostly succeeds. It fails only if: - * home_dir isn't given so supposed to relies on the local SystemWideUserHome() - * but SystemWideUserHome() call fails. - */ -Result EmulateAbsolutePath(const InputPathForm& path_info); - std::vector Path(const std::string& env_name = "PATH"); Result Search(const std::vector& path, diff --git a/base/cvd/cuttlefish/common/libs/utils/files_test.cpp b/base/cvd/cuttlefish/common/libs/utils/files_test.cpp index 3cd20a48dc8..b76f6912f4a 100644 --- a/base/cvd/cuttlefish/common/libs/utils/files_test.cpp +++ b/base/cvd/cuttlefish/common/libs/utils/files_test.cpp @@ -24,7 +24,6 @@ #include "absl/cleanup/cleanup.h" #include "absl/strings/str_cat.h" -#include "cuttlefish/common/libs/utils/files_test_helper.h" #include "cuttlefish/result/result.h" #include "cuttlefish/result/result_matchers.h" @@ -99,89 +98,6 @@ TEST_F(FilesTests, MoveDirectoryContents) { EXPECT_THAT(FileExists(dst_dir_ + "/sub_dir/file2.txt"), IsTrue()); } -TEST_P(EmulateAbsolutePathBase, NoHomeNoPwd) { - const bool follow_symlink = false; - auto emulated_absolute_path = - EmulateAbsolutePath({.current_working_dir = std::nullopt, - .home_dir = std::nullopt, - .path_to_convert = input_path_, - .follow_symlink = follow_symlink}); - - ASSERT_TRUE(emulated_absolute_path.ok()) - << emulated_absolute_path.error().Trace(); - ASSERT_EQ(*emulated_absolute_path, expected_path_); -} - -INSTANTIATE_TEST_SUITE_P( - CommonUtilsTest, EmulateAbsolutePathBase, - testing::Values(InputOutput{.path_to_convert_ = "/", .expected_ = "/"}, - InputOutput{.path_to_convert_ = "", .expected_ = ""}, - InputOutput{.path_to_convert_ = "/a/b/c/", - .expected_ = "/a/b/c"}, - InputOutput{.path_to_convert_ = "/a", .expected_ = "/a"})); - -TEST_P(EmulateAbsolutePathWithPwd, NoHomeYesPwd) { - const bool follow_symlink = false; - auto emulated_absolute_path = - EmulateAbsolutePath({.current_working_dir = current_dir_, - .home_dir = "/a/b/c", - .path_to_convert = input_path_, - .follow_symlink = follow_symlink}); - - ASSERT_TRUE(emulated_absolute_path.ok()) - << emulated_absolute_path.error().Trace(); - ASSERT_EQ(*emulated_absolute_path, expected_path_); -} - -INSTANTIATE_TEST_SUITE_P( - CommonUtilsTest, EmulateAbsolutePathWithPwd, - testing::Values(InputOutput{.path_to_convert_ = "", - .working_dir_ = "/x/y/z", - .expected_ = ""}, - InputOutput{.path_to_convert_ = "a", - .working_dir_ = "/x/y/z", - .expected_ = "/x/y/z/a"}, - InputOutput{.path_to_convert_ = ".", - .working_dir_ = "/x/y/z", - .expected_ = "/x/y/z"}, - InputOutput{.path_to_convert_ = "..", - .working_dir_ = "/x/y/z", - .expected_ = "/x/y"}, - InputOutput{.path_to_convert_ = "./k/../../t/./q", - .working_dir_ = "/x/y/z", - .expected_ = "/x/y/t/q"})); - -TEST_P(EmulateAbsolutePathWithHome, YesHomeNoPwd) { - const bool follow_symlink = false; - auto emulated_absolute_path = - EmulateAbsolutePath({.current_working_dir = std::nullopt, - .home_dir = home_dir_, - .path_to_convert = input_path_, - .follow_symlink = follow_symlink}); - - ASSERT_TRUE(emulated_absolute_path.ok()) - << emulated_absolute_path.error().Trace(); - ASSERT_EQ(*emulated_absolute_path, expected_path_); -} - -INSTANTIATE_TEST_SUITE_P( - CommonUtilsTest, EmulateAbsolutePathWithHome, - testing::Values(InputOutput{.path_to_convert_ = "~", - .home_dir_ = "/x/y/z", - .expected_ = "/x/y/z"}, - InputOutput{.path_to_convert_ = "~/a", - .home_dir_ = "/x/y/z", - .expected_ = "/x/y/z/a"}, - InputOutput{.path_to_convert_ = "~/.", - .home_dir_ = "/x/y/z", - .expected_ = "/x/y/z"}, - InputOutput{.path_to_convert_ = "~/..", - .home_dir_ = "/x/y/z", - .expected_ = "/x/y"}, - InputOutput{.path_to_convert_ = "~/k/../../t/./q", - .home_dir_ = "/x/y/z", - .expected_ = "/x/y/t/q"})); - TEST(FilesTest, PathWithCustomEnv) { const std::string env_name = "TEST_PATH"; const std::string dir1 = "/foo/bar"; diff --git a/base/cvd/cuttlefish/common/libs/utils/files_test_helper.cpp b/base/cvd/cuttlefish/common/libs/utils/files_test_helper.cpp deleted file mode 100644 index 6e941f6ba77..00000000000 --- a/base/cvd/cuttlefish/common/libs/utils/files_test_helper.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright (C) 2023 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "cuttlefish/common/libs/utils/files_test_helper.h" - -namespace cuttlefish { - -EmulateAbsolutePathBase::EmulateAbsolutePathBase() { - input_path_ = GetParam().path_to_convert_; - expected_path_ = GetParam().expected_; -} - -EmulateAbsolutePathWithPwd::EmulateAbsolutePathWithPwd() { - input_path_ = GetParam().path_to_convert_; - expected_path_ = GetParam().expected_; - current_dir_ = GetParam().working_dir_; -} - -EmulateAbsolutePathWithHome::EmulateAbsolutePathWithHome() { - input_path_ = GetParam().path_to_convert_; - expected_path_ = GetParam().expected_; - home_dir_ = GetParam().home_dir_; -} - -} // namespace cuttlefish diff --git a/base/cvd/cuttlefish/common/libs/utils/files_test_helper.h b/base/cvd/cuttlefish/common/libs/utils/files_test_helper.h deleted file mode 100644 index 10de19d1872..00000000000 --- a/base/cvd/cuttlefish/common/libs/utils/files_test_helper.h +++ /dev/null @@ -1,60 +0,0 @@ -// -// Copyright (C) 2023 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include -#include - -#include - -#include "cuttlefish/common/libs/utils/files.h" - -namespace cuttlefish { - -struct InputOutput { - std::string path_to_convert_; - std::string working_dir_; - std::string home_dir_; - std::string expected_; -}; - -class EmulateAbsolutePathBase : public testing::TestWithParam { - protected: - EmulateAbsolutePathBase(); - - std::string input_path_; - std::string expected_path_; -}; - -class EmulateAbsolutePathWithPwd : public testing::TestWithParam { - protected: - EmulateAbsolutePathWithPwd(); - - std::string input_path_; - std::string current_dir_; - std::string expected_path_; -}; - -class EmulateAbsolutePathWithHome : public EmulateAbsolutePathBase { - protected: - EmulateAbsolutePathWithHome(); - - std::string input_path_; - std::string home_dir_; - std::string expected_path_; -}; - -} // namespace cuttlefish diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/create.cpp b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/create.cpp index 4bd72ed37af..6c36b49baa5 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/create.cpp +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/create.cpp @@ -167,17 +167,12 @@ Result GetEnvs(const CommandRequest& request) { // As the end-user may override HOME, this could be a relative path // to client's pwd, or may include "~" which is the client's actual // home directory. - auto client_pwd = CurrentDirectory(); const auto given_home_dir = envs["HOME"]; // Substituting ~ is not supported by cvd CF_EXPECT(!absl::StartsWith(given_home_dir, "~") && !absl::StartsWith(given_home_dir, "~/"), "The HOME directory should not start with ~"); - envs["HOME"] = CF_EXPECT( - EmulateAbsolutePath({.current_working_dir = client_pwd, - .home_dir = CF_EXPECT(SystemWideUserHome()), - .path_to_convert = given_home_dir, - .follow_symlink = false})); + envs["HOME"] = AbsolutePath(given_home_dir); } return envs; } diff --git a/base/cvd/cuttlefish/host/commands/snapshot_util_cvd/main.cc b/base/cvd/cuttlefish/host/commands/snapshot_util_cvd/main.cc index d1465513b41..be6b06a76d4 100644 --- a/base/cvd/cuttlefish/host/commands/snapshot_util_cvd/main.cc +++ b/base/cvd/cuttlefish/host/commands/snapshot_util_cvd/main.cc @@ -38,19 +38,6 @@ namespace cuttlefish { namespace { -Result ToAbsolutePath(const std::string& snapshot_path) { - const InputPathForm default_path_form{ - .current_working_dir = std::nullopt, - .home_dir = std::nullopt, - .path_to_convert = snapshot_path, - .follow_symlink = false, - }; - return CF_EXPECTF( - EmulateAbsolutePath(default_path_form), - "The snapshot path, \"{}\", cannot be converted to an absolute path", - snapshot_path); -} - // Send a `LauncherAction` RPC to every instance specified in `parsed`. Result BroadcastLauncherAction( const CuttlefishConfig& config, const Parsed& parsed, @@ -89,7 +76,7 @@ Result SnapshotCvdMain(std::vector args) { } case SnapshotCmd::kSnapshotTake: { CF_EXPECT(!parsed.snapshot_path.empty(), "--snapshot_path is required"); - parsed.snapshot_path = CF_EXPECT(ToAbsolutePath(parsed.snapshot_path)); + parsed.snapshot_path = AbsolutePath(parsed.snapshot_path); if (parsed.force && FileExists(parsed.snapshot_path, /* follow symlink */ false)) { CF_EXPECT(RecursivelyRemoveDirectory(parsed.snapshot_path), diff --git a/base/cvd/cuttlefish/host/commands/snapshot_util_cvd/snapshot_taker.cc b/base/cvd/cuttlefish/host/commands/snapshot_util_cvd/snapshot_taker.cc index 4f8850973a3..95dfe04eb3f 100644 --- a/base/cvd/cuttlefish/host/commands/snapshot_util_cvd/snapshot_taker.cc +++ b/base/cvd/cuttlefish/host/commands/snapshot_util_cvd/snapshot_taker.cc @@ -42,12 +42,7 @@ Result HandleHostGroupSnapshot(const std::string& path) { CF_EXPECT(!cuttlefish_home.empty(), "\"HOME\" environment variable must be set."); - const std::string snapshot_path = CF_EXPECT(EmulateAbsolutePath(InputPathForm{ - .current_working_dir = CurrentDirectory(), - .home_dir = CF_EXPECT(SystemWideUserHome()), - .path_to_convert = path, - .follow_symlink = false, - })); + const std::string snapshot_path = AbsolutePath(path); auto* cuttlefish_config = CuttlefishConfig::Get(); CF_EXPECT(cuttlefish_config != nullptr, "Cannot find cuttlefish_config.json"); diff --git a/base/cvd/cuttlefish/host/libs/command_util/snapshot_utils.cc b/base/cvd/cuttlefish/host/libs/command_util/snapshot_utils.cc index 923f335819a..c6e65b2da20 100644 --- a/base/cvd/cuttlefish/host/libs/command_util/snapshot_utils.cc +++ b/base/cvd/cuttlefish/host/libs/command_util/snapshot_utils.cc @@ -146,10 +146,7 @@ std::string RealpathOrSelf(const std::string& path) { if (output.ok()) { return *output; } - struct InputPathForm input_form { - .path_to_convert = path, .follow_symlink = true, - }; - auto absolute_path = EmulateAbsolutePath(input_form); + auto absolute_path = RealPath(path); return absolute_path.ok() ? *absolute_path : path; }