[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: use of lchmod
Re: use of lchmod
Tue, 15 Sep 2009 21:50:24 +0200
Eric Blake wrote:
> I'm thinking we should change things to be a bit more consistent, as part of
> preparing copy.c to be rewritten to use fts, but I'm not sure which way to go.
> Does anyone have preference?
> If we go with POSIX, then:
> If we go with glibc behavior, then:
> The replacement lchmod should be changed to blindly fail with ENOTSUP, rather
> than the current behavior of calling chmod. No standards compliance issue,
> since lchmod is not standardized.
> We do not need to replace native Linux fchmodat(), and we only have to tweak
> our existing replacement fchmodat() to blindly fail with ENOTSUP instead of
> ENOSYS on other platforms. This is not strictly POSIX, but if used correctly,
> is more efficient on Linux.
> In coreutils, we have to be careful to call chmod rather than lchmod on non-
> symlinks, saving lchmod for when we know that the target should be a symlink.
> On ENOTSUP failure, we have to fall back to chmod for non-symlinks.
> Either way:
> cp.c has two uses of lchmod, to implement 'cp --parents --preserve a/b c/d'
> with correct permissions on c/d/a according to the original a. One use is
> always on a directory (making it temporarily writable); the other is in
> re_protect to restore permissions, although I didn't spend enough time seeing
> whether the restore path could ever happen on a symlink to a directory
> installed in place of the original directory. So it seems like cp.c should be
> using chmod, not lchmod.
You might argue that the lchmod on just-created-directory is useful,
in case that directory is replaced with a symlink. Then, thanks
to our use of lchmod, the code affects the symlink and doesn't
chmod through it. However, the next iteration of that loop will
effectively dereference that interposed symlink by operating on
.../symlink/next-element, so in a way we've already lost.
> copy.c has several uses of lchmod (including via the wrapper
> but again, all of them look like they are used for temporarily adding
> permissions to read-only destinations, or for granting additional permissions
> that were intentionally omitted at the beginning. In particular, for the case
> of fchmod_or_lchmod, chmod should always be sufficient, as you cannot have an
> open fd on a symlink, but the function is designed for use on an open fd.
> Meanwhile, it looks like on a BSD system, 'cp --preserve' is missing a use of
> lchmod to preserve permissions on a copied symlink; here, we can safely ignore
> ENOTSUP failure of lchmod on Linux.
> Finally, we should consider adding 'chmod -h' to mirror 'chown -h', where it
> would actually work on BSD, and would just print an error message on Linux
> attempted on symlinks but behave like plain 'chmod' on regular files. This
> would always require an lstat() or reliable d_type (either in the gnulib
> wrapper if we choose to make fchmodat match POSIX, or in chmod.c if we make
> fchmodat match glibc).
> Right now, I'm leaning towards matching glibc behavior, and making the burden
> of the lstat() fall on the caller; particularly since the caller can use
> information instead of lstat() in some cases. Does all of this sound
Yes. I agree. This is consistent with policy:
Favor systems/interfaces that do things right or
that permit a higher quality implementation.
- use of lchmod, Eric Blake, 2009/09/15
- Re: use of lchmod,
Jim Meyering <=