12

About std::filesystem::is_regular_file(path), cppreference.com says:

Checks if the given file status or path corresponds to a regular file […] Equivalent to s.type() == file_type::regular.

For example, in the Linux kernel, file types are declared in the header file sys/stat.h. The type name and symbolic name for each Linux file type is listed below:

  • Socket (S_IFSOCK)
  • Symbolic link (S_IFLNK)
  • Regular File (S_IFREG)
  • Block special file (S_IFBLK)
  • Directory (S_IFDIR)
  • Character device (S_IFCHR)
  • FIFO (named pipe) (S_IFIFO)

What is the thing that this function checks on Windows?

Amit
  • 645
  • 1
  • 3
  • 19
  • 1
    It's exactly the same? There are regular files and other files like symlinks on Windows too. It looks like Microsoft's implementation might not do anything with symlinks https://learn.microsoft.com/en-us/cpp/standard-library/filesystem-enumerations?view=msvc-170#file_type – Alan Birtles Apr 18 '22 at 07:23
  • 1
    @AlanBirtles I don't think Windows has symlinks for files, only directories (aka reparse points, aka junctions). EDIT looking at the answer just posted here, seems I might be wrong. – Paul Sanders Apr 18 '22 at 07:38
  • 3
    @PaulSanders it does these days https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10/#:~:text=Symlinks%2C%20or%20symbolic%20links%2C%20are,supported%20symlinks%20since%20Windows%20Vista. (Since vista) – Alan Birtles Apr 18 '22 at 07:39
  • @AlanBirtles Interesting, that's very welcome news. And long overdue! – Paul Sanders Apr 18 '22 at 07:42
  • 4
    @PaulSanders to be fair, they've been available for 15 years so not particularly overdue – Alan Birtles Apr 18 '22 at 07:49
  • 1
    @AlanBirtles True. Just rather low profile, not sure if many people know about them (I forgot about `mklink`, I use Sysinternals' Junction tool). – Paul Sanders Apr 18 '22 at 07:52

1 Answers1

18

Since we are talking about Windows we can consider MS implementation of the standard library, and that's how they determine if the file is regular:

if (_Bitmask_includes(_Attrs, __std_fs_file_attr::_Reparse_point)) {
    if (_Stats._Reparse_point_tag == __std_fs_reparse_tag::_Symlink) {
        this->type(file_type::symlink);
        return;
    }

    if (_Stats._Reparse_point_tag == __std_fs_reparse_tag::_Mount_point) {
        this->type(file_type::junction);
        return;
    }

    // All other reparse points considered ordinary files or directories
}

if (_Bitmask_includes(_Attrs, __std_fs_file_attr::_Directory)) {
    this->type(file_type::directory);
} else {
    this->type(file_type::regular);
}

So if it isn't IO_REPARSE_TAG_MOUNT_POINT, IO_REPARSE_TAG_SYMLINK or a directory, then it is a regular file.

ixSci
  • 13,100
  • 5
  • 45
  • 79
  • 2
    So when NFS clients store device nodes or fifos using IO_REPARSE_TAG_NFS, or when WSL stores device nodes using IO_REPARSE_TAG_LX_CHR, the stdlib considers them to be regular files? – user1686 Apr 18 '22 at 18:22
  • 3
    @user1686 I've no idea about the attributes you mentioned, but you can see the code. – ixSci Apr 18 '22 at 18:53
  • @ScottMcPeak added a link to the implementation. As to the citation: I've mentioned from the beginning that the code is from the MS implementation and there is only one standard C++ library from MS. – ixSci Apr 19 '22 at 05:28