Using IO::Select on STDIN on Windows

Viewed 365

When I run the code below on a Linux system, as expected it outputs Nothing is ready about every two seconds, and also outputs anything entered on to console.

But on Windows, can_read returns instantly with zero items.

use IO::Select;

my $sel = IO::Select->new();
$sel->add(\*STDIN);

while ( 1 ) {

    my @ready = $sel->can_read(2);

    if ( scalar @ready == 0 ) {
        print "Nothing is ready\n";
    }

    foreach my $fh ( @ready ) {

        if ( $fh eq \*STDIN ) {
            my $in = <STDIN>;
            print "got $in from stdin\n";
        }
    }
}

It seems that select works only on Windows sockets and not on STDIN. How can I use IO::Select on STDIN on a Windows system?

1 Answers

You cannot, perldoc perlport states:

select  Only implemented on sockets. (Win32, VMS)

This is caused by Windows itself implementing select() only for sockets, see https://docs.microsoft.com/de-de/windows/desktop/api/winsock2/nf-winsock2-select.

The Windows equivalent seems to be I/O Completion Ports. But you have to find a way to use them from Perl.

If you really just care about STDIN, you can poll in a loop with Term::ReadKey with a ReadMode of -1 (non-blocking). As the name of the module suggests, this may only work on a tty.

Related