memstream — POSIX memory streams for BSD

memstream.c is an implementation of the POSIX function open_memstream() for BSD and BSD-like operating systems. The open_memstream() function is very useful but its absence on the Three BSDs (and Darwin) makes it difficult to justify in portable programs. The implementation offered here has been tested on Darwin (Mac OS X 10.6 and 10.8).

To use it, compile makestream.c and link the object with your program. On a recent GNU/Linux machine the object file will be empty (the open_memstream() function is part of libc). On anything derived from 4.4BSD (Darwin, the Three BSDs, etc.) it will contain an implementation of open_memstream() as described in the Linux manual pages. On anything else it will probably cause a compilation error.

Download the source code: memstream-0.1.tar.gz
Browse the source code: memstream-0.1

In lieu of a proper manual page, please accept this pilfered and slightly midofied version of the POSIX manual page.

    open_memstream - open a dynamic memory buffer stream

    #include "memstream.h"

    FILE *open_memstream(char **bufp, size_t *sizep);


    The  open_memstream() function creates  an I/O  stream associated  with a
    dynamically-allocated memory buffer.  The stream is byte-oriented, opened
    for writing and seekable.

    The stream  maintains a  current position in  the allocated buffer  and a
    current buffer length.  The position  is initially set to zero (the start
    of the buffer).  Each write to  the stream starts at the current position
    and moves this position by the number of successfully-written bytes.  The
    length is  initially set  to zero.  If  a write  moves the position  to a
    value larger than  the current length, the current length  is set to this
    position.   In this  case a  null character  is appended  to  the current
    buffer.  The terminating  null is not included in  the calculation of the
    buffer length.

    After a successful  fflush() or fclose(), the pointer  referenced by bufp
    contains the address of the buffer,  and the variable pointed to by sizep
    contains the  current buffer length.  During fclose()  the current buffer
    length is set to the smaller  of the current buffer length and the number
    of  bytes  between the  beginning  of the  buffer  and  the current  file
    position indicator.

    After  a successful  fflush()  the  pointer referenced  by  bufp and  the
    variable  referenced by  sizep remain  valid  only until  the next  write
    operation on the stream or a call to fclose().

    Upon  successful completion,  open_memstream() returns  a pointer  to the
    object controlling  the stream.  Otherwise,  a null pointer  is returned,
    and errno is set to indicate the error.

    After a successful  fclose() the caller must reclaim  the storage used by
    the buffer, when it is no longer needed, by calling free().

        bufp or sizep are NULL.

        Memory for the stream or the buffer could not be allocated.
(The Linux manual page for open_memstream() says more or less the same thing, in a woollier fashion.)

memstream is distributed under the MIT license. It will not infect your project with a contagious disease if you decide to use it.

If you find bugs or have suggestions, please send them to Ian at the domain name of this web site. Thanks!

Version history

2013-08-17 memstream-0.1
First release. Written to support a weekend project and tested very little outside of that context. Bugs could well be present.