Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Any way to allow clobbering empty files when noclobber is set?



On Sat, Jun 6, 2020 at 1:58 PM Peter Stephenson
<p.w.stephenson@xxxxxxxxxxxx> wrote:
>
> My understanding of the semantics (feel free to put me right, of
> course), is that as any use of fstat() would be on a non-clobbering
> open, you can't stop anyone else writing to the file (the same file,
> rahter than a newly created one with the same one) at any point.  Worse,
> you're now claiming you've clobbered that open file, and you haven't.
> So now you have Roman's nightmare scneario where you're claiming you've
> opened a new file because the old one was empty, but actually two
> processes have written to it.  Not only have you not fixed a race,
> you've created a new one.

Yep. Having unspecified file content that is the result of interleaved
writes seems pretty bad.

> Assuming both processes are actually doing clobbering opens (O_CREAT |
> O_EXCL), you can't get into that position.  You can't guarantee that
> someone else hasn't written to a file of that name, but you can
> guarantee that two so-called clobbering opens actually are that.

Let me put this in code:

  { print hello >file } &
  hello_pid=$!

  { print bye >file } &
  bye_pid=$!

  { print -n >file } &
  empty_pid=$!

  wait $hello_pid
  print "print hello => $?"

  wait $bye_pid
  print "print bye => $?"

  wait $empty_pid
  print "print -n => $?"

  print "file => $(<file)"

This program concurrently writes "hello", "bye" and "" (empty) to the
same file. Any implementation of clobber_empty that uses just POSIX C
API will allow multiple writes to succeed, resulting in this output:

  print hello => 0
  print bye => 0

This output implies that one command has overwritten the output of
another and the user has received no indication to this effect.

In addition, no implementation restricted to POSIX C API can guarantee
that the last line of the output is one of these:

  file => hello
  file => bye

Different implementations will violate this expectation in different
ways. Some will allow abominations such as "byelo" or "hellobye". If I
understand Peter's point correctly, his preferred implementation will
guarantee that the file exists and contains either "hello", "bye" or
"" (empty). The possibility of an empty file is unfortunate. In
addition, this implementation requires unlinking files (when the file
exists prior to a write and is empty), which may be prohibited while
writes to the file are allowed. Unlinking also introduces the
possibility of losing files, together with their permissions and
ownership, which could've been informative. This happens when one of
the writes gets interrupted or fails to create a file after unlinking.

All these issues can be fixed through the use of advisory locks on
systems that support them.

Roman.



Messages sorted by: Reverse Date, Date, Thread, Author