Hello,

The platform is Windows XP, and Perl is ActiveState. I am in the process of writing a perl script that needs to control an external driver, which is written in C++. This script launches the driver, and needs to communicate with it using bidirectional pipes (or something better). The driver is constantly spewing output, which this script needs to read. However, at some point along the way, the user needs to suspend reading from the pipe, and take input from the command line to change the driver parameters. This input is written to the pipe, and reading from the pipe must continue.

I am using a separate thread to ask for user input, because it should be non blocking (to allow the constant spewing of the driver to appear on the screen). ReadKey() is used to determine what was pressed, such as 'p' for change parameter, or 'q' to quit. I base this design from this link:

http://www.perlmonks.org/?node_id=928062

It is important that reading from the user is initially non blocking, then blocking until a full line is entered. This changing of parameters should not effect the bidirectional pipe. I cannot use IO::Select because it is not supported on Windows. Perhaps a better idea would be sockets, but I believe this can be done using pipes.

Appreciate any help.

#!/usr/bin/perl use strict; use warnings; use IPC::Open2; use Term::ReadKey; use threads; use threads::shared; my $pid = open2(\*Reader, \*Writer, "driver.exe") or die "Failed to open pipe! $!"; ReadMode('cbreak'); my $state : shared = 0; my $i : shared = 0; my $thr = threads->new(\&read_in)->detach; while (1) { # Continue reading the spam from the driver if ($state == 0) { my $got = <Reader>; if (defined $got) { print $got; } } #User paused spam reading, changed value of $i, and #needs to pipe it to the driver, spam output will be updated elsif ($state == 1) { $state = 0; #reset state print Writer "$i\n"; } #User quit! elsif ($state == 2) { print Writer "quit\n"; # Before the driver exits, it does output a message, which # for some reason does not get grabbed here my $goodbye = <Reader>; print $goodbye; last; } } ReadMode('normal'); sub read_in { while (1) { my $char = 0; # A key was pressed to change state if (defined ($char = ReadKey(0))) { # 'p' was pressed to signal paramter change, stop # outputting from driver output, get new value from consol +e, # and update it if ($char eq 'p') { $state = 1; # How to make this work? $i = <STDIN>; chomp $i; } # User quit elsif ($char eq 'q') { $state = 2; } } } } waitpid($pid, 0); __END__

In reply to Bidirectional Pipe While Reading From STDIN by rem45acp

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.