From: glen herrmannsfeldt on
Tobias Burnus <burnus(a)net-b.de> wrote:
> On 12/02/2009 08:38 AM, David Duffy wrote:
>> I am a bit confused by the following example, which tries to call the
>> unix (linux) popen(), fgets(), pclose(). It works as I would expect
>> when compiled by g95, but the gfortran compiled code hangs around the first
>> fgets()

> Well, the reason why you are confused is because you looked at the wrong
> spot.

>> call get_command(lin)
>> if (lin == ' ' .or. lin == '-h' .or. lin == '--help') then
> [...]
>> fp%handle = popen(trim(lin) // C_NULL_CHAR, [...]

> You assume that g95 returns the same result as gfortran for
> get_command(). If I call "./a.out echo" then g95's get_command returns
> lin == "echo" while gfortran, NAG, ifort, and open95 return "./a.out echo".

> Thus you are popening your program all the time when compiling with
> gfortran ...

In that case, it should recursively popen() until it runs
out of something and popen() fails. That would seem to indicate
that the test for success on popen() isn't working.

I presume the c_associated() test is right. In C, you just do:

while(fgets(...)) { /* process the line */ }

-- glen

-- glen
From: m_b_metcalf on
On Dec 2, 8:38 am, David Duffy <dav...(a)orpheus.qimr.edu.au> wrote:

>and sunf95 gives
>INTERNAL COMPILER ERROR around c_associated(fgets(lin,
>clen, fp%handle).


This should be reported to Sun as it's a clear compiler error.

Regards,

Mike Metcalf
From: robert.corbett on
On Dec 2, 1:31 am, m_b_metcalf <michaelmetc...(a)compuserve.com> wrote:
> On Dec 2, 8:38 am, David Duffy <dav...(a)orpheus.qimr.edu.au> wrote:
>
> >and sunf95 gives
> >INTERNAL COMPILER ERROR around c_associated(fgets(lin,
> >clen, fp%handle).
>
> This should be reported to Sun as it's a clear compiler error.
>
> Regards,
>
> Mike Metcalf

I filed a bug report. It is CR 6906888.

Bob Corbett
From: David Thompson on
On Wed, 2 Dec 2009 08:54:56 +0000 (UTC), glen herrmannsfeldt
<gah(a)ugcs.caltech.edu> wrote:
<snip>
> 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.)