                                     README

lpty

   A package that provides a simple interface to start programs and
   control them via a pty for Lua.

   Author: Gunnar Zötl , 2010.
   Released under MIT/X11 license. See file LICENSE for details.

Introduction

   This is a simple interface to pty functionality, providing the ability
   to fork a process and run it under pty control. It does not try to
   mimic the posix API but instead focuses on the function of running and
   controlling a program. The interface is very bare bones, no additional
   functionality is provided, especially nothing like expect, which should
   be a different package.

   This has been developed on Linux and tested on MacOS X. It should
   compile and run on any platform supporting the Unix 98 interface to
   pty's. Support for additional Unixen might follow in the future,
   depending on demand (especially my own ;) ). No support for windows is
   planned, as ptys are a Unix thing. It might work with cygwin.

Installing

   This uses only stuff that comes with your system. Normally, calling
   sudo luarocks install lpty

   or when you have an unpacked source folder,
   sudo luarocks make

   should do the right thing.

   There is also a Makefile in the distribution directory, which has been
   created for and on Linux, basically for special needs. You will have to
   edit it by hand, so the luarocks method is preferrable.

Using

   require "lpty"

  Constructor

   pty = lpty.new([{[throw_errors = true|false], [no_local_echo =
          true|false]}])
          Creates and fully initializes the master side of a pty. Options
          for the pty may be passed in a table. These options are:

        throw_errors
                If true, errors are thrown, otherwise they are returned as
                a standard (nil, error message) pair. Default is false.

        no_local_echo
                If true, stuff sent to the parent side of the pty will not
                be echoed back to the parent side, otherwise it will be
                echoed back. Default is false.

          If you do not want to pass any options, you may omit the table
          altogether.

  Methods

   pty:startproc("command", "arg1", "arg2", ...)
          Starts a process with the slave side of the pty as its
          controlling terminal. The child processes stdin, stdout and
          stderr are set to use the slave side of th pty. Command and its
          arguments must be separate arguments to the startproc method.
          This uses the PATH environment variable to find any executables,
          so specifying a ful path to the command is not always necessary.
          Returns true if the fork() was successful, false if there is
          already an active process attached to the pty, and throws an
          error if anything goes wrong.

   pty:endproc([kill])
          Terminates the process running with the pty as its controlling
          terminal. If the optional parameter kill is false or omitted,
          send the child process a SIGTERM, otherwise send a SIGKILL. It
          is not an error to call this on a pty object that has no active
          child processes. You do not need to call it when you have
          already terminated the child process using more civilized means
          (like, for example, sending it a quit command it understands).
          After the child process has been terminated, a new one can be
          started using the same PTY.

   pty:hasproc()
          returns true if the pty has an active child process, false if
          not (none has been created, the child has terminated, ...)

   pty:readok([timeout])
          returns true if the pty has data available to be read, false
          otherwise. If a timeout value is specified, the call will wait
          at most that long for data to become available to read. No value
          is equivalent to a timeout of 0 seconds.

   pty:read([timeout])
          reads data from the pty. This is a blocking read, so you can
          specify an optional timeout after which the read should return
          to the caller whether there was data or not. If the timeout is
          omitted, the read will block until there is something to read.
          Returns the data read, or nil if the request timed out. If an
          error occurred during the read attempt, it is thrown to lua.
          Note: unless you specified no_local_echo=true when creating the
          pty, this reads data output from the client process as well as
          data sent to the client process from the controlling skript

   pty:sendok([timeout])
          returns true if the pty can accept data sent to it, false
          otherwise. If a timeout value is specified, the call will wait
          at most that long for the pty to accept data, No value is
          equivalent to a timeout of 0 seconds.

   pty:send(data [, timeout])
          sends data to the pty. This will then be available to the child
          process on its stdin. Sending data may block, there is an
          optional argument for a timeout on the send operation. If the
          timeout argument is omitted, the send operation will block until
          the pty can accept the data. Returns the number of bytes
          written, or nil if the send timed out. If an error occurred
          during the attempt to write it is thrown to lua.

Additional Info

   the read() method reads its data ito a buffer. The size of this buffer
   determines how much data can be returned from an individual read. It is
   set by a #define at the start of the module source and by default is
   set to 4096. Considering the C-typical terminating zero, this will
   leave a maximum of 4095 bytes to be read in one go. In order to fetch
   all available data, just loop while pty:readok() and concatenate the
   results.

   Similar things hold for send(). It may not send all data you gave it in
   one go. For small amounts of data this is quite improbable, but in
   industrial strength applications you should probably check the return
   value of the send() method against the length of the data you intended
   to send.

   If you have a pty without a running child process, you can only read
   from it what you write to it (unless you specified no_local_echo=true
   for pty creation, in which case you can not read anything from it).
   This means that if you (or the last active child process) have nothing
   written to it, a read with timeout will always time out, and a read
   without timeout will block. However, if you later start a child
   process, anything you have written to the pty before that will be
   available as input to the child. Reading stuff back from the master
   side of a pty does not remove it from the slave side.

   The startproc() method can not check whether running the command in the
   child process or basically anything that happens in the child process
   after the fork is successful. If startproc() returns true, this means
   that setting up the client side of the tty and fork()ing went well and
   yielded a running child process. You may want to check wether it is
   still running when you need it using the hasproc() method, especially
   if you're dealing with an interactive program. If the program the child
   was supposed to start is not running when you expect it to, you will
   have to check the contents of the pty for the reason.

   When a lpty object is garbage collected, its master side pty handle is
   closed, and if it as a child process, that is terminated with a
   SIGKILL. So it is reasonably safe to let pty's with active processes
   become garbage, it just isn't very friendly towards the child
   processes.

Example

   See the samples folder in the distribution archive.

References

   Read up on ptys on your local friendly linux system: man 7 pty and
   friends. This is linux specific, but as I use Unix 98 pseudo ttys, this
   holds whereever they're available.
