-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Use non-throw version of fs::recursive_directory_iterator
#8392
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use non-throw version of fs::recursive_directory_iterator
#8392
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! It's possible to see the bug here: https://web.archive.org/web/20160804003617/https://svn.boost.org/trac/boost/ticket/4494, but that's for a pretty old version of boost, I would expect for that to have been fixed.
Either way the issue you created and the crash shown there talks about recursive_directory_iterator
causing the exception, but we are using all of the boost APIs with their exception throwing variant.
If instead we use the other constructor, it's possible for the API to register errors into a return value; I would use that instead of an exception, since exception throwing is pretty slow, and it's especially not ideal in a loop like this.
You can see the various functions docs here: https://www.boost.org/doc/libs/1_77_0/libs/filesystem/doc/reference.html
Furthermore a Permission Denied is not totally unexpected or "exceptional", so it makes sense to handle it differently.
I agree, but I'm not much of a c++ programmer. Is there an example I can borrow from? |
Cribbing from the internet, if I do this:
It stops on the first permission denied error. Obviously not the behavior we want. |
As I understand it, there are a couple of things. The first issue, is that we want the non-throw form -- to get this, we pass in an error receiver. The second issue, is that short form of the for loop uses I've also opted to pass in I opted to ignore the errors, half because I didn't know how to read them, and half because all we'd do is For my future self, these links had some okay explanations, and some possible helpers if we wanted to make a class for it.
|
fs::recursive_directory_iterator
fs::recursive_directory_iterator
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay, but yes passing the error_code to the constructor so that it can be set is what I meant.
But we have to do it to all the functions, otherwise other can still throw.
42db834
to
8309709
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. By my interpretation we should be getting the same semantics while skipping permission errors and avoiding throws.
Fixes #8391
Modifies the
recursive_directory_iterator
to the non throwing formLooking at our code, I notice that we callfs::recursive_directory_iterator
in two places. One has a try/catch, one does not. The internet suggests some versions of boost have a bug that causes is_symlink to raise if there's no permissions. They reference https://svn.boost.org/trac/boost/ticket/4494 which doesn't exist any more