summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2023-09-05 20:25:14 -0500
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2023-09-05 20:25:14 -0500
commit12d039fcc78cb917176ea3080a6a94c883cf9e3f (patch)
tree8b5f3ed705d3d896d599fdb1b874855ab8f0031d
parent2fe8d9c80e2b1297f90a53c01900c0415d8ef622 (diff)
downloadhorizon-12d039fcc78cb917176ea3080a6a94c883cf9e3f.tar.gz
horizon-12d039fcc78cb917176ea3080a6a94c883cf9e3f.tar.bz2
horizon-12d039fcc78cb917176ea3080a6a94c883cf9e3f.tar.xz
horizon-12d039fcc78cb917176ea3080a6a94c883cf9e3f.zip
image: Tar backend: Fix ups
* Use <filesystem> portably. * Create the target directory if it doesn't exist. * Fix symlink detection bug that could cause target mtab to halt image creation.
-rw-r--r--image/backends/tar.cc36
1 files changed, 26 insertions, 10 deletions
diff --git a/image/backends/tar.cc b/image/backends/tar.cc
index efd38e5..d9c2248 100644
--- a/image/backends/tar.cc
+++ b/image/backends/tar.cc
@@ -48,6 +48,7 @@ public:
int prepare() override {
int res;
+ error_code ec;
a = archive_write_new();
archive_write_set_format_pax_restricted(a);
@@ -66,6 +67,20 @@ public:
break;
}
+ output_info("tar backend", "creating directory tree");
+ fs::create_directory(this->ir_dir, ec);
+ if(ec && ec.value() != EEXIST) {
+ output_error("tar backend", "could not create IR directory",
+ ec.message());
+ return 1;
+ }
+ fs::create_directory(this->ir_dir + "/target", ec);
+ if(ec && ec.value() != EEXIST) {
+ output_error("tar backend", "could not create target directory",
+ ec.message());
+ return 1;
+ }
+
res = archive_write_open_filename(a, this->out_path.c_str());
if(res < ARCHIVE_OK) {
if(res < ARCHIVE_WARN) {
@@ -93,17 +108,18 @@ public:
for(const auto& dent : fs::recursive_directory_iterator(target, ec)) {
fs::path relpath = dent.path().lexically_relative(target);
+ std::string pathstr(dent.path().native());
#define OUTPUT_FAILURE(x) \
- output_error("tar backend", "failed to " x " '" + std::string(dent.path()) + "'",\
+ output_error("tar backend", "failed to " x " '" + pathstr + "'",\
strerror(errno));
- r = lstat(dent.path().c_str(), &s);
+ r = lstat(pathstr.c_str(), &s);
if(r == -1) {
OUTPUT_FAILURE("stat")
code = -1;
goto ret;
}
archive_entry_copy_stat(entry, &s);
- if(dent.is_symlink()) {
+ if(fs::is_symlink(dent)) {
archive_entry_set_filetype(entry, AE_IFLNK);
fs::path resolved = fs::read_symlink(dent.path(), ec);
if(ec) {
@@ -112,31 +128,31 @@ public:
code = -1;
goto ret;
}
- const auto r_path = resolved.u8string();
+ const auto r_path = resolved.native();
archive_entry_update_symlink_utf8(entry, r_path.c_str());
}
- archive_entry_update_pathname_utf8(entry, relpath.u8string().c_str());
+ archive_entry_update_pathname_utf8(entry, relpath.native().c_str());
if(archive_write_header(this->a, entry) != ARCHIVE_OK) {
output_error("tar backend", archive_error_string(a));
code = -1;
goto ret;
}
- if(dent.is_regular_file() && dent.file_size() > 0) {
- fd = open(dent.path().c_str(), O_RDONLY);
+ if(fs::is_regular_file(dent) && !fs::is_symlink(dent) &&
+ s.st_size > 0) {
+ fd = open(pathstr.c_str(), O_RDONLY);
if(fd == -1) {
OUTPUT_FAILURE("open")
code = -1;
goto ret;
}
- buff = mmap(NULL, dent.file_size(), PROT_READ, MAP_SHARED,
- fd, 0);
+ buff = mmap(NULL, s.st_size, PROT_READ, MAP_SHARED, fd, 0);
if(buff == MAP_FAILED) {
OUTPUT_FAILURE("map")
close(fd);
code = -1;
goto ret;
}
- archive_write_data(this->a, buff, dent.file_size());
+ archive_write_data(this->a, buff, s.st_size);
close(fd);
}
archive_write_finish_entry(this->a);