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

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



Peter Stephenson wrote on Sun, 07 Jun 2020 18:00 +0100:
> On Sun, 2020-06-07 at 11:55 +0000, Daniel Shahaf wrote:
> > My point here is really just the one I already made in 45976, and
> > wasn't answered there: can't we avoid the close()-then-open() sequence
> > that 45968 does?  That one seems to be an _avoidable_ race condition,
> > unlike the above ones.  
> 
> I think what it boils down to here is either you test using fstat() the
> the file is empty, or you re-open using O_TRUNC, both of which ensure
> the file is empty at that point.  Then at some later point, the file
> will be written to.  Between the two it's there but empty, which is
> unavoidable.

*nod*

> So my last change, closing and opening with O_TRUNC,
> doesn't really gain anything over leaving it open after checking the
> size with fstat(), I don't think, in which case the extra open() is
> redundant and best removed (and that puts us in the fortuitous position
> where we haven't actually added any system calls in adding
> CLOBBER_EMPTY).  But I don't think taking it out actually removes a
> race.

The race is:

1. zsh runs «: > existing-empty-file».
2. zsh calls open(O_EXCL) which fails, then open() and fstat(), which both succeeds.
3. Some other process writes data to the file.
4. zsh opens the file with O_TRUNC.
5. bin_true() returns, not having written anything to the file.
6. zsh closes the file.

Step #4 will have deleted the other process's data.  If we remove the
close()/open() pair, the step #4 data will survive.

It's an edge case, yes.

Cheers,

Daniel



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