Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: JRuby 1.6.5
-
Fix Version/s: JRuby 1.6.6, JRuby 1.7.0.pre1
-
Component/s: None
-
Labels:None
-
Environment:linux
-
Number of attachments :
Description
JRuby fails to open a fifo for writing because it tries to seek in it.
Create a fifo on the filesystem like so:
% mkfifo /tmp/fifo
I tested this on Linux. It is likely other platforms are affected.
Example code showing it working in MRI 1.9.2 and failing in JRuby 1.6.5 (both 1.8 and 1.9 mode)
% rvm use 1.9.2; ruby -e 'File.new("/tmp/fifo", "w"); puts :OK'
Using /home/jls/.rvm/gems/ruby-1.9.2-p290
OK
% rvm use 1.6.5; ruby -e 'File.new("/tmp/fifo", "w"); puts :OK'
Using /home/jls/.rvm/gems/jruby-1.6.5
IOError: Illegal seek
initialize at org/jruby/RubyFile.java:442
new at org/jruby/RubyIO.java:868
(root) at -e:1
% rvm use 1.6.5; ruby --1.9 -e 'File.new("/tmp/fifo", "w"); puts :OK'
Using /home/jls/.rvm/gems/jruby-1.6.5
IOError: Illegal seek
initialize at org/jruby/RubyFile.java:464
new at org/jruby/RubyIO.java:868
(root) at -e:1
Relevant data from strace:
3086 open("/tmp/fifo", O_RDWR|O_CREAT, 0666) = 5
3086 lseek(5, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
Example code showing using the Java API working fine. Mainly, the point of me trying this in 'pure java api' was to see if it was a something related to a missed-feature in Java's cross-platformness
>> writer = java.io.FileWriter.new(java.io.File.new("/tmp/fifo"))
=> #<Java::JavaIo::FileWriter:0x33cfa965>
>> writer.write("Hello")
=> nil
>> writer.flush()
=> nil
It's interesting to note that the specific lseek(2) call that fails is one that is trying to ask the OS what the current position the file write cursor is. It seems possible to skip any lseek(2) calls until the position in the file needs to be known (stat calls, file.pos, etc), but I"ll leave the specifics of implementation and resolution up to you fine folks
Let me know if you need any more data!
(I may offer a patch for this if I can find some energy to do so)