filesystem-proposal icon indicating copy to clipboard operation
filesystem-proposal copied to clipboard

not possible to check whether a directory_iterator was created via a symlink

Open jiixyj opened this issue 12 years ago • 5 comments

It would be nice to have a way to make sure a directory_iterator does not open a symlink to a directory; maybe by adding a function to get a directory_entry structure of the root directory, or by adding another constructor. Currently it is possible to do this:

fs::path root("root");
fs::recursive_directory_iterator iter;
if (!fs::is_symlink(root)) {
     iter = fs::recursive_directory_iterator(root, fs::symlink_option::no_recurse);
}

However, there is a race condition here: After having checked that root is not a symlink, the world may change and the constructor may open a symlink.

jiixyj avatar Nov 14 '12 10:11 jiixyj

Another example from the proposal (operator++ of recursive_directory_iterator):

Otherwise if recursion_pending() && is_directory(this->status()) && (!is_symlink(this->symlink_status()) || (options() & directory_options::follow_directory_symlink) != 0) then directory (*this)->path() is recursively iterated into.

This has the same problem as above, as (*this)->path() may become a symlink after the check.

jiixyj avatar Nov 14 '12 10:11 jiixyj

The BSD fts file hierarchy traversal functions solve this by providing an option "FTS_COMFOLLOW" to fts_open. Only if this option or FTS_LOGICAL (directory_options::follow_directory_symlink) is specified root symlinks will be followed.

I think the default for the directory_iterators should be to never follow root symlinks, unless follow_directory_symlink or a new directory_option "follow_root_symlink" (or similarly named) is given to the constructor.

jiixyj avatar Nov 14 '12 18:11 jiixyj

Hi jiixyj,

If I understand what you are requesting, exactly that functionality is already present in the proposal.

Symlinks are only followed if directory_options::follow_directory_symlink is given as an argument. Thus I'm closing this issue.

Are you looking at a recent version of the proposal? The last official version is found at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3399.html. The most recent draft is found at http://beman.github.com/filesystem-proposal/

Please note that a number of decisions reached at the October C++ committee meeting have not yet been applied yet.

Thanks,

--Beman

Beman avatar Nov 15 '12 14:11 Beman

Yes, I am referring to the current proposal. Sorry for using the soon to be deprecated notation of the Boost Filesystem library.

The problem is that is it currently not clear in the proposal whether the root path will be resolved if it is a symlink when follow_directory_symlink is not specified. I'm asking because the reference implementation here at github and Boost Filesystem V3 always resolve the root path, even if follow_directory_symlink is not specified. This makes workarounds as in the first post necessary, which result in race conditions.

My suggestion would be to explicitly disallow resolving of root symlinks when follow_directory_symlink is not specified, and enable the current behavior with another directory_option "follow_root_symlink".

Thanks, Jan

jiixyj avatar Nov 15 '12 15:11 jiixyj

It is the proposal that matters. Implementations are immaterial, and tend to lag the proposal.

That said, the proposed wording has a couple of problems:

  • It isn't clear in the recursive_directory_iterator constructor specs that the effects of options apply to the initial directory.
  • directory_iterator should also have the options, because they could apply to the initial directory.

I'll reopen the issue.

Thanks,

--Beman

Beman avatar Nov 15 '12 17:11 Beman