bug-coreutils
[Top][All Lists]
Advanced

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

Re: mkdir when target exists and is a broken symlink


From: Eric Blake
Subject: Re: mkdir when target exists and is a broken symlink
Date: Tue, 17 May 2005 22:04:04 +0000

> ln -s nonexistent foo
> There could be some kind of -f, --follow option so that mkdir will
> create the directory pointed to.  You'd probably use it together with
> -p.  Then 'mkdir -fp' would be a way to try everything sensible to make
> sure the destination exists and can be used as a directory (ie, is a
> directory itself or a symlink to one).

This sounds somewhat similar to cp -f, --force.  cp uses slightly different 
semantics, required by POSIX (rather than try to create the new file at the 
location specified by the dangling symlink, it unlinks the symlink and creates 
the new file in its place).  I would lean more toward force semantics than 
follow semantics if `mkdir -fp' were supported.  In particular, how would 
follow semantics behave with `mkdir -fp circular'?

> I note that 'touch foo' when foo is a broken symlink will create the
> link destination if possible

Hmm, you may have unconvered a POSIX bug or coreutils compliance bug:
POSIX requires that touch do the equivalent of calling creat() if the file does 
not exist, then call utime() whether or not creat() was called.  A broken 
symlink exists, so step one should be skipped, then in step two, utime() should 
fail with ENOENT when trying to resolve the (still) broken symlink.  But 
coreutils is using open(O_CREAT) as the simultaneous check for existance and 
replacement call for creat().  Normally, this is identical, but in the case of 
a broken symlink, it is not (remember, POSIX states that open("foo", 
O_CREAT|O_EXCL) must fail with EEXIST; but without O_EXCL, it follows the link 
as if open("nonexistent", O_CREAT) had been called, thus creating the target).  
Then in step two, since nonexistent now exists, futimens (coreutils much nicer 
replacement for utime) is successfully changing nonexistent's time.  This may 
be an unintentional oversight in POSIX, worthy of bringing before the Austin 
group, because the semantics of touch populating a previously dangling symlink 
are useful.

Furthermore, create() is equal to open(O_WRONLY|O_CREAT|O_TRUNC), but coreutils 
is using open(O_WRONLY|O_CREAT|O_NONBLOCK|O_NOCTTY).  The omission of O_TRUNC 
is okay (it has no semantics when the file did not exist, touch should only 
create the file if it did not exist, and checking for existance with O_TRUNC is 
destructive).  But the addition of O_NONBLOCK and O_NOCTTY, while reasonable, 
are not allowed by the strict reading.

Finally, a related feature request: on systems that support lutime() and family 
(and where lstat() provides meaningful times on the symlink), touch should 
probably support -L,--logical and -P,--physical to control whether the time 
being touched is of the actual symlink or of its target.

--
Eric Blake






reply via email to

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