2012-08-02 41 views
8

Tôi đang cố gắng để có được một ứng dụng fortran 90 để mở một năm và ghi dữ liệu đã định dạng vào nó. Tôi đã rút gọn điều này xuống một ví dụ tối thiểu. Hãy foo.f90 được chương trình sau đây:Viết tới nămo (tên là pipe)

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

Bây giờ biên dịch và chạy chương trình:

$ 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 +++ 

Vì vậy, các chương trình hoạt động tốt đủ khi viết vào một tập tin bình thường. Tuy nhiên, khi viết vào FIFO, nó cố gắng thay đổi kích thước tệp sau khi viết đầu tiên, chấm dứt ứng dụng sau khi không làm như vậy.

Tôi khá mới đối với Fortran, vì vậy tôi không chắc chắn đây có phải là lỗi trong gfortran hay không hoặc liệu có cách nào để mở tệp sẽ ngăn chặn syscall ftruncate này không. Tôi muốn gắn bó với phương pháp tiếp cận được định dạng tuần tự: Các dòng của tôi có độ dài khác nhau và tôi muốn tránh phải chỉ định một số bản ghi với mỗi số write.

Trả lời

4

Đây là một old feature (thậm chí không dám nghĩ đó là một lỗi!) Trong libgfortran đã được vá các phiên bản trước, nhưng đã được giới thiệu lại cho GCC 4.7 chi nhánh, cụ thể hơn trong SVN revision 180701. Rõ ràng gfortran nhà phát triển không kiểm tra mã I/O của họ với các đường ống có tên.

Bạn nên sử dụng phiên bản gfortran cũ hơn (hoạt động với 4.6.1) hoặc trình biên dịch Fortran khác từ một nhà cung cấp khác. Tôi sẽ gửi báo cáo lỗi cho GCC.

+1

Sử dụng 'gfortran-4.6.3' Tôi nhận được cùng một hành vi. 'gfortran-4.1.2' không thành công với' Tìm kiếm bất hợp pháp ', tức là một syscall trước đó. 'gfortran-4.2.4' thực sự có vẻ hoạt động như dự định, nhưng sẽ không hỗ trợ mã trong ứng dụng thực tế của tôi. Khi bạn gửi một lỗi, hãy cho tôi biết URL của nó để tôi có thể đăng ký. – MvG

+1

Nó hoạt động với 'gfortran' 4.6.1. Quá lười để thực sự kiểm tra xem thẻ nào thuộc về r180701 và chỉ giả định rằng không có thay đổi lớn nào được thực hiện giữa các phiên bản nhỏ. –

+0

@MvG, tôi đã đưa ra nhận xét mới về lỗi cũ. Hãy xem điều gì sẽ xảy ra. –