nmh-workers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Nmh-workers] extensions on tmp filenames?


From: Robert Elz
Subject: Re: [Nmh-workers] extensions on tmp filenames?
Date: Mon, 03 Feb 2014 14:45:14 +0700

  | > >     If the link named by the new argument exists, it shall be removed
  | > >     and old renamed to new. In this case, a link named new shall
  | > >     remain visible to other processes throughout the renaming
  | > >     operation and refer either to the file referred to by new or old
  | > >     before the operation began.
  | > >
  | > > and that's what Linux still uses for its documentation.

I really cannot believe that anyone is confused by any of this.   The
documentation is all correct, the operation is all correct, and (assuming
there are no implementation bugs) nothing has any security holes.

All the documentation quoted above says, is that if you have two files A and B
and do rename("A", "B") then a file named B is always existing and visible
(the name A vanishes) through the rename - and that as time passes, the name B
will initially refer to its old contents (nothing surprising there, the rename
hasn't happened yet) and later will refer to what was in file A, and that 
anyone that opens the file will get one version or the other - depending upon
exactly when they open.

What else is possible?  If my process opens B today, it must get the old B
right?

Tomorrow you do the rename.

The day after my process opens B again, now it gets the content that used to
be A, right?

No-one could possibly expect, or want, anything different.   All you need
then is to compress the intervals until everything is happening very close
together.  As long as the sequence stays the same, the results remain the
same.

Of course, these two processes (the one renaming, and the one opening B)
have a race - what results the second one (the opening one) gets depends on
whether it opens before or after the rename.  That's not rename's fault,
the same happens (exactly) using link/unlink - or any other way of getting
the data in the file named A accessible using the name B ... just that
all ways of accomplishing this are inferior (in other ways) to rename().

Lastly, if rename(2) exists, there is absolutely no reason to prefer a
link();unlink() sequence over it.   Rename is precisely that - except
guaranteed as an atomic operation (it is impossible from outside to observe
the filesystem in the period between the link and unlink, unlike when the
same thing is accomplished using the 2 sys call variant).   Using link()/
unlink() makes sense only on systems that don't have rename() - and good luck
finding one of those that you'd really want to use these days.

I have no idea what mkstemps() is (I assume some linux invention) or how it
is defined to work, so I can't say if it would be better to use that than
mkstemp()/rename() (possibly, mkstemp() guarantees a new file name is
created, not destroying any other file, the mkstemp()/rename() doesn't
promise that on the target of the rename, and there's no way to guarantee
it is safe ... I'm guessing that is what mkstemps() accomplishes).

But certainly prefer rename() over link()/unlink().

Of course, another option is mkstemp()/link() (with no unlink) - using
the mkstemp() created filename as a lock, so that a later mkstemp() won't
create the same thing.   That's workable, as long as you can assume that
nothing ever creates a file names like the link() target using any other
mechanism, and that the two files get unlinked in the correct order.

kre




reply via email to

[Prev in Thread] Current Thread [Next in Thread]