aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2022-08-05 11:20:57 +0200
committerSven Gothel <[email protected]>2022-08-05 11:20:57 +0200
commitb32f4be36c408509c7adce8fc3f147ce94bd2809 (patch)
treebf7628bcdd69e28734cb02d710d1b5145a7b2b7d /src
parent0347d71dd0cadb3e19196afbdf5b4b0c8d904eb1 (diff)
file_util: fix mem leak, robustness changes
- jau::fs::to_named_fd(): Describe stdio names - file_stats::file_stats - fix mem leak: Use std::vector<char> for temp buffer, no need to miss ::free() - initialize dir_item item late via assignment (use default ctor first) - statx(linux): Only set size if has(field_t::size) - to_string(): Show size n/a, if n/a
Diffstat (limited to 'src')
-rw-r--r--src/file_util.cpp52
1 files changed, 24 insertions, 28 deletions
diff --git a/src/file_util.cpp b/src/file_util.cpp
index 0acde0f..c04df02 100644
--- a/src/file_util.cpp
+++ b/src/file_util.cpp
@@ -415,24 +415,24 @@ file_stats::file_stats() noexcept
#endif
file_stats::file_stats(const ctor_cookie& cc, int dirfd, const dir_item& item, const bool dirfd_is_item_dirname) noexcept
-: has_fields_(field_t::none), item_(item), link_target_path_(), link_target_(), mode_(fmode_t::none), fd_(-1),
- uid_(0), gid_(0), size_(0), btime_(), atime_(), ctime_(), mtime_(),
- errno_res_(0)
+: has_fields_(field_t::none), item_(), link_target_path_(), link_target_(), mode_(fmode_t::none), fd_(-1),
+ uid_(0), gid_(0), size_(0), btime_(), atime_(), ctime_(), mtime_(), errno_res_(0)
{
constexpr const bool _debug = false;
(void)cc;
- const std::string full_path( item_.empty() ? "" : item_.path() );
- if( item_.empty() && AT_FDCWD != dirfd ) {
+ const std::string full_path( item.empty() ? "" : item.path() );
+ if( item.empty() && AT_FDCWD != dirfd ) {
if( 0 <= dirfd ) {
has_fields_ |= field_t::fd;
fd_ = dirfd;
item_ = dir_item(jau::fs::to_named_fd(fd_));
} else {
ERR_PRINT("rec_level %d, dirfd %d < 0, %s, dirfd_is_item_dirname %d, AT_EMPTY_PATH",
- (int)cc.rec_level, dirfd, item_.to_string().c_str(), dirfd_is_item_dirname);
+ (int)cc.rec_level, dirfd, item.to_string().c_str(), dirfd_is_item_dirname);
return;
}
} else {
+ item_ = item;
int scan_value = jau::fs::from_named_fd(full_path);
if( 0 <= scan_value ) {
has_fields_ |= field_t::fd;
@@ -452,7 +452,7 @@ file_stats::file_stats(const ctor_cookie& cc, int dirfd, const dir_item& item, c
return;
}
}
- const std::string dirfd_path = has( field_t::fd ) ? "" : ( dirfd_is_item_dirname ? item.basename() : full_path );
+ const std::string dirfd_path = has( field_t::fd ) ? "" : ( dirfd_is_item_dirname ? item_.basename() : full_path );
#if _USE_STATX_
struct ::statx s;
@@ -548,22 +548,18 @@ file_stats::file_stats(const ctor_cookie& cc, int dirfd, const dir_item& item, c
std::string link_path;
{
const ssize_t path_link_max_len = 0 < s.stx_size ? s.stx_size + 1 : PATH_MAX;
- char* buffer = (char*) ::malloc(path_link_max_len);
+ std::vector<char> buffer;
+ buffer.reserve(path_link_max_len);
+ buffer.resize(path_link_max_len);
ssize_t path_link_len = 0;;
- if( nullptr == buffer ) {
- errno_res_ = errno;
- link_target_ = std::make_shared<file_stats>();
- goto errorout;
- }
- path_link_len = ::readlinkat(dirfd, dirfd_path.c_str(), buffer, path_link_max_len);
+ path_link_len = ::readlinkat(dirfd, dirfd_path.c_str(), buffer.data(), path_link_max_len);
if( 0 > path_link_len ) {
errno_res_ = errno;
- ::free(buffer);
link_target_ = std::make_shared<file_stats>();
goto errorout;
}
// Note: if( path_link_len == path_link_max_len ) then buffer may have been truncated
- link_path = std::string(buffer, path_link_len);
+ link_path = std::string(buffer.data(), path_link_len);
}
link_target_path_ = std::make_shared<std::string>(link_path);
if( 0 == cc.rec_level ) {
@@ -613,8 +609,10 @@ file_stats::file_stats(const ctor_cookie& cc, int dirfd, const dir_item& item, c
mode_ |= fmode_t::dir;
} else if( link_target_->is_file() ) {
mode_ |= fmode_t::file;
- has_fields_ |= field_t::size;
- size_ = link_target_->size();
+ if( link_target_->has( field_t::size ) ) {
+ has_fields_ |= field_t::size;
+ size_ = link_target_->size();
+ }
} else if( !link_target_->exists() ) {
mode_ |= fmode_t::not_existing;
} else if( !link_target_->has_access() ) {
@@ -685,22 +683,18 @@ file_stats::file_stats(const ctor_cookie& cc, int dirfd, const dir_item& item, c
std::string link_path;
{
const ssize_t path_link_max_len = 0 < s.st_size ? s.st_size + 1 : PATH_MAX;
- char* buffer = (char*) ::malloc(path_link_max_len);
+ std::vector<char> buffer;
+ buffer.reserve(path_link_max_len);
+ buffer.resize(path_link_max_len);
ssize_t path_link_len = 0;;
- if( nullptr == buffer ) {
- errno_res_ = errno;
- link_target_ = std::make_shared<file_stats>();
- goto errorout;
- }
- path_link_len = ::readlinkat(dirfd, dirfd_path.c_str(), buffer, path_link_max_len);
+ path_link_len = ::readlinkat(dirfd, dirfd_path.c_str(), buffer.data(), path_link_max_len);
if( 0 > path_link_len ) {
errno_res_ = errno;
- ::free(buffer);
link_target_ = std::make_shared<file_stats>();
goto errorout;
}
// Note: if( path_link_len == path_link_max_len ) then buffer may have been truncated
- link_path = std::string(buffer, path_link_len);
+ link_path = std::string(buffer.data(), path_link_len);
}
link_target_path_ = std::make_shared<std::string>(link_path);
if( 0 == cc.rec_level ) {
@@ -854,6 +848,8 @@ std::string file_stats::to_string() const noexcept {
}
if( has( field_t::size ) ) {
res.append( ", size " ).append( jau::to_decstring( size_ ) );
+ } else {
+ res.append( ", size n/a" );
}
if( has( field_t::btime ) ) {
res.append( ", btime " ).append( btime_.to_iso8601_string() );
@@ -1406,7 +1402,7 @@ static bool copy_file(const int src_dirfd, const file_stats& src_stats,
}
goto errout;
}
- dst = __posix_openat64 (dst_dirfd, dst_basename.c_str(), O_CREAT|O_WRONLY|O_BINARY|O_EXCL|O_NOCTTY, jau::fs::posix_protection_bits( dest_mode & ~omitted_permissions ) );
+ dst = __posix_openat64 (dst_dirfd, dst_basename.c_str(), O_CREAT|O_EXCL|O_WRONLY|O_BINARY|O_NOCTTY, jau::fs::posix_protection_bits( dest_mode & ~omitted_permissions ) );
if ( 0 > dst ) {
ERR_PRINT("Failed to open target_path '%s'", dst_basename.c_str());
goto errout;