Chapter 4. Named Pipe Support

Named pipes or UNIX FIFO special files are created with the mknod(2) system call; these special files allow any two processes to exchange information. The system call creates an inode for the named pipe and establishes it as a read/write named pipe. It can then be used by standard Fortran I/O or C I/O. Piped I/O is faster than normal I/O; it requires less memory than memory-resident files.

Named Pipes

After a named pipe is created, Fortran programs can access that pipe almost as if it were a typical file; the differences between process communication using named pipes and process communication using normal files is discussed in the following list. The examples show how a Fortran program can use standard Fortran I/O on pipes.

  • A named pipe must be created before a Fortran program opens it. The following is the syntax for the command to create a named pipe called fort.13:

    /etc/mknod fort.13 p    

    A named pipe can be created from within a Fortran program by using ISHELL(3f) or by using the C language library interface to the mknod(2) system call; either of the following examples creates a named pipe:

    CALL ISHELL('/etc/mknod fort.13 p')    

    I = MKNOD ('fort.13',010600B,0)

  • Fortran programs can communicate using two named pipes: one to read and one to write. A Fortran program must either read from or write to any named pipe, but it cannot do both at the same time. This is a Fortran restriction on pipes, not a system restriction. It occurs because Fortran does not allow read and write access at the same time.

  • I/O transfers through named pipes use memory for buffering. A separate buffer is created for each named pipe that is created. The PIPE_BUF parameter defines the kernel buffer size in the /sys/param.h parameter file. The default value of PIPE_BUF is 8 blocks (8 * 512 words), but the full size may not be needed or used. I/O to named pipes does not transfer to or from a disk. However, if I/O transfers fill the buffer, the writing process waits for the receiving process to read the data before refilling the buffer. If the size of the PIPE_BUF parameter is increased, I/O performance may decrease; there may be more I/O buffer contention. If memory has already been allocated for buffers, more space will not be allocated.

  • Binary data transferred between two processes through a named pipe must use the correct file structure. The undefined file structure (specified by assign -s u) should be specified for a pipe by the sending process. The unblocked structure (specified by assign -s unblocked) should be specified for a pipe by the receiving process.

    The file structure for the pipe of the sending (write) process should be set to undefined (assign -s u), which issues a system call for each write. You can also select a file specification of system (assign -F system) for the sending process.

    The file structure of the receiving or read process can be set to either the undefined or the unblocked file structure. However, if the sending process writes a request that is larger than MAXPIPE, it is essential for the receiving process to read the data from a pipe set to the unblocked file structure. A read of a transfer larger than MAXPIPE on an undefined file structure yields only MAXPIPE amount of data. The receiving process would not wait to see whether the sending process is refilling the buffer. The pipe may be less than MAXPIPE.

    For example, the following assign commands specify that the file structure of the named pipe (unit 13, file name pipe) for the sending process should be undefined (-s u). The named pipe (unit 15, file name pipe) is type unblocked (-s unblocked) for the read process.

    assign -s u -a pipe u:13
    assign -s unblocked -a pipe u:15   

  • A read from a pipe that is closed by the sender causes a detection of end-of-file (EOF).

    To detect EOF on a named pipe, the pipe must be opened as read-only by the receiving process. Use the ACTION=READ specifier on the OPEN statement to open a file as read-only.

Piped I/O Example without End-of-file Detection

In this example, two Fortran programs communicate without end-of-file (EOF) detection. In the example, program writerd generates an array that contains the elements 1 to 3 and writes the array to named pipe pipe1. Program readwt reads the three elements from named pipe pipe1, prints out the values, adds 1 to each value, and writes the new elements to named pipe pipe2. Program writerd reads the new values from named pipe pipe2 and prints them. The -a option of the assign(1) command allows the two processes to access the same file with different assign characteristics.

Example 4-1. No EOF detection: writerd

        program writerd
        parameter(n=3)
        dimension ia(n)
        do 10 i=1,n
           ia(i)=i
10      continue
        write (10) ia
        read (11) ia
        do 20 i=1,n
           print*,'ia(',i,') is ',ia(i),' in writerd'
20      continue
        end


Example 4-2. No EOF detection: readwt

        program readwt
        parameter(n=3)
        dimension ia(n)
        read (15) ia
        do 10 i=1,n
           print*,'ia(',i,') is ',ia(i),' in readwt'
           ia(i)=ia(i)+110      continue
        write (16) ia
        end

The following commands execute the programs:

f90 -o readwt readwt.f
f90 -o writerd writerd.f
/etc/mknod pipe1 p
/etc/mknod pipe2 p
assign -s u -a pipe1 u:10
assign -s unblocked -a pipe2 u:11
assign -s unblocked -a pipe1 u:15
assign -s u -a pipe2 u:16
readwt &
writerd

The following is the output of the two programs:

ia(1) is 1 in readwt
ia(2) is 2 in readwt
ia(3) is 3 in readwt
ia(1) is 2 in writerd
ia(2) is 3 in writerd
ia(3) is 4 in writerd

Detecting End-of-file on a Named Pipe

The following conditions must be met to detect end-of-file on a read from a named pipe within a Fortran program: the program that sends data must open the pipe in a specific way, and the program that receives the data must open the pipe as read-only.

The program that sends or writes the data must open the named pipe as read and write or write-only. This is the default because the /etc/mknod command creates a named pipe with read and write permission.

The program that receives or reads the data must open the pipe as read-only. A read from a named pipe that is opened as read and write waits indefinitely for the data. Use the ACTION=READ specifier on the OPEN statement to open a file as read-only.

Piped I/O Example with End-of-file Detection

This example uses named pipes for communication between two Fortran programs with end-of-file detection. The programs in this example are similar to the programs used in the preceding section. This example shows that program readwt can detect the EOF.

Program writerd generates array ia and writes the data to the named pipe pipe1. Program readwt reads the data from the named pipe pipe1, prints the values, adds one to each value, and writes the new elements to named pipe pipe2. Program writerd reads the new values from pipe2 and prints them. Finally, program writerd closes pipe1 and causes program readwt to detect the EOF.

The following commands execute these programs:

f90 -o readwt readwt.f
f90 -o writerd writerd.f
assign -s u -a pipe1 u:10
assign -s unblocked -a pipe2 u:11
assign -s unblocked -a pipe1 u:15
assign -s u -a pipe2 u:16
/etc/mknod pipe1 p
/etc/mknod pipe2 p
readwt &
writerd  

Example 4-3. EOF detection: writerd

      program writerd
      parameter(n=3)
      dimension ia(n)
      do 10 i=1,n
        ia(i)=i
10    continue
      write (10) ia
      read (11) ia
      do 20 i=1,n
        print*,'ia(',i,') is',ia(i),' in writerd'
20    continue 
      close (10)
      end


Example 4-4. EOF detection: readwt

      program readwt
      parameter(n=3)
      dimension ia(n)
C     open the pipe as read-only
      open(15,form='unformatted', action='read')
      read (15,end = 101) ia
      do 10 i=1,n
        print*,'ia(',i,') is ',ia(i),' in readwt'
        ia(i)=ia(i)+1
 10   continue
      write (16) ia
      read (15,end = 101) ia
      goto 102
101   print *,'End of file detected'
102   continue
      end

The output of the two programs is as follows:

ia(1) is 1 in readwt
ia(2) is 2 in readwt
ia(3) is 3 in readwt
ia(1) is 2 in writerd
ia(2) is 3 in writerd
ia(3) is 4 in writerd
End of file detected