diff options
| author | Billy O'Neal <bion@microsoft.com> | 2020-05-19 13:43:30 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-05-19 13:43:30 -0700 |
| commit | 3b0080e3b0d395de7551cc2ce1ec89189e539eab (patch) | |
| tree | d0a6877c62dc90eab4a7ac1d7b9530985522cca9 /toolsrc/src | |
| parent | e806b2ed384fce2487562371fb32d9528d0c178a (diff) | |
| download | vcpkg-3b0080e3b0d395de7551cc2ce1ec89189e539eab.tar.gz vcpkg-3b0080e3b0d395de7551cc2ce1ec89189e539eab.zip | |
[vcpkg] Harden file removals and clean directory contents in "CI" inside vcpkg itself. (#11432)
`files.h/files.cpp`:
* Add end and else comments to all macros.
* Add "remove_all_inside" function which empties a directory without actually deleting the directory. This is necessary to handle the case where the directory is actually a directory symlink.
* Change remove_all to use std::remove when VCPKG_USE_STD_FILESYSTEM is set; this will engage POSIX delete support available on current Win10.
`commands.ci.cpp`: empty "installed".
`*/initialize_environment.*`: No longer clean the directories outside the tool.
`ci-step.ps1`: Remove unused console output tee-ing.
Diffstat (limited to 'toolsrc/src')
| -rw-r--r-- | toolsrc/src/vcpkg/base/files.cpp | 139 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg/commands.ci.cpp | 6 |
2 files changed, 118 insertions, 27 deletions
diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 2d12b1757..24e2038d9 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -13,12 +13,12 @@ #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> -#endif +#endif // ^^^ !defined(_WIN32) #if defined(__linux__) #include <sys/sendfile.h> #elif defined(__APPLE__) #include <copyfile.h> -#endif +#endif // ^^^ defined(__APPLE__) namespace vcpkg::Files { @@ -80,7 +80,7 @@ namespace vcpkg::Files return fs::file_status(ft, permissions); -#else +#else // ^^^ defined(_WIN32) // !defined(_WIN32) vvv auto result = follow_symlinks ? fs::stdfs::status(p, ec) : fs::stdfs::symlink_status(p, ec); // libstdc++ doesn't correctly not-set ec on nonexistent paths if (ec.value() == ENOENT || ec.value() == ENOTDIR) @@ -89,7 +89,7 @@ namespace vcpkg::Files return fs::file_status(file_type::not_found, perms::unknown); } return fs::file_status(result.type(), result.permissions()); -#endif +#endif// ^^^ !defined(_WIN32) } fs::file_status status(const fs::path& p, std::error_code& ec) noexcept @@ -119,7 +119,7 @@ namespace vcpkg::Files { ec.assign(GetLastError(), std::system_category()); } -#else +#else // ^^^ defined(_WIN32) // !defined(_WIN32) vvv struct stat s; if (lstat(path.c_str(), &s)) { @@ -137,7 +137,7 @@ namespace vcpkg::Files ec.assign(errno, std::system_category()); } } -#endif +#endif // ^^^ !defined(_WIN32) } } @@ -272,6 +272,31 @@ namespace vcpkg::Files this->remove_all(path, ec, failure_point); } + void Filesystem::remove_all_inside(const fs::path& path, LineInfo li) + { + std::error_code ec; + fs::path failure_point; + + this->remove_all_inside(path, ec, failure_point); + + if (ec) + { + Checks::exit_with_message(li, + "Failure to remove_all_inside(%s) due to file %s: %s", + path.string(), + failure_point.string(), + ec.message()); + } + } + + void Filesystem::remove_all_inside(const fs::path& path, ignore_errors_t) + { + std::error_code ec; + fs::path failure_point; + + this->remove_all_inside(path, ec, failure_point); + } + fs::path Filesystem::absolute(LineInfo li, const fs::path& path) const { std::error_code ec; @@ -477,7 +502,7 @@ namespace vcpkg::Files auto written_bytes = sendfile(o_fd, i_fd, &bytes, info.st_size); #elif defined(__APPLE__) auto written_bytes = fcopyfile(i_fd, o_fd, 0, COPYFILE_ALL); -#else +#else // ^^^ defined(__APPLE__) // !(defined(__APPLE__) || defined(__linux__)) vvv ssize_t written_bytes = 0; { constexpr std::size_t buffer_length = 4096; @@ -505,7 +530,7 @@ namespace vcpkg::Files copy_failure:; } -#endif +#endif // ^^^ !(defined(__APPLE__) || defined(__linux__)) if (written_bytes == -1) { ec.assign(errno, std::generic_category()); @@ -522,7 +547,7 @@ namespace vcpkg::Files if (ec) return; this->remove(oldpath, ec); } -#endif +#endif // ^^^ !defined(_WIN32) } virtual bool remove(const fs::path& path, std::error_code& ec) override { return fs::stdfs::remove(path, ec); } virtual void remove_all(const fs::path& path, std::error_code& ec, fs::path& failure_point) override @@ -574,13 +599,20 @@ namespace vcpkg::Files { ec.assign(GetLastError(), std::system_category()); } -#else +#else // ^^^ defined(_WIN32) // !defined(_WIN32) vvv if (rmdir(current_path.c_str())) { ec.assign(errno, std::system_category()); } -#endif +#endif // ^^^ !defined(_WIN32) } +#if VCPKG_USE_STD_FILESYSTEM + else + { + fs::stdfs::remove(current_path, ec); + if (check_ec(ec, current_path, err)) return; + } +#else // ^^^ VCPKG_USE_STD_FILESYSTEM // !VCPKG_USE_STD_FILESYSTEM vvv #if defined(_WIN32) else if (path_type == fs::file_type::directory_symlink) { @@ -596,7 +628,7 @@ namespace vcpkg::Files ec.assign(GetLastError(), std::system_category()); } } -#else +#else // ^^^ defined(_WIN32) // !defined(_WIN32) vvv else { if (unlink(current_path.c_str())) @@ -604,7 +636,8 @@ namespace vcpkg::Files ec.assign(errno, std::system_category()); } } -#endif +#endif // ^^^ !defined(_WIN32) +#endif // ^^^ !VCPKG_USE_STD_FILESYSTEM check_ec(ec, current_path, err); } @@ -651,6 +684,58 @@ namespace vcpkg::Files ec = std::move(err.ec); failure_point = std::move(err.failure_point); } + + virtual void remove_all_inside(const fs::path& path, std::error_code& ec, fs::path& failure_point) override + { + fs::directory_iterator last{}; + fs::directory_iterator first(path, ec); + if (ec) + { + failure_point = path; + return; + } + + for (;;) + { + if (first == last) + { + return; + } + + auto stats = first->status(ec); + if (ec) + { + break; + } + + auto& thisPath = first->path(); + if (stats.type() == fs::stdfs::file_type::directory) + { + this->remove_all(thisPath, ec, failure_point); + if (ec) + { + return; // keep inner failure_point + } + } + else + { + this->remove(thisPath, ec); + if (ec) + { + break; + } + } + + first.increment(ec); + if (ec) + { + break; + } + } + + failure_point = first->path(); + } + virtual bool is_directory(const fs::path& path) const override { return fs::stdfs::is_directory(path); } virtual bool is_regular_file(const fs::path& path) const override { return fs::stdfs::is_regular_file(path); } virtual bool is_empty(const fs::path& path) const override { return fs::stdfs::is_empty(path); } @@ -693,10 +778,10 @@ namespace vcpkg::Files FILE* f = nullptr; #if defined(_WIN32) auto err = _wfopen_s(&f, file_path.native().c_str(), L"wb"); -#else +#else // ^^^ defined(_WIN32) // !defined(_WIN32) vvv f = fopen(file_path.native().c_str(), "wb"); int err = f != nullptr ? 0 : 1; -#endif +#endif // ^^^ !defined(_WIN32) if (err != 0) { ec.assign(err, std::system_category()); @@ -720,19 +805,22 @@ namespace vcpkg::Files #if VCPKG_USE_STD_FILESYSTEM return fs::stdfs::absolute(path, ec); #else // ^^^ VCPKG_USE_STD_FILESYSTEM / !VCPKG_USE_STD_FILESYSTEM vvv -#if _WIN32 +#if defined(_WIN32) // absolute was called system_complete in experimental filesystem return fs::stdfs::system_complete(path, ec); -#else // ^^^ _WIN32 / !_WIN32 vvv - if (path.is_absolute()) { +#else // ^^^ defined(_WIN32) / !defined(_WIN32) vvv + if (path.is_absolute()) + { return path; - } else { + } + else + { auto current_path = this->current_path(ec); if (ec) return fs::path(); return std::move(current_path) / path; } -#endif -#endif +#endif // ^^^ !defined(_WIN32) +#endif // ^^^ !VCPKG_USE_STD_FILESYSTEM } virtual fs::path canonical(const fs::path& path, std::error_code& ec) const override @@ -740,20 +828,17 @@ namespace vcpkg::Files return fs::stdfs::canonical(path, ec); } - virtual fs::path current_path(std::error_code& ec) const override - { - return fs::stdfs::current_path(ec); - } + virtual fs::path current_path(std::error_code& ec) const override { return fs::stdfs::current_path(ec); } virtual std::vector<fs::path> find_from_PATH(const std::string& name) const override { #if defined(_WIN32) static constexpr StringLiteral EXTS[] = {".cmd", ".exe", ".bat"}; auto paths = Strings::split(System::get_environment_variable("PATH").value_or_exit(VCPKG_LINE_INFO), ";"); -#else +#else // ^^^ defined(_WIN32) // !defined(_WIN32) vvv static constexpr StringLiteral EXTS[] = {""}; auto paths = Strings::split(System::get_environment_variable("PATH").value_or_exit(VCPKG_LINE_INFO), ":"); -#endif +#endif // ^^^ !defined(_WIN32) std::vector<fs::path> ret; std::error_code ec; diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 0ea23cd82..eadfd8bdd 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -397,6 +397,12 @@ namespace vcpkg::Commands::CI const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); + auto& filesystem = paths.get_filesystem(); + if (filesystem.is_directory(paths.installed)) + { + filesystem.remove_all_inside(paths.installed, VCPKG_LINE_INFO); + } + std::set<std::string> exclusions_set; auto it_exclusions = options.settings.find(OPTION_EXCLUDE); if (it_exclusions != options.settings.end()) |
