Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

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

by almut (Canon)
on Jul 15, 2010 at 16:27 UTC ( #849804=note: print w/ replies, xml ) Need Help??


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

...but just to file descriptor 2.

Still, it's a little weird that it only prints to file descriptor 2 (hard-wired), if STDERR is closed. I.e., if you reopen STDERR after fd 2 has been taken by something else, so STDERR is then associated with fd 3 for example, the warning is nicely printed to fd 3, not fd 2...

In other words, it seems this behaviour is explicitly coded somewhere as a fallback for when STDERR is closed.


Comment on Re^2: Using warn() when STDERR is closed
Re^3: Using warn() when STDERR is closed
by JavaFan (Canon) on Jul 15, 2010 at 17:57 UTC
    Still, it's a little weird that it only prints to file descriptor 2 (hard-wired), if STDERR is closed.
    Uhm, the kernel itself doesn't know anything about stderr. It's a convention used by utilities. And the convention is, "file descriptor 2 is stderr". (Just as file descriptor 1 is stdout, and file descriptor 0 is stdin).

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

      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 ^
        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
Node Status?
node history
Node Type: note [id://849804]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (6)
As of 2014-07-30 00:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (229 votes), past polls