More about disabling standard I/O buffering
In yesterday's article I
described a simple and useful feature that could have been added to
the standard I/O library, to allow an environment variable to override
the default buffering behavior. This would allow the invoker of a
program to request that the program change its buffering behavior even
if the program itself didn't provide an option specifically for doing
Simon Tatham directed me to the GNU Coreutils
which does something of this sort. It is rather like the
pseudo-tty-pipe program I described, but instead of using the
pseudo-tty hack I suggested, it works by forcing the child program to
a custom replacement for
There appears to be a very similar command in FreeBSD.
Roderick Schertler pointed out that Dan Bernstein wrote a utility
pty, in 1990, atop which my
pseudo-tty-pipe program could
easily be built; or maybe its
ptybandage utility is exactly what I
wanted. Jonathan de Boyne Pollard has a page explaining it in
detail, and related
A later version of
pty is still
Here's M. Bernstein's blurb about it:
ptyget is a universal pseudo-terminal interface. It is designed to be
used by any program that needs a pty.
ptyget can also serve as a wrapper to improve the behavior of existing
programs. For example,
ptybandage telnet is like
be put into a pipeline.
nobuf grep is like
grep but won't
block-buffer if it's redirected.
Previous pty-allocating programs —
expect, etc. — have caused dozens of security problems.
There are two fundamental reasons for this. First, these programs are
installed setuid root so that they can allocate ptys; this turns every
little bug in hundreds of thousands of lines of code into a potential
security hole. Second, these programs are not careful enough to
the pty from access by other users.
ptyget solves both of these problems. All the privileged code is in
tiny program. This program guarantees that one user can't touch
ptyget is a complete rewrite of
pty 4.0, my previous pty-allocating
pty 4.0's session management features have been split off
a separate package,
Leonardo Taccari informed me that NetBSD's
has the environment variable feature I was asking for! Christos
Zoulas suggested adding
stdbuf similar to the GNU and FreeBSD
implementations, but the NetBSD people observed, as I did, that it
would be simpler to just control
stdio directly with an environment
variable, and did it. Here's the relevant part of the NetBSD
The default buffer settings can be overwritten per descriptor
STDBUFn) where n is the numeric value of the file descriptor
represented by the stream, or for all descriptors (
environment variable value is a letter followed by an optional
numeric value indicating the size of the buffer. Valid sizes range
from 0B to 1MB. Valid letters are:
L line buffered
F fully buffered
Here's the discussion from the NetBSD
The actual patch looks almost exactly the way I imagined it would.
Finally, Mariusz Ceier pointed out that there is an ancient bug report in
suggesting essentially the same environment variable mechanism that I
suggested and that was adopted in NetBSD. The suggestion was firmly
and summarily rejected. (“Hell, no … this is a terrible idea.”)
Interesting wrinkle: the bug report was submitted by Pádraig Brady,
who subsequently wrote the
stdbuf command I described above.
Thank you, Gentle Readers!
[Other articles in category /Unix]