Thanks Mark!


On Thu, Jan 30, 2014 at 9:14 AM, Mark Evenson <evenson@panix.com> wrote:

On Jan 10, 2014, at 15:51, Alan Ruttenberg <alanruttenberg@gmail.com> wrote:

> There are, I would offer, several arguments suggesting that the
> current behavior should not be the default.
>
> 1) Exceptions: Generally, listing the contents of a directory is not
> considered an exception unless the directory structure is corrupted.
> In some cases (e.g. unix "rm") you can't even do anything to the
> target of the link. So ABCL signals an exception when most would not
> expect it. Consider the case where the link points to a file on a
> device that may or not be mounted. If the device is taken offline,
> nothing in the directory changes, and yet the behavior does. It seems
> that this situation is more properly handled by an exception when
> opening the file.
>
> The doc for truename says, about conditions: "An error of type
> file-error is signaled if an appropriate file cannot be located within
> the file system for the given file spec or if the file system cannot
> perform the requested operation.". Whether or not the symbolic link is
> a file or not. Certainly for some cases it is, for example when
> handled by archiving or certain version control systems, or in the
> cases I list in (4). In the case of "rm", the answer is yes, it is a
> file, implicit from the documentation: "The rm utility attempts to
> remove the non-directory type files specified on the command line.
> [...] The rm utility removes symbolic links, not the files referenced
> by the links. In ABCL, (directory "/") -> (#P"/"). This means that a)
> ABCL is inconsistent in that it sometimes returns truenames for things
> that can not be "opened" or b) ABCL admits that there can be truenames
> for entities other than files, which makes it's treatment of symbolic
> links inconsistent.
>
> 2) Pragmatism: With the current default, the only possible
> programmatic repair in the common case that you don't care about these
> entries - for example if you are looking for a file whose name matches
> a pattern not expressible using the directory wild card expressivity -
> is to use an implementation-specific keyword. CCL's implementation
> also has this property, which I also consider to be a fail. In
> practical terms this means that the unsuspecting programmer must wrap
> all calls to directory with a catch and have the handler respond in an
> implementation-specific way. It is much more common to protect
> accesses to a file than accesses to a directory.
>
> 3) Truth in advertising:  The exception happens independent of the
> value of the :resolve-symlinks keyword. If the function is told not to
> resolve symlinks, one would expect it doesn't resolve symlinks. Yet it
> does, since that's the only way that it could figure out that the
> "file does not exist".
>
> 4) File system operations other than opening: There are legitimate
> operations on unresolvable links. For example, such files can be
> removed, renamed, and there are retrievable dates and other metadata
> retrievable about them. One would not expect directory to balk in the
> case that you are retrieving file names for one of these purposes.
>
> My conclusion:
> - If resolve-symlinks is false, the behavior should be either that of
> SBCL's (return the name) or CCL's (don't return the name) depending on
> which answer the implementation takes towards the question "is a
> symbolic link a file?".
> - If resolve-symlinks is true then signal an error.
> - The default should be :resolve-symlinks nil, because cognate
> directory operations in every operation's default case that I'm aware
> of is to not consider this case an exception.

With a (hopefully) carefully done refactoring of the underlying Pathname.listDirectory() routine, the semantics of CL:DIRECTORY are now:

  (PATHSPEC &KEY (RESOLVE-SYMLINKS NIL))
  Determines which, if any, files that are present in the file system have names matching PATHSPEC, and returns
a fresh list of pathnames corresponding to the potential truenames of those files.

In the default behavior with :RESOLVE-SYMLINKS set to nil, a
CL:TRUENAME call an individual pathname in the list may signal an error,
i.e. the pathnames have been constructed as truenames, without calling
the entire resolution routine of CL:TRUENAME.

If RESOLVE-SYMLINKS is T, and any of the pathnames have truenames
which do not exist, this routine will signal a file error to its caller.

This should satisfy the basic issues here:  there may be some corner cases to chase down.  Patches are welcome.

This should also (mostly) fix the ASDF BUNDLE-OP problem (which was a problem with DIRECTORY called with :WILD-INFERIORS in a symlinked directory, as ‘/tmp' is under OS X).

[r14619]: http://abcl.org/trac/changeset/14619

--
"A screaming comes across the sky.  It has happened before but there is nothing
to compare to it now."