Open p5pRT opened 8 years ago
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;
\
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 '\
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/
Fixing this would probably resolve a few older bugs involving closing stdin/out/err and opening a new file as fd 0/1/2. On Jul 10\, 2016 10:07\, "Aaron Crane" \perlbug\-followup@​perl\.org wrote:
# 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-archive.perl.org/perl5/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/
The RT System itself - Status changed from 'new' to 'open'
Is this at all connected to https://rt-archive.perl.org/perl5/Ticket/Display.html?id=128530
On Jul 10\, 2016 10:15 AM\, "Dan Collins" \dcollinsn@​gmail\.com wrote:
Fixing this would probably resolve a few older bugs involving closing stdin/out/err and opening a new file as fd 0/1/2. On Jul 10\, 2016 10:07\, "Aaron Crane" \perlbug\-followup@​perl\.org wrote:
# 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-archive.perl.org/perl5/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/
Not directly\, at least as far as I can tell; at the very least\, fixing this by removing the CANREAD and CANWRITE tests wouldn't affect that at all. However\, someone with more knowledge of perlio may be able to say whether a smarter fix for this issue would touch the same parts of the codebase.
Chad Granum \exodist7@​gmail\.com wrote:
Is this at all connected to https://rt-archive.perl.org/perl5/Ticket/Display.html?id=128530
On Jul 10\, 2016 10:15 AM\, "Dan Collins" \dcollinsn@​gmail\.com wrote:
Fixing this would probably resolve a few older bugs involving closing stdin/out/err and opening a new file as fd 0/1/2.
On Jul 10\, 2016 10:07\, "Aaron Crane" \perlbug\-followup@​perl\.org wrote:
# 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-archive.perl.org/perl5/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/
-- Aaron Crane ** http://aaroncrane.co.uk/
Migrated from rt.perl.org#128591 (status was 'open')
Searchable as RT128591$