mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-13 06:16:55 -04:00
fix: use shared_ptr to manage archive_entry and prevent leaks
This commit is contained in:
parent
5b82810a81
commit
b8459adc05
@ -264,12 +264,12 @@ bool filesystem_extractor_<LoggerPolicy>::extract(
|
|||||||
std::atomic<uint64_t> bytes_written{0};
|
std::atomic<uint64_t> bytes_written{0};
|
||||||
uint64_t const bytes_total{vfs.blocks};
|
uint64_t const bytes_total{vfs.blocks};
|
||||||
|
|
||||||
auto do_archive = [&](::archive_entry* ae,
|
auto do_archive = [&](std::shared_ptr<::archive_entry> ae,
|
||||||
reader::inode_view entry) { // TODO: inode vs. entry
|
reader::inode_view entry) { // TODO: inode vs. entry
|
||||||
if (auto size = ::archive_entry_size(ae);
|
if (auto size = ::archive_entry_size(ae.get());
|
||||||
entry.is_regular_file() && size > 0) {
|
entry.is_regular_file() && size > 0) {
|
||||||
auto fd = fs.open(entry);
|
auto fd = fs.open(entry);
|
||||||
std::string_view path{::archive_entry_pathname(ae)};
|
std::string_view path{::archive_entry_pathname(ae.get())};
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
size_t remain = size;
|
size_t remain = size;
|
||||||
|
|
||||||
@ -284,12 +284,12 @@ bool filesystem_extractor_<LoggerPolicy>::extract(
|
|||||||
|
|
||||||
if (!ec) {
|
if (!ec) {
|
||||||
archiver.add_job([this, &sem, &hard_error, &soft_error, &opts,
|
archiver.add_job([this, &sem, &hard_error, &soft_error, &opts,
|
||||||
ranges = std::move(ranges), ae, pos, remain, bs,
|
ranges = std::move(ranges), ae, pos, bs, size, path,
|
||||||
size, path, &bytes_written, bytes_total]() mutable {
|
&bytes_written, bytes_total]() mutable {
|
||||||
try {
|
try {
|
||||||
if (pos == 0) {
|
if (pos == 0) {
|
||||||
LOG_DEBUG << "extracting " << path << " (" << size << " bytes)";
|
LOG_DEBUG << "extracting " << path << " (" << size << " bytes)";
|
||||||
check_result(::archive_write_header(a_, ae));
|
check_result(::archive_write_header(a_, ae.get()));
|
||||||
}
|
}
|
||||||
for (auto& r : ranges) {
|
for (auto& r : ranges) {
|
||||||
auto br = r.get();
|
auto br = r.get();
|
||||||
@ -301,9 +301,6 @@ bool filesystem_extractor_<LoggerPolicy>::extract(
|
|||||||
opts.progress(path, bytes_written, bytes_total);
|
opts.progress(path, bytes_written, bytes_total);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bs == remain) {
|
|
||||||
archive_entry_free(ae);
|
|
||||||
}
|
|
||||||
sem.post(bs);
|
sem.post(bs);
|
||||||
} catch (archive_error const& e) {
|
} catch (archive_error const& e) {
|
||||||
LOG_ERROR << exception_str(e);
|
LOG_ERROR << exception_str(e);
|
||||||
@ -316,7 +313,6 @@ bool filesystem_extractor_<LoggerPolicy>::extract(
|
|||||||
LOG_ERROR << exception_str(std::current_exception());
|
LOG_ERROR << exception_str(std::current_exception());
|
||||||
++hard_error;
|
++hard_error;
|
||||||
}
|
}
|
||||||
archive_entry_free(ae);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -331,9 +327,8 @@ bool filesystem_extractor_<LoggerPolicy>::extract(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
archiver.add_job([this, ae, &hard_error] {
|
archiver.add_job([this, ae, &hard_error] {
|
||||||
scope_exit free_entry{[&] { ::archive_entry_free(ae); }};
|
|
||||||
try {
|
try {
|
||||||
check_result(::archive_write_header(a_, ae));
|
check_result(::archive_write_header(a_, ae.get()));
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
LOG_ERROR << exception_str(std::current_exception());
|
LOG_ERROR << exception_str(std::current_exception());
|
||||||
++hard_error;
|
++hard_error;
|
||||||
@ -388,8 +383,12 @@ bool filesystem_extractor_<LoggerPolicy>::extract(
|
|||||||
|
|
||||||
::archive_entry_linkify(lr, &ae, &spare);
|
::archive_entry_linkify(lr, &ae, &spare);
|
||||||
|
|
||||||
|
auto shared_entry_ptr = [](::archive_entry* e) {
|
||||||
|
return std::shared_ptr<::archive_entry>(e, ::archive_entry_free);
|
||||||
|
};
|
||||||
|
|
||||||
if (ae) {
|
if (ae) {
|
||||||
do_archive(ae, inode);
|
do_archive(shared_entry_ptr(ae), inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spare) {
|
if (spare) {
|
||||||
@ -398,7 +397,7 @@ bool filesystem_extractor_<LoggerPolicy>::extract(
|
|||||||
LOG_ERROR << "find() failed";
|
LOG_ERROR << "find() failed";
|
||||||
}
|
}
|
||||||
LOG_INFO << "archiving spare " << ::archive_entry_pathname(spare);
|
LOG_INFO << "archiving spare " << ::archive_entry_pathname(spare);
|
||||||
do_archive(spare, *ev);
|
do_archive(shared_entry_ptr(spare), *ev);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -413,6 +412,7 @@ bool filesystem_extractor_<LoggerPolicy>::extract(
|
|||||||
::archive_entry* ae = nullptr;
|
::archive_entry* ae = nullptr;
|
||||||
::archive_entry_linkify(lr, &ae, &spare);
|
::archive_entry_linkify(lr, &ae, &spare);
|
||||||
if (ae) {
|
if (ae) {
|
||||||
|
::archive_entry_free(ae);
|
||||||
DWARFS_THROW(runtime_error, "unexpected deferred entry");
|
DWARFS_THROW(runtime_error, "unexpected deferred entry");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user