zsh-workers
 help / color / mirror / code / Atom feed
From: Roman Perepelitsa <roman.perepelitsa@gmail.com>
To: Peter Stephenson <p.w.stephenson@ntlworld.com>
Cc: Zsh hackers list <zsh-workers@zsh.org>
Subject: Re: Any way to allow clobbering empty files when noclobber is set?
Date: Sat, 6 Jun 2020 14:48:15 +0200	[thread overview]
Message-ID: <CAN=4vMrtTugN6gBmC1A75m9Q2xLDuEzbf2sBacZNgAKcSoa6-w@mail.gmail.com> (raw)
In-Reply-To: <13acd486e6457c1f708304026c3e1b59521ad328.camel@ntlworld.com>

On Sat, Jun 6, 2020 at 1:58 PM Peter Stephenson
<p.w.stephenson@ntlworld.com> 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.

  reply	other threads:[~2020-06-06 12:49 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20200603020919eucas1p13e26ebcbb335784d14bfb97b137f385a@eucas1p1.samsung.com>
2020-06-03  2:08 ` Martin Tournoij
2020-06-03 12:04   ` Peter Stephenson
2020-06-04  1:48     ` Daniel Shahaf
2020-06-04  2:43       ` Bart Schaefer
2020-06-04  4:06         ` Daniel Shahaf
2020-06-04  5:00           ` Bart Schaefer
2020-06-05  3:10             ` Daniel Shahaf
2020-06-05  3:18               ` Daniel Shahaf
2020-06-06  1:07               ` Bart Schaefer
2020-06-06  4:48                 ` Daniel Shahaf
2020-06-06  7:04                   ` Bart Schaefer
2020-06-04  6:31       ` Martin Tournoij
2020-06-05  2:22         ` Daniel Shahaf
2020-06-04  2:13     ` Vin Shelton
2020-06-04  2:35       ` Bart Schaefer
2020-06-04  2:36       ` Daniel Shahaf
2020-06-04 11:57         ` Vin Shelton
2020-06-04  5:06     ` Bart Schaefer
2020-06-04  5:41       ` Roman Perepelitsa
2020-06-05  2:07         ` Daniel Shahaf
2020-06-05  4:38           ` Roman Perepelitsa
2020-06-06  1:41             ` Bart Schaefer
2020-06-06  4:55               ` Daniel Shahaf
2020-06-06  6:25                 ` Roman Perepelitsa
2020-06-06  7:08                 ` Bart Schaefer
2020-06-06  8:03                   ` Daniel Shahaf
     [not found]           ` <1941572212.466119.1591360860372@mail2.virginmedia.com>
     [not found]             ` <e7f7dfe2-eb4a-457b-85fb-091935a74c0e@www.fastmail.com>
2020-06-06 11:57               ` Peter Stephenson
2020-06-06 12:48                 ` Roman Perepelitsa [this message]
2020-06-06 15:24                   ` Bart Schaefer
2020-06-06 16:24                     ` Peter Stephenson
2020-06-07 11:55                       ` Daniel Shahaf
2020-06-07 17:00                         ` Peter Stephenson
2020-06-08  3:27                           ` Daniel Shahaf
2020-06-08  9:30                             ` Peter Stephenson
2020-06-07 17:20                         ` Bart Schaefer
2020-06-06 15:09                 ` Bart Schaefer
2020-06-04  6:47       ` Martin Tournoij
2020-06-04  9:42       ` Peter Stephenson
2020-06-04 12:20         ` Roman Perepelitsa
2020-06-04 12:26           ` Peter Stephenson
2020-06-04 12:15     ` Peter Stephenson
2020-06-04 20:35       ` Bart Schaefer
2020-06-05  1:59         ` Daniel Shahaf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAN=4vMrtTugN6gBmC1A75m9Q2xLDuEzbf2sBacZNgAKcSoa6-w@mail.gmail.com' \
    --to=roman.perepelitsa@gmail.com \
    --cc=p.w.stephenson@ntlworld.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).