Re: C interop to popen

On Wed, 2 Dec 2009 08:54:56 +0000 (UTC), glen herrmannsfeldt
<gah@xxxxxxxxxxxxxxxx> wrote:
Some years ago (about 1990) I was working with HP/UX Fortran,
which has its own C interoperability. Among others, there is
a way to associate a unix file descriptor with a Fortran I/O
unit. I wrote a subroutine that would do popen, use a unix/C
macro to extract the file descriptor, and then open a Fortran
I/O unit. I could then do Fortran I/O (specifically O) to the
pipe. I was a little unsure what would happen on close, as
Fortran would likely fclose() the file instead of pclose(), but
it seemed to work. (The specific use was piping to lpr.)

If you just gave Fortran the fd, it presumably did a close() not an
fclose(). The actual closing of the underlying pipe is the same; in
Unix at the API level pipe opens are the same as any other file opens.
But you probably leaked the memory for the FILE structure -- which
probably doesn't hurt unless you do this zillions of times in one
process (and if you're printing zillions of things, each with its own
cover/banner page, I don't want this running in my shop <G> *).

The only important difference between pclose() and fclose() is that
pclose() returns the termination status of the child, waiting for it
if necessary. Most programs, once they have officially ended = closed
their output to you, terminate immediately or very soon; and if their
output didn't indicate any error, probably terminate successfully; so
the loss of this status probably doesn't matter, except possibly
confusing a later wait() if the same program creates *other* children.
(Although the OP's code, presumably only a testcase or example, didn't
examine the output from the child, just relayed it.)

About all I can think of is to write wrappers for the C functions,
and print out the arguments. Probably with %P for the pointers.

If you mean in C (*printf) that's %p . Specifiers are case-sensitive.

I wonder, though, if some important part of the C I/O library
is not being initialized.

Historically that has sometimes (often?) been an issue for Fortran/C
I/O in general, but I would be a bit surprised it it was particular to
popen/pipes. And I would expect any sane implementator providing C
interop to make it work with the C RTL, although I don't recall and on
a quick search didn't find an explicit requirement to do so.

Also, a nit in the OP's code: it isn't necessary to reduce the len
argument to fgets() by 1 to allow for the terminating null. On some
other C routines you do, but fgets() handles this for you. OTOH it
doesn't hurt, unless you've set the buffer size so exactly one char
matters, which on modern systems would usually be nutso.

(* Actually, this is not as absurd as I make it sound; I once worked
on a system for a then-major financial institution which, among other
things, after close of stock markets each business day generated a
report to a printer at each of several thousand branch offices.)