views:

1111

answers:

2

I've run into a bit of an odd circumstance while using boost::filesystem::exists. If you attempt to check for the existance of a file on a drive that isn't ready or has no media in it, it throws a basic_filesystem_error. As far as I'm concerned for most all uses of bfs::exists, if a drive isn't ready it means the file doesn't exist.

I can wrap my calls with a try-catch to properly handle this condition, however it becomes a bit cumbersome and makes the code a bit clunky. And worse, it means I'm using a special case of basic_filesystem_error for flow control, which means if a different reason for that exception were to arrise, I wouldn't be handling it properly anymore.

The general case where this comes up is if I attempt to check if a file exists on a CD or DVD drive. My code which used to be:

if( bfs::exists( myFilePath ) )
{
...
}

Becomes:

bool fileExists( false );
try
{
   fileExists = bfs::exists( myFilePath );
}
catch( bfs::basic_filesystem_error<bfs::path> e )
{
   fileExists = false;
}
if( fileExists )
{
...
}

I'm not overly enamored with the thought of making this change all over the place in my existing code base.

I'm considering making a seperate function somewhere that wrapps up the try-catch and replacing my bfs::exist calls with that, but I'm still not satisfied that using the try-catch in that manner is a good idea. It seems like I'm opening the door for missing more important and relevant exceptional conditions.

I'm aware that you can recompile boost for a non-throwing version of the function, but I don't think that really avoids my exception handling concerns.

Has anyone run into this problem with removable media drives before, and if so how did you overcome it?

+1  A: 

It's a bug, probably related to:

https://svn.boost.org/trac/boost/ticket/2725

Are you using the latest Boost version? If yes, report another bug there. See:

http://www.boost.org/support/bugs.html

e.tadeu
We're using 1.36.Oddly enough, that bug isn't the behavior we're seeing. If the drive letter doesn't exist, it returns false as expected. However if I try to query a drive mapped to a removable media device (like a DVD player), it throws if there is no media present.Does that still sound like a bug?
Perculator
Yep, so it sounds like another bug!Report the bug there ;)
e.tadeu
+3  A: 

According to the documentation, exists(file_status s) returns "status_known(s) && s.type() != file_not_found".

The documentation also states that:

If the underlying file system reports an error during [file_status] attribute determination:

  • If the error indicating that p could not be resolved, as if by POSIX errors ENOENT [i.e., not found] ... return file_status(not_found_flag).

It seems to me that throwing an exception is not the intended behavior. (when you create the status object its status is known, and that status is not_found).

However, the documentation continues by saying:

[Note: The effect of this behavior is to distinguish between knowing that p does not exist, and not being able to determine the status of p. This distinction is important to users. --end note]

Which implies that the library does intend to make a distinction between "file does not exist" and "I can't determine that file does not exist." You may wish to contact the library's authors for a clearer statement.

However, testing for the existence of a file is a race condition: the file may have existed when the OS looked, but there is no guarantee that it will continue to exist; likewise, the file may not have existed when the OS looked, but there is no guarantee that it will continue not existing. The race condition can have security implications.

Instead, open the file and then see what its attributes are. Once the file is open, the OS makes certain guarantees about what will change and what won't.

Max Lybbert
"Once the file is open, the OS makes certain guarantees about what will change and what won't." Actually, it normally just guarantees that if anything does change (an admin forcibly dismounts the volume or something), then your handle will start reporting errors.
Steve Jessop
I'm less concerned about the race condition situation. If something happens to the files that are being checked, I think our users have bigger problems on their hands.I believe I'm going to be waiting until I have an opportunity to check this in 1.38 to see if this is still an issue or not.
Perculator