[cmucl-imp] DIRECTORY and symlinks
When a directory contains a symbolic link to a non-existent file DIRECTORY signals an error. E.g. create a link like this: bash> cd /tmp ; ln -s non-existent bad-link bash> ls -l bad-link lrwxrwxrwx 1 helmut helmut 12 Dec 1 15:29 bad-link -> non-existent and then in CMUCL: CMU Common Lisp snapshot-2012-10 (20C Unicode), running on ix With core: /opt/cmucl/cmucl-2012-10/lib/cmucl/lib/lisp-sse2.core Dumped on: Sun, 2012-09-30 08:33:59+02:00 on lorien2 See <http://www.cmucl.org/> for support information. Loaded subsystems: Unicode 1.28 with Unicode version 6.1.0 Python 1.1, target Intel x86/sse2 CLOS based on Gerd's PCL 2010/03/19 15:19:03 * (directory "/tmp/*.*") File-error in function TRUENAME: The file "/tmp/bad-link" does not exist. [Condition of type KERNEL:SIMPLE-FILE-ERROR] Is that necessary? Or is there some (portable) way to avoid the error? Helmut
"Helmut" == Helmut Eller <heller@common-lisp.net> writes:
Helmut> When a directory contains a symbolic link to a Helmut> non-existent file DIRECTORY signals an error. E.g. create Helmut> a link like this: bash> cd /tmp ; ln -s non-existent bad-link ls -l bad-link Helmut> lrwxrwxrwx 1 helmut helmut 12 Dec 1 15:29 bad-link -> Helmut> non-existent Helmut> and then in CMUCL: Helmut> CMU Common Lisp snapshot-2012-10 (20C Unicode), running on Helmut> ix With core: Helmut> /opt/cmucl/cmucl-2012-10/lib/cmucl/lib/lisp-sse2.core Helmut> Dumped on: Sun, 2012-09-30 08:33:59+02:00 on lorien2 See Helmut> <http://www.cmucl.org/> for support information. Loaded Helmut> subsystems: Unicode 1.28 with Unicode version 6.1.0 Python Helmut> 1.1, target Intel x86/sse2 CLOS based on Gerd's PCL Helmut> 2010/03/19 15:19:03 Helmut> * (directory "/tmp/*.*") Helmut> File-error in function TRUENAME: The file "/tmp/bad-link" Helmut> does not exist. [Condition of type Helmut> KERNEL:SIMPLE-FILE-ERROR] Helmut> Is that necessary? Or is there some (portable) way to Helmut> avoid the error? Ooes (directory "/tmp/*.*" :truenamep nil) do what you want? Ray
Ooes (directory "/tmp/*.*" :truenamep nil) do what you want?
Yes, that's better. It should probably be the default.
It can't be the default: the standard mandates truenames. On the other hand, you could be using asdf-utils:directory* as a portable solution. asdf-utils has many utilities to survive CL pathname hell. —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Any sufficiently advanced misquotation is indistinguishable from an original statement. — John McCarthy, misquoted
On Sat, Dec 01 2012, Faré wrote:
Ooes (directory "/tmp/*.*" :truenamep nil) do what you want?
Yes, that's better. It should probably be the default.
It can't be the default: the standard mandates truenames.
Does the standard specify what the truename of a dead symlink is? The glossary says: truename n. 1. the canonical filename of a file in the file system. See Section 20.1.3 (Truenames). 2. a pathname representing a truename[1]. My file system in this case is Linux tempfs. It seems reasonable to assume that all files returned by readdir(3) have a "canonical filename", namely the value of the d_name slot of the dirent structure. I also don't see the harm if CMUCL chooses to define the "canonical filename" of a dead link as just the link itself.
On the other hand, you could be using asdf-utils:directory* as a portable solution. asdf-utils has many utilities to survive CL pathname hell.
Well, asdf-utils:directory* is full of #+. That's the kind of code I like to avoid. Helmut
Does the standard specify what the truename of a dead symlink is?
No, but the assumption is that implementations will take steps to compute this truename, which might result in errors, and it is not portable to assume otherwise.
Well, asdf-utils:directory* is full of #+. That's the kind of code I like to avoid.
The whole point is that it has the #+ for each and every of the 9 active implementations plus 6 more, so you don't have to. (And yes there might be bugs or missing #+'es, but at least they only have to be fixed in one place.) Alternatively, there's IOLib. —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Be liberal in what you accept and conservative in what you send. — Jon Postel
On Sat, Dec 01 2012, Faré wrote:
Does the standard specify what the truename of a dead symlink is?
No, but the assumption is that implementations will take steps to compute this truename, which might result in errors, and it is not portable to assume otherwise.
That would be a strange assumption. It's important that DIRECTORY can be used to traverse directories. If I want to have truenames, I can just call TRUENAME or perhaps PROBE-FILE on the results of DIRECTORY. But I can't call anything else to traverse directories besides DIRECTORY.
Well, asdf-utils:directory* is full of #+. That's the kind of code I like to avoid.
The whole point is that it has the #+ for each and every of the 9 active implementations plus 6 more, so you don't have to. (And yes there might be bugs or missing #+'es, but at least they only have to be fixed in one place.) Alternatively, there's IOLib.
I shouldn't need to install third party libraries just to list the files in a directory. Helmut
No, but the assumption is that implementations will take steps to compute this truename, which might result in errors, and it is not portable to assume otherwise.
That would be a strange assumption.
Yet, it's how things actually are today. Welcome to Common Lisp!
It's important that DIRECTORY can be used to traverse directories.
It's important that it CANNOT, because that defeats the standard. It's important that something ELSE can be used to traverse directories, and becomes a new de facto standard.
But I can't call anything else to traverse directories besides DIRECTORY.
What do you call to connect to a socket? What do you call to play a sound? What do you call to create a symlink? The CL standard does not cover everything. Get over it. Now work on stuff beyond the CL standard.
Well, asdf-utils:directory* is full of #+. That's the kind of code I like to avoid.
The whole point is that it has the #+ for each and every of the 9 active implementations plus 6 more, so you don't have to. (And yes there might be bugs or missing #+'es, but at least they only have to be fixed in one place.) Alternatively, there's IOLib.
I shouldn't need to install third party libraries just to list the files in a directory.
In the real world, the choice is between: 1- be not portable 2- use a bad portability layer 3- greenspun your own bad a portability layer 4- use and contribute to a good portability layer, one that is robust and comprehensive enough that it becomes the defacto standard and deserves to be included in a future formal standard (if any). I say 4. —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org "Reality is that which, when you stop believing in it, doesn't go away". — Philip K. Dick
On Sun, Dec 02 2012, Faré wrote:
No, but the assumption is that implementations will take steps to compute this truename, which might result in errors, and it is not portable to assume otherwise.
That would be a strange assumption.
Yet, it's how things actually are today. Welcome to Common Lisp!
It's important that DIRECTORY can be used to traverse directories.
It's important that it CANNOT, because that defeats the standard.
If that is true, then other implementations (e.g. SBCL, Allegro) defeat the standard. But I don't believe that it's true. The standard does not specify what the relation of symlinks and truenames is. Since the meaning of truenames is implementation dependent, CMUCL can choose whatever meaning is useful without defeating the standard. Therefore it can also choose not to signal errors when DIRECTORY encounters symlinks. It could also filter them out. Anyway, there is plenty of room for reasonable solutions.
It's important that something ELSE can be used to traverse directories, and becomes a new de facto standard.
Well, the standard is the de facto standard.
But I can't call anything else to traverse directories besides DIRECTORY.
What do you call to connect to a socket? What do you call to play a sound? What do you call to create a symlink?
The CL standard does not cover everything. Get over it. Now work on stuff beyond the CL standard.
I want to list the files in my home directory. That's about the most mundane task DIRECTORY should be able to do. If it can't be used for that then it would be truly useless to have it in the standard.
Well, asdf-utils:directory* is full of #+. That's the kind of code I like to avoid.
The whole point is that it has the #+ for each and every of the 9 active implementations plus 6 more, so you don't have to. (And yes there might be bugs or missing #+'es, but at least they only have to be fixed in one place.) Alternatively, there's IOLib.
I shouldn't need to install third party libraries just to list the files in a directory.
In the real world, the choice is between: 1- be not portable 2- use a bad portability layer 3- greenspun your own bad a portability layer 4- use and contribute to a good portability layer, one that is robust and comprehensive enough that it becomes the defacto standard and deserves to be included in a future formal standard (if any).
I say 4.
5. ask my friendly CMUCL wizard to apply a reasonable interpretation of the standard. Helmut
On Sat, Dec 1, 2012 at 7:23 PM, Helmut Eller <heller@common-lisp.net> wrote:
It's important that it CANNOT, because that defeats the standard.
If that is true, then other implementations (e.g. SBCL, Allegro) defeat the standard. But I don't believe that it's true.
The standard does not specify what the relation of symlinks and truenames is. Since the meaning of truenames is implementation dependent, CMUCL can choose whatever meaning is useful without defeating the standard. Therefore it can also choose not to signal errors when DIRECTORY encounters symlinks. It could also filter them out. Anyway, there is plenty of room for reasonable solutions.
In my experience, "reasonable" doesn't sound well in a sentence involving CL pathnames, all the less where portability is intended.
It's important that something ELSE can be used to traverse directories, and becomes a new de facto standard.
Well, the standard is the de facto standard.
It is also immutable and only covering a tiny subset of interesting APIs. Instead of trying to change it then convince 15 implementations to change and piss off their user base used to the current situation, what about developing a new API that makes sense from day one and doesn't require backwards incompatibility or fighting with stubborn maintainers?
I want to list the files in my home directory. That's about the most mundane task DIRECTORY should be able to do. If it can't be used for that then it would be truly useless to have it in the standard.
It is useless indeed. Welcome to the realization that not all of the CL standard is useful. The question is how to fix it. You're saying: "let's fight the system for a tiny gain", I'm saying "let's build something else that has a consistent API without having to fight anyone".
In the real world, the choice is between: 1- be not portable 2- use a bad portability layer 3- greenspun your own bad a portability layer 4- use and contribute to a good portability layer, one that is robust and comprehensive enough that it becomes the defacto standard and deserves to be included in a future formal standard (if any).
I say 4.
5. ask my friendly CMUCL wizard to apply a reasonable interpretation of the standard.
That's still not portable, until you get all 9 actively maintained implementations to agree on the *same* reasonable interpretation of the standard (not talking about the 6 semi-surviving legacy implementations). —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Every program has at least one bug and can be shortened by at least one instruction — from which, by induction, one can deduce that every program can be reduced to one instruction which doesn't work.
It's important that something ELSE can be used to traverse directories, and becomes a new de facto standard.
Well, the standard is the de facto standard.
It is also immutable and only covering a tiny subset of interesting APIs.
I'm not asking for a new API.
Instead of trying to change it then convince 15 implementations to change and piss off their user base used to the current situation, what about developing a new API that makes sense from day one and doesn't require backwards incompatibility or fighting with stubborn maintainers?
Well, it's only one implementation and Ray tends to be the opposite of stubborn.
I want to list the files in my home directory. That's about the most mundane task DIRECTORY should be able to do. If it can't be used for that then it would be truly useless to have it in the standard.
It is useless indeed. Welcome to the realization that not all of the CL standard is useful.
The question is how to fix it. You're saying: "let's fight the system for a tiny gain", I'm saying "let's build something else that has a consistent API without having to fight anyone".
As you say: I'm not interested in your API. Helmut
I'm not asking for a new API.
Then you won't get a portable solution. And you won't get non-truenames without specifying some non-standard flag to DIRECTORY. And you won't get truename to mean something different to DIRECTORY and to TRUENAME without confusing users.
Well, it's only one implementation and Ray tends to be the opposite of stubborn.
If you're looking for CMUCL-only thing, then (directory "*.*" :follow-links nil :truenamep nil) will do what you want (I'm not sure :follow-links nil does anything when you already specify :truenamep nil). —♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org There are a thousand hacking at the branches of evil to one who is striking at the root. — Thoreau
"Helmut" == Helmut Eller <heller@common-lisp.net> writes:
>>>> It's important that something ELSE can be used to traverse >>>> directories, and becomes a new de facto standard. >>> >>> Well, the standard is the de facto standard. >>> >> It is also immutable and only covering a tiny subset of interesting >> APIs. Helmut> I'm not asking for a new API. >> Instead of trying to change it then convince 15 implementations to >> change and piss off their user base used to the current situation, >> what about developing a new API that makes sense from day one and >> doesn't require backwards incompatibility or fighting with stubborn >> maintainers? Helmut> Well, it's only one implementation and Ray tends to be the opposite of Helmut> stubborn. Heh. In this case, unless there is general consensus on the issue, I'm reluctant on changing the default value of truenamep from T to NIL. It's been that way since at least 18c (I just checked) and perhaps even before. Doesn't mean it's right, but in these many years, there hasn't been enough reason to change it. Ray
participants (3)
-
Faré -
Helmut Eller -
Raymond Toy