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
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |