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

open() dies for invalid modes, instead of returning undef, as documented #16687

Open
p5pRT opened this issue Sep 8, 2018 · 8 comments
Open

Comments

@p5pRT
Copy link

p5pRT commented Sep 8, 2018

Migrated from rt.perl.org#133505 (status was 'open')

Searchable as RT133505$

@p5pRT
Copy link
Author

p5pRT commented Sep 8, 2018

From rdiezmail-perl@yahoo.de

The following code​:

my $memFileContents;

open( my $memFile, 'ERROR_HERE', \$memFileContents )
  or die "Cannot create in-memory file​: $!\n";

yields this error message​:

Unknown open() mode 'ERROR_HERE' at main.pl line 8.

The error message seems like a run-time error, and not a compilation error. However, the documentation states​: "Open returns nonzero on success, the undefined value otherwise." Therefore, open() should not die itself, but return undef, and hopefully also set $! accordingly.

I tested it with Perl version v5.22.1, and also online with this site, which has version v5.24.2​:

http​://www.compileonline.com/execute_perl_online.php

@p5pRT
Copy link
Author

p5pRT commented Sep 8, 2018

From @jkeenan

On Sat, 08 Sep 2018 11​:18​:12 GMT, rdiezmail-perl@​yahoo.de wrote​:

The following code​:

my $memFileContents;

open( my $memFile, 'ERROR_HERE', \$memFileContents )
or die "Cannot create in-memory file​: $!\n";

yields this error message​:

Unknown open() mode 'ERROR_HERE' at main.pl line 8.

The error message seems like a run-time error, and not a compilation
error. However, the documentation states​: "Open returns nonzero on
success, the undefined value otherwise." Therefore, open() should not
die itself, but return undef, and hopefully also set $! accordingly.

I believe your interpretation of the documentation for 'open' (pod/perlfunc.pod) is incorrect. The discussion in that document of open's return value *comes after* the discussion of the two- and three-argument versions of open in which the valid modes for open are described. So it presumes that someone understands those nine paragraphs. Given that, it shouldn't be surprising that you get what is indeed a run-time error when you use open with an invalid mode.

A correctly formulated open call will indeed return an undefined value when it cannot open a file​:

#####
$ ls -l foo.txt
ls​: cannot access 'foo.txt'​: No such file or directory

$ perl -e 'my $rv = open my $IN, q|<|, q|foo.txt|; defined $rv ? print "$rv\n" : print "not defined\n";'
not defined
#####

And a correctly formulated open call will return a non-zero value when it succeeds​:

#####
$ echo "This is a test" > 133505.txt

$ perl -e 'my $rv = open my $IN, q|<|, q|133505.txt|; print "$rv\n";'
1
#####

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Sep 8, 2018

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

@p5pRT
Copy link
Author

p5pRT commented Sep 11, 2018

From rdiezmail-perl@yahoo.de

[...]
Given that, it shouldn't be surprising that you get what
is indeed a run-time error when you use open with an invalid mode.

I think you misinterpreted my report. Getting a run-time error is fine. The trouble is, the documentation states that run-time errors in open() are signalled by returning "undef", but in this particular case, open() dies itself, instead of returning undef. So my own "die" statement afterwards does not run at all. Try my example and you will see what I mean.

Best regards,
  rdiez

@p5pRT
Copy link
Author

p5pRT commented Sep 11, 2018

From @eserte

Dana Sat, 08 Sep 2018 04​:18​:12 -0700, rdiezmail-perl@​yahoo.de reče​:

[...]

The error message seems like a run-time error, and not a compilation
error. However, the documentation states​: "Open returns nonzero on
success, the undefined value otherwise." Therefore, open() should not
die itself, but return undef, and hopefully also set $! accordingly.

The exception in this case is intentional, a fact you can easily prove by running the code under "use diagnostics" (there is a diagnostical message for this case). So if something needs to be changed then it's the open() documentation.

(Also there's no way to set $! in this case, because no system call is executed, so errno is not set at all)

@p5pRT
Copy link
Author

p5pRT commented Sep 11, 2018

From @tonycoz

On Mon, 10 Sep 2018 22​:38​:48 -0700, slaven@​rezic.de wrote​:

(Also there's no way to set $! in this case, because no system call is
executed, so errno is not set at all)

I don't have strong opinions either way with the base issue here, but this statement is incorrect.

There's plenty of code in core that sets errno and hence $! on error without a system call, for example​:

$ perl -le 'print $!; tell(*FOO); print $!'

Bad file descriptor
$ perl -Wle 'print $!; unlink "abc\0def"; print $!'

Invalid \0 character in pathname for unlink​: abc\0def at -e line 1.
No such file or directory

Tony

@p5pRT
Copy link
Author

p5pRT commented Sep 11, 2018

From @eserte

Dana Mon, 10 Sep 2018 23​:07​:47 -0700, tonyc reče​:

On Mon, 10 Sep 2018 22​:38​:48 -0700, slaven@​rezic.de wrote​:

(Also there's no way to set $! in this case, because no system call
is
executed, so errno is not set at all)

I don't have strong opinions either way with the base issue here, but
this statement is incorrect.

There's plenty of code in core that sets errno and hence $! on error
without a system call, for example​:

$ perl -le 'print $!; tell(*FOO); print $!'

Bad file descriptor
$ perl -Wle 'print $!; unlink "abc\0def"; print $!'

Invalid \0 character in pathname for unlink​: abc\0def at -e line 1.
No such file or directory

So I stand corrected. In this case the equivalent would be to set $! to something like EINVAL. But probably not needed, we already have the exception.

@p5pRT
Copy link
Author

p5pRT commented Oct 5, 2018

From @xsawyerx

On 09/08/2018 05​:58 PM, R. Diez via perl5-porters wrote​:

[...]
Given that, it shouldn't be surprising that you get what
is indeed a run-time error when you use open with an invalid mode.
I think you misinterpreted my report. Getting a run-time error is fine. The trouble is, the documentation states that run-time errors in open() are signalled by returning "undef", but in this particular case, open() dies itself, instead of returning undef. So my own "die" statement afterwards does not run at all. Try my example and you will see what I mean.

The documentation mentioning a run-time return value for open() is
describing the result of trying to open a file. This happens after
open() has a legal mode for opening it. If it does not have a legal mode
for opening a file, it will crash, because it cannot attempt that. There
are other cases in which open() would set $! (EPIPE), but there are also
additional cases in which it will croak without returning a value and
setting $! (too many arguments to open).

Think of it as when open() tries to (or is about to try to) open
something and does system checks and when open() is simply making sure
you called it correctly.

I don't see what should be changed here.

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

No branches or pull requests

2 participants