chris@mimsy.UUCP (Chris Torek) (05/20/88)
(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@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@comp.vuw.ac.nz> andrew@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@mimsy.umd.edu Path: uunet!mimsy!chris
chris@mimsy.UUCP (Chris Torek) (05/20/88)
In article <11582@mimsy.UUCP> I wrote: > char (*_cookie)(); /* for lack of void* */ Oops, that should be char *cookie; /* for lack of void* */ -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
sullivan@vsi.UUCP (05/20/88)
Does anybody else find it ironic that IBM doesn't want to be tied down to a single vendor's standard, and to avoid that will make its own clone of that standard? Why is IBM expecting AT&T to act in a way that IBM won't act regarding PS/2? -- Michael Sullivan {uunet|attmail}!vsi!sullivan sullivan@vsi.com HE V MTL Anybody out there remember Max Webster?
scs@athena.mit.edu (Steve Summit) (06/02/88)
In article <11582@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >As for obtaining it: that is somewhat difficult. funopen() is >based upon the existing 4.3BSD stdio... >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. I've been meaning to respond to this stdio discussion for a while: I started writing a stdio replacement based on exactly this idea. I'd assumed I'd post it when I was finished with it, but I haven't worked on it in a while. I do know that it runs well enough for me to have linked RCS against it to get RCS to work on my v7 pdp11, which didn't have fopen("w+"). I suppose it wouldn't take much to convince me to cast it to the four winds "as is"... Steve Summit scs@adam.pika.mit.edu