Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

STDOUT "reopened"

119 views
Skip to first unread message

Chris Nandor

unread,
Jul 28, 2003, 5:47:33 PM7/28/03
to perl5-...@perl.org
Regarding this discussion:
http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2002-09/msg00942.html

In reference to this code:

perl -we "close STDOUT; open F, q{.bashrc} or die"

Which produces this warning upon success:

Filehandle STDOUT opened only for input at -e line 1.

I have two questions:

1. Why is opening a filehandle that happens to share the same fd as STDOUT
cause for concern, such that a warning is warranted?

2. If it IS a cause for concern, why doesn't perl prevent it from happening
in the first place? It's not something a user SHOULD need to be concerned
about, and there is no reasonable way to prevent the warning from being
issued.

Maybe this has already been fixed in perl 5.8.1; I don't have access right
now to test.

--
Chris Nandor pu...@pobox.com http://pudge.net/
Open Source Development Network pu...@osdn.com http://osdn.com/

Chip Salzenberg

unread,
Jul 28, 2003, 6:22:50 PM7/28/03
to Chris Nandor, perl5-...@perl.org
According to Chris Nandor:

> 1. Why is opening a filehandle that happens to share the same fd as STDOUT
> cause for concern, such that a warning is warranted?

Standard output _is_ fd 1. C's stdout and Perl's STDOUT are just
interfaces.

> 2. If it IS a cause for concern, why doesn't perl prevent it from
> happening in the first place?

I'd guess it's because what's usually silly is occasionally required,
in which case there should be a way to suppress the, perhaps with
C<no warnings>.
--
Chip Salzenberg - a.k.a. - <ch...@pobox.com>
"I wanted to play hopscotch with the impenetrable mystery of existence,
but he stepped in a wormhole and had to go in early." // MST3K

Chris Nandor

unread,
Jul 28, 2003, 6:29:49 PM7/28/03
to Chip Salzenberg, perl5-...@perl.org
At 18:22 -0400 2003.07.28, Chip Salzenberg wrote:
>> 2. If it IS a cause for concern, why doesn't perl prevent it from
>> happening in the first place?
>
>I'd guess it's because what's usually silly is occasionally required,
>in which case there should be a way to suppress the, perhaps with
>C<no warnings>.

Sorry, "prevent" was confusing. I meant, prevent unless explicitly
requested. open FILE, "<foo" should not ever assign the same as fd as is
normally given to STDOUT, unless the user explicitly requests it, if indeed
this sort of thing is something worth warning about.

I don't think it is useful for the mere act of successfully opening a file
for reading to generate a warning, just because you happened to close
STDOUT previously.

Kurt Starsinic

unread,
Jul 28, 2003, 6:39:25 PM7/28/03
to Chris Nandor, perl5-...@perl.org
On Jul 28, Chris Nandor wrote:
> Regarding this discussion:
> http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2002-09/msg00942.html
>
> In reference to this code:
>
> perl -we "close STDOUT; open F, q{.bashrc} or die"
>
> Which produces this warning upon success:
>
> Filehandle STDOUT opened only for input at -e line 1.
>
> I have two questions:
>
> 1. Why is opening a filehandle that happens to share the same fd as STDOUT
> cause for concern, such that a warning is warranted?

Because STDOUT is, per se, the stream associated with fd 1.

> 2. If it IS a cause for concern, why doesn't perl prevent it from happening
> in the first place?

Because stdio has a well-defined behavior of assigning the lowest
available fd to an open(). In particular, the classic idiom for forking
a child and opening a pipe to its STDIN (here in C, for transparency) . . .

pipe(&fd);

if (fork()) {
// Do parent stuff
} else {
close(fd[1]);
close(0);
dup(fd[0]);
close(fd[0]);
}

. . . won't work if this behavior isn't maintained.

> It's not something a user SHOULD need to be concerned
> about, and there is no reasonable way to prevent the warning from being
> issued.

Maybe the warning could become optional?

- Kurt

Rafael Garcia-Suarez

unread,
Jul 28, 2003, 6:45:15 PM7/28/03
to Chris Nandor, ch...@pobox.com, perl5-...@perl.org
Chris Nandor wrote:
> Sorry, "prevent" was confusing. I meant, prevent unless explicitly
> requested. open FILE, "<foo" should not ever assign the same as fd as is
> normally given to STDOUT, unless the user explicitly requests it, if indeed
> this sort of thing is something worth warning about.

This thing actually is not decided by perl. Quoting my open(2) manpage :

When the call is successful, the file descriptor returned will be
the lowest file descriptor not currently open for the pro cess.

> I don't think it is useful for the mere act of successfully opening a file
> for reading to generate a warning, just because you happened to close
> STDOUT previously.

But STDOUT still refers to the filehandle #1. This warning could be
useful. Although one can argue that further uses of STDOUT as an output
filehandle will trigger a warning as well...

Michael G Schwern

unread,
Jul 28, 2003, 6:42:21 PM7/28/03
to Chris Nandor, Chip Salzenberg, perl5-...@perl.org
On Mon, Jul 28, 2003 at 03:29:49PM -0700, Chris Nandor wrote:
> Sorry, "prevent" was confusing. I meant, prevent unless explicitly
> requested. open FILE, "<foo" should not ever assign the same as fd as is
> normally given to STDOUT, unless the user explicitly requests it, if indeed
> this sort of thing is something worth warning about.

I'd more than agree. It sounds like just an oversight in the way Perl
allocates file descriptors.


--
11. Every old idea will be proposed again with a different name and
a different presentation, regardless of whether it works.
-- RFC 1925

Michael G Schwern

unread,
Jul 28, 2003, 6:48:42 PM7/28/03
to Rafael Garcia-Suarez, Chris Nandor, ch...@pobox.com, perl5-...@perl.org
On Tue, Jul 29, 2003 at 12:45:15AM +0200, Rafael Garcia-Suarez wrote:
> This thing actually is not decided by perl. Quoting my open(2) manpage :
>
> When the call is successful, the file descriptor returned will be
> the lowest file descriptor not currently open for the pro cess.

I'd hope Perl could abstract away this sort of issue. Though I have
no idea if its possible.


--
WOOHOO! I'm going to Disneyland!
http://www.goats.com/archive/980805.html

Chris Nandor

unread,
Jul 28, 2003, 6:55:20 PM7/28/03
to Rafael Garcia-Suarez, perl5-...@perl.org
At 00:45 +0200 2003.07.29, Rafael Garcia-Suarez wrote:
>Chris Nandor wrote:
>> Sorry, "prevent" was confusing. I meant, prevent unless explicitly
>> requested. open FILE, "<foo" should not ever assign the same as fd as is
>> normally given to STDOUT, unless the user explicitly requests it, if indeed
>> this sort of thing is something worth warning about.
>
>This thing actually is not decided by perl. Quoting my open(2) manpage :
>
> When the call is successful, the file descriptor returned will be
> the lowest file descriptor not currently open for the pro cess.

Hrm. And perl has no control over this? I won't suggest anything silly
like having perl reopen the file if a "bad" fd is returned. :-)


>> I don't think it is useful for the mere act of successfully opening a file
>> for reading to generate a warning, just because you happened to close
>> STDOUT previously.
>
>But STDOUT still refers to the filehandle #1. This warning could be
>useful.

I was not referring to the "useful"ness of the warning, but that such
action as described should perform any action deserving of a warning.

Yes, if someone tries to read from or write to an fd that is the same as
STDOUT, but it is not the STDOUT filehandle, that should trigger a warning,
but for a user to have to worry about this -- especially with no reasonable
workaround to NOT get the STDOUT fd! -- is a bit troubling.

Michael G Schwern

unread,
Jul 28, 2003, 7:11:16 PM7/28/03
to Chris Nandor, Rafael Garcia-Suarez, perl5-...@perl.org
On Mon, Jul 28, 2003 at 03:55:20PM -0700, Chris Nandor wrote:
> Yes, if someone tries to read from or write to an fd that is the same as
> STDOUT, but it is not the STDOUT filehandle, that should trigger a warning,

No it shouldn't. Otherwise this existing idiom will start chucking
warnings for little reason.

open(REAL_STDOUT, ">&STDOUT") || die $!;
open(STDOUT, '>', "foo.out") || die "Can't redirect stdout";
print REAL_STDOUT "This goes to the screen";
print STDOUT "This goes to a file";


> but for a user to have to worry about this -- especially with no reasonable
> workaround to NOT get the STDOUT fd! -- is a bit troubling.

This I agree with. A user shouldn't be able to open one of the STD* file
descriptors by accident.

By analogy, the current behavior would be as if when you deleted /dev/random
the next file you created would have /dev/random's inode and be a pipe to the
random number generator! Perhaps not a perfect analogy, but its about the
same level of user astonishment and abstraction breakage.


--
The eye opening delightful morning taste of expired cheese bits in sour milk!

h...@crypt.org

unread,
Jul 29, 2003, 12:45:34 AM7/29/03
to Michael G Schwern, perl5-...@perl.org
Michael G Schwern <sch...@pobox.com> wrote:
:On Mon, Jul 28, 2003 at 03:55:20PM -0700, Chris Nandor wrote:
:> but for a user to have to worry about this -- especially with no reasonable

:> workaround to NOT get the STDOUT fd! -- is a bit troubling.
:
:This I agree with. A user shouldn't be able to open one of the STD* file
:descriptors by accident.

But normal non-accidental usage of this is pretty much identical, and
will be hard to distinguish. It is possible that docs need improving
somewhere, but the "open using the lowest available fd" must stay
(or lots of important code will break) and I think the warnings on
opening STDIN for write or STDOUT for read in this way should stay
(because it is consistent behaviour that nevertheless is rarely
desirable).

Hugo

Michael G Schwern

unread,
Jul 29, 2003, 3:04:43 AM7/29/03
to h...@crypt.org, perl5-...@perl.org
On Tue, Jul 29, 2003 at 05:45:34AM +0100, h...@crypt.org wrote:
> But normal non-accidental usage of this is pretty much identical, and
> will be hard to distinguish.

I'd think it would be very easy to distinguish inside Perl's open().
Unless they're dup'ing a filehandle with the file descriptor of 1 (ie.
STDOUT) they're not to be given fd 1. Now whether or not that's *possible*
because of how C's open() works is another thing, but I'd think noticing
non-accidental usage would be pretty straight-forward.

What scenarios were you thinking of that would be hard to distinguish?


> It is possible that docs need improving
> somewhere, but the "open using the lowest available fd" must stay
> (or lots of important code will break) and

I'm curious what would be depending on:

# no other open filehandles
close STDOUT;
open FOO, "somefile";

and if someone is depending on that, why we should support it.


> I think the warnings on
> opening STDIN for write or STDOUT for read in this way should stay
> (because it is consistent behaviour that nevertheless is rarely
> desirable).

That part is ok.


--
"That's what Jagulars always do," said Pooh, much interested. "They call
'Help! Help!' and then when you look up they drop down on you."

Rafael Garcia-Suarez

unread,
Jul 29, 2003, 3:56:40 AM7/29/03
to Michael G Schwern, h...@crypt.org, perl5-...@perl.org
Michael G Schwern wrote:
> On Tue, Jul 29, 2003 at 05:45:34AM +0100, h...@crypt.org wrote:
> > But normal non-accidental usage of this is pretty much identical, and
> > will be hard to distinguish.
>
> I'd think it would be very easy to distinguish inside Perl's open().
> Unless they're dup'ing a filehandle with the file descriptor of 1 (ie.
> STDOUT) they're not to be given fd 1. Now whether or not that's *possible*
> because of how C's open() works is another thing, but I'd think noticing
> non-accidental usage would be pretty straight-forward.

You're missing an important point : in Perl, the STDOUT symbol always
refer to the filehandle #1 (ie. fileno(STDOUT)==1 always if it's open),
no matter whether it's been closed or dup'd or reopened. (Likewise in
C.) How would you distinguish non-accidental use ? By warning when
another symbol than STDOUT is used for fd #1 ?

The warning is there to warn that fileno #1 is now (unusually) referring
to a file that's open for input. I prefer to have a warning on open()
_and_ on use of STDOUT as an output handle, because this situation can
mess up things with forked children that expect STDOUT to be an output
handle.

> What scenarios were you thinking of that would be hard to distinguish?
>
>
> > It is possible that docs need improving
> > somewhere, but the "open using the lowest available fd" must stay
> > (or lots of important code will break) and
>
> I'm curious what would be depending on:
>
> # no other open filehandles
> close STDOUT;
> open FOO, "somefile";
>
> and if someone is depending on that, why we should support it.

It's not an uncommon technique in daemons. Although I only have seen it
in C so far. Perl provides the piped form of open that hides this
between higher-level language constructs.

Note that those who want to discard STDOUT usually prefer open it to
/dev/null or equivalent.

Michael G Schwern

unread,
Jul 29, 2003, 2:02:31 PM7/29/03
to Rafael Garcia-Suarez, h...@crypt.org, perl5-...@perl.org
On Tue, Jul 29, 2003 at 09:56:40AM +0200, Rafael Garcia-Suarez wrote:
> > I'd think it would be very easy to distinguish inside Perl's open().
> > Unless they're dup'ing a filehandle with the file descriptor of 1 (ie.
> > STDOUT) they're not to be given fd 1. Now whether or not that's *possible*
> > because of how C's open() works is another thing, but I'd think noticing
> > non-accidental usage would be pretty straight-forward.
>
> You're missing an important point : in Perl, the STDOUT symbol always
> refer to the filehandle #1 (ie. fileno(STDOUT)==1 always if it's open),
> no matter whether it's been closed or dup'd or reopened. (Likewise in
> C.) How would you distinguish non-accidental use ? By warning when
> another symbol than STDOUT is used for fd #1 ?

By sticking a seperate flag on the filehandle that says "This is STDOUT"
as opposed to simply checking the fileno?


> > # no other open filehandles
> > close STDOUT;
> > open FOO, "somefile";
> >
> > and if someone is depending on that, why we should support it.
>
> It's not an uncommon technique in daemons. Although I only have seen it
> in C so far. Perl provides the piped form of open that hides this
> between higher-level language constructs.

When I wrote that I was confused that FOO would actually *be* STDOUT as
opposed to simply a filehandle with fd 1 that Perl is confusing for STDOUT.


> Note that those who want to discard STDOUT usually prefer open it to
> /dev/null or equivalent.

To avoid "aaah! you tried to write to STDOUT and its CLOSED!" warnings?


--
"Never underestimate the bandwidth of a mag tape on a bicycle."
-- Carl Friedberg in
<04716E70DA1C6046BEC...@babbage.esb.com>

Nick Ing-Simmons

unread,
Aug 10, 2003, 1:35:02 PM8/10/03
to pu...@pobox.com, perl5-...@perl.org
Chris Nandor <pu...@pobox.com> writes:
>Regarding this discussion:
> http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2002-09/msg00942.html
>
>In reference to this code:
>
> perl -we "close STDOUT; open F, q{.bashrc} or die"
>
>Which produces this warning upon success:
>
> Filehandle STDOUT opened only for input at -e line 1.
>
>I have two questions:
>
>1. Why is opening a filehandle that happens to share the same fd as STDOUT
>cause for concern, such that a warning is warranted?

fd with value 1 is inherited by child processes as stdout.

>
>2. If it IS a cause for concern, why doesn't perl prevent it from happening
>in the first place?

You mean don't open and die rather than warn?

>It's not something a user SHOULD need to be concerned
>about, and there is no reasonable way to prevent the warning from being
>issued.

Sure there is - don't close STDOUT unless you are about to
re-create a STDOUT.

There are "mountains" of legacy code which closes STDOUT and then
"knows" that next file it opens will become STDOUT by Posix semantics.

Nick Ing-Simmons

unread,
Aug 10, 2003, 1:40:54 PM8/10/03
to pu...@pobox.com, perl5-...@perl.org, Rafael Garcia-Suarez
Chris Nandor <pu...@pobox.com> writes:
>>This thing actually is not decided by perl. Quoting my open(2) manpage :
>>
>> When the call is successful, the file descriptor returned will be
>> the lowest file descriptor not currently open for the pro cess.
>
>Hrm. And perl has no control over this?

Of course it does ;-)

>I won't suggest anything silly
>like having perl reopen the file if a "bad" fd is returned. :-)

Large slabs of the test suite fail unless close(STDOUT) and re-open
does what is implied by the POSIXy thing above.

>
>Yes, if someone tries to read from or write to an fd that is the same as
>STDOUT, but it is not the STDOUT filehandle,

It is now ;-)

>that should trigger a warning,
>but for a user to have to worry about this -- especially with no reasonable
>workaround to NOT get the STDOUT fd! -- is a bit troubling.

Don't close(STDOUT)
do

open(STDOUT,">/dev/null");

or whatever.

Nick Ing-Simmons

unread,
Aug 10, 2003, 1:50:46 PM8/10/03
to raphel.gar...@hexaflux.com, perl5-...@perl.org, h...@crypt.org, Michael G Schwern
Rafael Garcia-Suarez <raphel.gar...@hexaflux.com> writes:
>Michael G Schwern wrote:
>> On Tue, Jul 29, 2003 at 05:45:34AM +0100, h...@crypt.org wrote:
>> > But normal non-accidental usage of this is pretty much identical, and
>> > will be hard to distinguish.
>>
>> I'd think it would be very easy to distinguish inside Perl's open().
>> Unless they're dup'ing a filehandle with the file descriptor of 1 (ie.
>> STDOUT) they're not to be given fd 1. Now whether or not that's *possible*
>> because of how C's open() works is another thing, but I'd think noticing
>> non-accidental usage would be pretty straight-forward.
>
>You're missing an important point : in Perl, the STDOUT symbol always
>refer to the filehandle #1 (ie. fileno(STDOUT)==1 always if it's open),
>no matter whether it's been closed or dup'd or reopened. (Likewise in
>C.) How would you distinguish non-accidental use ? By warning when
>another symbol than STDOUT is used for fd #1 ?

But that is common too! there is many a
open(FOO,">&=STDOUT");

You now have two streams that write to fd 1 but have separate buffers.
An oft' used hack to prevent lines of two logical streams getting
intertwined.

>
>Note that those who want to discard STDOUT usually prefer open it to
>/dev/null or equivalent.

Quite.


Chris Nandor

unread,
Aug 11, 2003, 1:09:47 PM8/11/03
to Nick Ing-Simmons, perl5-...@perl.org
At 18:35 +0100 2003.08.10, Nick Ing-Simmons wrote:
>Chris Nandor <pu...@pobox.com> writes:
>>Regarding this discussion:
>>
>>http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2002-09/msg00942.html

>>2. If it IS a cause for concern, why doesn't perl prevent it from happening


>>in the first place?
>
>You mean don't open and die rather than warn?

No, I mean don't give the fh the same fd as STDOUT.


>>It's not something a user SHOULD need to be concerned
>>about, and there is no reasonable way to prevent the warning from being
>>issued.
>
>Sure there is - don't close STDOUT unless you are about to
>re-create a STDOUT.

OK, but that is commonly not done, and it is not documented in perlfunc.
Hence the confusion.

Vadim Konovalov

unread,
Aug 11, 2003, 1:30:27 PM8/11/03
to Chris Nandor, Nick Ing-Simmons, perl5-...@perl.org
>>>It's not something a user SHOULD need to be concerned
>>>about, and there is no reasonable way to prevent the warning from being
>>>issued.
>>
>>Sure there is - don't close STDOUT unless you are about to
>>re-create a STDOUT.

CN> OK, but that is commonly not done, and it is not documented in perlfunc.
CN> Hence the confusion.

Indeed: "perldoc -f open" explains:
....
In the 2-arguments (and 1-argument) form opening "'-'" opens
STDIN and opening "'>-'" opens STDOUT.

However, once STDOUT closed, it could not be reopened again, at least
on Win32 and Linux.

One of URLs that discussed issue: http://www.perlmonks.org/index.pl?node_id=281848

--
Best regards,
Vadim mailto:vkono...@peterstar.ru

0 new messages