10 auto* result= getpwuid(
owner);
11 return NString(result ? result->pw_name :
"?");
18 #if !defined ( _WIN32)
19 auto* result= getgrgid(
group);
20 return NString(result ? result->gr_name :
"?");
30 #if ALIB_SYSTEM_FILE_STATUS_IMPL == ALIB_SYSTEM_FILE_POSIX_STATUS
37 fs::path stdPath(nPath.Terminate());
38 return fs::exists(stdPath);
49#if ALIB_SYSTEM_FILE_STATUS_IMPL == ALIB_SYSTEM_FILE_POSIX_STATUS
52 Path alibPath(path.c_str());
53 return Update(alibPath, isCanonical);
63 "Non-canonical path given, while parameter 'isCanonical' is true: {}", path)
74# if defined(__NR_statx)
75# define TMP_STATX_AVAILABLE 1
76# define STATMEMBER(Name) stats.stx_ ## Name
77# define STAT_DEV_MAJOR stats.stx_dev_major
78# define STAT_DEV_MINOR stats.stx_dev_minor
80# define TMP_STATX_AVAILABLE 0
81# define STATMEMBER(Name) stats.st_ ## Name
82# define STAT_DEV_MAJOR major(stats.st_dev)
83# define STAT_DEV_MINOR minor(stats.st_dev)
87# define DBG_CHECKERRNO_WITH_PATH \
88ALIB_ASSERT_WARNING(errno == 0, "SYSTEM", "Errno set ({})\"{}\". Current path: {}", \
89errno, std::errc(errno), path ) \
92# define DBG_CHECKERRNO_WITH_PATH
99 #
if TMP_STATX_AVAILABLE
101 int statResult= statx( AT_FDCWD,
103 AT_STATX_DONT_SYNC | AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW,
104 STATX_BASIC_STATS | STATX_BTIME,
109 int statResult= lstat ( path.
Terminate(), &stats );
112 ALIB_ASSERT_WARNING( errno == ENOENT,
"SYSTEM",
"Unknown error {} while stating file \"{}\"",
113 std::errc(errno), path )
119 DBG_CHECKERRNO_WITH_PATH
122 SetPosixDevice((uint64_t(STAT_DEV_MAJOR) << 32L) + STAT_DEV_MINOR);
125 #if defined(__linux__)
126 struct statfs fsStats;
127 if (statfs(path.
Terminate(), &fsStats) == 0) {
129 switch(fsStats.f_type) {
130 case PROC_SUPER_MAGIC:
132 case CGROUP_SUPER_MAGIC:
133 case CGROUP2_SUPER_MAGIC:
135 case DEVPTS_SUPER_MAGIC:
137 case SECURITYFS_MAGIC:
144 #elif defined(__APPLE__)
145 struct statfs fsStats;
146 if (statfs(path.
Terminate(), &fsStats) == 0) {
148 if (strcmp(fsStats.f_fstypename,
"devfs") == 0 ||
149 strcmp(fsStats.f_fstypename,
"autofs") == 0) {
154 if( STAT_DEV_MAJOR == 0
155 && STAT_DEV_MINOR != 35 )
160 "Internal error: stat'ed file is symbolic link. Path not canonical \"{}\"", path )
166 auto posixType= STATMEMBER(mode) & S_IFMT;
177 "Internal error. 'unknown' file type can't happen. File: \"{}\"", path )
break;
187 #if defined(__APPLE__)
188 # define st_mtime_name STATMEMBER(mtimespec)
189 # define st_ctime_name STATMEMBER(ctimespec)
190 # define st_atime_name STATMEMBER(atimespec)
192 # if TMP_STATX_AVAILABLE
193 # define st_mtime_name STATMEMBER(mtime)
194 # define st_ctime_name STATMEMBER(ctime)
195 # define st_atime_name STATMEMBER(atime)
196 # define st_btime_name STATMEMBER(btime)
198 # define st_mtime_name STATMEMBER(mtim)
199 # define st_ctime_name STATMEMBER(ctim)
200 # define st_atime_name STATMEMBER(atim)
205 std::chrono::system_clock::time_point {
206 std::chrono::duration_cast<std::chrono::system_clock::duration>(
207 std::chrono::seconds {st_mtime_name.tv_sec }
208 + std::chrono::nanoseconds{st_mtime_name.tv_nsec} ) } );
212 std::chrono::system_clock::time_point {
213 std::chrono::duration_cast<std::chrono::system_clock::duration>(
214 std::chrono::seconds {st_ctime_name.tv_sec }
215 + std::chrono::nanoseconds{st_ctime_name.tv_nsec} ) } );
219 std::chrono::system_clock::time_point {
220 std::chrono::duration_cast<std::chrono::system_clock::duration>(
221 std::chrono::seconds {st_atime_name.tv_sec }
222 + std::chrono::nanoseconds{st_atime_name.tv_nsec} ) } );
225 #if TMP_STATX_AVAILABLE
226 if( STATMEMBER(mask) & STATX_BTIME ) {
228 std::chrono::system_clock::time_point {
229 std::chrono::duration_cast<std::chrono::system_clock::duration>(
230 std::chrono::seconds {st_btime_name.tv_sec }
231 + std::chrono::nanoseconds{st_btime_name.tv_nsec} ) } );
267 #undef DBG_CHECKERRNO_WITH_PATH
268 #undef TMP_STATX_AVAILABLE
276#if ALIB_SYSTEM_FORCE_STD_FILE_STATUS
277# pragma message ("ALIB_SYSTEM_FORCE_STD_FILE_STATUS given. Using std::filesystem for " \
278 "FileStatus::Update(). (Limited functionality) " )
280# pragma message ("Non-posix platform. Using std::filesystem for " \
281 "FileStatus::Update(). (Limited functionality) " )
285 std::filesystem::path stdPath(path.
Terminate());
286 return Update(stdPath, isCanonical);
294 auto pc= fs::canonical(path);
296 "Non-canonical path given, while parameter 'isCanonical' is true: {}", path.c_str())
302 path= fs::canonical(path);
304 std::error_code errorCode;
309 fs::file_status stats= fs::symlink_status(path);
314 "Unhandled error code invoking 'fs::symlink_status()': {} (\"{}\")\n"
315 " With file: \"{}\"",
316 errorCode.value(), errorCode.message(), path.c_str() )
326 "Internal error: stat'ed file is symbolic link. Path not canonical \"{}\"", path.c_str() )
332 switch( stats.type() )
334 case fs::file_type::directory: type= FileStatus::Types::DIRECTORY ; break;
335 case fs::file_type::regular : type= FileStatus::Types::REGULAR ; break;
336 case fs::file_type::symlink : type= FileStatus::Types::SYMBOLIC_LINK; break;
337 case fs::file_type::block : type= FileStatus::Types::BLOCK ; break;
338 case fs::file_type::character: type= FileStatus::Types::CHARACTER ; break;
339 case fs::file_type::fifo : type= FileStatus::Types::FIFO ; break;
340 case fs::file_type::socket : type= FileStatus::Types::SOCKET ; break;
342 case fs::file_type::not_found:
343 SetScanState(FileStatus::ScanStates::UNKNOWN_ERROR);
344 ALIB_WARNING(
"SYSTEM",
"Internal error. 'not found' file type can't happen. File: ", path.c_str() )
345 ALIB_DBG( errno= 0;) return ScanState();
346 case fs::file_type::none :
347 SetScanState(FileStatus::ScanStates::UNKNOWN_ERROR);
348 ALIB_WARNING(
"SYSTEM",
"Internal error. 'none' file type can't happen. File: ", path.c_str())
349 ALIB_DBG( errno= 0;) return ScanState();
350 case fs::file_type::unknown :
351 SetScanState(FileStatus::ScanStates::UNKNOWN_ERROR);
352 ALIB_WARNING(
"SYSTEM",
"Internal error. Can't happen. File: ", path.c_str())
353 ALIB_DBG( errno= 0;) return ScanState();
355 SetScanState(FileStatus::ScanStates::UNKNOWN_ERROR);
356 ALIB_WARNING(
"SYSTEM",
"Unknown fs::file_status::type '{}' with file {}.", stats.type(), path.c_str())
357 ALIB_DBG( errno= 0;) return ScanState();
369 auto fsTime= std::filesystem::file_time_type(std::filesystem::file_time_type::clock::now());
372 fsTime= fs::last_write_time( path, errorCode );
374 if(errorCode)
switch( std::errc(errorCode.value()) )
376 case std::errc::no_such_file_or_directory:
377 ALIB_ERROR(
"SYSTEM",
"Internal error. This should never happen, checked above. "
378 "Undefined system error handling" )
ALIB_DBG( errno= 0;)
384 "Unhandled error code invoking 'fs::last_write_time()': {} (\"{}\")\n"
385 " With file \"{}\".", errorCode.value(), errorCode.message(), path.c_str() )
386 fsTime= (decltype(fsTime)::min)();
ALIB_DBG( errno= 0;)
393 #if defined(__APPLE__) || defined(_LIBCPP_VERSION) || defined(__ANDROID_NDK__)
397 std::chrono::clock_cast<std::chrono::system_clock>(fsTime) ) ) );
410 switch( std::errc(errorCode.value()) )
413 case std::errc::is_a_directory:
416 case std::errc::no_such_file_or_directory:
419 "Internal error. This should never happen. Undefined system error handling" )
423 case std::errc::operation_not_supported: break;
425 "Unhandled error code invoking 'directory_entry::file_size()':{} (\"{}\")\n"
426 " With file \"{}\".",
427 errorCode.value(), errorCode.message(), path.c_str() )
ALIB_DBG( errno= 0;)
438 qtyHardLinks= uint32_t( fs::hard_link_count(path, errorCode ) );
443 if( !( std::errc(errorCode.value()) == std::errc::no_such_file_or_directory
446 "Unhandled error code invoking 'fs::hard_link_count()': {} (\"{}\")\n"
447 " With file: \"{}\"",
448 errorCode.value(), errorCode.message(), path.c_str() )
#define ALIB_MESSAGE(domain,...)
#define ALIB_ALLOW_SPARSE_ENUM_SWITCH
#define ALIB_ASSERT_WARNING(cond, domain,...)
#define ALIB_ERROR(domain,...)
#define ALIB_POP_ALLOWANCE
#define ALIB_ASSERT_ERROR(cond, domain,...)
#define ALIB_BOXING_VTABLE_DEFINE(TMapped, Identifier)
constexpr const PathCharType * Terminate() const
bool Equals(const TString< TChar > &rhs) const
@ DIRECTORY
Directory/folder.
@ CHARACTER
A character special file.
@ BLOCK
A block special file.
@ FIFO
A FIFO (also known as pipe) file.
constexpr DateTime MDate() const noexcept
void SetScanState(ScanStates v) noexcept
void SetType(Types v) noexcept
constexpr uinteger Size() const noexcept
const NString GetOwnerName() const
void SetArtificialFS() noexcept
Mark the entry as residing on an artificial filesystem.
void SetADate(DateTime v) noexcept
uinteger size
The file size. In case of a directory, this is 0.
FileStatus()
Default constructor.
uint32_t group
The group id that owns the file.
void SetMDate(DateTime v) noexcept
constexpr Types Type() const noexcept
uint32_t owner
The user id that owns the file.
constexpr DateTime ADate() const noexcept
void SetSize(uinteger v) noexcept
Permissions
Permission flags. Compatible with POSIX definition.
@ MASK
All valid permission bits. Equivalent to all | set_uid | set_gid | sticky_bit.
void SetOwner(uint32_t v) noexcept
void SetPerms(Permissions v) noexcept
static constexpr TOwnerAndGroupID UnknownID
Constant value for owner and group IDs to denote that the field was not determined.
const NString GetGroupName() const
void SetBDate(DateTime v) noexcept
constexpr DateTime CDate() const noexcept
ScanStates Update(Path &path, bool isCanonical=false)
uint32_t qtyHardLinks
The number of hard links to the file.
void SetPosixDevice(uint64_t deviceCode) noexcept
constexpr ScanStates ScanState() const noexcept
void SetCDate(DateTime v) noexcept
ScanStates
Per-entry information about how a node was scanned.
@ STATS
Only stats (size, date, owner, etc.) read.
@ RESOLVED
Read symlink target strings.
@ UNKNOWN_ERROR
Unknown scanner failure.
@ NOT_EXISTENT
Set if a given start path does not exist.
void SetQtyHardlinks(uint32_t v) noexcept
void SetGroup(uint32_t v) noexcept
std::errc MakeCanonical()
static DateTime FromEpochSeconds(time_t epochSeconds)
void Import(TTimePoint timePoint)
strings::TString< nchar > NString
Type alias in namespace #"%alib".
lang::uinteger uinteger
Type alias in namespace #"%alib".
time::DateTime DateTime
Type alias in namespace #"%alib".
#define ALIB_STRINGS_TO_NARROW( src, dest, bufSize)