-
Notifications
You must be signed in to change notification settings - Fork 560
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
Can open() to an in-memory scalar return false? #16010
Comments
From @epaCreated by @epaperlfunc has some example code like open(MEMORY, ">", \$var) Under what circumstances would that open() call return false? I would have expected that opening a filehandle to a scalar would be If I'm wrong, and open() to a scalar can return false for some cases, Perl Info
|
From @tonycozOn Fri, 09 Jun 2017 09:33:58 -0700, eda@waniasset.com wrote:
opening to a read-only scalar returns false (it doesn't die): $ ./perl -Ilib -E 'say ">",open(my
opening without truncating on a scalar with code points over 0xff can also fail: $ ./perl -Ilib -E '$x = "\x{100}"; say ">",open(my
opening with an unknown layer will also fail: $ ./perl -Ilib -E '$x = "\x{100}"; say ">",open(my
Only one of those is unique to scalars (writing to read-only scalars is conceptually the same as writing to read-only files) and they all produce reasonable warnings if warnings are enabled. I've attached a patch against perlfunc documenting the code point limitation. Tony |
From @tonycoz0001-perl-131546-note-code-point-limitation-for-in-memory.patchFrom ddb23c4046193709d450aaa4a58a002f5273bd5d Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Mon, 12 Jun 2017 11:03:35 +1000
Subject: (perl #131546) note code point limitation for in-memory files
---
pod/perlfunc.pod | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod
index bb0383f..b47039a 100644
--- a/pod/perlfunc.pod
+++ b/pod/perlfunc.pod
@@ -4530,6 +4530,10 @@ To (re)open C<STDOUT> or C<STDERR> as an in-memory file, close it first:
open(STDOUT, ">", \$variable)
or die "Can't open STDOUT: $!";
+The scalars for in-memory files are treated as octet strings: unless
+the file is being opened with truncation the scalar may not contain
+any code points over 0xFF.
+
See L<perliol> for detailed info on PerlIO.
General examples:
--
2.1.4
|
The RT System itself - Status changed from 'new' to 'open' |
From @epa
Actually, it depends: $ perl -MReadonly -E 'Readonly my $x; say ">",open(my Can this be made more consistent so it either always dies or always returns false? There is a further difference between your example and that in the manual page. open I don't see how this can return false: if $x is readonly then it fails before that point, as above. Thanks for your other two examples where you show that the '>>' or '>:foo' file modes can return false given a scalar.
In that case shouldn't the error code be the same as the one you get for doing that? |
From @AbigailOn Sun, Jun 11, 2017 at 10:57:35PM -0700, Ed Avis via RT wrote:
$ perl -E 'for (1) {open my Abigail |
From @epaThanks Abigail, and to show it's not something special with $_: % perl -E 'for $x (1) {open my So the error check is necessary in general and the example in perlfunc is correct. What about open my $fh, '>', \ my $x; Can that fail? |
From @tonycozOn Sun, 11 Jun 2017 22:57:34 -0700, ed wrote:
That's because Readonly::Readonly() implements read-onlyness via a tie rather than by marking the SV read only: https://metacpan.org/source/SANKO/Readonly-2.05/lib/Readonly.pm#L409 (try Devel::Peek's Dump() on your scalar) If you use Readonly::Scalar1 or SvREADONLY() instead: tony@mars:.../git/perl$ ~/perl/5.22.0/bin/perl -MReadonly=Scalar1 -wE 'Scalar1 my $x => undef; say ">", open( my $fh, ">", \$x); say "<"; ' < < you get only a warning.
Abigail covered this.
Not using Readonly::Readonly() fixes this.
The cases above all produce a warning, which can be captured with $SIG{__WARN__}. I'll produce a patch for some better $! values. Tony |
From @petdance
I think the key to this ticket is that perlfunc should say that in-memory files can still fail on open, and that it would be good to explicitly say that. It’s not at all unreasonable for a user to quickly conclude “It’s opening in memory? That can never fail, so I don’t need to check the return from open." |
From @tonycozOn Wed, 21 Jun 2017 00:09:15 -0700, tonyc wrote:
Attached, this includes the note I had in my previous patch, an extra note as suggested by Andy, and changing the $! set when the scalar is read only. Tony |
From @tonycozscalar-open.patchFrom b8cabe26715d7db6eeec54f9928efec8d6beb553 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Mon, 12 Jun 2017 11:03:35 +1000
Subject: (perl #131546) some notes on in-memory files for open()
---
pod/perlfunc.pod | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod
index bb0383f..c7dcbd0 100644
--- a/pod/perlfunc.pod
+++ b/pod/perlfunc.pod
@@ -4530,6 +4530,13 @@ To (re)open C<STDOUT> or C<STDERR> as an in-memory file, close it first:
open(STDOUT, ">", \$variable)
or die "Can't open STDOUT: $!";
+The scalars for in-memory files are treated as octet strings: unless
+the file is being opened with truncation the scalar may not contain
+any code points over 0xFF.
+
+Opening in-memory files I<can> fail for a variety of reasons, as with
+any other open check the return value for success.
+
See L<perliol> for detailed info on PerlIO.
General examples:
--
2.1.4
From 0fd5ed42acad11d081f56f2c34903138626ce610 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Wed, 21 Jun 2017 17:07:02 +1000
Subject: (perl #131546) return a reasonable error code opening a read-only
scalar
---
ext/PerlIO-scalar/scalar.xs | 2 +-
ext/PerlIO-scalar/t/scalar.t | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/ext/PerlIO-scalar/scalar.xs b/ext/PerlIO-scalar/scalar.xs
index 4c5d2c1..5c2ff5f 100644
--- a/ext/PerlIO-scalar/scalar.xs
+++ b/ext/PerlIO-scalar/scalar.xs
@@ -43,7 +43,7 @@ PerlIOScalar_pushed(pTHX_ PerlIO * f, const char *mode, SV * arg,
&& mode && *mode != 'r') {
if (ckWARN(WARN_LAYER))
Perl_warner(aTHX_ packWARN(WARN_LAYER), "%s", PL_no_modify);
- SETERRNO(EINVAL, SS_IVCHAN);
+ SETERRNO(EACCES, RMS_PRV);
return -1;
}
s->var = SvREFCNT_inc(SvRV(arg));
diff --git a/ext/PerlIO-scalar/t/scalar.t b/ext/PerlIO-scalar/t/scalar.t
index 3dfcced..bd06d64 100644
--- a/ext/PerlIO-scalar/t/scalar.t
+++ b/ext/PerlIO-scalar/t/scalar.t
@@ -13,10 +13,11 @@ BEGIN {
}
use Fcntl qw(SEEK_SET SEEK_CUR SEEK_END); # Not 0, 1, 2 everywhere.
+use Errno qw(EACCES);
$| = 1;
-use Test::More tests => 122;
+use Test::More tests => 123;
my $fh;
my $var = "aaa\n";
@@ -185,6 +186,7 @@ EOF
my $ro = \43;
ok(!(defined open(F, '>', $ro)), $!);
+ is($!+0, EACCES, "check we get a read-onlyish error code");
close F;
# but we can read from it
ok(open(F, '<', $ro), $!);
--
2.1.4
From 29e859c47f784b17d3d38229098c0fe41787575e Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Wed, 21 Jun 2017 17:07:17 +1000
Subject: bump $PerlIO::scalar::VERSION
---
ext/PerlIO-scalar/scalar.pm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ext/PerlIO-scalar/scalar.pm b/ext/PerlIO-scalar/scalar.pm
index bcbb56c..0276f21 100644
--- a/ext/PerlIO-scalar/scalar.pm
+++ b/ext/PerlIO-scalar/scalar.pm
@@ -1,5 +1,5 @@
package PerlIO::scalar;
-our $VERSION = '0.27';
+our $VERSION = '0.28';
require XSLoader;
XSLoader::load();
1;
--
2.1.4
|
From @petdance
The punctuation is a little misleading. It should be "Opening in-memory files I<can> fail for a variety of reasons. As with any other open, check the return value for success." (Or maybe "any other C<open>"?) -- |
From @tonycozOn Wed, 21 Jun 2017 19:16:33 -0700, petdance wrote:
Applied as 54e7f05, 45ef9d4 and aef23d3 with your suggested changes. Tony |
@tonycoz - Status changed from 'open' to 'pending release' |
From @khwilliamsonThank you for filing this report. You have helped make Perl better. With the release yesterday of Perl 5.28.0, this and 185 other issues have been Perl 5.28.0 may be downloaded via: If you find that the problem persists, feel free to reopen this ticket. |
@khwilliamson - Status changed from 'pending release' to 'resolved' |
Migrated from rt.perl.org#131546 (status was 'resolved')
Searchable as RT131546$
The text was updated successfully, but these errors were encountered: