The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

IO::Pty::HalfDuplex - Treat interactive programs like subroutines

SYNOPSIS

    use IO::Pty::HalfDuplex;

    my $pty = IO::Pty::HalfDuplex->new;

    $pty->spawn("nethack");

    $pty->read;
    # => "\nNetHack, copyright...for you? [ynq] "

    $pty->write("nvd");
    $pty->read;

    # => "... Velkommen sorear, you are a lawful dwarven Valkyrie.--More--"

DESCRIPTION

IO::Pty::HalfDuplex is designed to perform impedence matching between driving programs which expect commands and responses, and driven programs which use a terminal in full-duplex mode. In this vein it is somewhat like expect, but less general and more robust (but see CAVEATS below).

This module is used in object-oriented style. IO::Pty::HalfDuplex objects are connected to exactly one system pseudoterminal, which is allocated on creation; input and output are done using methods. The interface is deliberately kept similar to Jesse Luehrs' IO::Pty::Easy module; notable incompatibilities from the latter are:

  • The spawn() method reports failure to exec inline, on output followed by an exit. I see no reason why exec failures should be different from post-exec failures such as "dynamic library not found", and it considerably simplifes the code.

  • write() does not immediately write anything, but merely queues data to be released all at once by read(). It does not have a timeout parameter.

  • read() should generally not be passed a timeout, as it finds the end of output automatically.

  • The two-argument form of kill() interprets its second argument in the opposite sense.

METHODS

new(%args)

Allocates and returns a IO::Pty::HalfDuplex object. The named argument 'backend' selects a backend, other arguments, if any, are in the backend's documentation. If the backend is not specified, one will be defaulted based on platform, or using $ENV{IO_PTY_HALFDUPLEX_BACKEND} if it exists. Currently supported backends:

JobControl

Using POSIX job control. Theoretically portable to all UNIXes, in practice bugs require workarounds on many systems. Most BSDs (but not recent Darwin) have a kernel issue which makes this unusably slow (several seconds per read). The default on UNIX.

SysctlPoll

Using BSD-style sysctl process access. The default on FreeBSD, OpenBSD, and NetBSD.

PTrace

Using the highly nonportable ptrace call. Could be ported to most Unixes, but at present only works on i386 and amd64 FreeBSD; other popular platforms support simpler methods.

spawn(LIST)

Starts a subprocess under the control of IO::Pty::HalfDuplex. LIST may be a single string or list of strings as per Perl exec.

recv([TIMEOUT])

Reads all output that the subprocess will send. If TIMEOUT is specified and the process has not finished writing, undef is returned and the existing output is retained in the read buffer for use by subsequent recv calls.

TIMEOUT is in (possibly fractional) seconds.

write(TEXT)

Appends TEXT to the write buffer to be sent on the next recv.

is_active()

Returns true if the slave process currently exists.

kill()

Sends a signal to the process currently running on the pty (if any). Optionally blocks until the process dies.

kill() takes an even number of arguments. They are interpreted as pairs of signals and a length of time to wait after each one, or 0 to not wait at all. Signals may be in any format that the Perl kill() command recognizes. Any output generated while waiting is discarded.

Returns 1 immediately if the process exited during a wait, 0 if it was successfully signalled but did not exit, and undef if the signalling failed.

kill() (with no arguments) is equivalent to kill(TERM => 3, KILL => 3).

kill() may not be fully implemented on non-UNIX backends.

close()

Kills any subprocesses and closes the pty. No other operations are valid after this call.

CAVEATS

In general, IO::Pty::HalfDuplex relies on processes accessing the terminal in a single-threaded way. If you manage to write while blocking on a read, or never use blocking reads, IO::Pty::HalfDuplex will break. In particular, programs like qemu and telnet cannot be expected to ever work with this.

Each backend has its own long list of caveats; see the relevant documentation.

SEE ALSO

IO::Pty::HalfDuplex::JobControl and related modules. IO::Pty::Easy. TAEB, the first and motivating user of this module. Expect, a superficially similar module with an entirely different implementation.

AUTHOR

Stefan O'Rear, <stefanor@cox.net>

BUGS

No known bugs.

Please report any bugs through RT: email bug-io-pty-halfduplex at rt.cpan.org, or browse http://rt.cpan.org/NoAuth/ReportBug.html?Queue=IO-Pty-HalfDuplex.

COPYRIGHT AND LICENSE

Copyright 2008-2009 Stefan O'Rear.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.