Attachment "wr.tcl" to
ticket [2176669fff]
added by
andreas_kupries
2009-11-21 02:48:01.
# Here is a small example how Tcl is not maintaining the virtual seek
# location in the presence of unflushed output.
set fd [open testfile r+] ; # (0)
puts [tell $fd] ; # (1) == 0
puts -nonewline $fd Z ; # (2)
puts [read $fd 2] ; # (3)
puts [tell $fd] ; # (4) == -1, error
exit
# (1) open file, location at 0.
#
# (2) Write single byte.
# Tcl buffers 1 byte for output.
# Tcl's file location is 0! Would be 1 after a flush.
#
# (3) The read bytes come from locations 0 and 1, see above. Note (*).
# Tcl read 4096 bytes (default -buffersize), a delivered 2
# => OS' location = 4096
# => Buffered 4094 bytes
# => Tcl's location = 2
#
# (4) [tell] is (in essence) [seek 0 current], i.e. move nothing, at
# the current location, and return new location. What it doesn't
# do is flushing the out. It takes input/output buffering into
# account to go from OS location to Tcl's location.
#
# As we have both input and output buffered we got -1, error.
#
# What if the check is disabled. Then we get 2.
#
# Because that is what we have read, starting from location 0.
#
# However, we have unflushed data pending for write, which now has
# an _indeterminate_ location. It was likely intended to be at
# location 0, but due to the intervening read it would end up at
# location 2 if flushed now.
#
# The main thing, [read] is not accounting for buffered
# output when it determines from where to read in the channel.
#
# OTOH, if it were doing so a read operation may write to the
# channel (flush). This is not good for an operation supposed to
# 'query' the channel only, not modify it.
#
# The upshot is that having buffered input and output is a signal
# that Tcl cannot really determine a proper location in the file
# any longer, because of this "read after buffered/unflushed write".
#
# (*) See maketestfile.tcl, the file contains a pattern of chars
# which allows us to tell the location from the chars themselves,
# instead of asking Tcl