Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

What is wrong in blocking?

by madtoperl (Friar)
on May 11, 2006 at 11:58 UTC ( #548678=perlquestion: print w/replies, xml ) Need Help??

madtoperl has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks
For some time when i turn blocking off for a file handle that points to *STDERR,
it also turns blocking off for *STDIN. I am using perl 5.8.1 . Here is the code:
my $fhandle = IO::Handle->new(); if (!$fhandle->fdopen(*STDERR, "a")) { die("Error: Unable to open \"err\" file handle: $!\n"); } $fhandle->autoflush(1); $fhandle->blocking(0); In a: while ( <STDIN> ) { doIt($_); }
As soon as we turn blocking off for STDERR, STDIN no longer blocks.
I tried to turn blocking on for STDIN with STDIN->blocking(1),
but then STDERR now has blocking turned on.

Expecting your help

Replies are listed 'Best First'.
Re: What is wrong in blocking?
by blazar (Canon) on May 11, 2006 at 12:57 UTC
    if (!$fhandle->fdopen(*STDERR, "a"))

    I'm not really sure if it can be used like that... the documentation says:

    $io->fdopen ( FD, MODE ) "fdopen" is like an ordinary "open" except that its first p +arameter is not a filename but rather a file han- dle name, an IO::Handle object, or a file descriptor number +.

    I don't know if a typeglob is acceptable there. OTOH if it were not one would expect the call to fail... isn't it that *STDERR is being considered numeric and equal to 0 there?

    $ perl -le 'print 0+*STDERR' 0

    Mind you, I'm just wild-guessing... in doubt try with fileno STDERR (==2 if you haven't changed it!)

Re: What is wrong in blocking?
by sgifford (Prior) on May 11, 2006 at 13:10 UTC
    How very strange. For me, the problem only seems to happen when STDIN and STDERR are left at their defaults. For example, these work:
    perl t50 </dev/tty perl t50 2>/dev/null
    The problem may stem from this attribute of dup(2):
    dup and dup2 create a copy of the file descriptor oldfd.

    After successful return of dup or dup2, the old and new descriptors may be used interchangeably. They share locks, file position pointers and flags; for example, if the file position is modified by using lseek on one of the descriptors, the position is also changed for the other.

    I suspect this dup happens in your login program, such as ssh or /bin/login.

    Note that this behavior isn't perl-specific; I see the exact same thing with this C program:

    #include <unistd.h> #include <stdio.h> #include <fcntl.h> void main() { char buf[8192]; int rr; fcntl(STDERR_FILENO,F_SETFL,O_NONBLOCK); while ( (rr = read(STDIN_FILENO,buf,8192)) > 0) { write(STDOUT_FILENO,buf,rr); } if (rr < 0) { perror("read error:"); exit(1); } exit(0); }

    Whether or not this is a bug depends on POSIX, I suppose.

    At any rate, hopefully one of the above workarounds will help. Good luck!

    Update: It looks like this is How Things Have Always Worked. If you look at init.c from V7 Unix, the dfork function takes the tty on standard input and dup's it twice to create standard output and standard error. session.c from OpenSSH does essentially the same thing in its do_exec_pty function.

Re: What is wrong in blocking?
by chromatic (Archbishop) on May 11, 2006 at 18:50 UTC

    I don't understand the assumptions behind this question.

    How did you open STDERR for writing, so that it blocks?

    How did you get STDERR in a state where it buffers writes?

A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://548678]
Approved by jesuashok
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2020-10-20 06:47 GMT
Find Nodes?
    Voting Booth?
    My favourite web site is:

    Results (209 votes). Check out past polls.