From: Peter Zotov Date: 2013-01-10T07:24:06+09:00 Subject: Re: Illegal seek (Errno::ESPIPE) when reading from named pipe Maarten Berkel писал 09.01.2013 19: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 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); Try IO#sysread. -- WBR, Peter Zotov.