Filehandle STDIN reopened as $fh1 only for output

L

Larry

I have the following code:

open STDERR, ">>", ".log.txt";

if ( $ENV{"REQUEST_METHOD"} eq 'HEAD' )
{
close(STDIN);
if($ENV{"HTTP_USER_AGENT"})
{
if(&_check_header_password($ENV{"HTTP_USER_AGENT"}))
{
print "Status: 200 OK\n\n";
} else {
print "Status: 401 Wrong Password\n\n";
}
}
exit;
}

sub _check_header_password
{
my $pswd = shift;
my $pswdfile = '_pswd.txt';
my $header_pswd; ($header_pswd) = ($pswd =~ /<pwd>(.*?)<\/pwd>/sg);

if (-e $pswdfile)
{
my $savedpswd;
{open my $fh1, '<', $pswdfile or die "$pswdfile $!";undef
$/;$savedpswd = <$fh1>;close $fh1;};
if ($header_pswd eq $savedpswd) { return 1; } else { return 0; }
} else {
open my $fh1, ">", $pswdfile or die "$!";
print $fh1 $header_pswd;
close $fh1;
return 1;
}
}
__END__;

it fires thi error/warn: "Filehandle STDIN reopened as $fh1 only for
output"

this seems to happen when it encounters this: open my $fh1, ">",
$pswdfile or die "$!";

what am I actually doing wrong?

thanks
 
T

Tad J McClellan

Larry said:
close(STDIN);
if($ENV{"HTTP_USER_AGENT"})
{
if(&_check_header_password($ENV{"HTTP_USER_AGENT"}))


You should not use an ampersand of subroutine calls unless you know
what it does (perlsub.pod), and what it does is what you want (it seldom is):

if( _check_header_password($ENV{HTTP_USER_AGENT}) )

my $header_pswd; ($header_pswd) = ($pswd =~ /<pwd>(.*?)<\/pwd>/sg);


No need for 2 statements when 1 statement will do:

if (-e $pswdfile)


Warning Will Robinson!

You are introducing a race condition...

perldoc -q lock

open my $fh1, ">", $pswdfile or die "$!";

it fires thi error/warn:


All of perl's diagnostic messages are described in perldiag.pod,
where you can see that it is a warning message rather than an
error message.

"Filehandle STDIN reopened as $fh1 only for
output"


Let's see what perldiag says about that message:

=item Filehandle STDIN reopened as %s only for output

(W io) You opened for writing a filehandle that got the same filehandle id
as STDIN. This occurred because you closed STDIN previously.
 
C

C.DeRykus

I have the following code:

open STDERR, ">>", ".log.txt";

if ( $ENV{"REQUEST_METHOD"} eq 'HEAD' )
{
close(STDIN);
if($ENV{"HTTP_USER_AGENT"})
{
if(&_check_header_password($ENV{"HTTP_USER_AGENT"}))
{
print "Status: 200 OK\n\n";
} else {
print "Status: 401 Wrong Password\n\n";
}
}
exit;
}

sub _check_header_password
{
my $pswd = shift;
my $pswdfile = '_pswd.txt';
my $header_pswd; ($header_pswd) = ($pswd =~ /<pwd>(.*?)<\/pwd>/sg);

if (-e $pswdfile)
{
my $savedpswd;
{open my $fh1, '<', $pswdfile or die "$pswdfile $!";undef
$/;$savedpswd = <$fh1>;close $fh1;};
if ($header_pswd eq $savedpswd) { return 1; } else { return 0; }
} else {
open my $fh1, ">", $pswdfile or die "$!";
print $fh1 $header_pswd;
close $fh1;
return 1;
}
}
__END__;

it fires thi error/warn: "Filehandle STDIN reopened as $fh1 only for
output"

this seems to happen when it encounters this: open my $fh1, ">",
$pswdfile or die "$!";

what am I actually doing wrong?

This is just a warning that an unusual
write-only tweak has been made to STDIN.

$ perl -Mdiagnostics -w
close STDIN;open(my $fh, ">",undef)
^D

Filehandle STDIN reopened as $fh only for output at - line 1 (#1)
(W io) You opened for writing a filehandle that got the same
filehandle id
as STDIN. This occured because you closed STDIN previously.


You could suppress the warning by
opening the file for both read/write
for instance (perldoc -f open).

Also you sure though you need this kind of
"Do It Yourself" password handling...
 
E

Eric Pozharski

I have the following code: *SKIP*
*SKIP*
{open my $fh1, '<', $pswdfile or die "$pswdfile $!";undef *SKIP*
open my $fh1, ">", $pswdfile or die "$!"; *SKIP*
it fires thi error/warn: "Filehandle STDIN reopened as $fh1 only for
output"

this seems to happen when it encounters this: open my $fh1, ">",
$pswdfile or die "$!";

what am I actually doing wrong?

When you've closed I<STDIN> it become unused (IOW -- free). The 2nd
time you open it for reading -- it's OK. The 3rd time you open it for
writing. B<open(2)> picks whatever filehandle is free -- accidentally
it's filehandle number 0 (it's I<STDIN>).

You have an option -- ether ignore the warning or do it this way
C<open STDIN, '<', '/dev/null' or die "$!";> in first place.
 
X

xhoster

Tad J McClellan said:
Let's see what perldiag says about that message:

=item Filehandle STDIN reopened as %s only for output

(W io) You opened for writing a filehandle that got the same
filehandle id as STDIN. This occurred because you closed STDIN
previously.

But that is a pretty useless explanation. OK, so some file handle got
opened to some file descriptor. So what? Why should I care? What is
likely to happen? If there is some danger, what is it? If not, then why
warn me?

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Eric Pozharski

Just in case: I think the (correct) explanation below needs some minor
clarification.
When you've closed I<STDIN> it become unused (IOW -- free). The 2nd ^^^^^^^
time you open it for reading -- it's OK.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The 1st time you open A FILE for reading, the OS looks for the first
unused handle. Since STDIN is handle 0, and it is unused, OS choses
to open a new file as handle 0. So, effectively you reopen STDIN.

Then you close it again...
The 3rd time you open it for writing. B<open(2)> picks whatever
filehandle is free -- accidentally it's filehandle number 0 (it's I<STDIN>).

Likewise:

The 2nd time you open A FILE for writing, OS (again!) chooses the
first unused handle, so get handle 0 again. This time Perl detects
that STDIN is opened for write, and decides to warn().

This time Perl heuristic is wrong, and this warning is not relevant.
You can selectively disable it, as another poster recommends.
You have an option -- ether ignore the warning or do it this way
C<open STDIN, '<', '/dev/null' or die "$!";> in first place.

Hope this helps,
Ilya
 
E

Eric Pozharski

On 2008-10-23 said:
The 2nd time you open A FILE for writing, OS (again!) chooses the
first unused handle, so get handle 0 again. This time Perl detects
that STDIN is opened for write, and decides to warn().

This time Perl heuristic is wrong, and this warning is not relevant.
You can selectively disable it, as another poster recommends.

What heuristic?
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Eric Pozharski
What heuristic?

Compiler warnings are always heuristic:

"I see something fishy".

Should I risk to annoy the user if this is an intended behaviour? Is
this annoyance balanced against having good enough chance that this
behaviour is not intended?

This is a difference between compiler warnings and compliler errors...

Hope this helps,
Ilya
 
E

Eric Pozharski

[A complimentary Cc of this posting was sent to Eric Pozharski
What heuristic?
Compiler warnings are always heuristic: "I see something fishy".
Should I risk to annoy the user if this is an intended behaviour? Is
this annoyance balanced against having good enough chance that this
behaviour is not intended? This is a difference between compiler
warnings and compliler errors...

=begin rant

Begging for favor. What exactly in my post, posting history, spelling,
style, formatting, first name, last name, Path:, Message-Id:, From:,
whatever made you believe that I'm dying to be spoon-feeded?

=end rant

What heuristic?
 
P

Peter J. Holzer

But that is a pretty useless explanation. OK, so some file handle got
opened to some file descriptor.

It is not "some filehandle", it is STDIN. STDIN is supposed to be opened
for input, and some library function may break if STDIN is not opened
for input. It is also almost certainly a bug - how often do
intentionally open STDIN for output?

While this is easy to detect and warn about, STDIN is actually the most
harmless of the three standard file handles. The most dangerous is
STDERR, because perl itself and lots of library functions assume that
they can write anything to STDERR. If you have inadvertently reopened
STDERR as an output file, you may end up with a corrupted output (this
is especially dangerous for setuid programs, so Linux/glibc makes sure
that the first three file handles are always open before main is called
in this case).

hp
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Peter J. Holzer
It is not "some filehandle", it is STDIN.

No it's not.
STDIN is supposed to be opened for input, and some library function
may break if STDIN is not opened for input.

What library? CRTL knows nothing about what Perl calls STDIN [*]. Perl
libraries know zilch about '&=0' (I did my `grep' ;-).
It is also almost certainly a bug - how often do
intentionally open STDIN for output?

Nobody opened STDIN for anything: input, or output.

Try:

perl -wle "close STDIN; open my $f, q(<), q(o) or die; print fileno $f; defined(my $x = <STDIN>) or die 11"
0
readline() on closed filehandle STDIN at -e line 1.
11 at -e line 1.

The message we are discussing is VERY misleading.

[*] Of course, if Perl is not compiled to use stdstdio, then CRTL's
stdin may be left "dangling" after close(STDIN). So it is
close(STDIN) which causes problems, not open()...

Yours,
Ilya
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Eric Pozharski
[A complimentary Cc of this posting was sent to Eric Pozharski
*SKIP*
The 2nd time you open A FILE for writing, OS (again!) chooses the
first unused handle, so get handle 0 again. This time Perl detects
that STDIN is opened for write, and decides to warn(). This time
Perl heuristic is wrong, and this warning is not relevant. You can
selectively disable it, as another poster recommends.
What heuristic?
Compiler warnings are always heuristic: "I see something fishy".
Should I risk to annoy the user if this is an intended behaviour? Is
this annoyance balanced against having good enough chance that this
behaviour is not intended? This is a difference between compiler
warnings and compliler errors...

=begin rant

Begging for favor. What exactly in my post, posting history, spelling,
style, formatting, first name, last name, Path:, Message-Id:, From:,
whatever made you believe that I'm dying to be spoon-feeded?

=end rant

What heuristic?

??? See above.

Hope this helps,
Ilya

P.S. Hmm, maybe you indeed need to be spoon-fed... Then: the heuristic

"if fd=0 is opened for write, then it is a user error"
 
P

Peter J. Holzer

It is not "some filehandle", it is STDIN.

No it's not.
Right.

[...]
The message we are discussing is VERY misleading.

Misleading enough that I went off on a tangent and wrote about a quite
different problem than the one at hand. Sorry for the confusion.

hp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top