From: Daniel B. <da...@te...> - 2001-06-13 18:47:15
|
:; cd /tmp :; mkdir sbcltest :; cd sbcltest/ :; ln -s orphaned nonexistent :; ls -l total 0 lrwxrwxrwx 1 dan dan 8 Jun 13 19:31 nonexistent -> orphaned :; sbcl This is SBCL 0.6.12.21, an implementation of ANSI Common Lisp. [...] * (directory *default-pathname-defaults*) debugger invoked on condition of type SB-INT:SIMPLE-FILE-ERROR: The file "/tmp/sbcltest/nonexistent" does not exist. restarts: 0: [ABORT ] Reduce debugger level (leaving debugger). 1: [TOPLEVEL] Restart at toplevel READ/EVAL/PRINT loop. (TRUENAME "/tmp/sbcltest/nonexistent") This bug is present in 0.6.12.32 as well. So. DIRECTORY is supposed to return truenames. It is common for implementations to chase symlinks when resolving a truename, so we end up with a non-existent filename. The TRUENAME function is supposed to signal FILE-ERROR if the file does not exist. Problem. The reasonable solutions I can think of are (1) replace the call to (truename name) in DIRECTORY with (or (probe-file name) name), or (2) change TRUENAME to only follow symlinks as far as it can see them, and stop there. I don't think that breaks any invariants: people can't expect to do (and (truename p) (open p ... )) as it could be an unreadable file anyway. Anybody got any better ideas? (In other news, I cvs updated this morning, and you'll be pleased to know that there are no outstanding patches in my tree that want merging. 0.6.12.32 builds on Alpha without changes) -dan -- http://ww.telent.net/cliki/ - Link farm for free CL-on-Unix resources |
From: William H. N. <wil...@ai...> - 2001-06-15 16:49:33
|
On Wed, Jun 13, 2001 at 07:46:53PM +0100, Daniel Barlow wrote: > > :; cd /tmp > :; mkdir sbcltest > :; cd sbcltest/ > :; ln -s orphaned nonexistent > :; ls -l > total 0 > lrwxrwxrwx 1 dan dan 8 Jun 13 19:31 nonexistent -> orphaned > :; sbcl > This is SBCL 0.6.12.21, an implementation of ANSI Common Lisp. > [...] > * (directory *default-pathname-defaults*) > > debugger invoked on condition of type SB-INT:SIMPLE-FILE-ERROR: > The file "/tmp/sbcltest/nonexistent" does not exist. > restarts: > 0: [ABORT ] Reduce debugger level (leaving debugger). > 1: [TOPLEVEL] Restart at toplevel READ/EVAL/PRINT loop. > (TRUENAME "/tmp/sbcltest/nonexistent") > > This bug is present in 0.6.12.32 as well. > > So. DIRECTORY is supposed to return truenames. It is common for > implementations to chase symlinks when resolving a truename, so we end > up with a non-existent filename. The TRUENAME function is supposed to > signal FILE-ERROR if the file does not exist. Problem. > > The reasonable solutions I can think of are (1) replace the call to > (truename name) in DIRECTORY with (or (probe-file name) name), or (2) > change TRUENAME to only follow symlinks as far as it can see them, and > stop there. I don't think that breaks any invariants: people can't > expect to do (and (truename p) (open p ... )) as it could be an > unreadable file anyway. > > Anybody got any better ideas? I'm not sure it's better, but how about (3) making DIRECTORY simply skip dangling symlinks (and making an explicit call to TRUENAME on a dangling symlink signal an error)? There seems to be nothing useful (or at least nothing useful and unsurprising) that you can do with a representing a dangling symlink in the Common Lisp world, so it might be reasonable to ignore them. The ANSI spec for DIRECTORY says "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 truenames of those files." The ANSI spec for TRUENAME says "An error of type FILE-ERROR is signaled if an appropriate file cannot be located within the file system for the given filespec, or if the file system cannot perform the requested operation." As I see it: * Solution (1) isn't good because it doesn't return the truename, as required by the spec for DIRECTORY. * Solution (2) would work, as far as I can see. I expect users would find it a little surprising to have TRUENAME return a dangling symlink, but since ANSI defines "file" as "a named entry in a file system, having an implementation-defined nature", it seems it should certainly be allowed. * Solution (3) would work too, taking the other side of the "implementation-defined" freedom in the definition of "file" to say in effect that dangling symlinks don't really exist. I think this is slightly more convenient behavior than (2), but it might also be more surprising. I don't think anyone is likely to guess, at least without some fairly deep thought, that DIRECTORY would silently skip over dangling symlinks. On the other hand, no one is likely to guess that FILE-LENGTH on a file will blow up with a weird error about it being a dangling symlink. Also, as above, no one will guess that TRUENAME on a dangling symlink will return the dangling symlink. So maybe (2) and (3) are comparably surprising. Another way of looking at the difference: Are dangling symlinks Lisp files or not? (2) Yes. TRUENAME and DIRECTORY can return them. But various other file operations blow up on them more or less randomly (e.g. they have authors and dates but not lengths). (3) No. DIRECTORY skips them, and TRUENAME signals an error on them. You can't do other file operations on them because they don't have TRUENAMEs. At this point I'm leaning toward (3), but there might be other issues I'm overlooking, so I'll think about it for a while longer (and encourage comments). -- William Harold Newman <wil...@ai...> pending patches from sbcl-devel: null-*PRINT-LENGTH* bugfix from Alexey Dejneka (sbcl-devel 2001-06-14) PGP key fingerprint 85 CE 1C BA 79 8D 51 8C B9 25 FB EE E0 C3 E5 7C |
From: Daniel B. <da...@te...> - 2001-06-16 13:47:28
|
William Harold Newman <wil...@ai...> writes: > [I wrote] > > The reasonable solutions I can think of are (1) replace the call to > > (truename name) in DIRECTORY with (or (probe-file name) name), or (2) > > change TRUENAME to only follow symlinks as far as it can see them, and > > stop there. > I'm not sure it's better, but how about (3) making DIRECTORY simply > skip dangling symlinks (and making an explicit call to TRUENAME on a > dangling symlink signal an error)? There seems to be nothing useful > (or at least nothing useful and unsurprising) that you can do with a > representing a dangling symlink in the Common Lisp world, so it might > be reasonable to ignore them. * You might want to delete them ;-) * Emacs uses dangling symlinks to manage file locking: for any file foo.lisp that you're editing, it creates the link lrwxrwxrwx 1 dan dan 37 Jun 16 12:47 .#foo.lisp -> da...@no....893:992399701 (in fact it was through editing one of the test scripts while running tests that I came across this bug). So, if a Common Lisp program should want to interoperate with Emacs in this way, it needs to be able to see them. * A directory cannot be deleted unless it's empty: if it contains a dangling symlink which we don't know about, we'll get an unexpected error when we try to delete it. > On the other hand, no one is likely to guess that FILE-LENGTH > on a file will blow up with a weird error about it being > a dangling symlink. Also, as above, no one will guess that > TRUENAME on a dangling symlink will return the dangling > symlink. So maybe (2) and (3) are comparably surprising. FILE-LENGTH takes a stream as argument (which I found odd - there seems to be no way of getting the length of an unreadable file). I think that all the accessors in CLHS 20.2 make sense for dangling links. > Another way of looking at the difference: Are dangling symlinks > Lisp files or not? > (2) Yes. TRUENAME and DIRECTORY can return them. But various other > file operations blow up on them more or less randomly (e.g. they > have authors and dates but not lengths). > (3) No. DIRECTORY skips them, and TRUENAME signals an error on > them. You can't do other file operations on them because they > don't have TRUENAMEs. > > At this point I'm leaning toward (3), but there might be other issues > I'm overlooking, so I'll think about it for a while longer (and > encourage comments). I'm inclined towards (2); I grat that it may be considered conceptually uglier, but it doesn't hide facts from me which might later have odd effects (e.g. the apparently empty directories which actually aren't, as above). Remember that the user already gets to encounter pathnames that turn out not to be openable files (insufficient unix permissions, read-only file systems, unix-domain sockets, etc) so adding dead links to that set of "odd things" is probably justifiable. -dan -- http://ww.telent.net/cliki/ - Link farm for free CL-on-Unix resources |
From: William H. N. <wil...@ai...> - 2001-06-22 17:28:56
|
On Sat, Jun 16, 2001 at 02:47:19PM +0100, Daniel Barlow wrote: > William Harold Newman <wil...@ai...> writes: > > > [I wrote] > > > The reasonable solutions I can think of are (1) replace the call to > > > (truename name) in DIRECTORY with (or (probe-file name) name), or (2) > > > change TRUENAME to only follow symlinks as far as it can see them, and > > > stop there. > > > I'm not sure it's better, but how about (3) making DIRECTORY simply > > skip dangling symlinks (and making an explicit call to TRUENAME on a > > dangling symlink signal an error)? There seems to be nothing useful > > (or at least nothing useful and unsurprising) that you can do with a > > representing a dangling symlink in the Common Lisp world, so it might > > be reasonable to ignore them. > > * You might want to delete them ;-) > > * Emacs uses dangling symlinks to manage file locking: for any file > foo.lisp that you're editing, it creates the link > > lrwxrwxrwx 1 dan dan 37 Jun 16 12:47 .#foo.lisp -> da...@no....893:992399701 > > (in fact it was through editing one of the test scripts while running > tests that I came across this bug). So, if a Common Lisp program > should want to interoperate with Emacs in this way, it needs to be > able to see them. > > * A directory cannot be deleted unless it's empty: if it contains a > dangling symlink which we don't know about, we'll get an unexpected > error when we try to delete it. So, I was eventually able to implement something like proposal (2). Note that: a. The "see all links in a directory so that you can delete the links so that you can delete the directory" rationale only works in a somewhat ugly, nonintuitive way, since in general you have to do "while CL:DIRECTORY is nonempty delete everything it reports", with a potentially unlimited number of passes, before the Unix directory is actually empty of symlinks. b. In support of the principle that Unix files, even weird symlinks, should be visible in CL:DIRECTORY and thus CL:TRUENAME, I also made TRUENAME on a cyclic symlink return the cyclic symlink itself. This stuff is checked in as sbcl-0.6.12.36 now. Anyone with an opinion on how this ought to work should probably take a look at the new code and the new test cases, since my sales resistance for proposals to change the new behavior is very low right now but will probably increase somewhat whenever I get around to releasing sbcl-0.6.13 (likely early August, but possibly earlier) and increase further when I release sbcl-0.7.0 (late August?). -- William Harold Newman <wil...@ai...> As usual, this being a 1.3.x release, I haven't even compiled this kernel yet. So if it works, you should be doubly impressed. -- Linus Torvalds, announcing kernel 1.3.3 on the linux-kernel mailing list. PGP key fingerprint 85 CE 1C BA 79 8D 51 8C B9 25 FB EE E0 C3 E5 7C |