Boost logo

Boost :

From: Beman Dawes (bdawes_at_[hidden])
Date: 2005-03-31 18:25:11


At 01:06 PM 3/31/2005, Rob Stewart wrote:
>From: Beman Dawes <bdawes_at_[hidden]>
>>
>>...
>
>> But with the following errors I can't see any way to know if the path
>> actually exists or not:
>>
>> [EACCES] Search permission is denied for a component of the path
>prefix.
>
>Peter's query is key here: what does it mean for exist() to
>return true or false? You could say that returning false here is
>appropriate because, as far as the current user is concerned, the
>file doesn't exist.

I also think that Peter's query is key. To try to answer that, I looked at
about 25 uses of exists() in .cpp files in the boost/tools hierarchy.

Perhaps a third of the uses would still make total sense if [EACCES] was
treated as false. Perhaps another third of the uses (like using exists() to
see if create_directories() needs to be called) might technically be harmed
returning false, but no harm would actually be done because some other call
(create_directories() in the above case) would soon fail.

But perhaps a third of uses were simply to tell if some file system entry
was present as part of determining control flow within the code. There
wasn't an immediate use of the path after the exists() test, so it is very
hard to tell what the effect of returning false would be. Even when you can
see the immediate affect, it isn't always clear what is best. For example,
link_check.cpp uses exist() tell if an HTML link is broken. Seems to me
[EACCES] is an error condition - the link_check is being run with the wrong
permissions or something.

>> [EIO] An error occurred while reading from the file system.
>
>Is this a permanent failure?

There is no way to tell. POSIX doesn't give any indication. So it seems to
me it should be treated as an error causing exception.

> If so, it is reasonable to return
>false: at this time, the file doesn't exist, even if the
>intention is that it does. If it is a temporary failure, then a
>retry might succeed in finding the real answer. In that case, it
>is appropriate that the caller know that a retry is in order.
>
>> [ELOOP] A loop exists in symbolic links encountered during
resolution
>> of the path argument.
>
>While that is an error condition, it doesn't prevent declaring
>that the file, as given by the supplied pathname, doesn't exist.

While it doesn't prevent us declaring it doesn't exist, something is
clearly rotten so I'm much more comfortable throwing an exception (or doing
something else that doesn't gloss over the fact that a possilbe error has
occurred.)

>> [ENAMETOOLONG] The length of the path argument exceeds {PATH_MAX} or
>> a pathname component is longer than {NAME_MAX}.
>
>The pathname clearly doesn't exist because it is invalid.

What if the pathname was too long because of a long prefix of
"foo/../foo/../foo/../foo" eventually ending in a valid "/real-file"?

>Whether the file the caller is interested in actually exists is a
>separate question. You can only answer whether the supplied
>pathname refers to an existing file.
>
>If the caller wants to know whether a pathname is valid and names
>an existing file, isn't that a different question (or set of
>questions?).
>
>> If you agree with that analysis, then it looks like exists() should be
>> changed to throw on those last four errors. is_accessible() would have
a
>
>I disagree. All the caller wants to know is whether the supplied
>pathname refers to an existing file.

But if it isn't possible to reliably answer that query, shouldn't it be an
error?

OTOH, if there is a way (perhaps a status() function returning a bitmap as
you suggested in an earlier post) to detect these probably rare error
cases, then it would seem more acceptable for exists() to treat these
errors as false. An application which had more stringent requirements can
avoid exists() and use an explicit test of status() results.

--Beman


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk