[Ecls-list] open :supersede and rename-file advise
Geo Carncross
geocar at gmail.com
Tue Nov 27 03:14:52 UTC 2007
On Nov 26, 2007 8:36 PM, Richard M Kreuter <kreuter at progn.net> wrote:
> IMO that the truly Right Thing is for implementors to
> add a new :IF-EXISTS action, :TRUNCATE, which, if given, means to open
> the existing file and truncate it, and to have :SUPERSEDE, :NEW-VERSION,
> :RENAME, :RENAME-AND-DELETE all create a new file in some manner; I'd
> prefer write-beside openings with rename-at-close-time behavior for all
> those cases, too. But I recognize that any implementation that changes
> its implementation of the :IF-EXISTS actions will break compatibility
> with itself, which is likely to frustrate its users, so someone ends up
> losing in any case.)
This is interesting, and I'm glad I asked about this.
Something I feel is important to note is that almost every use of
O_TRUNC in unix applications is a bug; unix programs don't usually
need truncate and its pervasiveness probably has more to do with the
fact that the API is simpler. The fact that :TRUNCATE is curiously
otherwise lend itself well to that idea, but moreover, unix programs
rarely cooperate using O_TRUNC on files they expect other processes to
have open.
Something else important might be about hard links: They don't seem to
be as common as they used to be. In practice, replacing one side of a
hard-link usually occurs as part of some complicated protocol for
using the filesystem as a serialization point, to save disk-space (and
upgrades tend to occur all at once), or to show students how hard
links work :)
A better way to solve this particular may be a STREAM-FILE-TRUNCATE
function, but I wouldn't be adverse to a :IF-EXISTS :TRUNCATE option
either.
I think paying attention to what other CL implementations do is pretty
important. If implementations are too different from eachother then
being a common-lisp becomes about as valuable asthe label
"posix-compliance" when a player like Windows NT can get the label.
That said, I'm still not convinced that having :SUPERSEDE be
crashproof instead of buggy would actually introduce any real
incompatabilities. In most cases it'll simply deliver increase
robustness, and the necessary contortions that an application would
have to go through to be affected by this would also be affected by
network filesystems, and other platforms that you might run on.
Remember, not only does it have to assume the file is truncated, but
also that another process can see the same name as being truncated,
and that any writes done here, will also be seen by the other process.
Maybe instead of :SUPERSEDE, we should use :NEW-VERSION to signify a
crashproof replacement of the underlying file. After all, on a lispm,
someone could simply delete the old versions before this process had
an opportunity to do anything with the old version. If you really
wanted a backup~ file, two hard links, and two renames could do it
crashproof.
Or maybe instead of :SUPERSEDE, we should use :RENAME-AND-DELETE
because the state of the filesystem after the operation would be the
same, the implementation would simply be RENAME-AND-CLOBBER on the
inside.
An application that relies on :SUPERSEDE actually meaning :TRUNCATE
might exist. If it does, would it ever mean :RENAME-AND-DELETE to mean
:TRUNCATE? Might this whole thing be avoided by using
:RENAME-AND-DELETE instead?
More information about the ecl-devel
mailing list