aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src
diff options
context:
space:
mode:
authorBilly O'Neal <bion@microsoft.com>2020-05-19 13:43:30 -0700
committerGitHub <noreply@github.com>2020-05-19 13:43:30 -0700
commit3b0080e3b0d395de7551cc2ce1ec89189e539eab (patch)
treed0a6877c62dc90eab4a7ac1d7b9530985522cca9 /toolsrc/src
parente806b2ed384fce2487562371fb32d9528d0c178a (diff)
downloadvcpkg-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.cpp139
-rw-r--r--toolsrc/src/vcpkg/commands.ci.cpp6
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())