fmemopen: portable version?

M

Markus Dehmann

In the GNU C library (stdio.h), there is a function
FILE* fmemopen (void *buf, size_t size, const char *opentype)

It opens a FILE stream that allows read or write access to the buffer
buf.

Does anyone know how to implement this so that it can also be used on
non-GNU systems? Only read access would be okay.

Thanks
Markus
 
W

William Ahern

Markus Dehmann said:
In the GNU C library (stdio.h), there is a function
FILE* fmemopen (void *buf, size_t size, const char *opentype)

It opens a FILE stream that allows read or write access to the buffer
buf.

Does anyone know how to implement this so that it can also be used on
non-GNU systems? Only read access would be okay.

There's no way to do it in ISO C. If you're a glutton for punishment you
could override and provide custom implementations for fopen(), fread(),
fwrite(), fscanf(), et al, but you can't even manage that in a uniform way
across different Unices. And in any event that is _way_ beyond the scope of
anything standard C.

glibc has a peculiar (or not according to your persuasion) implementation
where fopen() maps a file into memory (using mmap()). Things like fscanf()
read from memory rather than doing lower-level platform I/O. fmemopen(), it
would seem, is a trap-door into this behavior.
 
E

Eric Sosman

Markus said:
In the GNU C library (stdio.h), there is a function
FILE* fmemopen (void *buf, size_t size, const char *opentype)

It opens a FILE stream that allows read or write access to the buffer
buf.

Does anyone know how to implement this so that it can also be used on
non-GNU systems? Only read access would be okay.

There is no Standard C facility specifically designed
for this purpose. However, the Standard does not specify
the form or meaning of the file name string passed to plain
fopen(), so if the system attaches special meaning to file
names like "/proc/pid/as" you might be able to do what you
want. Highly non-portable, of course, and likely to be
tricky even on systems where it "works."
 
M

Malcolm

Markus Dehmann said:
In the GNU C library (stdio.h), there is a function
FILE* fmemopen (void *buf, size_t size, const char *opentype)

It opens a FILE stream that allows read or write access to the buffer
buf.

Does anyone know how to implement this so that it can also be used on
non-GNU systems? Only read access would be okay.
Unfortunately there's no way to do this in ANSI C. I did suggest adding a
function to the standard library that would allow you to define your own
fputc / fgetc for a stream and then pass it to the stdio functions, but no
one took it up.
In C++ you can do this, in theory, by deriving a class from iostream.
 
R

Richard Tobin

Markus Dehmann said:
Does anyone know how to implement this so that it can also be used on
non-GNU systems? Only read access would be okay.

FILE *fmemopen (void *buf, size_t size, const char *opentype)
{
FILE *f;

assert(strcmp(opentype, "r") == 0);

f = tmpfile();
fwrite(buf, 1, size, f);
rewind(f);

return f;
}

On any particular implementation you may be able to work out how to
manually construct a FILE object that does what you want. For example,
on the system I'm using FILE is a struct which in part contains this:

/* operations */
void *_cookie; /* cookie passed to io functions */
int (*_close) __P((void *));
int (*_read) __P((void *, char *, int));
fpos_t (*_seek) __P((void *, fpos_t, int));
int (*_write) __P((void *, const char *, int));

I imagine that it would work if you set the cookie to the address of
your buffer and provided suitable functions for _read etc.

But of course if you want your code to be portable, you will have
to work this out for every system you care about.

-- Richard
 
D

Dave Thompson

Markus Dehmann said:
[glibc fmemopen] opens a FILE stream [on memory]
Unfortunately there's no way to do this in ANSI C. I did suggest adding a
function to the standard library that would allow you to define your own
fputc / fgetc for a stream and then pass it to the stdio functions, but no
one took it up.
In C++ you can do this, in theory, by deriving a class from iostream.
<OT> For what is usually wanted when this question is asked,
the better answer in C++ is to implement your own child of streambuf,
which is then used by standard {i,o,io}stream. </>

- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top