Daniel J. Bernstein's ptyget toolset

The ptyget package is a toolset for running programs in various ways under pseudo-terminals, making programs exhibit their "interactive mode" behaviours in circumstances where they would normally operate in non-interactive mode.

It is, incidentally, notable for exemplifying a very early version of, and one of the few published instances of, Berstein's own never-published "redo" build system. dependon, a command to be found in the .do files in the package, is a clear precursor to redo-ifchange.

What it contains

It comprises several minor tools (background, the obsolete ttydetach, exclon, excloff, and some internal utilities) and three major ones:

ptybandage

ptybandage is what people usually want in a login session. Its primary use case is making programs that are sensitive to whether their standard inputs, outputs, or errors are connected to terminals operate that way even though they are in fact in shell pipelines, or have their standard file descriptors redirected to file.

It takes a command to run (which has to be a proper external command, of course) and runs it in such a way that it thinks that its standard input, output, and error are attached to a terminal, connecting those through to ptybandage's original standard input and output. The command's standard output and error are merged into ptybandage's standard output.

It deals with the nuances of running under job control shells, ensuring that a terminal STOP character not only stops ptybandage but also stops the program running attached to the inner terminal.

ptyrun

ptyrun is what people usually want in TCP network servers. Its primary use case is remote execution environments that have not themselves set up terminals, running programs that don't operate as desired when there's no terminal.

It doesn't expect to be running under a job control shell, and if the command being run receives a stop signal it is simply restarted.

nobuf

nobuf is what people usually want when redirecting standard output to file. Its primary use case is making programs that use the C library's "streams" operate those streams in line buffered mode, the default for the standard input and output streams being block buffered mode if they are not directed to a terminal. Block buffered mode is not useful for (say) a program that generates output progressively, line by line, where one wants to watch that output happen by monitoring additions to the file it is directed to.

Unlike ptybandage, it does not affect standard error. The C library's semantics for standard error are that it is always in not buffered mode, so forcing it not to be block buffered is unnecessary. Programs that look to standard error to decide whether they are "interactive" will not see a terminal if standard error is redirected. Conversely, ptybandage cannot arrange to keep standard output and standard error separate.

Like ptyrun, it doesn't have any special handling for job control.

History

In the 1990s Daniel J. Bernstein wrote a pty package, in order to cheat at nethack. Version 1 of the package was published on 1990-10-10 to comp.sources.unix (volume 23 issues 031 to 036). Rich Salz described it:

This is the Ginsu knife (it slices, it dices, it never rusts) that Dan has been talking about in comp.unix.wixards/internals for some time now. It is a mind-blower.

Version 4 of the package was published on 1992-02-19 to comp.sources.unix (volume 25 issues 127 to 135). It is still locatable on the World Wide Web. Paul Vixie described it at the time:

What can I say? It slices, it dices, it washes dishes, it walks the dog. It "just works", meaning that if you follow the directions you'll get a working package without any pulling of hair or gnashing of teeth or other standard porting activities.

Bernstein later updated this, somewhen on or before 1999-04-07, with a ptyget package, which he announced:

I've put together a new pseudo-tty allocator, ptyget. An alpha version is at ftp://koobera.math.uic.edu/pub/software/ptyget-0.50.tar.gz. There's a ptyget mailing list; to join, send an empty message to djb-ptyget-requests@koobera.math.uic.edu. I designed ptyget's interface from scratch. It's much more modular than pty; the basic pty interface has now been split into three pieces:

ptyget
a tiny, low-level program — the only setuid program in the package — that allocates a new pseudo-tty and passes it to the program of your choice
ptyspawn
another small program that runs a child process under a pseudo-tty, waiting for it to exit and watching for stops
ptyio
another, only slightly larger, program that moves data back and forth

The old Ginsu knife pty is now spelled ptybandage, which is a synonym for ptyget ptyio -t ptyspawn; pty -d, for attaching network programs to pseudo-ttys, is now spelled ptyrun, which is a synonym for ptyget ptyio ptyspawn; and nobuf is a synonym for ptyget ptyio -r ptyspawn -23x. I've split off the session management features into a separate package.

That separate package was the "sess" package, implementing Bernstein's ideas about session management.

Where it is available

Originals

Of course, Google Groups still has the original comp.sources.unix postings. Enjoy shell archives; these are how we used to share our programs with the world, before curl $URL|bash came along and eliminated both portability and human middle-men in one fell swoop.

The aforementioned FTP site at ftp://koobera.math.uic.edu/pub/software/ptyget-0.50.tar.gz has long since been shut down. Bernstein himself has no documentation on his WWW site, nor any indication that the package even still exists. However, it does and the source archive is still published as ptyget-0.50.tar.gz there.

Dru Nelson publishes both pty version 4 and ptyget in source form using GitHub.

There are a few problems with the original packages. One is that they are written in a programming language that effectively does not exist this century. C 1999 and C 2011 compilers are a lot stricter about function declarations (missing and K&R style), const-ness, and other stuff. There are also two long-since defunct BSDisms in the package that prevent it from compiling and working on most modern operating systems: a pseudo-terminal ioctl that sets a "remote mode" that doesn't exist any more (outwith OpenBSD), and the 1980s-style pseudo-terminal device names (again only to be found on OpenBSD nowadays). The "remote mode" is a particular difficulty — nobuf relies upon it.

Fixed versions

Paul Jarc publishes two differently fixed versions of ptyget that attempt to deal with the two long-since defunct BSDisms.

The Daniel J. Bernstein softwares all-in-one toolset has similarly adjusted versions of the tools.

Alternatives

The nosh package comes with workalike ptybandange and ptyrun scripts, which use Laurent Bercot's execline tool and the nosh package's own pseudo-terminal management commands. As of nosh version 1.23 these are available pre-packaged in the nosh-terminal-extras package. (Earlier versions only supplied them to people who built from source.)

A few example uses

Jurjgen Oskam using ptybandage on AIX to feed input from a here document to a program that explicity opens and read its controlling terminal for a password prompt:

$ ptybandage dsmadmc <<EOF >uit.txt
joskam
password
query session
query process
quit
EOF

Andy Bradford using ptyrun on OpenBSD under daemontools and ucspi-tcp to make the bgplgsh interactive router control program accessible via the network whilst making it think that it is talking to a terminal:

#!/bin/sh
exec 2>&1
exec envuidgid rviews tcpserver -vDRHl0 0 23 ptyrun /usr/bin/bgplgsh

© Copyright 2016 Jonathan de Boyne Pollard. "Moral" rights asserted.
Permission is hereby granted to copy and to distribute this web page in its original, unmodified form as long as its last modification datestamp information is preserved.