Re: Glib::IO watcher unbuffered? [SOLUTION]



On Fri, Jan 19, 2007 at 06:21:57PM +0100, Philipp Letschert wrote:
On Fri, Jan 19, 2007 at 06:15:21AM -0500, zentara wrote:
On Fri, 19 Jan 2007 09:24:53 +0100
"Philipp E. Letschert" <phil uni-koblenz de> wrote:

I would like to have unbuffered output processing from an external command
(command prints a line, sleeps, prints a line, sleeps ...):

It is common behaviour that the C library uses isatty(3) to decide if stdout
is line-buffered or block-buffered. When reading from a pipe to an external
command the output is block-buffered, which explains the reported behaviour.

Solution is using a pseudo-terminal and connect the watcher to it, following is
a complete example:

use Glib;
use IO::Pty;

my $pty = IO::Pty->new;

my $cmd = "external_command -with_args";

my $pid;

unless ($pid = fork) {  # child process
        die "problem spawning program: $!\n" unless defined $pid;

        use POSIX ();
        POSIX::setsid
            or die "setsid failed: $!";

        my $tty = $pty->slave;
        my $tty_fd = $tty->fileno;
 
        open STDIN, "<&$tty_fd" or die $!;
        open STDOUT, ">&$tty_fd" or die $!;
        open STDERR, ">&STDOUT" or die $!;
        close $pty;
        close $tty;

        exec $cmd;
}

my $watcher;
$watcher = Glib::IO->add_watch( fileno( $pty ), ['in', 'hup'], \&callback);

sub callback {
        if ( $pty->eof ) {
                Gtk2::Helper->remove_watch( $watcher );
                close( $pty );
        }
        else {
                my $line = $pty->getline;
                print $line;
        }
}


HTH, Phil





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]