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

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

Replies are listed 'Best First'.
Re^9: Please suggest a non-forking way to do this (OS: windows)
by ikegami (Patriarch) on Sep 29, 2008 at 21:43 UTC

    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.

        Win32API::File has a function that returns the system file handle associated with a Perl file handle, and Win32::API can give access to PeekNamedPipe with minimal fuss.

        Sounds like it's another working solution in this case, even if it can't be integrated with select.

      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

        This slightly modified version using STDIN works fine, in a non-blocking manner for me on linux.

        I just showed that your fcntl command doesn't work on Windows.

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

        Windows does have an equivalent to unix's file handles and select (events that can be tied to file handles and WaitForMultipleObjects), but Perl doesn't support them.