[Module::Build] Re: Preserving files' executable bits, once more (was: r5891 - in Module-Build/trunk
Status: Beta
Brought to you by:
kwilliams
|
From: Julian M. <ju...@me...> - 2006-04-23 17:13:37
|
Ken Williams wrote:
> demerphq wrote:
> > Randy W. Sims wrote:
> > > Ken Williams wrote:
> > > > I wonder whether we should check for executability with "-x $file"
> > > > rather than "(stat $file)[2] & 0111". Besides being simpler, it
> > > > seems like it might DTRT on more platforms, where stat values might
> > > > be nontrustworthy.
> > >
> > > You mean like so:
> > >
> > > $mode =3D 0444 | ( -x $file ? 0111 : 0 );
> >
> > Seems to me that if -x and stat with the appropriate mask arent
> > returning the same thing you have a bug in Perl.
>
> Not necessarily. On Unix, for example, if the permissions on a file
> you own are 0445, then "(stat $file)[2] & 0111" will return true but
> "-x $file" will return false. Maybe that means we're not using "the
> appropriate mask", but what would an appropriate mask be in all the
> situations we care about? Probably none exists.
Sorry for my late comment on this.
`perldoc -f -x` is interesting:
| The interpretation of the file permission operators "-r", "-R", "-w",
| "-W", "-x", and "-X" is by default based solely on the mode of the file
| and the uids and gids of the user. There may be other reasons you can't
| actually read, write, or execute the file. Such reasons may be for
| example network filesystem access controls, ACLs (access control lists),
| read-only filesystems, and unrecognized executable formats.
|=20
| Also note that, for the superuser on the local filesystems, the "-r",
| "-R", "-w", and "-W" tests always return 1, and "-x" and "-X" return 1
| if any execute bit is set in the mode. Scripts run by the superuser may
| thus need to do a stat() to determine the actual mode of the file, or
| temporarily set their effective uid to something else.
On Linux/Unix:
| $ ls -go --time-style=3D+
| total 0
| -rw-r--r-- 1 0 f---------
| -rw-r--r-x 1 0 f--------x
| -rw-r-xr-- 1 0 f-----x---
| -rw-r-xr-x 1 0 f-----x--x
| -rwxr--r-- 1 0 f--x------
| -rwxr--r-x 1 0 f--x-----x
| -rwxr-xr-x 1 0 f--x--x--x
| $ perl -e 'printf("%s: -x =3D %s\n", $_, -x $_ || "0") for @ARGV' *
| f---------: -x =3D 0
| f--------x: -x =3D 0
| f-----x---: -x =3D 0
| f-----x--x: -x =3D 0
| f--x------: -x =3D 1
| f--x-----x: -x =3D 1
| f--x--x--x: -x =3D 1
| $ sudo perl -e 'printf("%s: -x =3D %s\n", $_, -x $_ || "0") for @ARGV' *
| f---------: -x =3D 0
| f--------x: -x =3D 1
| f-----x---: -x =3D 1
| f-----x--x: -x =3D 1
| f--x------: -x =3D 1
| f--x-----x: -x =3D 1
| f--x--x--x: -x =3D 1
So apparently -x always returns true for root, and (mode & 0100) for=20
non-root.
Also:
| $ sudo -u julian ./f--x------
| $ sudo -u julian ./f--------x
| sudo: unable to execute ./f--------x: Permission denied
| $ sudo ./f--x------
| $ sudo ./f--------x
| $
If a file really is 0445 (0455), then I think it is reasonably safe to=20
assume that either ug-x (u-x) was _deliberately_ set or that o+x (go+x)=20
was _accidentally_ set, and that therefore "not x" should be assumed. IOW,=
=20
it should be reasonably safe to consider the user x bit authoritative.
Thus Module::Build should use -x for the executable check. However since=20
root (e.g. during `Build install`) always sees files as "x" if _any_ x bit=
=20
is set, M::B would have to emulate -x's non-root behavior:
my $mode =3D 0444 | ( (stat($file))[2] & 0100 ? 0111 : 0 );
|