From: David Duffy on 2 Dec 2009 02:38 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(), #0 0xb7fcd424 in __kernel_vsyscall () #1 0xb7f091e3 in read () from /lib/i686/cmov/libc.so.6 #2 0xb7ea2fde in _IO_file_underflow () from /lib/i686/cmov/libc.so.6 #3 0xb7ea4d3b in _IO_default_uflow () from /lib/i686/cmov/libc.so.6 #4 0xb7ea62f2 in __uflow () from /lib/i686/cmov/libc.so.6 #5 0xb7e98c96 in _IO_getline_info () from /lib/i686/cmov/libc.so.6 #6 0xb7e98be1 in _IO_getline () from /lib/i686/cmov/libc.so.6 #7 0xb7e97aea in fgets () from /lib/i686/cmov/libc.so.6 and sunf95 gives INTERNAL COMPILER ERROR around c_associated(fgets(lin, clen, fp%handle). Unfortunately g95 seems fairly forgiving when I do stupid things interoperating with C. ! ! Fortran interface to popen ! module fpipes use, intrinsic :: ISO_C_BINDING type, public :: streampointer type (c_ptr) :: handle = c_null_ptr end type streampointer ! popen interface function popen(path, mode) bind(C, name='popen') use, intrinsic :: ISO_C_BINDING character(kind=c_char), dimension(*) :: path, mode type (c_ptr) :: popen end function end interface ! fgets interface function fgets(buf, siz, handle) bind(C, name='fgets') use, intrinsic :: ISO_C_BINDING type (c_ptr) :: fgets character(kind=c_char), dimension(*) :: buf integer(kind=c_int), value :: siz type (c_ptr), value :: handle end function end interface ! pclose interface function pclose(handle) bind(C, name='pclose') use, intrinsic :: ISO_C_BINDING integer(c_int) :: pclose type (c_ptr), value :: handle end function end interface end module fpipes ! ! Main program ! program test use fpipes integer, parameter :: BUFLEN=50000 character(len=BUFLEN) :: lin character (len=3) :: mode integer (kind=c_int) :: clen integer :: eos, i type(streampointer) :: fp call get_command(lin) if (lin == ' ' .or. lin == '-h' .or. lin == '--help') then write(*,'(a)') 'Usage: run-process <command>' stop end if clen=BUFLEN-1 mode='r' fp%handle = popen(trim(lin) // C_NULL_CHAR, trim(mode) // C_NULL_CHAR) if (.not.c_associated(fp%handle)) then write(*,*) 'ERROR: Could not open pipe!' stop else write(*,*) 'Opened pipe successfully' end if do while (c_associated(fgets(lin, clen, fp%handle))) eos=2 do i=1, BUFLEN if (lin(i:i) == C_NULL_CHAR) then eos=i-2 exit end if end do write(*,*) eos, ': "', trim(lin(1:eos)), '"' end do ios = pclose(fp%handle) end program test -- | David Duffy (MBBS PhD) ,-_|\ | email: davidD(a)qimr.edu.au ph: INT+61+7+3362-0217 fax: -0101 / * | Epidemiology Unit, Queensland Institute of Medical Research \_,-._/ | 300 Herston Rd, Brisbane, Queensland 4029, Australia GPG 4D0B994A v
From: Tobias Burnus on 2 Dec 2009 03:31 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 ... Tobias
From: Reinhold Bader on 2 Dec 2009 03:37 Hello, David Duffy schrieb: > 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(), > > #0 0xb7fcd424 in __kernel_vsyscall () > #1 0xb7f091e3 in read () from /lib/i686/cmov/libc.so.6 > #2 0xb7ea2fde in _IO_file_underflow () from /lib/i686/cmov/libc.so.6 > #3 0xb7ea4d3b in _IO_default_uflow () from /lib/i686/cmov/libc.so.6 > #4 0xb7ea62f2 in __uflow () from /lib/i686/cmov/libc.so.6 > #5 0xb7e98c96 in _IO_getline_info () from /lib/i686/cmov/libc.so.6 > #6 0xb7e98be1 in _IO_getline () from /lib/i686/cmov/libc.so.6 > #7 0xb7e97aea in fgets () from /lib/i686/cmov/libc.so.6 > > and sunf95 gives > INTERNAL COMPILER ERROR around c_associated(fgets(lin, > clen, fp%handle). I can reproduce this for SS 12U1. > > Unfortunately g95 seems fairly forgiving when I do stupid things > interoperating with C. I think there is a difference in how different compilers execute the subroutine get_command(). In particular, g95 appears to not include the name of the executed command itself in the returned string; from the description in the standard I consider this to be a bug in g95. Replacing the call by call get_command_argument(1,lin) which I think is nearer to the semantics you want anyway, things seem to be fine for ifort, nagfor, gfortran. Regards Reinhold >
From: glen herrmannsfeldt on 2 Dec 2009 03:54 David Duffy <davidD(a)orpheus.qimr.edu.au> 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(), > #0 0xb7fcd424 in __kernel_vsyscall () > #1 0xb7f091e3 in read () from /lib/i686/cmov/libc.so.6 > #2 0xb7ea2fde in _IO_file_underflow () from /lib/i686/cmov/libc.so.6 > #3 0xb7ea4d3b in _IO_default_uflow () from /lib/i686/cmov/libc.so.6 > #4 0xb7ea62f2 in __uflow () from /lib/i686/cmov/libc.so.6 > #5 0xb7e98c96 in _IO_getline_info () from /lib/i686/cmov/libc.so.6 > #6 0xb7e98be1 in _IO_getline () from /lib/i686/cmov/libc.so.6 > #7 0xb7e97aea in fgets () from /lib/i686/cmov/libc.so.6 (snip of actual code) It looks fine to me. 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.) 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. I wonder, though, if some important part of the C I/O library is not being initialized. -- glen
From: David Duffy on 2 Dec 2009 04:12 Tobias Burnus <burnus(a)net-b.de> wrote: > On 12/02/2009 08:38 AM, David Duffy wrote: > 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 ... Indeed this was the problem, and explains the even wilder behaviour when I used popen(commandline,"w") ;) Cheers, David Duffy. -- | David Duffy (MBBS PhD) ,-_|\ | email: davidD(a)qimr.edu.au ph: INT+61+7+3362-0217 fax: -0101 / * | Epidemiology Unit, Queensland Institute of Medical Research \_,-._/ | 300 Herston Rd, Brisbane, Queensland 4029, Australia GPG 4D0B994A v
|
Next
|
Last
Pages: 1 2 Prev: Difference between passing a number and a variable to a subroutine Next: BINARY FILE FORMAT |