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

Posted by Maarten Berkel (mvberkel)
on 2013-01-09 16:38
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 <x> 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);
Posted by Peter Zotov (Guest)
on 2013-01-09 23:25
(Received via mailing list)
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.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.