Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

What is wrong in blocking?

by madtoperl (Pilgrim)
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?

Re: What is wrong in blocking?
by jesuashok (Curate) on May 11, 2006 at 12:01 UTC

    Both the main process and the backgrounded one (the "child" process) share the same STDIN, STDOUT and STDERR filehandles. If both try to access them at once, strange things can happen. You may want to close or reopen these for the child.
    You can get around this with opening a pipe (see open) but on some systems this means that the child process cannot outlive the parent. That might be the reason for it.

    "Keep pouring your ideas"

      Which "backgrounded child process"?!?

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://548678]
Approved by jesuashok
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (5)
As of 2018-06-22 23:45 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (124 votes). Check out past polls.