Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re^4: Using warn() when STDERR is closed

by almut (Canon)
on Jul 15, 2010 at 18:39 UTC ( [id://849827]=note: print w/replies, xml ) Need Help??


in reply to Re^3: Using warn() when STDERR is closed
in thread Using warn() when STDERR is closed

Uhm, the kernel itself doesn't know anything about stderr.

With "it" I was referring to Perl, not the kernel...

What I find weird is that while Perl normally is printing warnings to whatever file descriptor is associated with the Perl file handle STDERR (typically 2, but not necessarily), it no longer seems to go via STDERR when it's closed (which would mean to just not print), but simply prints to fd 2 anyway — that's what I meant with "hard-wired".

Making the file descriptor variable would break many things, not in the least the expectation of users.

The file descriptor (associated with STDERR) is variable — as long as STDERR isn't closed:

#!/usr/bin/perl close STDERR; open AA, ">/tmp/myfd2" or die $!; # gets fd 2 open STDERR, ">/tmp/myfd3" or die $!; # gets fd 3 warn "Hello";
$ strace -eopen,write ./849816.pl ... open("/tmp/myfd2", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 2 open("/tmp/myfd3", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3 write(3, "Hello at ./849816.pl line 6.\n", 29) = 29 ^

Replies are listed 'Best First'.
Re^5: Using warn() when STDERR is closed (>&2)
by tye (Sage) on Jul 17, 2010 at 17:36 UTC
    The file descriptor (associated with STDERR) is variable

    By similar logic, I can argue that "But what is used to inflate the tires of my car is variable: (insert demonstration of me filling my car's tires with tapioca)".

    Where do you think Perl got the file descriptor that it associated with STDERR? It just grabs, hard-coded file descriptor 2. Why do you think the shell uses >&2 if you want to redirect to STDERR?

    If you do something stupid and make it so file descriptor 2 is used for something different from STDERR, then you better not use system nor qx// nor anything that uses exec(3) nor anything that calls any external libraries. Because you've put your process into a broken state.

    There are parts of Perl that write out errors through write_to_stderr() which knows how to write to tied file handles (see pp_warn in p5git://pp_sys.c. and warn_sv and write_to_stderr in p5git://util.c.). There are parts of Perl that aren't at such a high layer of abstraction and just write to whatever handle is returned by Perl_error_log. These write to the IO handle associated with STDERR if there is one, otherwise they fall back to the next level (see Perl_error_log in p5git://perl.h.).

    There is a ton of Perl that is at this next (and lowest) layer of abstraction which just writes to file descriptor 2 (there are actually still a lot of layers of abstraction over the top of the hard-coded 2, but they don't have any practical impact as the end result is still just always using file descriptor 2).

    (Update)

    Yes, it isn't terribly difficult to use file descriptor 2 for something different from STDERR. Perl goes to some effort to keep fd 2 associated with STDERR, but you can still thwart those efforts. And there are even situations where that is a reasonable thing to do (which is part of why Perl doesn't completely prevent it).

    But, yes, if you do such without knowing what you are doing, then you are likely to run into a few surprises.

    If you just refrain from close()ing STDERR, then you will very likely avoid all of these problems.

    - tye        

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://849827]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (4)
As of 2024-04-24 06:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found