Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

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; }
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 during install. It is possible then, that someone might not have, however ActiveState's distribution of Perl does include it.

Replies are listed 'Best First'.
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 => '', 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 line 10.

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

      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:\ 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.

        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.


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://65814]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (5)
As of 2017-01-24 02:10 GMT
Find Nodes?
    Voting Booth?
    Do you watch meteor showers?

    Results (200 votes). Check out past polls.