develooper Front page | perl.perl5.porters | Postings from June 2012

NWCLARK TPF grant report #38

From:
Nicholas Clark
Date:
June 12, 2012 09:39
Subject:
NWCLARK TPF grant report #38
Message ID:
20120612163942.GS37285@plum.flirble.org
[Hours]		[Activity]
2012/05/23	Wednesday
 3.00		reading/responding to list mail
 2.00		t/op/filetest.t
=====
 5.00

2012/05/24	Thursday
 0.75		AIX ccache
 0.50		reading/responding to list mail
 3.25		t/op/filetest.t
=====
 4.50

2012/05/25	Friday
 7.50		reading/responding to list mail
=====
 7.50

Which I calculate is 17.00 hours

Not a massive amount to report, as I wasn't able to get much done in the
first half of the week as still ill, and then spent most of the rest of the
week catching up with e-mail.

I spent a bit of time looking at a (seeming) ccache bug on AIX. On AIX, IBM
use the same front-end driver binary to invoke the various different available
C and C++ compilers. They hard link the same binary on disk, and use the
name to determine which compiler to use. Different compilers can
generate different output for identical command line flags. This is not
surprising. The fact that the different compilers are actually the same
file on disk (with the same device and inode), and that *all* that changes
is the name in argv[0] can be. I'm still not *sure* what's going on, why,
and how to fix it, and haven't had more time to look since.

The rest of the time was spent tidying up t/op/filetest.t

This file had caused some nervousness just before the release of 5.16.0
thanks to a failure report from an Ubuntu user. This shouldn't happen. It
turned out that the test couldn't cope with a combination of circumstances -
running the test as root, *but* the build tree not being owned by root,
*and* the file permissions being such that other users couldn't read files
in the test tree. This all being because testing that -w isn't true on a
read only file goes wrong if you're root, so there's special-case code to
detect if it's running as root, which temporarily switches to an arbitrary
non-zero UID for that test. Unfortunately it also had a %Config::Config
based skip within that section, and the read of obscure configuration
information triggers a disk read from lib/, which fails if the build tree's
permissions just happened to be restrictive. The problem had actually been
around for quite a while, so Ricardo documented it as a known issue and
shipped it unchanged.


So I went to fix it. And this turned into quite a yak shaving exercise, as
layer upon layer of historical complexity was revealed. Originally,
t/op/filetest.t was added to test that various file test operators worked as
expected. (Commit 42e55ab11744b52a in Oct 1998.) It used the file t/TEST and
the directory t/op for targets. To test that read-only files were detected
correctly, it would chmod 0555 TEST to set it read only.
    
The test would fail if run as root, because root can write to anything. So
logic was added to set the effective user ID to 1 by assigning to $> in an
eval (unconditionally), and restoring $> afterwards. (Commit
846f25a3508eb6a4 in Nov 1988.) Curiously, the restoration was done after the
test for C<-r op>, rather than before it.
    
Most strangely, a skip was then added for the C<-w op> test based on
$Config{d_seteuid}. The test runs after $> has been restored, so should have
nothing to do with setuid. It was added as part of the VMS-related changes
of commit 3eeba6fb8b434fcb in May 1999. As d_seteuid is not defined in VMS,
this makes the test skip on VMS.
    
Commit 15fe5983b126b2ad in July 1999 added a skip for the read-only file
test if d_seteuid is undefined. Which is actually the only test where having
a working seteuid() *might* matter (but only if running as root, so that $>
can be used to drop root privileges).
    
Commit fd1e013efb606b51 in August 1999 moved the restoration of $> earlier,
ahead of the test for C<-r op>, as that test could fail if run as root with
the source tree unpacked with a restrictive umask. (Bug ID 19990727.039)


"Obviously no bugs" vs "no obvious bugs". Code that complex can hide
anything. As it turned out, the code to check $Config{d_seteuid} was
incomplete, as it should also have been checking for $Config{d_setreuid} and
$Config{d_setresuid}, as $> can use any of these. So I refactored the test
to stop trying to consult %Config::Config to see whether root assigning to
$> is going to work - just try it in an eval, and skip if it didn't. Only
restore $> if we know we changed it, and as we only change it from root, we
already know which value to restore it to.

Much simpler, and avoids having to duplicate the entire logic of which
probed Configure variables affect the operation of $>

Finally, I spotted that I could get rid of a skip by using the temporary
file the test (now) creates rather than t/TEST for a couple of the tests.
The skip is necessary when building "outside" the source tree using a
symlink forest back to it (./Configure -Dmksymlinks), because in that case
t/TEST is actually a symlink.

So now the test is clearer, simpler, less buggy, and skips less often.

Nicholas Clark



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About