in reply to Re^6: Please suggest a non-forking way to do this (OS: windows)
in thread Please suggest a non-forking way to do this (OS: windows)

A timer calling sysread at a fast interval will not block

Why do you say sysread won't block?

than to figure out hacks to make win32 work. :-)

Win32 works fine. It's fighting Perl on Win32 that requires effort.

Replies are listed 'Best First'.
Re^8: Please suggest a non-forking way to do this (OS: windows)
by zentara (Cardinal) on Sep 29, 2008 at 21:29 UTC
    Why do you say sysread won't block?

    This script does it, by adding the O_NONBLOCK flag to the piped open. top is set to give output every 10 secs, yet the Tk gui is still running fine.

    #!/usr/bin/perl use warnings; use strict; use Tk; my $mw = MainWindow->new(-background => 'gray50'); my $text = $mw->Scrolled('Text')->pack(); my $pid; my $startb = $mw->Button( -text => 'Start', -command=> \&work, )->pack(); my $count = 0; my $label = $mw->Label(-textvariable=>\$count)->pack(); my $testtimer = $mw->repeat(500, sub { $count++} ); my $stopb = $mw->Button( -text => 'Exit', -command=>sub{ kill 9,$pid; exit; }, )->pack(); MainLoop; ##################################### sub work{ $startb->configure(-state=>'disabled'); use Fcntl; #long 10 second delay between outputs $pid = open (my $fh, "top -b -d 10 |" ) or warn "$!\n"; fcntl($fh, F_SETFL, O_NONBLOCK) || die "$!\n"; # Set the non-block flags my $repeater; $repeater = $mw->repeat(10, sub { if(my $bytes = sysread( $fh, my $buf, 1024)){; $text->insert('end',$buf); $text->see('end'); } } ); }

    I'm not really a human, but I play one on earth Remember How Lucky You Are

      Not quite.

      use strict; use warnings; use Fcntl qw( F_SETFL O_NONBLOCK ); my $fh = \*STDIN; fcntl($fh, F_SETFL, O_NONBLOCK) || die "$!\n"; sysread($fh, my $buf, 1);
      Your vendor has not defined Fcntl macro F_SETFL, used at ...

      Similarly, $fh->blocking(0); is a no-op.

      Like I said earlier, as far as I know, it's impossible to detect whether the pipe has data waiting.

        as far as I know, it's impossible to detect whether the pipe has data waiting.

        Actually, you can. See PeekNamedPipe() which is explicitly documented as also working on:

        a handle to the read end of an anonymous pipe, as returned by the CreatePipe function.

        Though it is difficult to see how to integrate it with win32/win32sck.c win32_select() in order to allow select to operate in the *nix fashion on pipes as well as sockets?


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
        Not quite

        Are you saying the non-blocking script I posted didn't work for you? This slightly modified version using STDIN works fine, in a non-blocking manner for me on linux. Is your error coming on a Windows platform? If thats so, nothing I can do, except encourage people to switch to a real operating system, instead of a game platform. :-)

        s far as I know, it's impossible to detect whether the pipe has data waiting.

        On linux you can, see "perldoc -q waiting".


        I'm not really a human, but I play one on earth Remember How Lucky You Are