use threads;
use Socket qw( AF_UNIX SOCK_STREAM PF_UNSPEC );
use IO::Handle qw( );
sub _pipe {
socketpair($_[0], $_[1], AF_UNIX, SOCK_STREAM, PF_UNSPEC)
or return undef;
shutdown($_[0], 1); # No more writing for reader
shutdown($_[1], 0); # No more reading for writer
return 1;
}
sub sockify_stdin {
open(my $real_stdin, '<&', *STDIN)
or die("Can't dup STDIN: $^E\n");
_pipe(*STDIN, my $stdin_w)
or die("Can't create socketpair: $^E\n");
$stdin_w->autoflush(1);
async {
close(STDIN); # Close this threads's copy.
print $stdin_w $_ while <$real_stdin>;
close($stdin_w);
}->detach();
close($stdin_w); # Close this threads's copy.
}
Sample usage:
use IO::Select qw( );
sockify_stdin();
my $stdin_buf = '';
my $sel = IO::Select->new(*STDIN);
while (my (@ready) = $sel->can_read()) {
my $rv = sysread(*STDIN, $stdin_buf, 64*1024, length($stdin_buf));
die if !defined($rv);
last if !$rv;
while ($stdin_buf =~ s/(.*\n)//g) {
print "$1";
}
}
print "$stdin_buf\n" if length($stdin_buf);
|