Illegal seek (Errno::ESPIPE) when reading from named pipe

Hi all,

What is the correct procedure to read one line from a named pipe?
I tried opening it with f = File.open ; input = f.gets, but that raises
Errno::ESPIPE (invalid seek) every now and then.

Thanks!

Maarten

More info:

I am running Ruby 1.8.7 on an embedded computer that runs linux
2.6.35.14.

I have created a named pipe manually (mkfifo /example/file.fifo)

I have multiple processes that write into this named pipe and one
‘reader’ process that reads AND also writes into this named pipe.

The reader process opens the pipe like this:
@raw = File.open(CONFIG[“fifo_raw”], File::RDWR)

In a background thread, it writes to the named pipe every seconds
(configurable, e.g. 3 of 60):
ticker = Thread.new do
while true
start_of_this_tick = (Time.now.to_i / rate) * rate
start_of_next_tick = start_of_this_tick + rate
seconds_to_sleep = start_of_next_tick - Time.now.to_f
sleep(seconds_to_sleep) if seconds_to_sleep > 0
@raw.write(“tick #{start_of_this_tick.to_i}\n”)
end
end
ticker.priority += 1

in the main thread the fifo is read:
while input = @raw.gets

process input

end

Every now and then, the gets call raises Errno::ESPIPE (invalid seek). I
have also tried readline, with the same behavior.

My impression is that I have to explicitly ‘tell’ ruby that this file is
a pipe instead of a regular file and that it cannot be seeked. In io.c I
found that there is a method rb_io_getline_fast which seems to be
buffering and seeking in appendline:
fread(RSTRING(str)->ptr + last, 1, pending, f);

Maarten Berkel писал 09.01.2013 19:38:

sleep(seconds_to_sleep) if seconds_to_sleep > 0

Every now and then, the gets call raises Errno::ESPIPE (invalid
seek). I
have also tried readline, with the same behavior.

My impression is that I have to explicitly ‘tell’ ruby that this file
is
a pipe instead of a regular file and that it cannot be seeked. In
io.c I
found that there is a method rb_io_getline_fast which seems to be
buffering and seeking in appendline:
fread(RSTRING(str)->ptr + last, 1, pending, f);

Try IO#sysread.