findinglisp wrote:If I remember right, there is an internal ECL function for converting between these two. Hmmm... or maybe that was between a raw Unix file descriptor and a stream, not a C FILE*. Look in the source files for ECL (not that large, actually), and you can probably find it. It's in the C section of the source.
Thanks for the advice! Here's what I got:
- Code: Select all
void
c_stream_to_lisp_stream (cl_object* lisp_stream,
FILE* c_stream,
int* const info)
{
int fd = -1;
/* Get integer file descriptor number for the given C stream.
fileno must always return (under Linux at least), but may return
-1 and set errno to EBADF if it can detect that the given stream
(FILE*) is not valid. */
errno = 0;
fd = fileno (c_stream);
if (errno == EBADF || fd == -1)
{
errno = 0;
*info = -1;
return;
}
/* Make a Lisp stream from the given file descriptor. Note: it had
better be an input stream of some kind, or you'll be sorry!!! */
*lisp_stream = ecl_make_stream_from_fd (Cnil, fd, smm_input);
*info = 0;
}
(I work with LAPACK a lot, so the INFO mutable parameter is my usual way of returning errors in the C world.)
This should work (I haven't tested it yet), but it seems like a kludge. The ECL function ecl_make_stream_from_fd() actually calls fdopen() on the FILE* which lives inside the Lisp stream. It's silly to go from a FILE* to an int and back to a FILE* again. Also, I'm not sure if I have to call fflush() first on the original FILE*, before I push it into Lisp world, as FILE* may buffer or do some other nonobvious things that aren't expressed by the integer file descriptor. I'd much rather work directly with the FILE*. I could just extend the ECL API to create a Lisp stream directly from the FILE*, but I need to do some legal investigation to see whether that would make my code a derivative work of ECL. (ECL is LGPL, but some of my users prefer that my code stay BSD, perhaps because it's common for them to make derivative works out of my code rather than just to invoke it as a library, or perhaps because they need to placate some lawyers or managers.)