Subject: fmemopen(3C) implementation
To: None <tech-userlevel@netbsd.org>
From: Bruce Korb <bkorb@veritas.com>
List: tech-userlevel
Date: 02/14/2004 14:46:38
Hello,

I've reimplemented an fmemopen that makes handling stream i/o to buffers
fairly simple to handle.  Leastwise, it does for my pet project.  I herewith
offer it for your consideration.  The source can be found here:

http://cvs.sf.net/viewcvs.py/*checkout*/autogen/autogen/agen5/fmemopen.c?content-type=text%2Fplain&rev=HEAD

and the formatted man page follows.  If you-all are interested, I'll fix it
up for a proper submission for your code.  [[NOTE: if the above file looks
too much like it only works with glibc, then you've beaten the source forge
update.  There is a delay of some hours, as I recall....]]

Cheers  - Bruce

NAME
       fmemopen - Open a stream to a string

SYNOPSIS
       #include <libfmem.h>
       cc [...] -o outfile infile.c -lfmem [...]

       FILE* fmemopen(void* buf, size_t len, char* mode);

DESCRIPTION
       If  buf  is NULL, then a buffer is allocated.  It is allo-
       cated to size len, unless that is zero.  If len  is  zero,
       then  getpagesize()  is  used  and the buffer is marked as
       "extensible".  Any  allocated  memory  is  free()-ed  when
       fclose(3C) is called.

       The  mode  string is interpreted as follows.  If the first
       character of the mode is:

       a Then the string is opened in "append" mode.  Append mode
       is  always  extensible.   In binary mode, "appending" will
       begin from the end  of  the  initial  buffer.   Otherwise,
       appending  will  start  at  the first NUL character in the
       initial buffer (or the end of the buffer if  there  is  no
       NUL character).

       w Then the string is opened in "write" mode.  Writing (and
       any reading) start at the beginning of the buffer.  If the
       buffer  was supplied by the caller and it is allowed to be
       extended, then the initial buffer may or may not be in use
       at any point in time, and the user is responsible for han-
       dling the disposition of the initial memory.

       r Then the string is opened in "read" mode.

       If it is not one of these three, the open fails and  errno
       is  set  to  EINVAL.  These initial characters may be fol-
       lowed by:

       + The buffer is marked as extensible and both reading  and
       writing is enabled.

       b  The  I/O  is marked as "binary" and a trailing NUL will
       not be inserted into the buffer.

       x This is ignored.

       Any other letters following the inital  'a',  'w'  or  'r'
       will cause an error.

       buf    buffer to use for i/o
       len    size of the buffer
       mode   mode string, a la fopen(3C)

RETURN VALUE
       a stdio FILE* pointer

ERRORS
       NULL is returned and errno is set

SEE ALSO
       The info documentation for the -lfmem library.
       fmem_ioctl(3)

===================================================================

NAME
       fmem_ioctl - get information about a string stream

SYNOPSIS
       #include <libfmem.h>
       cc [...] -o outfile infile.c -lfmem [...]

       void fmem_ioctl(FILE* fptr, int req, void* ptr);

DESCRIPTION
       This  routine  surreptitiously slips in a special request.
       The commands supported are:  FMEM_IOCTL_BUF_ADDR  Retrieve
       the  address  of  the buffer.  Future output to the stream
       might cause this buffer  to  be  freed  and  the  contents
       copied to another buffer.  You must ensure that either you
       have saved the buffer (see FMEM_IOCTL_SAVE_BUF below),  or
       do  not  do  any  more  I/O to it while you are using this
       address.

       FMEM_IOCTL_SAVE_BUF Do not deallocate the buffer on close.
       You  would  likely  want to use this after writing all the
       output data  and  just  before  closing.   Otherwise,  the
       buffer might get relocated.  Once you have specified this,
       the current buffer becomes the client  program's  resposi-
       bility to free().

       The third argument is never optional and must be a pointer
       to where data are to be retrieved or stored.   It  may  be
       NULL if there are no data to transfer.

       fptr   the string stream
       req    the requested data
       ptr    ptr to result area

ERRORS
       non-zero is returned and errno is set.

SEE ALSO
       The info documentation for the -lfmem library.
       fmemopen(3)