Updated tty Connection for R

Below are some links to a patch against the R-2.12.2 source code that implements a tty connection for R. Since the release of R-2.13.0 is coming soon, I'll have a patch for it soon also.

What's a tty connection?

The tty connection is an R interface to computer terminals, as defined by the Portable Operating System Interface (POSIX). Computer terminals are special files used for asynchronous communications, and may represent a USB or serial port, input from a keyboard, or the terminal software used to communicate with an operating system kernel.

For users of GNU Linux and similar platforms, most tty's are stored in the /dev file system (try ls /dev). These files have special settings that control how data is written to, and read from the terminal. For instance, suppose a terminal represents keyboard input. By default, read operations from the terminal usually wait (block) until a complete line is typed (i.e. the 'Enter' key is pressed). Using the tty connection, we can modify this behavior. If the terminal represents a serial port, then we can use the tty connection to set how fast data is transmitted across the port (i.e. the baud rate).

I was motivated to implement a tty connection in order to collect data from a serial port using R. I have written about this several times before (See http://biostatmatt.com/tag/serial). But, the tty connection has much broader application. The following is a useR interface application:

Password entry without echoing characters to the screen

The tty connection patch ultimately defines the tty function, which creates an object of the class c("tty", "connection"), and sets the special features associated with ttys. This connection can be read and written using existing functions (e.g. cat, readBin).

We can use the tty function to accomplish specific tasks. Consider this getpass function:

#get a password from the terminal, don't echo characters
getpass <- function(prompt="password:", device="/dev/tty") {
    cat(prompt)
    con <- tty(device, local=list(ICANON=TRUE,ECHO=FALSE))
    pw  <- readLines(con, 1)
    close(con)
    cat("\n")
    invisible(pw)
}

This function behaves as follows:

> pw <- getpass()
password:
> pw
[1] "secret"

where "secret" was entered from the keyboard following the prompt "password:". Notice that the password wasn't printed to the terminal as it was entered! There are many more applications of this type, including "press any key to continue" functionality, and timed pauses in execution.

Patching Instructions

There are two versions of the patch, the first requires that the user regenerate the configure script with autoconf (e.g. using autoreconf -Im4). The second also patches the configure script, so that regenerating the configure script is unnecessary.

configure patch not included R-2.12.2-tty.patch
configure patch included R-2.12.2-tty+conf.patch

Generic steps for patching R are as follows:

  1. Download the R source code
  2. Download the patch file
  3. Apply the patch
  4. Compile the patched source code

Here is a shell sequence to apply the most recent patch and compile the patched code:

wget http://lib.stat.cmu.edu/R/CRAN/src/base/R-2/R-2.12.2.tar.gz
tar -xvzf R-2.12.2.tar.gz
cd R-2.12.2
wget http://biostatmatt.com/R/R-2.12.2-tty+conf.patch
patch -p1 < R-2.12.2-tty+conf.patch
./configure && make