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

A

Alan Davies

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
 
T

ts

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

try to add a flush

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

file.flush

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


Guy Decoux
 
R

Robert Klemme

Alan Davies said:
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
 
T

ts

R> "Do not mix with other methods that write to ios or you may get
R> unpredictable results."
R> 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
 
N

nobu.nokada

Hi,

At Thu, 20 Nov 2003 18:50:20 +0900,
ts said:
R> "Do not mix with other methods that write to ios or you may get
R> unpredictable results."
R> 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.
 
T

ts

n> This behavior is not guaranteed. And also, once stdio layer
n> 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
 
A

Alan Davies

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top