And thank you again, ikegami.
The need for the synchonizing code with sysread came from graff's observation that he needed to add a sleep 1; the first line or so of output gets lost unless the main script waits a bit before it sends anything.
I hadn't thought about spaces embedded in the password, but it would only be a problem if the script read more than one byte at a time. Using getc, $_ will never contain embedded whitespace, because it would have been found on a previous pass through the loop.
Last night you pointed out that checking for /\s/ (or /\s$/) doesn't work if the password contains spaces. After I though about it for a while, I think it can be fixed by changing
next unless /\s/;
to see if $_ is the beginning of the password
next if $_ eq substr "' . (quotemeta $password) . '", 0, length;
when reading one character at a time.
If it was really necessary to read more than one character at a time and the passwords would contain spaces, it would probably work to check if any trailing substring of the buffer matches any leading substring of the password like this:
[[... beginning of the code as above...]]
print '
use warnings;
use strict;
use List::Util qw(min);
select STDOUT;
$| = 1;
my $chr;
$_ = "";
CHAR:
while (defined ($chr = getc DATA)) {
$_ .= $chr;
foreach my $n (1..min ' . (length $password) . ', length) {
next CHAR if substr ("' . (quotemeta $password) . '", 0, $n)
eq substr ($_, (length)-$n, $n);
}
s/' . (quotemeta $password) . '/removed/ig;
print;
$_ = "";
}
print;
__DATA__
';
[[... the rest of the code is as above...]]
... but I think I prefer the simplicity of reading one character at a time.
Take care,
quester |