2012-08-02 27 views
8

Sto cercando di ottenere un'applicazione fortran 90 per aprire un fifo e scrivere dati formattati su di esso. Ho spogliato questo per un esempio minimo. Diciamo foo.f90 essere il seguente programma:Scrivi su fifo (named pipe)

program foo 
    open(1,file='fifo',position='asis',action='write') 
    write(1,*)'Hello, world!' 
    write(1,*)'Goodbye.' 
end program 

Ora compilare ed eseguire il programma:

$ gfortran-4.7.1 -o foo foo.f90 
$ rm -f fifo 
$ ./foo 
$ cat fifo 
Hello, world! 
$ rm -f fifo 
$ mkfifo fifo 
$ cat fifo > bar & 
[1] 6115 
$ strace -o foo.st ./foo 
At line 3 of file foo.f90 (unit = 1, file = 'fifo') 
Fortran runtime error: Invalid argument 
[1]+ Done     cat fifo > bar 
$ tail foo.st 
write(3, " Hello, world!\n", 15)  = 15 
lseek(3, 0, SEEK_CUR)     = -1 ESPIPE (Illegal seek) 
ftruncate(3, 18446744073709551615)  = -1 EINVAL (Invalid argument) 
write(2, "At line 3 of file foo.f90 (unit "..., 52) = 52 
write(2, "Fortran runtime error: ", 23) = 23 
write(2, "Invalid argument", 16)  = 16 
write(2, "\n", 1)      = 1 
close(3)        = 0 
exit_group(2)       = ? 
+++ exited with 2 +++ 

Così il programma funziona abbastanza bene quando si scrive in un file normale. Tuttavia, quando si scrive su fifo, tenta di cambiare la dimensione del file dopo la prima scrittura, terminando l'applicazione dopo aver fallito.

Sono abbastanza nuovo per Fortran, quindi non sono sicuro se questo è un bug in gfortran, o se c'è un modo per aprire il file che sopprimerà questo syscall ftruncate. Preferirei seguire l'approccio sequenziale formattato: le mie linee hanno lunghezze diverse e preferirei evitare di dover specificare un numero di record con ogni write.

risposta

4

Questo è un old feature (non hanno nemmeno il coraggio di pensare che sia un bug!) In libgfortran che è stato patchato versioni fa, ma è stato ripristinato, per la 4.7 ramo GCC, più precisamente in SVN revision 180701. Apparentemente gli sviluppatori di gfortran non testano il loro codice I/O con pipe denominate.

È necessario utilizzare una versione precedente gfortran (funziona con 4.6.1) o un altro compilatore Fortran di un altro fornitore. Presenterò una segnalazione di bug a GCC.

+1

Uso 'gfortran-4.6.3' Ho lo stesso comportamento. 'gfortran-4.1.2' fallisce con' Illegal seek', cioè un syscall in precedenza. 'gfortran-4.2.4' sembra funzionare come previsto, ma non supporta il codice nella mia applicazione reale. Quando invii un bug, fammi sapere il suo URL così posso iscriverti. – MvG

+1

Funziona con 'gfortran' 4.6.1. Era troppo pigro per verificare effettivamente quale tag r180701 appartenesse e presumevo che non ci fossero grandi cambiamenti tra le versioni minori. –

+0

@MvG, ho fatto un nuovo commento al vecchio bug. Vediamo cosa succederà. –

Problemi correlati