Why is it that is_regular_file
function that is part of std::filesystem
reports true for a symbolic link? I have looked at the documentation for the call and can't find the reason and the examples on cppreference exhibit the same behaviour.
As an example, if we look at the binary pidof
; It exists as /usr/sbin/pidof
and correctly labelled as a symbolic link as shown here by stat
:
[@rhel9 ~]$ stat /usr/sbin/pidof
File: /usr/sbin/pidof -> /usr/bin/pidof
Size: 14 Blocks: 0 IO Block: 4096 symbolic link
Device: fd00h/64768d Inode: 34952482 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
Context: system_u:object_r:bin_t:s0
Access: 2024-02-05 15:46:24.124158991 +0000
Modify: 2023-01-28 09:40:21.000000000 +0000
Change: 2023-05-09 17:34:59.432002380 +0100
Birth: 2023-05-09 17:34:59.432002380 +0100
If we follow the link and run stat
on it:
[@rhel9 ~]$ stat /usr/bin/pidof
File: /usr/bin/pidof
Size: 23760 Blocks: 48 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 18153014 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Context: system_u:object_r:bin_t:s0
Access: 2024-02-02 15:12:41.804334284 +0000
Modify: 2023-01-28 09:40:21.000000000 +0000
Change: 2023-05-09 17:34:59.418002380 +0100
Birth: 2023-05-09 17:34:59.417002380 +0100
If we run the following code:
const std::filesystem::path fsBin("/usr/sbin/pidof");
if (true == std::filesystem::is_regular_file(fsBin))
{
std::cout << "Regular File" << std::endl;
}
else if(true == std::filesystem::is_symlink(fsBin))
{
std::cout << "Symbolic Link" << std::endl;
}
The code always prints "Regular File" despite the path being a symbolic link. If I switch the cases around (have is_symlink
as the first check), it reports correctly that it is a symlink. What is interesting too is that if I use a std::filesystem::status
objects instead of the std::filesystem::path
, it never reports a symlink regardless of the order.
Is there an explanation for this behaviour that I'm maybe overlooking?
filesystem::status()
corresponding to POSIXstat()
andfilesystem::symlink_status()
corresponding to POSIXlstat()
.is_regular_file()
uses the result ofstatus()
, andis_symlink()
uses the result ofsymlink_status()
, so that the results are as presented by OP. – Clever