I would like to communicate between two fortran processes or a commandline and a fortran process.
I try to use a named pipe.
The named pipe is created by the fortran through :
subroutine PipeOPEN( FILENAME ) USE IFWIN IMPLICIT INTEGER (A-Z) CHARACTER*(*) FILENAME sts = CreateNamedPipe( FILENAME, & OR(PIPE_ACCESS_DUPLEX,FILE_FLAG_FIRST_PIPE_INSTANCE), & OR(OR(PIPE_TYPE_MESSAGE,PIPE_READMODE_MESSAGE),PIPE_NOWAIT), & PIPE_UNLIMITED_INSTANCES, & 256, & 256, & NMPWAIT_USE_DEFAULT_WAIT, & NULL) end subroutine
I got a handle.
When I want to write to the pipe, I use
open(51,name='\\.\pipe\pierre',status='UNKNOWN',form='FORMATTED',ACTION='write') msg='test' write(51,'(a)') msg close(51)
But when I want to read,
I've got the error : "All pipe instances are busy"
The error message is the same if I want to redirect the output of a command line window.
Can you help me to resolve this issue ?
Thank in advance
1. the filename argument to CreateNamedPipe() needs to be null-terminated
2. IMPLICIT INTEGER(A-Z) may be legal, but is not good practice; much better to use IMPLICIT NONE and then have explicit type declarations for all variables; this also makes attributes such as the KIND for integers explicit & obvious
3. To set multiple bitflags, the Fortran function is Inclusive-OR, IOR(flag1, flag2)
4. Try not to use numerical values (ie, '256') directly as arguments; much better to define an integer parameter with an explicit KIND attribute
Thank you for your remarks.
I agree with you and I adapted my code.
subroutine PipeOPEN(FILENAME) USE IFWIN CHARACTER*(*) FILENAME integer(4) buff_out,buff_in, unit, sts buff_out = 256 buff_in = 256 sts = CreateNamedPipe( trim(FILENAME)//char(0), & IOR(PIPE_ACCESS_DUPLEX,FILE_FLAG_OVERLAPPED), & IOR(IOR(PIPE_TYPE_MESSAGE,PIPE_READMODE_MESSAGE),PIPE_WAIT), & PIPE_UNLIMITED_INSTANCES, & BUFF_OUT, & BUFF_IN, & NMPWAIT_USE_DEFAULT_WAIT, & NULL) end subroutine
However, the conclusion is the same: "All pipe instances are busy".
Maybe do you have an example of pipes in fortran?
I have not used pipes, but I took a look at the MSDN chat on that function. The return from sts = CreateNamedPipe() is a handle to the pipe (and should be declared INTEGER(HANDLE) :: sts), anticipating that further i/o to that pipe will be done in the customary Windows manner by, say, ReadFile() and WriteFile() which are handle-based. This is not the same as Fortran read/write statements to a file opened with a Fortran unit number, and I cannot predict that creating a named pipe, and then subsequently attempting to re-open it as a Fortran unit for standard read/write i/o, will work.
What definitely will work, however, is to stick with Windows functions for file i/o, which are far more versatile than the older Fortran equivalents (albeit completely Windows-specific and not portable).
Let me also suggest a simple experiment. Try closing the pipe after creating it (rval = CloseHandle(sts)) and then try Fortran i/o to the pipe's filename. Your problem may be simply that the Fortran code is failing to open a pipefile because it is already open in Windows.
I solved the problem using Windows functions for file i/o as you mentioned.
On the client side, if I'm using the USEROPEN parameter of the OPEN statement to connect to the pipe with CreateFile, it's possible to use the WRITE Fortran statement with its UNIT.
On the server side, firstly I have to use the CreateNamedPipe. Then ConnectNamedPipe function waits a client. I don't know if it's possible to overwrite the READ statement to got the same result.
Thank you for your help.