Re: Why doesn't (open ... :if-exists) support :truncate?



"Steven M. Haflich" <smh@xxxxxxxxxxxx> writes:
Richard M Kreuter wrote:
Howcome the standard OPEN ... :IF-EXISTS actions don't include an
option for truncating the file when the stream is created?

Have you considered :supersede ? It isn't exactly the same as
:truncate (on certain operating systems, or some processes have the
file open) but the usual behavior will be the same.

Well, the CLHS entry for OPEN says that when :IF-EXISTS is :SUPERSEDE,
"a new file with the same name as the old one is created". ISTM that
there's some difference between truncating a file and replacing one
file with another (using something like POSIX rename(), say):

* On a file system with hard links (Unix and NTFS, say), given a file
with multiple links, replacing one of the file's names with a new
file "breaks" one of the links, and the other file names will still
be associated with the old contents. Opening the file in a
truncating way guarantees that all the file's truenames will be
associated with the new contents.

* With Unix's screwy file permissions, a user can write to a file he
can't delete, and can delete files he can't write to. So the ways
that a process can fail to create a new file or replace one file
with another are mostly disjoint from the ways that a process can
fail to open a file for truncation.

* Again under Unix, it's tricky and not always possible to ensure that
a new file has functionally equivalent metadata as an existing file.
For example, it's not usually possible for an unprivileged process
to change the ownership of a file, and implementations might miss
some exotic metadata like ACLs. By contrast, Unix's truncating open
only affects metadata describing file contents (file length, write
date). So software that depends on file metadata stands a chance of
breaking under file replacing schemes.

As a result, ISTM that not having an explicit way to ask for
truncation leaves implementation-independent Lisp unable to
deliberately interoperate with Unix software in various details.

(Several implementations implement :SUPERSEDE as a truncating open on
Unix. The conformance of this point seems debatable, but for the
detail that the term "file" is implementation-defined in CL, so that
the implementor can stipulate that their OPEN is conforming. But this
almost makes things worse: users might assume that :SUPERSEDE is
supposed to mean a truncating open, and their programs will lose on
implementations that do it differently. So again I think it would be
worthwhile to have a way to ask for truncating explicitly.)

Your "direct I/O" reference doesn't really mean anything. Perhaps you
should explain.

I was trying to come up with a story according to which some Lisp
could do all the OPEN :IF-EXISTS actions, but be unable to to a
truncating open. The entries for :OVERWRITE and :APPEND say "[o]utput
operations on the stream destructively modify the existing file",
which I take to mean that the existing file is to be scribbled on, and
not replaced by a new file. I can't think of a way to do this without
at some point doing I/O directly to the existing file. By contrast,
:NEW-VERSION, :SUPESEDE, :RENAME, :RENAME-AND-DELETE need not do I/O
to an existing file (unless a file system requires I/O to a file in
order to replace the file with another one, I suppose).

--
.