fix(windows): hopefully fix path tweaking / canonicalization

This commit is contained in:
Marcus Holland-Moritz 2024-02-13 00:20:49 +01:00
parent 23bcf046ff
commit f5ac66503d
6 changed files with 64 additions and 34 deletions

View File

@ -21,6 +21,7 @@
#pragma once
#include <filesystem>
#include <memory>
#include <ostream>
#include <string>
@ -44,7 +45,8 @@ class filesystem_extractor {
public:
filesystem_extractor(logger& lgr, os_access const& os);
void open_archive(std::string const& output, std::string const& format) {
void
open_archive(std::filesystem::path const& output, std::string const& format) {
return impl_->open_archive(output, format);
}
@ -52,7 +54,9 @@ class filesystem_extractor {
return impl_->open_stream(os, format);
}
void open_disk(std::string const& output) { return impl_->open_disk(output); }
void open_disk(std::filesystem::path const& output) {
return impl_->open_disk(output);
}
void close() { return impl_->close(); }
@ -66,10 +70,10 @@ class filesystem_extractor {
public:
virtual ~impl() = default;
virtual void
open_archive(std::string const& output, std::string const& format) = 0;
virtual void open_archive(std::filesystem::path const& output,
std::string const& format) = 0;
virtual void open_stream(std::ostream& os, std::string const& format) = 0;
virtual void open_disk(std::string const& output) = 0;
virtual void open_disk(std::filesystem::path const& output) = 0;
virtual void close() = 0;
virtual bool extract(filesystem_v2 const& fs,
filesystem_extractor_options const& opts) = 0;

View File

@ -104,13 +104,19 @@ class filesystem_extractor_ final : public filesystem_extractor::impl {
}
}
void
open_archive(std::string const& output, std::string const& format) override {
void open_archive(std::filesystem::path const& output,
std::string const& format) override {
a_ = ::archive_write_new();
check_result(::archive_write_set_format_by_name(a_, format.c_str()));
#ifdef _WIN32
check_result(::archive_write_open_filename_w(
a_, output.empty() ? nullptr : output.wstring().c_str()));
#else
check_result(::archive_write_open_filename(
a_, output.empty() ? nullptr : output.c_str()));
a_, output.empty() ? nullptr : output.string().c_str()));
#endif
}
void open_stream(std::ostream& os, std::string const& format) override {
@ -133,12 +139,9 @@ class filesystem_extractor_ final : public filesystem_extractor::impl {
check_result(::archive_write_open_fd(a_, pipefd_[1]));
}
void open_disk(std::string const& output) override {
void open_disk(std::filesystem::path const& output) override {
if (!output.empty()) {
if (::chdir(output.c_str()) != 0) {
DWARFS_THROW(runtime_error,
output + ": " + std::string(strerror(errno)));
}
std::filesystem::current_path(output);
}
a_ = ::archive_write_disk_new();

View File

@ -305,16 +305,18 @@ void shorten_path_string(std::string& path, char separator, size_t max_len) {
}
std::filesystem::path canonical_path(std::filesystem::path p) {
try {
p = std::filesystem::canonical(p);
} catch (std::filesystem::filesystem_error const&) {
p = std::filesystem::absolute(p);
}
if (!p.empty()) {
#ifdef _WIN32
p = std::filesystem::path(L"\\\\?\\" + p.wstring());
p = std::filesystem::path(L"\\\\?\\" + p.wstring());
#endif
try {
p = std::filesystem::canonical(p);
} catch (std::filesystem::filesystem_error const&) {
p = std::filesystem::absolute(p);
}
}
return p;
}

View File

@ -90,6 +90,7 @@
#include "dwarfs/metadata_v2.h"
#include "dwarfs/mmap.h"
#include "dwarfs/options.h"
#include "dwarfs/os_access.h"
#include "dwarfs/performance_monitor.h"
#include "dwarfs/tool.h"
#include "dwarfs/util.h"
@ -1289,9 +1290,11 @@ void load_filesystem(dwarfs_userdata& userdata) {
PERFMON_EXT_TIMER_SETUP(userdata, op_getxattr)
PERFMON_EXT_TIMER_SETUP(userdata, op_listxattr)
auto fsimage = canonical_path(std::filesystem::path(
auto fsimage = userdata.iol.os->canonical(std::filesystem::path(
reinterpret_cast<char8_t const*>(opts.fsimage->data())));
LOG_DEBUG << "attempting to load filesystem from " << fsimage;
userdata.fs =
filesystem_v2(userdata.lgr, *userdata.iol.os,
std::make_shared<mmap>(fsimage), fsopts, userdata.perfmon);

View File

@ -46,6 +46,7 @@
#include "dwarfs/mmap.h"
#include "dwarfs/options.h"
#include "dwarfs/os_access.h"
#include "dwarfs/program_options_helpers.h"
#include "dwarfs/tool.h"
#include "dwarfs/util.h"
#include "dwarfs/worker_group.h"
@ -162,7 +163,8 @@ int dwarfsck_main(int argc, sys_char** argv, iolayer const& iol) {
auto checksum_desc = "print checksums for all files (" +
(from(algo_list) | unsplit(", ")) + ")";
std::string input, export_metadata, image_offset, checksum_algo;
sys_string input, export_metadata;
std::string image_offset, checksum_algo;
logger_options logopts;
size_t num_workers;
int detail;
@ -178,7 +180,7 @@ int dwarfsck_main(int argc, sys_char** argv, iolayer const& iol) {
po::options_description opts("Command line options");
opts.add_options()
("input,i",
po::value<std::string>(&input),
po_sys_value<sys_string>(&input),
"input filesystem")
("detail,d",
po::value<int>(&detail)->default_value(2),
@ -214,7 +216,7 @@ int dwarfsck_main(int argc, sys_char** argv, iolayer const& iol) {
po::value<bool>(&output_json)->zero_tokens(),
"print information in JSON format")
("export-metadata",
po::value<std::string>(&export_metadata),
po_sys_value<sys_string>(&export_metadata),
"export raw metadata as JSON to file")
;
// clang-format on
@ -280,7 +282,9 @@ int dwarfsck_main(int argc, sys_char** argv, iolayer const& iol) {
fsopts.metadata.check_consistency = check_integrity;
fsopts.image_offset = parse_image_offset(image_offset);
std::shared_ptr<mmif> mm = iol.os->map_file(input);
auto input_path = iol.os->canonical(input);
std::shared_ptr<mmif> mm = iol.os->map_file(input_path);
if (print_header) {
if (auto hdr = filesystem_v2::header(mm, fsopts.image_offset)) {
@ -303,7 +307,7 @@ int dwarfsck_main(int argc, sys_char** argv, iolayer const& iol) {
if (!export_metadata.empty()) {
std::error_code ec;
auto of = iol.file->open_output(export_metadata, ec);
auto of = iol.file->open_output(iol.os->canonical(export_metadata), ec);
if (ec) {
LOG_ERROR << "failed to open metadata output file: " << ec.message();
return 1;

View File

@ -22,6 +22,7 @@
#include <exception>
#include <iostream>
#include <string>
#include <string_view>
#include <boost/program_options.hpp>
@ -37,6 +38,7 @@
#include "dwarfs/options.h"
#include "dwarfs/os_access.h"
#include "dwarfs/performance_monitor.h"
#include "dwarfs/program_options_helpers.h"
#include "dwarfs/tool.h"
#include "dwarfs/util.h"
#include "dwarfs_tool_main.h"
@ -45,8 +47,19 @@ namespace po = boost::program_options;
namespace dwarfs {
namespace {
#ifdef _WIN32
constexpr std::wstring_view kDash{L"-"};
#else
constexpr std::string_view kDash{"-"};
#endif
} // namespace
int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) {
std::string filesystem, output, format, cache_size_str, image_offset;
sys_string filesystem, output;
std::string format, cache_size_str, image_offset;
logger_options logopts;
#if DWARFS_PERFMON_ENABLED
std::string perfmon_str;
@ -59,10 +72,10 @@ int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) {
po::options_description opts("Command line options");
opts.add_options()
("input,i",
po::value<std::string>(&filesystem),
po_sys_value<sys_string>(&filesystem),
"input filesystem file")
("output,o",
po::value<std::string>(&output),
po_sys_value<sys_string>(&output),
"output file or directory")
("image-offset,O",
po::value<std::string>(&image_offset)->default_value("auto"),
@ -145,16 +158,17 @@ int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) {
std::shared_ptr<performance_monitor> perfmon =
performance_monitor::create(perfmon_enabled);
filesystem_v2 fs(lgr, *iol.os, iol.os->map_file(filesystem), fsopts,
perfmon);
auto fs_path = iol.os->canonical(filesystem);
filesystem_v2 fs(lgr, *iol.os, iol.os->map_file(fs_path), fsopts, perfmon);
filesystem_extractor fsx(lgr, *iol.os);
if (format.empty()) {
fsx.open_disk(output);
fsx.open_disk(iol.os->canonical(output));
} else {
std::ostream* stream{nullptr};
if (output.empty() or output == "-") {
if (output.empty() or output == kDash) {
if (stdout_progress) {
DWARFS_THROW(runtime_error,
"cannot use --stdout-progress with --output=-");
@ -170,7 +184,7 @@ int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) {
if (stream) {
fsx.open_stream(*stream, format);
} else {
fsx.open_archive(output, format);
fsx.open_archive(iol.os->canonical(output), format);
}
}