Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to port a Unix Perl IRC daemon (Pircd) to Windows 2000 (Active Perl 5.6).

I think maybe the only thing that I cannot handle is this thing about setting the socket (of a new client connection) to 'non-blocking'.

The orginal code refers to a setnonblocking() subroutine. See below.

foreach $client ($select->can_read(1)) { if($serversocks{$client}) { # Activity on the listening socket means we have a new # client attempting to connect. # Get ahold of the new socket, assign it to all the whatnot, etc $client = $client->accept; $select->add($client); &setnonblocking($client); # <--- SEE HERE $connections{$client} = Connection->new($client, \%outbuffer, $U +tils::thisserver); $unfinished{$client} = $connections{$client}; }

The problem is that the setnonblocking() subroutine uses some functions that are not available on Windows 2000 (namely F_GETFL and F_SETFL). Here is the subroutine.

sub setnonblocking { my $sock = shift; # Get the current state of the socket.. my $flags = fcntl($sock, F_GETFL, 0) or die "Can't get the flags on socket: $!\n"; # ..and then add O_NONBLOCK (nonblocking-ness) on to it. fcntl($sock, F_SETFL, $flags | O_NONBLOCK) or die "Can't set socket non-blocking: $!\n"; }

So the big question is:

How can I rewrite this subroutine so that it will work on Windows 2000 and accomplish the same purpose (set the socket to be non-blocking)?

Replies are listed 'Best First'.
(MeowChow) Re: porting this 'setnonblocking' subroutine to Windows
by MeowChow (Vicar) on Dec 30, 2001 at 00:55 UTC

      uhh MeowChow that seems to be exactly what i need in order to port this irc daemon to Windows. But I'm having a little trouble. Any chance I can pay you to put that part of the code in my script exactly as it should be?

      Ed@ChristianWeb.com

        Simply use the d/l code link at the bottom of the page and get the module. Then in your pircd directory, make a subdirectory named Portable, then rename the file you downloaded NonBlock.pm and put it in the Portable directory. Open it up and change setnonblock in the @EXPORT_OK declaration to setsocknonblock (Looks like a simple typo, correct me if I'm wrong). Then in the pircd file, put use Portable::NonBlock qw(setsocknonblock); at the top and replace all instances of setnonblocking to setsocknonblock (except for the sub declaration for setnonblocking. You can leave that as it is or take it out). Unfortunately, even though the IRCd will run now, you'll get an error after a user connects, which is "Your vendor has not defined POSIX macro EWOULDBLOCK".
Re: porting this 'setnonblocking' subroutine to Windows
by chromatic (Archbishop) on Dec 29, 2001 at 23:50 UTC
    I'm not the world's best socket programmer, nor am I completely up to capacity on a Saturday morning, but I don't understand the question. If you're already using IO::Select or the four-argument select, why do you need a non-blocking socket? Just provide a timeout.