Go to file
Jonathan Wakely a19f3e0c7c Fix sporadic test failure
One of the tests in test_pstreams.cc assumes that two adjacent 'date'
commands will produce the same output, but that's not true if the clock
happens to tick to a new second between the commands. This is very
unlikely to happen when run interactively, but is more likely on CI
systems that are slow, heavily loaded, shared by many processes, or all
of the above. Change the test to allow one second differences, but also
print out the times so that the logs will show why it failed if for some
reason the process stalls for more than a second.
2023-04-11 12:31:43 +01:00
images Added file back, with -kb option for binary file. 2001-12-13 02:15:11 +00:00
.cvsignore Add MANIFEST. 2004-10-17 15:44:05 +00:00
.gitignore Version 0.8.1 release. 2014-02-07 13:07:53 +00:00
AUTHORS Update email address 2018-10-19 10:52:37 +01:00
Doxyfile doc: Update Doxyfile using Doxygen 1.9.5 2022-09-29 13:00:51 +01:00
INSTALL.md INSTALL.md: Actually use markdown this time 2020-03-05 15:57:16 +00:00
LICENSE_1_0.txt Change licence and release version 1.0.1 2017-02-02 13:04:40 +00:00
Makefile Improve output of 'make check' target 2022-09-29 12:39:19 +01:00
README Change name in README 2017-02-02 13:29:54 +00:00
mainpage.html Regenerate HTML for 1.0.3 release 2020-06-10 20:24:47 +01:00
pstream.h pstream.h: Fix -Wenum-conversion warnings 2022-07-25 21:11:47 +01:00
pstream_compat.h Add SPDX license identifiers and update copyright dates 2020-06-10 20:25:09 +01:00
pstreams-devel.spec Copy latest spec file from Fedora 2022-09-29 13:00:54 +01:00
test_compat.cc Merge with old_popen-branch. 2004-03-30 11:51:26 +00:00
test_minimum.cc Remove outdated TODO comments. 2012-06-25 22:20:48 +01:00
test_pstreams.cc Fix sporadic test failure 2023-04-11 12:31:43 +01:00


PStreams README file

Release notes for recent versions
The PStream Buffer class
Signalling and Termination
The Good, the Bad and the Ugly


This is the README file for PStreams, a C++ utility for simple IOStream-based
Inter-Process Communication. PStreams is a tool. Not the most efficient or
flexible method of IPC, but fairly simple and IOStream-based, with all the
advantages that provides. I hope you find it useful.

PStreams is free software, see the file LICENSE_1_0.txt for copying permission.
The latest version can be found at http://pstreams.sourceforge.net/ and
frequently asked questions at http://pstreams.sourceforge.net/faq.html
The author can be contacted at pstreams@kayari.org

To use the PStreams classes copy the required header files to somewhere
your compiler can find them and #include them. The headers are commented
so that API documentation to be generated using Doxygen

This file contains some notes on PStreams, but is quite incomplete. There may
be some notes here that aren't covered in the API documentation, but see
those docs for most questions about usage (or at least, how things _should_

To run the test program compile and run test_pstreams.cc
This can be done with "make check" if you have GNU or BSD make.
The Makefile doesn't work with Solaris make, and probably other versions
of make.

Release notes for PStreams 1.0.1

The library is now licensed under the Boost Software License instead of
the GNU LGPL. There are no other changes in this release.

Release notes for PStreams 1.0.0

The only significant change since the 0.8.1 release is a workaround for a
bug in older versions of the GCC C++ standard library which allowed null
pointers to be passed to the memmove() function.

Release notes for PStreams 0.8.1

The change in version 0.8.0 that caused the child process to be put in
a new process group could prevent the child from exiting when the parent
process was killed by a signal. In version 0.8.1 it is still possible to
create a new process group for the child, but that must be explicitly
requested by setting the pstreams::newpg flag in the pmode argument
used to create the new process.

Release notes for PStreams 0.8.0

The child process will now switch to a new process group, with the
process group ID the same as the PID.  The basic_pstreambuf::killpg()
member function has been added to send a signal to the child's process

New constructors to simplify the common case where the string specifying
the file to be executed is the same as the first element of the argv_type

Fixes for compatibility with Clang++ and _FORTIFY_SOURCE.

Release notes for PStreams 0.7.0

When opening a pstream for reading with mode pstderr, the pstdout mode is
no longer added, and the initial read source will be set the the child
process' stdout stream.

The RPM spec file from the Fedora pstreams-devel package is now included.

Release notes for PStreams 0.6.0

The Library's licence has changed to LGPL version 3.

If the read buffer is empty pstreambuf::in_avail() now performs a
non-blocking read to fetch only as many characters as are available.
This means that istream::readsome() won't block and can be used to test
if characters are available on the child process' stdout or stderr pipes
without blocking.

Release notes for PStreams 0.5.2

Support for streambuf::in_avail() added for platforms that support the
FIONREAD ioctl request (known to work on Linux, FreeBSD and Solaris.)

It is now possible to detect when the shell command failed to execute,
as long as you open the pstream using the functions taking argv_type. If
the command is not found or cannot be executed then pstreambuf::is_open()
will return false.  This makes it possible to distinguish the cases where
the command cannot be run and when it runs but exits with an error.

Release notes for PStreams 0.5.0

Version numbering changed to the GNU-style major.minor.patchlevel scheme.
The PSTREAMS_VERSION macro has jumped to 0x0050, 1.0.0 will still be 0x0100.
The current release would have been 0.50 with the old scheme.

Because all names ending in _t are reserved by POSIX, the pstreambuf::fd_t
typedef has been renamed to fd_type. The fd_t name is still available, but
is deprecated and will be removed soon. If you've used that type in your
code please change it to fd_type (which is a better name anyway).  There
is also a new argv_type typedef for std::vector<std::string>, the type
used to hold the argument list for a command. Thanks to Tommi Maekitalo
for the argv_type suggestion.

Added a FAQ, which is very incomplete.

Thanks to Jez Bromley, Brett Williams, Danny Aizer and everyone else who
has helped.

The pstreambuf class will soon be split into separate process control and
stream buffer classes, thanks to Angus Leeming.
Possible Win32 version coming as well, thanks to Francis Andre.

Release notes for PStreams 0.49

Seek operations on the streams are not supported. Trying to seek on a
PStream object will cause std::ios_base::failbit to be set, requiring
a call to std::basic_ios::clear() to clear the stream state and allow
further I/O to take place. This behaviour is analogous to calling
std::fseek() on a pipe, which always fails and sets errno to ESPIPE
("Illegal seek").

Fixed memory and file descriptor leaks that occurred if wait() reported
the process had exited without close() having been called. Writing to
process that has already exited no longer raises SIGPIPE.

Fixed a serious bug where switching between reading stdout and stderr
didn't update the streambuf's read position to point into the correct

Jez Bromley has found that the eviscerated PStreams can not be used with
the alpha's native cxx compiler in strict_ansi mode. To workaround this
don't use strict_ansi and define __USE_STD_IOSTREAM to get the standard
IOStream classes.

Release notes for PStreams 0.48

This release includes changes to allow PStreams to be used with G++ 3.4,
which is far more standards compliant that previous releases and caught
several bugs in the code. Let me know if you have any problems.

I've removed the rpstream.h header and moved the definition of the
redi::rpstream class into pstream.h. This is now the only file needed.
Please ensure you remove any copies of rpstream.h from your system if
you're using this release.

Fixed a 64-bit bug where int was compared to a pointer.

The redi::peof IO manipulator now uses dynamic_cast not static_cast.
This is safer, but if you don't want to use dynamic_cast you'll have to
change it back to using static_cast.

Use POSIX's ::_exit() instead of std::exit() to terminate child if exec()
fails. This will prevent static destructors being run in the child process
(which could try to destroy resources twice).

I've also changed the macro that guards the pstream.h header from being
included multiple times, by appending "_SEEN" to the names. If this
causes any problems make sure you don't have any old versions of pstream.h
on your system.

This release has been long overdue and it shouldn't be as long before the
next one. I have some good suggestions to incorporate.

Thanks to everyone who suggested fixes and improvements, or just got
in touch to say they were using the code.

Jonathan Wakely

The PStream Buffer class
The pstreambuf used by the PStreams classes buffers all reads and writes
as of version 0.42 (released 2002-12-03).

Signalling and Termination
The pstreambuf class now provides a kill(int) member function which is
similar to the C library call and allows signals to be sent to the child.
The stream buffer class also provides an exited() member which will return
true if the child process has terminated, and a status() member which returns
the exit status of the child. This exit status can be evaluated using
the WIFEXITED() and related macros as with the C library function waitpid().

The Good, the Bad and the Ugly
PStreams is intended to be a clean design based on the standard IOStreams,
but first and foremost it's a handy little tool, and so should be as useful
as possible. Because it is not always possible to redesign a program to use
IOStreams instead of C-style I/O it is possible to expose some internal
details of the PStreams classes. If the macro REDI_EVISCERATE_PSTREAMS has
a non-zero value then the following public method is added to each stream

pmode fopen(FILE*& in, FILE*& out, FILE*& err);

    Obtains FILE pointers relating to each open pipe to the process and
    assigns them to the corresponding FILE* parameters.

These functions should be used with caution because mixing C++ and C I/O
on the same stream may cause problems. The caller should be aware of the
issues involved in using the stream buffer's FILE pointer (see your system's
docs for the fdopen() function that is used by the pstreambuf).
The fdopen() call to obtain a FILE* sets errno to ESPIPE because fdopen()
tries to lseek() on the stream, which is not supported on pipes. This error
is expected and does not cause a problem, so errno is set to zero before
returning from pstreambuf::fopen().

$Id: README,v 1.21 2010/05/12 13:33:54 redi Exp $
:vim: set tw=78