develooper Front page | perl.perl5.porters | Postings from July 2016

[perl #128591] PerlIO refuses to read STDOUT or write STDIN

Thread Next
From:
Aaron Crane
Date:
July 10, 2016 14:06
Subject:
[perl #128591] PerlIO refuses to read STDOUT or write STDIN
Message ID:
rt-4.0.18-15685-1468159598-178.128591-75-0@perl.org
# New Ticket Created by  Aaron Crane 
# Please include the string:  [perl #128591]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org/Ticket/Display.html?id=128591 >


Perl refuses to even try to read from STDOUT or write to STDIN, even if the underlying file descriptors are readable and/or writable as appropriate.

I originally observed this using a dup'ed STDOUT: a forked process wrote data to stdout, and I wanted to be able to re-read that data after the child exited:

    open STDOUT, "+>", $file or die;
    system 'generate_output';
    seek STDOUT, 0, 0 or die;
    <STDOUT>// die;

The readline emits a "Filehandle STDOUT opened only for output" warning, and yields undef.

My first thought was that dup'ing filehandles should copy the PERLIO_F_CANREAD and PERLIO_F_CANWRITE flags from the original handle to the new one. But that actually isn't sufficient: it's possible for Perl to be started with a readable stdout and/or a writable stdin:

    $ perl -we '<STDOUT> // die' 1<> /dev/null
    Filehandle STDOUT opened only for output at -e line 1.
    Died at -e line 1.
    $ perl -we 'STDIN->print("\n") // die' 0<> /dev/null
    Filehandle STDIN opened only for input at /Users/aaron/perl5/perlbrew/perls/perl-5.24.0/lib/5.24.0/darwin-2level/IO/Handle.pm line 420.
    Died at -e line 1

Running those commands under "strace -e trace=read,write" demonstrates that Perl makes no attempt to read from fd 1 or write to fd 0.

Perhaps the simplest fix would be to stop checking those flags before reading from or writing to a filehandle; we can expect the OS to yield EBADF iff the requested action is actually impossible.

Alternatively, the flags should be set correctly on any handle that's either dup'ed, or opened using the moral equivalent of fdopen (including the standard filehandles). That presumably involves using fcntl(F_GETFL) on the underlying descriptors in those cases.

-- 
Aaron Crane ** http://aaroncrane.co.uk/


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About