Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make require stop at the first found/failed file #12145

Closed
p5pRT opened this issue May 29, 2012 · 11 comments
Closed

make require stop at the first found/failed file #12145

p5pRT opened this issue May 29, 2012 · 11 comments

Comments

@p5pRT
Copy link
Collaborator

@p5pRT p5pRT commented May 29, 2012

Migrated from rt.perl.org#113422 (status was 'resolved')

Searchable as RT113422$

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented May 29, 2012

From @rjbs

Created by @rjbs

If @​INC contains ./a and ./b, and ./a/Foo.pm exists but is unreadable, the
attempt to "require Foo" should fail, regardless of the contents of b.

(Further, the error should probably be "./a/Foo.pm cannot be read​: $!", but
this may cause breakage on things that are overly-reliant on the error message
from require.)

For further reference, see [perl #112946]

Perl Info

Flags:
    category=core
    severity=wishlist

Site configuration information for perl 5.16.0:

Configured by rjbs at Sun May 20 14:03:44 EDT 2012.

Summary of my perl5 (revision 5 version 16 subversion 0) configuration:
   
  Platform:
    osname=darwin, osvers=11.4.0, archname=darwin-2level
    uname='darwin walrus.local 11.4.0 darwin kernel version 11.4.0: mon apr 9 19:32:15 pdt 2012; root:xnu-1699.26.8~1release_x86_64 x86_64 '
    config_args='-de -Dprefix=/Users/rjbs/perl5/perlbrew/perls/16.0'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-fno-common -DPERL_DARWIN -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -I/opt/local/include',
    optimize='-O3',
    cppflags='-fno-common -DPERL_DARWIN -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -I/opt/local/include'
    ccversion='', gccversion='4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='env MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags =' -fstack-protector -L/usr/local/lib -L/opt/local/lib'
    libpth=/usr/local/lib /opt/local/lib /usr/lib
    libs=-lgdbm -ldbm -ldl -lm -lutil -lc
    perllibs=-ldl -lm -lutil -lc
    libc=, so=dylib, useshrplib=false, libperl=libperl.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags=' -bundle -undefined dynamic_lookup -L/usr/local/lib -L/opt/local/lib -fstack-protector'

Locally applied patches:
    


@INC for perl 5.16.0:
    /Users/rjbs/.perlbrew/libs/16.0@std/lib/perl5/darwin-2level
    /Users/rjbs/.perlbrew/libs/16.0@std/lib/perl5/darwin-2level
    /Users/rjbs/.perlbrew/libs/16.0@std/lib/perl5
    /Users/rjbs/perl5/perlbrew/perls/16.0/lib/site_perl/5.16.0/darwin-2level
    /Users/rjbs/perl5/perlbrew/perls/16.0/lib/site_perl/5.16.0
    /Users/rjbs/perl5/perlbrew/perls/16.0/lib/5.16.0/darwin-2level
    /Users/rjbs/perl5/perlbrew/perls/16.0/lib/5.16.0
    .


Environment for perl 5.16.0:
    DYLD_LIBRARY_PATH (unset)
    HOME=/Users/rjbs
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/Users/rjbs/.perlbrew/libs/16.0@std/bin:/Users/rjbs/perl5/perlbrew/bin:/Users/rjbs/perl5/perlbrew/perls/16.0/bin:/Users/rjbs/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/local/bin:/Users/rjbs/code/hla:/Users/rjbs/code/hla:/Users/rjbs/code/hla
    PERL5LIB=/Users/rjbs/.perlbrew/libs/16.0@std/lib/perl5/darwin-2level:/Users/rjbs/.perlbrew/libs/16.0@std/lib/perl5
    PERLBREW_BASHRC_VERSION=0.42
    PERLBREW_HOME=/Users/rjbs/.perlbrew
    PERLBREW_LIB=std
    PERLBREW_MANPATH=/Users/rjbs/.perlbrew/libs/16.0@std/man:/Users/rjbs/perl5/perlbrew/perls/16.0/man
    PERLBREW_PATH=/Users/rjbs/.perlbrew/libs/16.0@std/bin:/Users/rjbs/perl5/perlbrew/bin:/Users/rjbs/perl5/perlbrew/perls/16.0/bin
    PERLBREW_PERL=16.0
    PERLBREW_ROOT=/Users/rjbs/perl5/perlbrew
    PERLBREW_VERSION=0.42
    PERLDOC=-n/opt/local/bin/groff
    PERL_AUTOINSTALL=--skipdeps
    PERL_BADLANG (unset)
    PERL_LOCAL_LIB_ROOT=/Users/rjbs/.perlbrew/libs/16.0@std
    PERL_MB_OPT=--install_base /Users/rjbs/.perlbrew/libs/16.0@std
    PERL_MM_OPT=INSTALL_BASE=/Users/rjbs/.perlbrew/libs/16.0@std
    SHELL=/opt/local/bin/zsh

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jun 2, 2012

From @Hugmeir

On Tue, May 29, 2012 at 12​:22 PM, Ricardo SIGNES
<perlbug-followup@​perl.org>wrote​:

# New Ticket Created by Ricardo SIGNES
# Please include the string​: [perl #113422]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=113422 >

This is a bug report for perl from rjbs@​cpan.org,
generated with the help of perlbug 1.39 running under perl 5.16.0.

-----------------------------------------------------------------
[Please describe your issue here]

If @​INC contains ./a and ./b, and ./a/Foo.pm exists but is unreadable, the
attempt to "require Foo" should fail, regardless of the contents of b.

(Further, the error should probably be "./a/Foo.pm cannot be read​: $!", but
this may cause breakage on things that are overly-reliant on the error
message
from require.)

For further reference, see [perl #112946]

How about something like the attached patch? The error message is different
from what was suggested, because I forgot that something had been suggested
at all; Feel free to change that. I'm currently having a failure on
porting/checkcase.t, but it looks unrelated (it's also happening on a clean
build of blead); sans that, all tests passes.

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jun 2, 2012

From @Hugmeir

0001-require-should-die-if-a-file-exists-but-can-t-be-rea.patch
From bed63792bb54ace3feff4b82bca6a0446c6f8e57 Mon Sep 17 00:00:00 2001
From: Brian Fraser <fraserbn@gmail.com>
Date: Sat, 2 Jun 2012 14:15:34 -0300
Subject: [PATCH] require should die if a file exists but can't be read.

See [perl #113422]. If a file exists but there's an error opening it,
we throw an exception and disregard the rest of @INC.
---
 pp_ctl.c              |   19 ++++++++++++++-----
 t/op/require_errors.t |   34 +++++++++++++++++++++++++++++++++-
 2 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/pp_ctl.c b/pp_ctl.c
index 2ccd812..0a45836 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -3931,7 +3931,7 @@ PP(pp_require)
 	tryname = name;
 	tryrsfp = doopen_pm(sv);
     }
-    if (!tryrsfp) {
+    if (!tryrsfp && !(errno == EACCES && path_is_absolute(name))) {
 	AV * const ar = GvAVn(PL_incgv);
 	I32 i;
 #ifdef VMS
@@ -4123,9 +4123,14 @@ PP(pp_require)
 			}
 			break;
 		    }
-		    else if (errno == EMFILE)
-			/* no point in trying other paths if out of handles */
-			break;
+            else if (errno == EMFILE || errno == EACCES) {
+                /* no point in trying other paths if out of handles;
+                 * on the other hand, if we couldn't open one of the
+                 * files, then going on with the search could lead to
+                 * unexpected results; see perl #113422
+                 */
+                break;
+            }
 		  }
 		}
 	    }
@@ -4137,7 +4142,11 @@ PP(pp_require)
 	    if(errno == EMFILE) {
 		/* diag_listed_as: Can't locate %s */
 		DIE(aTHX_ "Can't locate %s:   %s", name, Strerror(errno));
-	    } else {
+	    }
+        else if (errno == EACCES) {
+            DIE(aTHX_ "Can't open %s:   %s", name, Strerror(errno));
+        }
+        else {
 	        if (namesv) {			/* did we lookup @INC? */
 		    AV * const ar = GvAVn(PL_incgv);
 		    I32 i;
diff --git a/t/op/require_errors.t b/t/op/require_errors.t
index 8f5a26c..dea97e3 100644
--- a/t/op/require_errors.t
+++ b/t/op/require_errors.t
@@ -7,7 +7,7 @@ BEGIN {
     require './test.pl';
 }
 
-plan(tests => 4);
+plan(tests => 6);
 
 my $nonfile = tempfile();
 
@@ -34,6 +34,38 @@ like $@, qr/^Can't locate $nonfile\.h in \@INC \(change \.h to \.ph maybe\?\) \(
 eval 'require <foom>';
 like $@, qr/^<> should be quotes at /, 'require <> error';
 
+my $module   = tempfile();
+my $mod_file = "$module.pm";
+
+open my $module_fh, ">", $mod_file or die $!;
+print { $module_fh } "print 1; 1;\n";
+close $module_fh;
+
+chmod 0333, $mod_file;
+
+local @INC = ".";
+eval "use $module";
+like $@,
+    qr<^Can't open $mod_file>,
+    "special error message if the file exists but can't be opened";
+
+SKIP: {
+    skip_if_miniperl("Cwd may not be available to miniperl", 1);
+    push @INC, '../lib';
+    require Cwd;
+    require File::Spec::Functions;
+   
+    my $file = File::Spec::Functions::catfile(Cwd::getcwd(), $mod_file);
+    eval {
+        require($file);
+    };
+    like $@,
+        qr<^\QCan't open $file>,
+        "...even if we use a full path";
+}
+
+1 while unlink $mod_file;
+
 # I can't see how to test the EMFILE case
 # I can't see how to test the case of not displaying @INC in the message.
 # (and does that only happen on VMS?)
-- 
1.7.9.5

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jun 2, 2012

The RT System itself - Status changed from 'new' to 'open'

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jun 5, 2012

From @rjbs

* Brian Fraser <fraserbn@​gmail.com> [2012-06-02T14​:31​:04]

How about something like the attached patch? The error message is different
from what was suggested, because I forgot that something had been suggested
at all; Feel free to change that. I'm currently having a failure on
porting/checkcase.t, but it looks unrelated (it's also happening on a clean
build of blead); sans that, all tests passes.

Cool. I did not test it, but I'm guessing that this test will fail when run as
root. It should probably skip if the file, chmodded -r, is still readable.

--
rjbs

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jun 17, 2012

From @doy

Applied (with some modifications) as 2433d39. In particular, I fixed the
test when running as root, and changed the error message to match the
error already in perldiag. "Can't locate Foo.pm​: Permission denied"
isn't a great error, but we already have "Can't locate Foo.pm​: Too many
open files", so I figured it wouldn't be too bad (although if anyone
wants to change it, do feel free).

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jun 17, 2012

From [Unknown Contact. See original ticket]

Applied (with some modifications) as 2433d39. In particular, I fixed the
test when running as root, and changed the error message to match the
error already in perldiag. "Can't locate Foo.pm​: Permission denied"
isn't a great error, but we already have "Can't locate Foo.pm​: Too many
open files", so I figured it wouldn't be too bad (although if anyone
wants to change it, do feel free).

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jun 17, 2012

@doy - Status changed from 'open' to 'resolved'

@p5pRT p5pRT closed this Jun 17, 2012
@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 19, 2014

From lfrocha@gmail.com

We were bitten by this fix.

The description didn't help finding the reason of the error​:
-sh-4.1$ /usr/local/booking-perl/5.18.2/bin/perl5.18.2 -e 'print "@​INC\n"'
/usr/local/git_tree/main/lib /usr/local/booking-perl/5.18.2/site/lib /usr/local/booking-perl/5.18.2/lib .

-sh-4.1$ /usr/local/booking-perl/5.18.2/bin/perl5.18.2 -e 'use warnings; print "@​INC\n"'
Can't locate warnings.pm​: Permission denied at -e line 1.
BEGIN failed--compilation aborted at -e line 1.

-sh-4.1$ ls -l /usr/local/booking-perl/5.18.2/lib/warnings.pm
-r--r--r-- 1 root root 20624 Jan 28 2014 /usr/local/booking-perl/5.18.2/lib/warnings.pm

The problem was having a directory in PERL5LIB that had the wrong permissions.

Test case​:
$ PERL5LIB=/root /usr/local/booking-perl/5.18.2/bin/perl5.18.2 -e 'use warnings; print "@​INC\n"'
Can't locate warnings.pm​: Permission denied at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
$ PERL5LIB=/root /usr/local/booking-perl/5.14.2/bin/perl5.14.2 -e 'use warnings; print "@​INC\n"'
/root /usr/local/booking-perl/5.14.2/site/lib /usr/local/booking-perl/5.14.2/lib .

So perl isn't distinguishing from "no permission to read file" and "no permission to access a component in @​INC".

Could the fix be changed to only report on file permissions, or make the error more informative (include the path that gave the error, not just the module name)?

Regards.

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 19, 2014

From [Unknown Contact. See original ticket]

We were bitten by this fix.

The description didn't help finding the reason of the error​:
-sh-4.1$ /usr/local/booking-perl/5.18.2/bin/perl5.18.2 -e 'print "@​INC\n"'
/usr/local/git_tree/main/lib /usr/local/booking-perl/5.18.2/site/lib /usr/local/booking-perl/5.18.2/lib .

-sh-4.1$ /usr/local/booking-perl/5.18.2/bin/perl5.18.2 -e 'use warnings; print "@​INC\n"'
Can't locate warnings.pm​: Permission denied at -e line 1.
BEGIN failed--compilation aborted at -e line 1.

-sh-4.1$ ls -l /usr/local/booking-perl/5.18.2/lib/warnings.pm
-r--r--r-- 1 root root 20624 Jan 28 2014 /usr/local/booking-perl/5.18.2/lib/warnings.pm

The problem was having a directory in PERL5LIB that had the wrong permissions.

Test case​:
$ PERL5LIB=/root /usr/local/booking-perl/5.18.2/bin/perl5.18.2 -e 'use warnings; print "@​INC\n"'
Can't locate warnings.pm​: Permission denied at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
$ PERL5LIB=/root /usr/local/booking-perl/5.14.2/bin/perl5.14.2 -e 'use warnings; print "@​INC\n"'
/root /usr/local/booking-perl/5.14.2/site/lib /usr/local/booking-perl/5.14.2/lib .

So perl isn't distinguishing from "no permission to read file" and "no permission to access a component in @​INC".

Could the fix be changed to only report on file permissions, or make the error more informative (include the path that gave the error, not just the module name)?

Regards.

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Nov 21, 2014

From @ppisar

Dne Pá 19.zář.2014 02​:06​:38, lfrocha@​gmail.com napsal(a)​:

We were bitten by this fix.

The description didn't help finding the reason of the error​:
-sh-4.1$ /usr/local/booking-perl/5.18.2/bin/perl5.18.2 -e 'print
"@​INC\n"'
/usr/local/git_tree/main/lib /usr/local/booking-perl/5.18.2/site/lib
/usr/local/booking-perl/5.18.2/lib .

-sh-4.1$ /usr/local/booking-perl/5.18.2/bin/perl5.18.2 -e 'use
warnings; print "@​INC\n"'
Can't locate warnings.pm​: Permission denied at -e line 1.
BEGIN failed--compilation aborted at -e line 1.

I proposed a better error message in ticket #123270.

-- Petr

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant
You can’t perform that action at this time.