Skip Menu |
Report information
Id: 125774
Status: pending release
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: bulk88 <bulk88 [at] hotmail.com>
Cc:
AdminCc:

Operating System: mswin32
PatchStatus: (no value)
Severity: low
Type:
Perl Version: 5.23.2
Fixed In: (no value)

Attachments


To: perlbug [...] perl.org
Subject: do EXPR on dir fails but has no error code $!
From: bulk88 <bulk88 [...] hotmail.com>
Date: Sun, 9 Aug 2015 16:42:09 -0400
Download (untitled) / with headers
text/plain 9.5k
This is a bug report for perl from bulk88@hotmail.com, generated with the help of perlbug 1.40 running under perl 5.23.2. ----------------------------------------------------------------- [Please describe your issue here] The docs for "do EXPR" state --------------------------------------------------------------------------- If do can read the file but cannot compile it, it returns undef and sets an error message in $@ . If do cannot read the file, it returns undef and sets $! to the error. Always check $@ first, as compilation could fail in a way that also sets $! . If the file is successfully compiled, do returns the value of the last expression evaluated. --------------------------------------------------------------------------- Lets call do() on a dir. --------------------------------------------------------------------------- C:\perl521\srcnewb4opt>perl -MData::Dumper -E"my $r = do q|C:\Windows|; print Du mper($r, $@, $!);" $VAR1 = undef; $VAR2 = ''; $VAR3 = ''; C:\perl521\srcnewb4opt> C:\perl521\srcnewb4opt>perl -MData::Dumper -E"my $r = require q|C:\Windows|; pri nt Dumper($r, $@, $!);" Can't locate C:\Windows in @INC (@INC contains: C:/perl521/srcnewb4opt/lib .) at -e line 1. C:\perl521\srcnewb4opt> ------------------------------------------------------------------------ ~$perl5.22.0 -MData::Dumper -E'my $r = do q|/bin|; print Dumper($r,$@,$!);' $VAR1 = undef; $VAR2 = ''; $VAR3 = ''; ~$ ~$perl5.22.0 -MData::Dumper -E'my $r = require q|/bin|; print Dumper($r,$@,$!)> Can't locate /bin in @INC (@INC contains: /opt/perl32/lib/site_perl/5.22.0/PA-RISC2.0 /opt/perl32/lib/site_perl/5.22.0 /opt/perl32/lib/5.22.0/PA-RISC2.0 /opt/perl32/lib/5.22.0 .) at -e line 1. ~$ ~$perl5.22.0 -MData::Dumper -E'my $r = do q|/binnofile|; print Dumper($r,$@,$!> $VAR1 = undef; $VAR2 = ''; $VAR3 = 'No such file or directory'; ~$ ~$perl5.22.0 -MData::Dumper -E'my $r = do q|/sbin/passwd|; print Dumper($r,$@,> $VAR1 = undef; $VAR2 = ''; $VAR3 = 'Permission denied'; ~$ ------------------------------------------------------------------------ So where is the error in $!? http://perl5.git.perl.org/perl.git/blob/HEAD:/t/op/do.t never tests the numerical value of $! except against 0. http://perl5.git.perl.org/perl.git/commitdiff/b2da7ead6803119763b139be37b2cc8c8f522f75 errno = 0 is questionable API. POSIX never sets errno to 0. http://perl5.git.perl.org/perl.git/commitdiff/6b845e562be40aac749b544b6d494078c54de4aa if it is a dir, errno is effectivly uninitialized I am proposing that do() on a directory set $!/errno to EISDIR instead of 0. I found this bug due to me wanting to remove the -f syscall out of buildcustomize.pl loader code at http://perl5.git.perl.org/perl.git/blob/749f0eb1485a7bb7561d71f9539d9b7655363136:/perl.c#l2106 , the -f was added by http://perl5.git.perl.org/perl.git/commitdiff/404ad9dc9dfa2116d2907212d3650df6870ff9bc but later on commit http://perl5.git.perl.org/perl.git/commitdiff/af26e4f23ae11a43d1a3ac56ed110a974e093811 started doing better diagnostics including printing $! on error, since http://perl5.git.perl.org/perl.git/commitdiff/404ad9dc9dfa2116d2907212d3650df6870ff9bc is a commentless commit, IDK why it is doing -f, that leads me to wonder if its to stop do() on a dir, and I discover do() on a directory returns no useful error in $! to show the user. [Please do not change anything below this line] ----------------------------------------------------------------- --- Flags: category=core severity=low --- Site configuration information for perl 5.23.2: Configured by Owner at Wed Jul 22 12:17:22 2015. Summary of my perl5 (revision 5 version 23 subversion 2) configuration: Derived from: f8ccc6c719cd8ef25c59a4a21fe1bab9f6a38c5b Ancestor: 30dc90f1923c08aae65b60f713ac12490a716e10 Platform: osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread uname='' config_args='undef' hint=recommended, useposix=true, d_sigaction=undef useithreads=define, usemultiplicity=define use64bitint=undef, use64bitall=undef, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cl', ccflags ='-nologo -GF -W3 -O1 -MD -Zi -DNDEBUG -GL -DWIN32 -D_CONSOLE -DNO_STRICT -DPERL_TEXTMODE_SCRIPTS -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -D_USE_32BIT_TIME_T', optimize='-O1 -MD -Zi -DNDEBUG -GL', cppflags='-DWIN32' ccversion='13.10.6030', gccversion='', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234, doublekind=3 d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=8, longdblkind=0 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='link', ldflags ='-nologo -nodefaultlib -debug -opt:ref,icf -ltcg -libpath:"c:\perl521\lib\CORE" -machine:x86' libpth=\lib libs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib perllibs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib libc=msvcrt.lib, so=dll, useshrplib=true, libperl=perl523.lib gnulibc_version='' Dynamic Linking: dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' ' cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug -opt:ref,icf -ltcg -libpath:"c:\perl521\lib\CORE" -machine:x86' Locally applied patches: uncommitted-changes a3b5f9fb00dafcb11d1766baaec76abc90f9fd06 913cec4246caa89e35bb997c168e7ea2dfcadc4f 7f279091ed7e7241570d4e4abce94248caeb8869 ba4fc2b447d5c04e1ada54027c446d03452dcb25 931a625beed2a34b7d28dca23d41b17e658509d5 83c1fffeadddac231b705fc8a420de87fd4f5ea3 41349288283615495b6de1523783d60c9fd7310b 1c2511e0acc5a19f9f52fb2be58a4e2750213e6f ce0b42da7302bf923a6e4080a343f168e4b3b526 de6cb0abd243e5772b9783a2cbeef5755a8267d6 262309092c2de925e7ae4a527174f8dc2a0ec7b7 b92342550433b215a30d5d4b9bfe55321c69f8ac 9100b351e15341ed12d22822713635b0e4e2237d e68670aedff308b76d0c1076a6073146840fb322 97bf8a2377185e29b65c2d10276fb50d0ad63d41 fefb073f144151139233ca435fb1fc9edf684fe4 87518e92cecac2acea7073cceea51ca610774fb0 ce4793f183b29c423cb9d2d993fb4399c8d46baa c4e131a911a886c1978fea41bd198d709effb11e dc013420c1f83597b1da234ce2907e675a9e3107 6962a25d62cfc67866faccd188344d479b518d4a 0b8e484270e7477903f4a13f1bea68e427a03c70 3e3bbb9b3cd1149bba698cb5d92fa3150db92d89 082ce9c667e6d73783164fa1abab61806b678b4f 638ca15aeec3bf86124489c8c913c5b42d4fee16 46e58bd2391172ab5e4a73c29fb3313bebcf00bc 0d610ac116dfe1f7752682b7e30e8019569d8adb 9b1753cf7072d34b7e4bd1ea60369cbaf80e6152 fb7e9cdd4113e4cf1a43224b3f50ca540d8fc1b4 4d5d35d9def298c0adab2e34a187efa998cea923 db95646430f250935e9615b04eecb9c0d138c515 139271cd3e9cb3cf25072ebdd400e52275c61b96 bfab049986675c47a6b5030ff9c8f39c28e7945e 31221351abb3a508c369e8203d17da077adc667b 6114e455f60b0de62a0b74edee3c9e1841d49c42 ad06c68e1547b1a860919feac7df7c509e7efbaf d6525a59e9307fd297f8bc4c5e67aae146009637 1c9e1c249f3ee943b0090563811df613ebae456e 2ad3e690162d015bf2b0cc83f073d710e8e25fe4 c3de430b4163fa2425ce1f96c6979354f493ccf4 e89d87ccef460faf57b78f904d5113b01353308b 8656412da8e4f5fd0e75563115e66dc105a29bb3 f282dc56fa0121a54a0752163e66b158b3a60e69 c1883b8b014bf0c1dad3d50b6052ef68120c7247 904c4cac2b93435ab1ae1b204e376b99fc770895 c56f8d90b66d2ad5aab73a192124dbef90a32af0 cf73cedaf40b99f39f3b4c5d0fa1aa0f125c73e3 430812d753cb6126658aa5764d72c857935e7552 923c264ef19ba3c5a3351e7ae6c73b8bde122801 a619091c6e82aa7538af9defae3262a68921e66d 04edae75060b165358c49e90531901bb186e160e cc116ce7f30f9861a5b501456e5dfaf8e57de587 e7f1d4a74b38eea00e7928f048d1981610a4bced 14071f951e2facb2599e25258093b7c4426a2b4a 003900e275f0c45375d4d02ffb0ac0fcd2eacfa2 c7a622b32220ef59969124212598b6848bcaa247 86f4502880c5cbc7a5ec1510ab05a413bfb40e03 23fd77c01aafa1987698dc47bed34bd342178516 16bc0f484029674886960a735bef3fa497aeb6de 4ad176efffec2453196c8a3f35f73c0eeed776a0 5478a2b983aa7a04b93cfaf83bb9805713bf2d3f 6ffcffbd7dc3d42844ba051086599e4f70bfdb1f bbef9e8971749a5008bb4cd805eff6a7e0c584b4 b992490dd5c64d667e649dd0ee35a658034d93c0 f7e03a1013a0b759f99885c500f0e89656a992ba a55c5245146801ac2b2be2914342a6a829670513 f832b29a2b3f71c66c6e6b76a02b5faefe0ebeb1 e27be216b1132c5c017dc516d806edf309c90386 8a62d6b8193214bd476c275fc4b083b526108223 48e9f29d31f13e3ebfb9f77ed4effa561966c7a9 42d29f360f39f2ec518ddc4b80f4284099e75689 94dbd6cfe2263c2f66825f35679153e430e506e5 37b95795022b11ae328e98d5e247a2a8ca8593ca b36000125e2dbb5bf2e2e2580b5fa7572e13a768 f8ccc6c719cd8ef25c59a4a21fe1bab9f6a38c5b --- @INC for perl 5.23.2: C:/perl521/site/lib C:/perl521/lib . --- Environment for perl 5.23.2: HOME (unset) LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=C:\perl521\bin;C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE;C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\BIN;C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools;C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin\prerelease;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\system32\wbem; PERL_BADLANG (unset) SHELL (unset)
From: Glenn Golden <gdg [...] zplane.com>
To: perl5-porters [...] perl.org
Subject: Re: [perl #125774] do EXPR on dir fails but has no error code $!
CC: bulk88 <perlbug-followup [...] perl.org>
Date: Sun, 9 Aug 2015 17:04:19 -0600
Download (untitled) / with headers
text/plain 1.4k
bulk88 <perlbug-followup@perl.org> [2015-08-09 13:42:44 -0700]: Show quoted text
> # New Ticket Created by bulk88 > # Please include the string: [perl #125774] > # in the subject line of all future correspondence about this issue. > # <URL: https://rt.perl.org/Ticket/Display.html?id=125774 > > > This is a bug report for perl from bulk88@hotmail.com, > generated with the help of perlbug 1.40 running under perl 5.23.2. > > ----------------------------------------------------------------- > [Please describe your issue here] > > The docs for "do EXPR" state > > --------------------------------------------------------------------------- > If do can read the file but cannot compile it, it returns undef and sets > an error message in $@ . If do cannot read the file, it returns undef > and sets $! to the error. Always check $@ first, as compilation could > fail in a way that also sets $! . If the file is successfully compiled, > do returns the value of the last expression evaluated. > --------------------------------------------------------------------------- > > [ ... ] >
Would it make sense to somehow combine/consolidate the above perlbug with this thread http://www.nntp.perl.org/group/perl.perl5.porters/2015/05/msg227897.html which is an ongoing debate on the state of the "do EXPR" doc in general? I have no technical skin the game advocating any position, just trying to be a good "thread steward", since the above thread was started by me.
From: Eric Brine <ikegami [...] adaelis.com>
CC: perl5 porters <perl5-porters [...] perl.org>, bulk88 <perlbug-followup [...] perl.org>
Subject: Re: [perl #125774] do EXPR on dir fails but has no error code $!
To: gdg [...] zplane.com
Date: Sun, 9 Aug 2015 23:47:32 -0400
Download (untitled) / with headers
text/plain 269b
On Sun, Aug 9, 2015 at 7:04 PM, Glenn Golden <gdg@zplane.com> wrote:
Show quoted text
Would it make sense to somehow combine/consolidate the above perlbug with
this thread

bulk88 is reporting a failure of do() to report an error. This is independent of the wording of the docs.

Date: Mon, 10 Aug 2015 18:11:35 +0200
From: Aristotle Pagaltzis <pagaltzis [...] gmx.de>
Subject: Re: [perl #125774] do EXPR on dir fails but has no error code $!
To: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 720b
* Eric Brine <ikegami@adaelis.com> [2015-08-10 05:50]: Show quoted text
> bulk88 is reporting a failure of do() to report an error. This is > independent of the wording of the docs.
The reason the wording of the docs is in contention is that `do` has an error reporting interface so crappy that we cannot even agree on how to detect errors with it. Bulk88’s issue is just another aspect of that. Nevertheless these tickets are distinct aspects of the same thing; their kinship is of the “we need a metaticket about how to unhorriblify `do` in general” kind. I had a conversation about it with RJBS that I meant to summarize and post; I’ll get to that eventually. Regards, -- Aristotle Pagaltzis // <http://plasmasturm.org/>
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 150b
Since there were no comments on what the error code should be, I wrote a patch that fixes this bug. See attached. -- bulk88 ~ bulk88 at hotmail.com
Subject: 0001-perl-125774-fix-do-dir-returns-no.patch
From bc453c910fc935db8524e9d6ea19130407c19e9f Mon Sep 17 00:00:00 2001 From: Daniel Dragan <bulk88@hotmail.com> Date: Sun, 16 Aug 2015 04:30:23 -0400 Subject: [PATCH] [perl #125774] fix do dir returns no $! do()ing a directory was returning false/empty string in $!, which isn't an error, yet retval of do, and $@ say $! should have the error code in it. Fix this by returning EISDIR for dirs, and EINVAL for block devices, since there is no ENOTFILE, but ENOENT is inappropriate, since the block device exists. Also linux read() returns EINVAL if the underlying kernel driver does not implement a read method. Here we say read() (on a high level do()) is not implemented on a directory. Also linux swapon() uses EINVAL for paths which goto something that exists, but is of wrong type. Remove "errno = 0" and comment added in b2da7ead68, since now there is no scenario where errno is uninitialized, since the dir and block device failure branches now set errno, previously they didnt. --- pod/perldelta.pod | 6 ++++++ pp_ctl.c | 25 +++++++++++++++++-------- t/op/do.t | 14 +++++++++++++- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/pod/perldelta.pod b/pod/perldelta.pod index 157d9d1..2ec1f08 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -356,6 +356,12 @@ Perl can again be compiled with any Unicode version. This used to C<Name_Alias> did not exist prior to Unicode 5.0. L<Unicode::UCD> incorrectly said it did. This has been fixed. +=item * + +Calling C<do $path> on a directory or block device returned no error code in +C<$!> even though the retval of C<do> and C<$@> indicated the error is in C<$!>. +[perl #125774] + =back =head1 Known Problems diff --git a/pp_ctl.c b/pp_ctl.c index 9a81583..d80ed77 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -3505,15 +3505,22 @@ S_check_type_and_open(pTHX_ SV *name) errno EACCES, so only do a stat to separate a dir from a real EACCES caused by user perms */ #ifndef WIN32 - /* we use the value of errno later to see how stat() or open() failed. - * We don't want it set if the stat succeeded but we still failed, - * such as if the name exists, but is a directory */ - errno = 0; - st_rc = PerlLIO_stat(p, &st); - if (st_rc < 0 || S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode)) { + if (st_rc < 0) return NULL; + else { + int eno; + if(S_ISBLK(st.st_mode)) { + eno = EINVAL; + goto not_file; + } + else if(S_ISDIR(st.st_mode)) { + eno = EISDIR; + not_file: + errno = eno; + return NULL; + } } #endif @@ -3525,8 +3532,10 @@ S_check_type_and_open(pTHX_ SV *name) int eno; st_rc = PerlLIO_stat(p, &st); if (st_rc >= 0) { - if(S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode)) - eno = 0; + if(S_ISDIR(st.st_mode)) + eno = EISDIR; + else if(S_ISBLK(st.st_mode)) + eno = EINVAL; else eno = EACCES; errno = eno; diff --git a/t/op/do.t b/t/op/do.t index 49c0de3..7eb923d 100644 --- a/t/op/do.t +++ b/t/op/do.t @@ -7,6 +7,7 @@ BEGIN { } use strict; no warnings 'void'; +use Errno qw(ENOENT EISDIR); my $called; my $result = do{ ++$called; 'value';}; @@ -247,7 +248,7 @@ SKIP: { my $saved_errno = $!; ok(!$rv, "do returns false on io errror"); ok(!$saved_error, "\$\@ not set on io error"); - ok($saved_errno, "\$! set on io error"); + ok($saved_errno == ENOENT, "\$! is ENOENT for nonexistent file"); } # do subname should not be do "subname" @@ -280,4 +281,15 @@ SKIP: { } } +# do file $!s must be correct +{ + local @INC = ('.'); #want EISDIR not ENOENT + my $rv = do 'op'; # /t/op dir + my $saved_error = $@; + my $saved_errno = $!+0; + ok(!$rv, "do dir returns false"); + ok(!$saved_error, "\$\@ is false on do dir"); + ok($saved_errno == EISDIR, "\$! is EISDIR on do dir"); +} + done_testing(); -- 1.7.9.msysgit.0
Subject: [PATCH] do EXPR on dir fails but has no error code $!
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 203b
On Sun Aug 16 03:48:41 2015, bulk88 wrote: Show quoted text
> Since there were no comments on what the error code should be, I wrote > a patch that fixes this bug. See attached.
Bump. -- bulk88 ~ bulk88 at hotmail.com
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 245b
On Mon Aug 10 09:12:05 2015, aristotle wrote: Show quoted text
> I had a conversation about it with RJBS that I meant to summarize and > post; I’ll get to that eventually.
Have you gotten around to that? I don't see it in my folder, so if so: link? -- rjbs
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 335b
On Wed Sep 09 06:50:40 2015, bulk88 wrote: Show quoted text
> On Sun Aug 16 03:48:41 2015, bulk88 wrote:
> > Since there were no comments on what the error code should be, I wrote > > a patch that fixes this bug. See attached.
> > Bump.
Is there some reason not to apply this? My reading suggests it's a solution to a demonstrable problem. -- rjbs
From: Zefram <zefram [...] fysh.org>
To: perl5-porters [...] perl.org
Subject: Re: [perl #125774] do EXPR on dir fails but has no error code $!
Date: Sun, 12 Nov 2017 02:08:34 +0000
Patch applied as commit d1ac83c4011b4bf51ca3fb070737a97a6c6ac545. -zefram


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org