functional stdio
Chris Torek
chris at mimsy.UUCP
Fri May 20 05:03:10 AEST 1988
(The subject is something of a pun. Doug Gwyn answered the varargs-related
questions, and this is now focussed on stdio applied to functions.)
>In article <11439 at mimsy.UUCP> I mentioned my funopen():
>> FILE *funopen(void *cookie,
<relatively complex types, only one shown:>
int (*readfn)(void *cookie, char *buf, int nbytes),
writefn, seekfn, closefn)
In article <13621 at comp.vuw.ac.nz> andrew at comp.vuw.ac.nz (Andrew Vignaux)
writes:
>How {,un}standard is it? How can I get it?
Well, let me see. It runs on gyre, and mimsy, and brillig, and tove;
that makes four machines, out of what, perhaps several tens of thousands?
As you can see, it is immensely popular :-) . Oh yes, and rhodes: must
not forget rhodes.cs.umd.edu. Make that five machines.
As for obtaining it: that is somewhat difficult. funopen() is
based upon the existing 4.3BSD stdio. It is not much code in and
of itself, and I might be able to make up context diffs, if not
for some other work I did as well. I am afraid there is rather a
lot of difference now. With any luck some version of this will appear
in 4.4BSD; in the meantime, the intrepid but impatient stdio hacker
can add funopen() and its variants with just a little work. The
key is to add the following five members to `struct _iobuf':
char (*_cookie)(); /* for lack of void* */
int (*_read)();
int (*_write)();
long (*_seek)();
int (*_close)();
You will then need to put the following function and its obvious
analogues into one or several files:
int
_stdioread(cookie, buf, n)
char *cookie, *buf;
int n;
{
return (read(fileno((FILE *)cookie), buf, n));
}
and change the various places within /usr/src/lib/libc/stdio/*.c
that call `read', `write', `seek', and `close' from
n = read(iop->_file, iop->_base, iop->_bufsize);
to
n = (*iop->_read)(iop->_cookie, iop->_base, iop->_bufsize);
You will also have add to fopen.c and fdopen.c:
iop->_cookie = (char *)iop;
if (rwmode == readonly || rwmode == readwrite)
iop->_read = _stdioread;
else
iop->_read = NULL;
if (rwmode == writeonly || rwmode == readwrite)
iop->_write = _stdiowrite;
else
iop->_write = NULL;
iop->_seek = _stdioseek;
iop->_close = _stdioclose;
and of course these functions must be declared. Writing funopen.c
becomes trivial; all it need do is ensure that at least a read or
a write function is given, and calculate the proper flags, and so
forth. fseek.c must also ensure that a seek function exists
(iop->_seek!=NULL), and return an error if not.
The last task is to set up the descriptors for stdin, stdout, and
stderr properly; to aid this I included the following in the new
<stdio.h>:
/* help stdio source generate initial values for stdin, stdout, & stderr */
#ifdef _CONSTRUCT_IOB
#define STD_IOB(flag, file, cookie, r, w, s, c) \
{ 0, NULL, NULL, 0, flag, file, cookie, r, w, s, c }
/*cnt ptr base size flag fileno */
#endif
It might be nice if you also fixed the various sins in the existing
functions (for instance, try fprintf or fwrite on stdin!). But that
is the larger task.
>I can't quite pick up the semantics of funopen() from the declaration. My
>guess is that the f{whatever}open function performs the appropriate open,
>packages whatever info the virtual functions will need into a cookie record,
>and then returns the result of funopen()--or am I completely wrong again :-(.
This is correct: the cookie is implicit for fopen and fdopen (whatever
stdio needs for its internal functions---in this case iop itself), and
is explicit in the case of funopen (where the cookie is just passed on
to the io functions).
>Where/how do you describe the `open' call ... ?
That is unnecessary: it is implicit from the fact that the stream is
open in the first place. The open is given by the creation of the
stream (in principle, immediately before funopen()).
>Is there a funreopen() (for those cases where you want to
>change functions in mid-stream :-)?
No: if you intend to apply several functions, you must define a
wrapper function that knows when to switch.
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: chris at mimsy.umd.edu Path: uunet!mimsy!chris
More information about the Comp.unix.questions
mailing list