[BUG] File#rewind, File#syswrite, File#pos on Cygwin build

On the cygwin build of ruby v1.8.0, I have encountered a strange bug
when using rewind, syswrite and pos. If you open a file in read/write
mode, read the contents, rewind, syswrite some data, then File#pos
always seems to return zero. This does not happen if you use the
windows build, or you replace ‘syswrite’ with ‘write’.

e.g:

$ cat syswrite.rb
#!/bin/ruby

testStr = “hello\nthis is some example text\nblah blah blah”

read it, rewind, then write it back again

File.open(“out.txt”, ‘r+’) do |file|
file.readlines
file.rewind
bytes = file.syswrite(testStr)
puts "#{bytes} bytes written"
puts "Now at position #{file.pos}"
end

$ ls > out.txt

$ syswrite.rb
46 bytes written
Now at position 0

On the cygwin build of ruby v1.8.0, I have encountered a strange bug
when using rewind, syswrite and pos. If you open a file in read/write
mode, read the contents, rewind, syswrite some data, then File#pos
always seems to return zero. This does not happen if you use the
windows build, or you replace 'syswrite' with 'write'.

try to add a flush

File.open("out.txt", 'r+') do |file|
   file.readlines
   file.rewind
   bytes = file.syswrite(testStr)

      file.flush

   puts "#{bytes} bytes written"
   puts "Now at position #{file.pos}"
end

Guy Decoux

“Alan Davies” NOSPAMcs96and@yahoo.co.ukNOSPAM schrieb im Newsbeitrag
news:3fba526d@primark.com

On the cygwin build of ruby v1.8.0, I have encountered a strange bug
when using rewind, syswrite and pos. If you open a file in read/write
mode, read the contents, rewind, syswrite some data, then File#pos
always seems to return zero. This does not happen if you use the
windows build, or you replace ‘syswrite’ with ‘write’.

“Do not mix with other methods that write to ios or you may get
unpredictable results.”
http://www.rubycentral.com/book/ref_c_io.html#IO.syswrite

robert

"Do not mix with other methods that write to ios or you may get
unpredictable results."
http://www.rubycentral.com/book/ref_c_io.html#IO.syswrite

No, no.

moulon% cat b.rb
#!/usr/bin/ruby
testStr = "hello\nthis is some example text\nblah blah blah"

File.open("out.txt", 'r+') do |file|
   file.readlines
   puts "Now at position #{file.pos}"
   file.rewind
   puts "Now at position #{file.pos}"
   bytes = file.syswrite(testStr)
   puts "#{bytes} bytes written"
   puts "Now at position #{file.pos}"
end
moulon%

moulon% ruby -v b.rb
ruby 1.8.0 (2003-08-04) [sparc-solaris2.7]
Now at position 3330
Now at position 0
46 bytes written
Now at position 46
moulon%

the problem is in cygwin and linux ...

Guy Decoux

ts wrote:

the problem is in cygwin and linux …

Can we get this fixed in 1.8.1 then?

Hi,

“Do not mix with other methods that write to ios or you may get
unpredictable results.”
http://www.rubycentral.com/book/ref_c_io.html#IO.syswrite

No, no.

Robert is correct.

Note that IO#pos is shorthand for seek(0, IO::SEEK_CUR) which
an interface for fseek, that means it is buffered IO routine.
You have to use #sysseek instead.

puts “Now at position #{file.pos}”
puts “Now at position #{file.sysseek(0, IO::SEEK_CUR)}”

moulon% ruby -v b.rb
ruby 1.8.0 (2003-08-04) [sparc-solaris2.7]
Now at position 3330
Now at position 0
46 bytes written
Now at position 46
moulon%

the problem is in cygwin and linux …

This behavior is not guaranteed. And also, once stdio layer
operation is done, whether sysio works well or not is unknown.

···

At Thu, 20 Nov 2003 18:50:20 +0900, ts wrote:


Nobu Nakada

This behavior is not guaranteed. And also, once stdio layer
operation is done, whether sysio works well or not is unknown.

we just don't work on the same systems :

     When a file is opened with update mode (+ as the second or
     third character in the mode argument), both input and output
     may be performed on the associated stream. However, output
     must not be directly followed by input without an interven-
     ing call to fflush(3C) or to a file positioning function (
     fseek(3C), fsetpos(3C) or rewind(3C)), and input must not be
     directly followed by output without an intervening call to a
     file positioning function, unless the input operation
     encounters end-of-file.

Guy Decoux

Note that IO#pos is shorthand for seek(0, IO::SEEK_CUR) which
an interface for fseek, that means it is buffered IO routine.
You have to use #sysseek instead.

Ah that explains a lot. Why doesn’t #syspos exist then?

Alan.