Filehandle STDIN reopened as $fh1 only for output

Discussion in 'Perl Misc' started by Larry, Oct 23, 2008.

  1. Larry

    Larry Guest

    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
    Larry, Oct 23, 2008
    #1
    1. Advertising

  2. Larry <> wrote:

    > 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:

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


    > if (-e $pswdfile)



    Warning Will Robinson!

    You are introducing a race condition...

    perldoc -q lock

    Why can't I just open(FH, "E<gt>file.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.


    --
    Tad McClellan
    email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
    Tad J McClellan, Oct 23, 2008
    #2
    1. Advertising

  3. Larry

    C.DeRykus Guest

    On Oct 23, 1:02 am, Larry <> wrote:
    > 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...

    --
    Charles DeRykus
    C.DeRykus, Oct 23, 2008
    #3
  4. On 2008-10-23, Larry <> wrote:
    > I have the following code:

    *SKIP*
    > close(STDIN);

    *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.

    --
    Torvalds' goal for Linux is very simple: World Domination
    Eric Pozharski, Oct 23, 2008
    #4
  5. Larry

    Guest

    Tad J McClellan <> wrote:
    >
    > 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.
    , Oct 23, 2008
    #5
  6. [A complimentary Cc of this posting was sent to
    Eric Pozharski
    <>], who wrote in article <>:

    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
    Ilya Zakharevich, Oct 23, 2008
    #6
  7. On 2008-10-23, Ilya Zakharevich <> wrote:
    *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?

    --
    Torvalds' goal for Linux is very simple: World Domination
    Eric Pozharski, Oct 24, 2008
    #7
  8. [A complimentary Cc of this posting was sent to
    Eric Pozharski
    <>], who wrote in article <>:
    > On 2008-10-23, Ilya Zakharevich <> wrote:
    > *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...

    Hope this helps,
    Ilya
    Ilya Zakharevich, Oct 24, 2008
    #8
  9. On 2008-10-24, Ilya Zakharevich <> wrote:
    > [A complimentary Cc of this posting was sent to Eric Pozharski
    ><>], who wrote in article
    ><>:
    >> On 2008-10-23, Ilya Zakharevich <> wrote:
    >> *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?

    --
    Torvalds' goal for Linux is very simple: World Domination
    Eric Pozharski, Oct 25, 2008
    #9
  10. On 2008-10-23 15:34, <> wrote:
    > Tad J McClellan <> wrote:
    >> 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.


    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
    Peter J. Holzer, Oct 25, 2008
    #10
  11. [A complimentary Cc of this posting was NOT [per weedlist] sent to
    Peter J. Holzer
    <>], who wrote in article <>:
    > On 2008-10-23 15:34, <> wrote:
    > > Tad J McClellan <> wrote:
    > >> 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.


    > 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
    Ilya Zakharevich, Oct 26, 2008
    #11
  12. [A complimentary Cc of this posting was sent to
    Eric Pozharski
    <>], who wrote in article <>:
    > On 2008-10-24, Ilya Zakharevich <> wrote:
    > > [A complimentary Cc of this posting was sent to Eric Pozharski
    > ><>], who wrote in article
    > ><>:
    > >> On 2008-10-23, Ilya Zakharevich <> wrote:
    > >> *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"
    Ilya Zakharevich, Oct 26, 2008
    #12
  13. On 2008-10-26 01:15, Ilya Zakharevich <> wrote:
    ><>], who wrote in article <>:
    >> On 2008-10-23 15:34, <> wrote:
    >> > Tad J McClellan <> wrote:
    >> >> 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.

    >
    >> 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
    Peter J. Holzer, Oct 26, 2008
    #13
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jdm
    Replies:
    3
    Views:
    1,347
    James Kanze
    Nov 9, 2010
  2. sarah Fernandes
    Replies:
    0
    Views:
    253
    sarah Fernandes
    Apr 15, 2011
  3. Brian Takita
    Replies:
    3
    Views:
    148
    Jens Wille
    Sep 30, 2008
  4. Rocky
    Replies:
    22
    Views:
    223
    MichiganBob
    Jul 17, 2004
  5. Replies:
    2
    Views:
    415
Loading...

Share This Page