Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: fcntl on Windows

by Adam (Vicar)
on Mar 21, 2001 at 00:49 UTC ( #65814=note: print w/ replies, xml ) Need Help??


in reply to fcntl on Windows

Yes, you can get fcntl on windows*. As for using it to do non blocking, I have to admit that I've never done it in Perl. But here is how I do it in C, and I suspect that the Perl way is almost identical:

#include <stdio.h> #include <fcntl.h> void SetNonBlocking( int filehandle ) { int fhFlags; fhFlags = fcntl(filehandle,F_GETFL); if (fhFlags < 0) { perror("fcntl(F_GETFL)"); exit(1); } fhFlags |= O_NONBLOCK; if (fcntl(filehandle,F_SETFL,fhFlags) < 0) { perror("fcntl(F_SETFL)"); exit(1); } return; }
Update:
We discover this later in this thread, but rather deep, so I'll reiterate it here. It turns out that the fcntl module is available on Win32, but not fcntl(2) the method. That is *nix specific. Camel2 states, "fcntl will produce a fatal error if used on a machine that doesn't implement fcntl(2)."

My new recomendation is to use select to poll the socket, and when it has data, then read from it blocking. You can simulate non-blocking by using a small timeout on the select and only reading a few charaters (or even just 1) at a time.


*Note that the standard distribution uses the local c compiler to create Fcntl.pm during install. It is possible then, that someone might not have Fcntl.pm, however ActiveState's distribution of Perl does include it.


Comment on Re: fcntl on Windows
Download Code
Re: Re: fcntl on Windows
by Daimun (Novice) on Mar 21, 2001 at 00:57 UTC
    The point was not to figure out how to do it.. I know how to do it.. Here is my 'test' code.

    #!/usr/bin/perl use IO::Socket; $sock = IO::Socket::INET->new( PeerAddr => '192.168.0.4', PeerPort => 4000, Proto => 'tcp' ); $flags = fcntl($sock, F_GETFL, 0) or die "Can't get flags for socket: $!\n"; fcntl($sock, F_SETFL, $flags | O_NONBLOCK) or die "Can't make socket nonblocking: $!\n"; print $sock "logn 0607daimuntemp123\n"; while(1) { sleep 1; $str = <$sock>; chomp $str; print $str . "\n"; if( $str =~ /^$/ ) { print "null\n"; } }


    When run, it results in this error:
    fcntl is not implemented at sam.pl line 10.

    Daimun
      You forgot the line:
      use Fcntl;
      Easy mistake to make. That should fix it.

      Update:
      I tried your code (plus the use statement and a few print statements) on my NT box with Perl 5.6 and got this rather annoying message:

      Your vendor has not defined Fcntl macro F_GETFL, used at C:\temp.pl li +ne 10.
      That means the Fcntl implementation in my install is incomplete. I suspect this is going to be true across Windows installations, so you might want to write a wrapper around Fcntl that defaults to Fcntl but fills in the holes when they are missing.
        I apologize for the back-and-forth, but.. with that fix (Which I had already tried..) - I get:

        Your vendor has not defined Fcntl macro F_GETFL, used at ...

        If I then change F_GETFL to something random like F_GETFALLY or the such, I again get:

        fcntl is not implemented ...

        But.. again, it all works perfectly on the unix side. Frustrating me, indeed.

        Daimun
        Trying to tap the well of knowledge here..
        What other ways are there to do what fcntl does? I'm not clear on what my other options might be.

        Daimun

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (5)
As of 2014-09-17 22:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (100 votes), past polls