develooper Front page | perl.perl5.porters | Postings from November 2004

close(STDOUT) dups STDOUT, even if STDOUT is socket (perlbug #32446)

From:
Steffen Ullrich
Date:
November 25, 2004 23:30
Subject:
close(STDOUT) dups STDOUT, even if STDOUT is socket (perlbug #32446)
Message ID:
co6jse$cqb$1@sea.gmane.org
Hi,
Since there is no reply yet to this perlbug 
(http://rt.perl.org/rt3/Ticket/Display.html?id=32446) I'll try to get 
more help here:

I have a small IO::Socket::INET based server. When the server gets a new 
client socket from an "accept" call it dups this socket to STDIN + 
STDOUT and closes the original client socket. When it's done with the 
client it closes STDIN + STDOUT which should in theory free the socket.
The close(STDIN) works fine, but the close(STDOUT) duplicates the socket
to fd 0 before it closes fd 1, thus keeping the socket open (I got these 
details from a ktrace of the server)

Below is a small example program. It shows the problem on OpenBSD3.6 
with perl5.8.5. The problem seems to be specific for OpenBSD, at least I 
have no problems on Linux with perl5.8.3 and perl5.8.5.

-------------- The example program -----------------------------------

use strict;
use IO::Socket;
# Usage: test_server host:port

my $srv = IO::Socket::INET->new(
     LocalAddr => ( $ARGV[0] || die "no address" ),
     Listen => 10, Reuse => 1 )
     || die "listen: $!";

# wait for connection from client, e.g. telnet host port
my ($cl,$peer) = $srv->accept || next;

# dup client connection to STDIN+STDOUT
open( STDIN,"<&".fileno($cl));
open( STDOUT,">&".fileno($cl));
STDOUT->autoflush;

# close original client socket (socket is still open
#  because it is duped to STDIN+STDOUT)
$cl->close;

# this gets send to the client because STDOUT is
# the client socket
print "hallo\n";

# this closes STDIN, the client socket still exists
# in STDOUT
close(STDIN);

# ************************************************
# this closes STDOUT which should in theory destroy
# the the client socket. But instead it dups the socket
# to fd 0 (STDIN) and then closes STDOUT
# ************************************************
close(STDOUT);

# ************************************************
# client socket is still open here (fd 0)
# a reopen of STDIN keeps it open, because STDIN
# then gets associated with an free fd>0
# ************************************************

sleep(10);  # client is still connected




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About