in reply to Diagnosing blocking io (or: finding the WHY of my Open2 woes).

I would have thought open2 set the handle to autoflush, but that might not be the case. What happens when you add
use IO::Handle qw( ); # For autoflush ... my $pid = open2($JSREAD, $JSWRITE, ...); $JSWRITE->autoflush(1); ...

By the way, isn't `which js` the same thing as just js?

Replies are listed 'Best First'.
Re^2: Diagnosing blocking io (or: finding the WHY of my Open2 woes).
by Socrates (Acolyte) on Nov 18, 2008 at 22:24 UTC
    $JSWRITE->autoflush(1); Changes nothing, unfortunately. I tried that already, along with other things like:
    use Fcntl; ... my $flags |= O_NONBLOCK; fcntl($JSWRITE, F_SETFL, $flags); ...
    And, yes "`which js`" is the same... I forget why I had that in there. Still doesn't work, but I'll update the open2() call in the original post to avoid confusion.

      Your program works fine for me when I run a Perl script for the child.

      my $pid = open2($JSREAD, $JSWRITE, q{perl -e"{ $_=<>; last if /^END$/; + ++$i; $m=qq{$i: $_}; warn $m; print $m; redo}"});

      (The $|=1 isn't even necessary!)

      Seems to me the problem is in the js side. But I doubt it's in readline. Are you sure your Perl script reaches END? Are you sure END is causing the child to exit?

      By the way, you're adding newlines where they already exist in two different places.

        Yes, you're right about the unnecessary newlines. I fixed the newline where it feeds the file one line at a time to the child. The perl absolutely reaches "END".

        test.js is three simple lines:

        var foo=0; var bar=1; var baz=2;

        And I can type these in, one at a time, into the running javascript program from the command line:

        $ js js> load('jslint.js'); var foo=0; var bar=1; var baz=3; END jslint: No problems found. $

        If I drop warns in:

        open FILE, '<', "test.js"; while (<FILE>) { warn "printing $_"; print $JSWRITE "$_"; } close(FILE); warn "printing END\n"; print $JSWRITE "END\n";

        I see:

        $ ./jslint.pl printing var foo=0; printing var bar=1; printing var baz=3; printing END

        And strace shows this:

        ... write(4, "load(\'jslint.js\');\n", 19) = 19 open("test.js", O_RDONLY) = 3 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff8d5e9440) = -1 ENOTTY (I +nappropriate ioctl for device) lseek(3, 0, SEEK_CUR) = 0 fstat(3, {st_mode=S_IFREG|0664, st_size=33, ...}) = 0 fcntl(3, F_SETFD, FD_CLOEXEC) = 0 read(3, "var foo=0;\nvar bar=1;\nvar baz=3;"..., 4096) = 33 write(2, "printing var foo=0;\n", 20printing var foo=0; ) = 20 write(4, "var foo=0;\n", 11) = 11 write(2, "printing var bar=1;\n", 20printing var bar=1; ) = 20 write(4, "var bar=1;\n", 11) = 11 write(2, "printing var baz=3;\n", 20printing var baz=3; ) = 20 write(4, "var baz=3;\n", 11) = 11 read(3, "", 4096) = 0 close(3) = 0 write(2, "printing END\n", 13printing END ) = 13 write(4, "END\n", 4) = 4 close(4) = 0 read(5, <unfinished ...>

        Which, if I remove reading from $JSREAD, becomes:

        write(4, "load(\'jslint.js\');\n", 19) = 19 open("test.js", O_RDONLY) = 3 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff38afb950) = -1 ENOTTY (I +nappropriate ioctl for device) lseek(3, 0, SEEK_CUR) = 0 fstat(3, {st_mode=S_IFREG|0664, st_size=33, ...}) = 0 fcntl(3, F_SETFD, FD_CLOEXEC) = 0 read(3, "var foo=0;\nvar bar=1;\nvar baz=3;"..., 4096) = 33 write(2, "printing var foo=0;\n", 20printing var foo=0; ) = 20 write(4, "var foo=0;\n", 11) = 11 write(2, "printing var bar=1;\n", 20printing var bar=1; ) = 20 write(4, "var bar=1;\n", 11) = 11 write(2, "printing var baz=3;\n", 20printing var baz=3; ) = 20 write(4, "var baz=3;\n", 11) = 11 read(3, "", 4096) = 0 close(3) = 0 write(2, "printing END\n", 13printing END ) = 13 write(4, "END\n", 4) = 4 close(4) = 0 close(5) = 0 wait4(8790, <unfinished ...>