[comp.binaries.ibm.pc.d] Creating your own stream

raymond@ptolemy.arc.nasa.gov (Eric A. Raymond) (08/15/89)

Having built a windowing system of sorts, I would like to create
streams which would replace the stdio, stdout, and stderr streams.

That is, given a set of primitive I/O functions, can I create a
file-like device which will call these routines?  Then I can redirect
I/O as I please.


For instance:
    my_stream = make_stream(my_getc, my_putc, my_printstring);
                                              ^
                                              +-- for efficiency
    redirect_stream(stderr,my_stream);

    printf(my_stream,"Hello World.\n");


Unfortunately, me thinks this is highly system/compiler dependent (or
rather language dependent; it's a snap in common lisp).

Failing that, can I temporarily (only during program execution)
install a device driver which is part of the program to handle DOS's
stdout/stderr (I believe they're one in the same for DOS) streams?

Failing that, can I suppose I can clobber printf with my own routine
which uses vsprintf.  Similarly with putc.

Flailing that :-), I can just live with using "special versions" of
I/O functions.
-- 
Eric A. Raymond  (raymond@ptolemy.arc.nasa.gov)
G7 C7 G7 G#7 G7 G+13 C7 GM7 Am7 Bm7 Bd7 Am7 C7 Do13 G7 C7 G7 D+13: Elmore James

hughes@math.berkeley.edu (Eric Hughes) (08/16/89)

In article <1961@ptolemy.arc.nasa.gov>, raymond@ptolemy (Eric A. Raymond) writes:
>That is, given a set of primitive I/O functions, can I create a
>file-like device which will call these routines?  Then I can redirect
>I/O as I please.
>
>For instance:
>    my_stream = make_stream(my_getc, my_putc, my_printstring);
>    redirect_stream(stderr,my_stream);
>    printf(my_stream,"Hello World.\n");
>
>Unfortunately, me thinks this is highly system/compiler dependent (or
>rather language dependent; it's a snap in common lisp).

I know of no facility to do this directly, using the interface
that you specify.  That's not the whole story, however.

The DOS function call to do redirection is Int 21h, Function 46h.  It
takes as input two file handles, and the second handle is made to
point to the first one.  This is used in conjunction with the
duplicate handle call (function 45h) to be able to redirect back to
the original.  Germane to your question is that the OS support only
works on file handles, so in order to use this technique you'll have
to use a device driver.  And device drivers, I believe, are only
installable (legally, at least) at boot time, although I have 
heard that some have linked them in manually at the runtime of
an .EXE.

Nevertheless, you said you only needed a "file-like" device.  You
may be able to get this either by altering the system library 
(assuming you have or can get possession of source to it), or by
#define-ing over the I/O routines and testing for redirection yourself.

>Failing that, can I temporarily (only during program execution)
>install a device driver which is part of the program to handle DOS's
>stdout/stderr (I believe they're one in the same for DOS) streams?

Standard output and error are two separate file handles (which are,
incidentally, "always open"), but by default they both point to the
CON device.  They can be redirected independently.

As I mentioned above, temporarily installing drivers is not my idea
of a good time.  But device drivers can be very small, especially if
all they contain is a bunch of far pointers to code in your .EXE
which implements them.

Has anyone here ever linked in a driver themselves?  Just how *is* it
done, anyway?

>Failing that, can I suppose I can clobber printf with my own routine
>which uses vsprintf.  Similarly with putc.

By using this technique, you get portability to boot.  And if you
can get some compiler vendor to add it to their library, it just might
appear in the next standard :-).

Eric Hughes
hughes@math.berkeley.edu   ucbvax!math!hughes