OpenFPGA/libs/EXTERNAL/tcl8.6.12/tests/chanio.test

7785 lines
250 KiB
Tcl
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- tcl -*-
# Functionality covered: operation of all IO commands, and all procedures
# defined in generic/tclIO.c.
#
# This file contains a collection of tests for one or more of the Tcl built-in
# commands. Sourcing this file into Tcl runs the tests and generates output
# for errors. No output means no errors were found.
#
# Copyright (c) 1991-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
if {"::tcltest" ni [namespace children]} {
package require tcltest 2.5
}
namespace eval ::tcl::test::io {
namespace import ::tcltest::*
variable umaskValue
variable path
variable f
variable i
variable n
variable v
variable msg
variable expected
catch {
::tcltest::loadTestedCommands
package require -exact Tcltest [info patchlevel]
set ::tcltestlib [lindex [package ifneeded Tcltest [info patchlevel]] 1]
}
package require tcltests
testConstraint testbytestring [llength [info commands testbytestring]]
testConstraint testchannel [llength [info commands testchannel]]
testConstraint testfevent [llength [info commands testfevent]]
testConstraint testchannelevent [llength [info commands testchannelevent]]
testConstraint testmainthread [llength [info commands testmainthread]]
testConstraint testservicemode [llength [info commands testservicemode]]
testConstraint notWinCI [expr {
$::tcl_platform(platform) ne "windows" || ![info exists ::env(CI)]}]
testConstraint notOSX [expr {$::tcl_platform(os) ne "Darwin"}]
# You need a *very* special environment to do some tests. In particular,
# many file systems do not support large-files...
testConstraint largefileSupport [expr {$::tcl_platform(os) ne "Darwin"}]
# some tests can only be run is umask is 2 if "umask" cannot be run, the
# tests will be skipped.
set umaskValue 0
testConstraint umask [expr {![catch {set umaskValue [scan [exec /bin/sh -c umask] %o]}]}]
testConstraint makeFileInHome [expr {![file exists ~/_test_] && [file writable ~]}]
# set up a long data file for some of the following tests
set path(longfile) [makeFile {} longfile]
set f [open $path(longfile) w]
chan configure $f -eofchar {} -translation lf
for { set i 0 } { $i < 100 } { incr i} {
chan puts $f "#123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
\#123456789abcdef01
\#"
}
chan close $f
set path(cat) [makeFile {
set f stdin
if {$argv != ""} {
set f [open [lindex $argv 0]]
}
chan configure $f -encoding binary -translation lf -blocking 0 -eofchar \x1a
chan configure stdout -encoding binary -translation lf -buffering none
chan event $f readable "foo $f"
proc foo {f} {
set x [chan read $f]
catch {chan puts -nonewline $x}
if {[chan eof $f]} {
chan close $f
exit 0
}
}
vwait forever
} cat]
set thisScript [file join [pwd] [info script]]
proc contents {file} {
set f [open $file]
chan configure $f -translation binary
set a [chan read $f]
chan close $f
return $a
}
# Wrapper round butt-ugly pipe syntax
proc openpipe {{mode r+} args} {
open "|[list [interpreter] {*}$args]" $mode
}
test chan-io-1.5 {Tcl_WriteChars: CheckChannelErrors} {emptyTest} {
# no test, need to cause an async error.
} {}
set path(test1) [makeFile {} test1]
test chan-io-1.6 {Tcl_WriteChars: WriteBytes} {
set f [open $path(test1) w]
chan configure $f -encoding binary
chan puts -nonewline $f "a\u4e4d\0"
chan close $f
contents $path(test1)
} "a\x4d\x00"
test chan-io-1.7 {Tcl_WriteChars: WriteChars} {
set f [open $path(test1) w]
chan configure $f -encoding shiftjis
chan puts -nonewline $f "a\u4e4d\0"
chan close $f
contents $path(test1)
} "a\x93\xe1\x00"
set path(test2) [makeFile {} test2]
test chan-io-1.8 {Tcl_WriteChars: WriteChars} {
# This test written for SF bug #506297.
#
# Executing this test without the fix for the referenced bug applied to
# tcl will cause tcl, more specifically WriteChars, to go into an infinite
# loop.
set f [open $path(test2) w]
chan configure $f -encoding iso2022-jp
chan puts -nonewline $f [format %s%c [string repeat " " 4] 12399]
chan close $f
contents $path(test2)
} " \x1b\$B\$O\x1b(B"
test chan-io-1.9 {Tcl_WriteChars: WriteChars} {
# When closing a channel with an encoding that appends escape bytes, check
# for the case where the escape bytes overflow the current IO buffer. The
# bytes should be moved into a new buffer.
set data "1234567890 [format %c 12399]"
set sizes [list]
# With default buffer size
set f [open $path(test2) w]
chan configure $f -encoding iso2022-jp
chan puts -nonewline $f $data
chan close $f
lappend sizes [file size $path(test2)]
# With buffer size equal to the length of the data, the escape bytes would
# go into the next buffer.
set f [open $path(test2) w]
chan configure $f -encoding iso2022-jp -buffersize 16
chan puts -nonewline $f $data
chan close $f
lappend sizes [file size $path(test2)]
# With buffer size that is large enough to hold 1 byte of escaped data,
# but not all 3. This should not write the escape bytes to the first
# buffer and then again to the second buffer.
set f [open $path(test2) w]
chan configure $f -encoding iso2022-jp -buffersize 17
chan puts -nonewline $f $data
chan close $f
lappend sizes [file size $path(test2)]
# With buffer size that can hold 2 out of 3 bytes of escaped data.
set f [open $path(test2) w]
chan configure $f -encoding iso2022-jp -buffersize 18
chan puts -nonewline $f $data
chan close $f
lappend sizes [file size $path(test2)]
# With buffer size that can hold all the data and escape bytes.
set f [open $path(test2) w]
chan configure $f -encoding iso2022-jp -buffersize 19
chan puts -nonewline $f $data
chan close $f
lappend sizes [file size $path(test2)]
} {19 19 19 19 19}
test chan-io-2.1 {WriteBytes} {
# loop until all bytes are written
set f [open $path(test1) w]
chan configure $f -encoding binary -buffersize 16 -translation crlf
chan puts $f "abcdefghijklmnopqrstuvwxyz"
chan close $f
contents $path(test1)
} "abcdefghijklmnopqrstuvwxyz\r\n"
test chan-io-2.2 {WriteBytes: savedLF > 0} {
# After flushing buffer, there was a \n left over from the last
# \n -> \r\n expansion. It gets stuck at beginning of this buffer.
set f [open $path(test1) w]
chan configure $f -encoding binary -buffersize 16 -translation crlf
chan puts -nonewline $f "123456789012345\n12"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "123456789012345\r" "123456789012345\r\n12"]
test chan-io-2.3 {WriteBytes: flush on line} -body {
# Tcl "line" buffering has weird behavior: if current buffer contains a
# \n, entire buffer gets flushed. Logical behavior would be to flush only
# up to the \n.
set f [open $path(test1) w]
chan configure $f -encoding binary -buffering line -translation crlf
chan puts -nonewline $f "\n12"
contents $path(test1)
} -cleanup {
chan close $f
} -result "\r\n12"
test chan-io-2.4 {WriteBytes: reset sawLF after each buffer} {
set f [open $path(test1) w]
chan configure $f -encoding binary -buffering line -translation lf \
-buffersize 16
chan puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]
test chan-io-3.1 {WriteChars: compatibility with WriteBytes} {
# loop until all bytes are written
set f [open $path(test1) w]
chan configure $f -encoding ascii -buffersize 16 -translation crlf
chan puts $f "abcdefghijklmnopqrstuvwxyz"
chan close $f
contents $path(test1)
} "abcdefghijklmnopqrstuvwxyz\r\n"
test chan-io-3.2 {WriteChars: compatibility with WriteBytes: savedLF > 0} {
# After flushing buffer, there was a \n left over from the last
# \n -> \r\n expansion. It gets stuck at beginning of this buffer.
set f [open $path(test1) w]
chan configure $f -encoding ascii -buffersize 16 -translation crlf
chan puts -nonewline $f "123456789012345\n12"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "123456789012345\r" "123456789012345\r\n12"]
test chan-io-3.3 {WriteChars: compatibility with WriteBytes: flush on line} -body {
# Tcl "line" buffering has weird behavior: if current buffer contains a
# \n, entire buffer gets flushed. Logical behavior would be to flush only
# up to the \n.
set f [open $path(test1) w]
chan configure $f -encoding ascii -buffering line -translation crlf
chan puts -nonewline $f "\n12"
contents $path(test1)
} -cleanup {
chan close $f
} -result "\r\n12"
test chan-io-3.4 {WriteChars: loop over stage buffer} {
# stage buffer maps to more than can be queued at once.
set f [open $path(test1) w]
chan configure $f -encoding jis0208 -buffersize 16
chan puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "!)!)!)!)!)!)!)!)" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
test chan-io-3.5 {WriteChars: saved != 0} {
# Bytes produced by UtfToExternal from end of last channel buffer had to
# be moved to beginning of next channel buffer to preserve requested
# buffersize.
set f [open $path(test1) w]
chan configure $f -encoding jis0208 -buffersize 17
chan puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
test chan-io-3.6 {WriteChars: (stageRead + dstWrote == 0)} {
# One incomplete UTF-8 character at end of staging buffer. Backup in src
# to the beginning of that UTF-8 character and try again.
#
# Translate the first 16 bytes, produce 14 bytes of output, 2 left over
# (first two bytes of \uff21 in UTF-8). Given those two bytes try
# translating them again, find that no bytes are read produced, and break
# to outer loop where those two bytes will have the remaining 4 bytes (the
# last byte of \uff21 plus the all of \uff22) appended.
set f [open $path(test1) w]
chan configure $f -encoding shiftjis -buffersize 16
chan puts -nonewline $f "12345678901234\uff21\uff22"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "12345678901234\x82\x60" "12345678901234\x82\x60\x82\x61"]
test chan-io-3.7 {WriteChars: (bufPtr->nextAdded > bufPtr->length)} {
# When translating UTF-8 to external, the produced bytes went past end of
# the channel buffer. This is done on purpose - we then truncate the bytes
# at the end of the partial character to preserve the requested blocksize
# on flush. The truncated bytes are moved to the beginning of the next
# channel buffer.
set f [open $path(test1) w]
chan configure $f -encoding jis0208 -buffersize 17
chan puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
test chan-io-3.8 {WriteChars: reset sawLF after each buffer} {
set f [open $path(test1) w]
chan configure $f -encoding ascii -buffering line -translation lf \
-buffersize 16
chan puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]
test chan-io-4.1 {TranslateOutputEOL: lf} {
# search for \n
set f [open $path(test1) w]
chan configure $f -buffering line -translation lf
chan puts $f "abcde"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "abcde\n" "abcde\n"]
test chan-io-4.2 {TranslateOutputEOL: cr} {
# search for \n, replace with \r
set f [open $path(test1) w]
chan configure $f -buffering line -translation cr
chan puts $f "abcde"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "abcde\r" "abcde\r"]
test chan-io-4.3 {TranslateOutputEOL: crlf} {
# simple case: search for \n, replace with \r
set f [open $path(test1) w]
chan configure $f -buffering line -translation crlf
chan puts $f "abcde"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "abcde\r\n" "abcde\r\n"]
test chan-io-4.4 {TranslateOutputEOL: crlf} {
# Keep storing more bytes in output buffer until output buffer is full. We
# have 13 bytes initially that would turn into 18 bytes. Fill dest buffer
# while (dstEnd < dstMax).
set f [open $path(test1) w]
chan configure $f -translation crlf -buffersize 16
chan puts -nonewline $f "1234567\n\n\n\n\nA"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "1234567\r\n\r\n\r\n\r\n\r" "1234567\r\n\r\n\r\n\r\n\r\nA"]
test chan-io-4.5 {TranslateOutputEOL: crlf} {
# Check for overflow of the destination buffer
set f [open $path(test1) w]
chan configure $f -translation crlf -buffersize 12
chan puts -nonewline $f "12345678901\n456789012345678901234"
chan close $f
set x [contents $path(test1)]
} "12345678901\r\n456789012345678901234"
test chan-io-5.1 {CheckFlush: not full} {
set f [open $path(test1) w]
chan configure $f
chan puts -nonewline $f "12345678901234567890"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "" "12345678901234567890"]
test chan-io-5.2 {CheckFlush: full} {
set f [open $path(test1) w]
chan configure $f -buffersize 16
chan puts -nonewline $f "12345678901234567890"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "1234567890123456" "12345678901234567890"]
test chan-io-5.3 {CheckFlush: not line} {
set f [open $path(test1) w]
chan configure $f -buffering line
chan puts -nonewline $f "12345678901234567890"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "" "12345678901234567890"]
test chan-io-5.4 {CheckFlush: line} {
set f [open $path(test1) w]
chan configure $f -buffering line -translation lf -encoding ascii
chan puts -nonewline $f "1234567890\n1234567890"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "1234567890\n1234567890" "1234567890\n1234567890"]
test chan-io-5.5 {CheckFlush: none} {
set f [open $path(test1) w]
chan configure $f -buffering none
chan puts -nonewline $f "1234567890"
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
} [list "1234567890" "1234567890"]
test chan-io-6.1 {Tcl_GetsObj: working} -body {
set f [open $path(test1) w]
chan puts $f "foo\nboo"
chan close $f
set f [open $path(test1)]
chan gets $f
} -cleanup {
chan close $f
} -result {foo}
test chan-io-6.2 {Tcl_GetsObj: CheckChannelErrors() != 0} emptyTest {
# no test, need to cause an async error.
} {}
test chan-io-6.3 {Tcl_GetsObj: how many have we used?} -body {
# if (bufPtr != NULL) {oldRemoved = bufPtr->nextRemoved}
set f [open $path(test1) w]
chan configure $f -translation crlf
chan puts $f "abc\ndefg"
chan close $f
set f [open $path(test1)]
list [chan tell $f] [chan gets $f line] [chan tell $f] [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {0 3 5 4 defg}
test chan-io-6.4 {Tcl_GetsObj: encoding == NULL} -body {
set f [open $path(test1) w]
chan configure $f -translation binary
chan puts $f "\x81\u1234\0"
chan close $f
set f [open $path(test1)]
chan configure $f -translation binary
list [chan gets $f line] $line
} -cleanup {
chan close $f
} -result [list 3 "\x81\x34\x00"]
test chan-io-6.5 {Tcl_GetsObj: encoding != NULL} -body {
set f [open $path(test1) w]
chan configure $f -translation binary
chan puts $f "\x88\xea\x92\x9a"
chan close $f
set f [open $path(test1)]
chan configure $f -encoding shiftjis
list [chan gets $f line] $line
} -cleanup {
chan close $f
} -result [list 2 "\u4e00\u4e01"]
set a "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
append a $a
append a $a
test chan-io-6.6 {Tcl_GetsObj: loop test} -body {
# if (dst >= dstEnd)
set f [open $path(test1) w]
chan puts $f $a
chan puts $f hi
chan close $f
set f [open $path(test1)]
list [chan gets $f line] $line
} -cleanup {
chan close $f
} -result [list 256 $a]
test chan-io-6.7 {Tcl_GetsObj: error in input} -constraints stdio -body {
# if (FilterInputBytes(chanPtr, &gs) != 0)
set f [openpipe w+ $path(cat)]
chan puts -nonewline $f "hi\nwould"
chan flush $f
chan gets $f
chan configure $f -blocking 0
chan gets $f line
} -cleanup {
chan close $f
} -result {-1}
test chan-io-6.8 {Tcl_GetsObj: remember if EOF is seen} -body {
set f [open $path(test1) w]
chan puts $f "abcdef\x1aghijk\nwombat"
chan close $f
set f [open $path(test1)]
chan configure $f -eofchar \x1a
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {6 abcdef -1 {}}
test chan-io-6.9 {Tcl_GetsObj: remember if EOF is seen} -body {
set f [open $path(test1) w]
chan puts $f "abcdefghijk\nwom\u001abat"
chan close $f
set f [open $path(test1)]
chan configure $f -eofchar \x1a
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {11 abcdefghijk 3 wom}
# Comprehensive tests
test chan-io-6.10 {Tcl_GetsObj: lf mode: no chars} -body {
set f [open $path(test1) w]
chan close $f
set f [open $path(test1)]
chan configure $f -translation lf
list [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {-1 {}}
test chan-io-6.11 {Tcl_GetsObj: lf mode: lone \n} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "\n"
chan close $f
set f [open $path(test1)]
chan configure $f -translation lf
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {0 {} -1 {}}
test chan-io-6.12 {Tcl_GetsObj: lf mode: lone \r} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "\r"
chan close $f
set f [open $path(test1)]
chan configure $f -translation lf
set x [list [chan gets $f line] $line [chan gets $f line] $line]
} -cleanup {
chan close $f
} -result [list 1 "\r" -1 ""]
test chan-io-6.13 {Tcl_GetsObj: lf mode: 1 char} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f a
chan close $f
set f [open $path(test1)]
chan configure $f -translation lf
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {1 a -1 {}}
test chan-io-6.14 {Tcl_GetsObj: lf mode: 1 char followed by EOL} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "a\n"
chan close $f
set f [open $path(test1)]
chan configure $f -translation lf
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {1 a -1 {}}
test chan-io-6.15 {Tcl_GetsObj: lf mode: several chars} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
chan close $f
set f [open $path(test1)]
chan configure $f -translation lf
list [chan gets $f line] $line [chan gets $f line] $line \
[chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result [list 4 "abcd" 10 "efgh\rijkl\r" 4 "mnop" -1 ""]
test chan-io-6.16 {Tcl_GetsObj: cr mode: no chars} -body {
set f [open $path(test1) w]
chan close $f
set f [open $path(test1)]
chan configure $f -translation cr
list [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {-1 {}}
test chan-io-6.17 {Tcl_GetsObj: cr mode: lone \n} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "\n"
chan close $f
set f [open $path(test1)]
chan configure $f -translation cr
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result [list 1 "\n" -1 ""]
test chan-io-6.18 {Tcl_GetsObj: cr mode: lone \r} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "\r"
chan close $f
set f [open $path(test1)]
chan configure $f -translation cr
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {0 {} -1 {}}
test chan-io-6.19 {Tcl_GetsObj: cr mode: 1 char} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f a
chan close $f
set f [open $path(test1)]
chan configure $f -translation cr
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {1 a -1 {}}
test chan-io-6.20 {Tcl_GetsObj: cr mode: 1 char followed by EOL} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "a\r"
chan close $f
set f [open $path(test1)]
chan configure $f -translation cr
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {1 a -1 {}}
test chan-io-6.21 {Tcl_GetsObj: cr mode: several chars} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
chan close $f
set f [open $path(test1)]
chan configure $f -translation cr
list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result [list 9 "abcd\nefgh" 4 "ijkl" 5 "\nmnop" -1 ""]
test chan-io-6.22 {Tcl_GetsObj: crlf mode: no chars} -body {
set f [open $path(test1) w]
chan close $f
set f [open $path(test1)]
chan configure $f -translation crlf
list [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {-1 {}}
test chan-io-6.23 {Tcl_GetsObj: crlf mode: lone \n} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "\n"
chan close $f
set f [open $path(test1)]
chan configure $f -translation crlf
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result [list 1 "\n" -1 ""]
test chan-io-6.24 {Tcl_GetsObj: crlf mode: lone \r} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "\r"
chan close $f
set f [open $path(test1)]
chan configure $f -translation crlf
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result [list 1 "\r" -1 ""]
test chan-io-6.25 {Tcl_GetsObj: crlf mode: \r\r} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "\r\r"
chan close $f
set f [open $path(test1)]
chan configure $f -translation crlf
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result [list 2 "\r\r" -1 ""]
test chan-io-6.26 {Tcl_GetsObj: crlf mode: \r\n} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "\r\n"
chan close $f
set f [open $path(test1)]
chan configure $f -translation crlf
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {0 {} -1 {}}
test chan-io-6.27 {Tcl_GetsObj: crlf mode: 1 char} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f a
chan close $f
set f [open $path(test1)]
chan configure $f -translation crlf
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {1 a -1 {}}
test chan-io-6.28 {Tcl_GetsObj: crlf mode: 1 char followed by EOL} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "a\r\n"
chan close $f
set f [open $path(test1)]
chan configure $f -translation crlf
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {1 a -1 {}}
test chan-io-6.29 {Tcl_GetsObj: crlf mode: several chars} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
chan close $f
set f [open $path(test1)]
chan configure $f -translation crlf
list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result [list 14 "abcd\nefgh\rijkl" 4 "mnop" -1 ""]
test chan-io-6.30 {Tcl_GetsObj: crlf mode: buffer exhausted} -constraints {testchannel} -body {
# if (eol >= dstEnd)
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "123456789012345\r\nabcdefghijklmnoprstuvwxyz"
chan close $f
set f [open $path(test1)]
chan configure $f -translation crlf -buffersize 16
list [chan gets $f line] $line [testchannel inputbuffered $f]
} -cleanup {
chan close $f
} -result [list 15 "123456789012345" 15]
test chan-io-6.31 {Tcl_GetsObj: crlf mode: buffer exhausted, blocked} -setup {
set x ""
} -constraints {stdio testchannel fileevent} -body {
# (FilterInputBytes() != 0)
set f [openpipe w+ $path(cat)]
chan configure $f -translation {crlf lf} -buffering none
chan puts -nonewline $f "bbbbbbbbbbbbbb\r\n123456789012345\r"
chan configure $f -buffersize 16
lappend x [chan gets $f]
chan configure $f -blocking 0
lappend x [chan gets $f line] $line [chan blocked $f] \
[testchannel inputbuffered $f]
} -cleanup {
chan close $f
} -result {bbbbbbbbbbbbbb -1 {} 1 16}
test chan-io-6.32 {Tcl_GetsObj: crlf mode: buffer exhausted, more data} -constraints {testchannel} -body {
# not (FilterInputBytes() != 0)
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "123456789012345\r\n123"
chan close $f
set f [open $path(test1)]
chan configure $f -translation crlf -buffersize 16
list [chan gets $f line] $line [chan tell $f] [testchannel inputbuffered $f]
} -cleanup {
chan close $f
} -result {15 123456789012345 17 3}
test chan-io-6.33 {Tcl_GetsObj: crlf mode: buffer exhausted, at eof} -body {
# eol still equals dstEnd
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "123456789012345\r"
chan close $f
set f [open $path(test1)]
chan configure $f -translation crlf -buffersize 16
list [chan gets $f line] $line [chan eof $f]
} -cleanup {
chan close $f
} -result [list 16 "123456789012345\r" 1]
test chan-io-6.34 {Tcl_GetsObj: crlf mode: buffer exhausted, not followed by \n} -body {
# not (*eol == '\n')
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "123456789012345\rabcd\r\nefg"
chan close $f
set f [open $path(test1)]
chan configure $f -translation crlf -buffersize 16
list [chan gets $f line] $line [chan tell $f]
} -cleanup {
chan close $f
} -result [list 20 "123456789012345\rabcd" 22]
test chan-io-6.35 {Tcl_GetsObj: auto mode: no chars} -body {
set f [open $path(test1) w]
chan close $f
set f [open $path(test1)]
chan configure $f -translation auto
list [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {-1 {}}
test chan-io-6.36 {Tcl_GetsObj: auto mode: lone \n} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "\n"
chan close $f
set f [open $path(test1)]
chan configure $f -translation auto
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {0 {} -1 {}}
test chan-io-6.37 {Tcl_GetsObj: auto mode: lone \r} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "\r"
chan close $f
set f [open $path(test1)]
chan configure $f -translation auto
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {0 {} -1 {}}
test chan-io-6.38 {Tcl_GetsObj: auto mode: \r\r} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "\r\r"
chan close $f
set f [open $path(test1)]
chan configure $f -translation auto
list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {0 {} 0 {} -1 {}}
test chan-io-6.39 {Tcl_GetsObj: auto mode: \r\n} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "\r\n"
chan close $f
set f [open $path(test1)]
chan configure $f -translation auto
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {0 {} -1 {}}
test chan-io-6.40 {Tcl_GetsObj: auto mode: 1 char} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f a
chan close $f
set f [open $path(test1)]
chan configure $f -translation auto
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {1 a -1 {}}
test chan-io-6.41 {Tcl_GetsObj: auto mode: 1 char followed by EOL} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "a\r\n"
chan close $f
set f [open $path(test1)]
chan configure $f -translation auto
list [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {1 a -1 {}}
test chan-io-6.42 {Tcl_GetsObj: auto mode: several chars} -setup {
set x ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
chan close $f
set f [open $path(test1)]
chan configure $f -translation auto
lappend x [chan gets $f line] $line [chan gets $f line] $line
lappend x [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {4 abcd 4 efgh 4 ijkl 4 mnop -1 {}}
test chan-io-6.43 {Tcl_GetsObj: input saw cr} -setup {
set x ""
} -constraints {stdio testchannel fileevent} -body {
# if (chanPtr->flags & INPUT_SAW_CR)
set f [openpipe w+ $path(cat)]
chan configure $f -translation {auto lf} -buffering none
chan puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
chan configure $f -buffersize 16
lappend x [chan gets $f]
chan configure $f -blocking 0
lappend x [chan gets $f line] $line [testchannel queuedcr $f]
chan configure $f -blocking 1
chan puts -nonewline $f "\nabcd\refg\x1a"
lappend x [chan gets $f line] $line [testchannel queuedcr $f]
lappend x [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {bbbbbbbbbbbbbbb 15 123456789abcdef 1 4 abcd 0 3 efg}
test chan-io-6.44 {Tcl_GetsObj: input saw cr, not followed by cr} -setup {
set x ""
} -constraints {stdio testchannel fileevent} -body {
# not (*eol == '\n')
set f [openpipe w+ $path(cat)]
chan configure $f -translation {auto lf} -buffering none
chan puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
chan configure $f -buffersize 16
lappend x [chan gets $f]
chan configure $f -blocking 0
lappend x [chan gets $f line] $line [testchannel queuedcr $f]
chan configure $f -blocking 1
chan puts -nonewline $f "abcd\refg\x1a"
lappend x [chan gets $f line] $line [testchannel queuedcr $f]
lappend x [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {bbbbbbbbbbbbbbb 15 123456789abcdef 1 4 abcd 0 3 efg}
test chan-io-6.45 {Tcl_GetsObj: input saw cr, skip right number of bytes} -setup {
set x ""
} -constraints {stdio testchannel fileevent} -body {
# Tcl_ExternalToUtf()
set f [openpipe w+ $path(cat)]
chan configure $f -translation {auto lf} -buffering none
chan configure $f -encoding unicode
chan puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
chan configure $f -buffersize 16
chan gets $f
chan configure $f -blocking 0
lappend x [chan gets $f line] $line [testchannel queuedcr $f]
chan configure $f -blocking 1
chan puts -nonewline $f "\nabcd\refg"
lappend x [chan gets $f line] $line [testchannel queuedcr $f]
} -cleanup {
chan close $f
} -result {15 123456789abcdef 1 4 abcd 0}
test chan-io-6.46 {Tcl_GetsObj: input saw cr, followed by just \n should give eof} -setup {
set x ""
} -constraints {stdio testchannel fileevent} -body {
# memmove()
set f [openpipe w+ $path(cat)]
chan configure $f -translation {auto lf} -buffering none
chan puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
chan configure $f -buffersize 16
chan gets $f
chan configure $f -blocking 0
lappend x [chan gets $f line] $line [testchannel queuedcr $f]
chan configure $f -blocking 1
chan puts -nonewline $f "\n\x1a"
lappend x [chan gets $f line] $line [testchannel queuedcr $f]
} -cleanup {
chan close $f
} -result {15 123456789abcdef 1 -1 {} 0}
test chan-io-6.47 {Tcl_GetsObj: auto mode: \r at end of buffer, peek for \n} -constraints {testchannel} -body {
# (eol == dstEnd)
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "123456789012345\r\nabcdefghijklmnopq"
chan close $f
set f [open $path(test1)]
chan configure $f -translation auto -buffersize 16
list [chan gets $f] [testchannel inputbuffered $f]
} -cleanup {
chan close $f
} -result {123456789012345 15}
test chan-io-6.48 {Tcl_GetsObj: auto mode: \r at end of buffer, no more avail} -constraints {testchannel} -body {
# PeekAhead() did not get any, so (eol >= dstEnd)
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "123456789012345\r"
chan close $f
set f [open $path(test1)]
chan configure $f -translation auto -buffersize 16
list [chan gets $f] [testchannel queuedcr $f]
} -cleanup {
chan close $f
} -result {123456789012345 1}
test chan-io-6.49 {Tcl_GetsObj: auto mode: \r followed by \n} -constraints {testchannel} -body {
# if (*eol == '\n') {skip++}
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "123456\r\n78901"
chan close $f
set f [open $path(test1)]
list [chan gets $f] [testchannel queuedcr $f] [chan tell $f] [chan gets $f]
} -cleanup {
chan close $f
} -result {123456 0 8 78901}
test chan-io-6.50 {Tcl_GetsObj: auto mode: \r not followed by \n} -constraints {testchannel} -body {
# not (*eol == '\n')
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "123456\r78901"
chan close $f
set f [open $path(test1)]
list [chan gets $f] [testchannel queuedcr $f] [chan tell $f] [chan gets $f]
} -cleanup {
chan close $f
} -result {123456 0 7 78901}
test chan-io-6.51 {Tcl_GetsObj: auto mode: \n} -body {
# else if (*eol == '\n') {goto gotoeol;}
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "123456\n78901"
chan close $f
set f [open $path(test1)]
list [chan gets $f] [chan tell $f] [chan gets $f]
} -cleanup {
chan close $f
} -result {123456 7 78901}
test chan-io-6.52 {Tcl_GetsObj: saw EOF character} -constraints {testchannel} -body {
# if (eof != NULL)
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "123456\x1ak9012345\r"
chan close $f
set f [open $path(test1)]
chan configure $f -eofchar \x1a
list [chan gets $f] [testchannel queuedcr $f] [chan tell $f] [chan gets $f]
} -cleanup {
chan close $f
} -result {123456 0 6 {}}
test chan-io-6.53 {Tcl_GetsObj: device EOF} -body {
# didn't produce any bytes
set f [open $path(test1) w]
chan close $f
set f [open $path(test1)]
list [chan gets $f line] $line [chan eof $f]
} -cleanup {
chan close $f
} -result {-1 {} 1}
test chan-io-6.54 {Tcl_GetsObj: device EOF} -body {
# got some bytes before EOF.
set f [open $path(test1) w]
chan puts -nonewline $f abc
chan close $f
set f [open $path(test1)]
list [chan gets $f line] $line [chan eof $f]
} -cleanup {
chan close $f
} -result {3 abc 1}
test chan-io-6.55 {Tcl_GetsObj: overconverted} -body {
# Tcl_ExternalToUtf(), make sure state updated
set f [open $path(test1) w]
chan configure $f -encoding iso2022-jp
chan puts $f "there\u4e00ok\n\u4e01more bytes\nhere"
chan close $f
set f [open $path(test1)]
chan configure $f -encoding iso2022-jp
list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
} -cleanup {
chan close $f
} -result [list 8 "there\u4e00ok" 11 "\u4e01more bytes" 4 "here"]
test chan-io-6.56 {Tcl_GetsObj: incomplete lines should disable file events} -setup {
update
variable x {}
} -constraints {stdio fileevent} -body {
set f [openpipe w+ $path(cat)]
chan configure $f -buffering none
chan puts -nonewline $f "foobar"
chan configure $f -blocking 0
after 500 [namespace code {
lappend x timeout
}]
chan event $f readable [namespace code {
lappend x [chan gets $f]
}]
vwait [namespace which -variable x]
vwait [namespace which -variable x]
chan configure $f -blocking 1
chan puts -nonewline $f "baz\n"
after 500 [namespace code {
lappend x timeout
}]
chan configure $f -blocking 0
vwait [namespace which -variable x]
vwait [namespace which -variable x]
return $x
} -cleanup {
chan close $f
} -result {{} timeout foobarbaz timeout}
test chan-io-7.1 {FilterInputBytes: split up character at end of buffer} -body {
# (result == TCL_CONVERT_MULTIBYTE)
set f [open $path(test1) w]
chan configure $f -encoding shiftjis
chan puts $f "1234567890123\uff10\uff11\uff12\uff13\uff14\nend"
chan close $f
set f [open $path(test1)]
chan configure $f -encoding shiftjis -buffersize 16
chan gets $f
} -cleanup {
chan close $f
} -result "1234567890123\uff10\uff11\uff12\uff13\uff14"
test chan-io-7.2 {FilterInputBytes: split up character in middle of buffer} -body {
# (bufPtr->nextAdded < bufPtr->bufLength)
set f [open $path(test1) w]
chan configure $f -encoding binary
chan puts -nonewline $f "1234567890\n123\x82\x4f\x82\x50\x82"
chan close $f
set f [open $path(test1)]
chan configure $f -encoding shiftjis
list [chan gets $f line] $line [chan eof $f]
} -cleanup {
chan close $f
} -result {10 1234567890 0}
test chan-io-7.3 {FilterInputBytes: split up character at EOF} -setup {
set x ""
} -constraints {testchannel} -body {
set f [open $path(test1) w]
chan configure $f -encoding binary
chan puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
chan close $f
set f [open $path(test1)]
chan configure $f -encoding shiftjis
lappend x [chan gets $f line] $line
lappend x [chan tell $f] [testchannel inputbuffered $f] [chan eof $f]
lappend x [chan gets $f line] $line
} -cleanup {
chan close $f
} -result [list 15 "1234567890123\uff10\uff11" 18 0 1 -1 ""]
test chan-io-7.4 {FilterInputBytes: recover from split up character} -setup {
variable x ""
} -constraints {stdio fileevent} -body {
set f [openpipe w+ $path(cat)]
chan configure $f -encoding binary -buffering none
chan puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
chan configure $f -encoding shiftjis -blocking 0
chan event $f read [namespace code {
lappend x [chan gets $f line] $line [chan blocked $f]
}]
vwait [namespace which -variable x]
chan configure $f -encoding binary -blocking 1
chan puts $f "\x51\x82\x52"
chan configure $f -encoding shiftjis
vwait [namespace which -variable x]
return $x
} -cleanup {
chan close $f
} -result [list -1 "" 1 17 "1234567890123\uff10\uff11\uff12\uff13" 0]
test chan-io-8.1 {PeekAhead: only go to device if no more cached data} -constraints {testchannel} -body {
# (bufPtr->nextPtr == NULL)
set f [open $path(test1) w]
chan configure $f -encoding ascii -translation lf
chan puts -nonewline $f "123456789012345\r\n2345678"
chan close $f
set f [open $path(test1)]
chan configure $f -encoding ascii -translation auto -buffersize 16
# here
chan gets $f
testchannel inputbuffered $f
} -cleanup {
chan close $f
} -result 7
test chan-io-8.2 {PeekAhead: only go to device if no more cached data} -setup {
variable x {}
} -constraints {stdio testchannel fileevent} -body {
# not (bufPtr->nextPtr == NULL)
set f [openpipe w+ $path(cat)]
chan configure $f -translation lf -encoding ascii -buffering none
chan puts -nonewline $f "123456789012345\r\nbcdefghijklmnopqrstuvwxyz"
chan event $f read [namespace code {
lappend x [chan gets $f line] $line [testchannel inputbuffered $f]
}]
chan configure $f -encoding unicode -buffersize 16 -blocking 0
vwait [namespace which -variable x]
chan configure $f -translation auto -encoding ascii -blocking 1
# here
vwait [namespace which -variable x]
return $x
} -cleanup {
chan close $f
} -result {-1 {} 42 15 123456789012345 25}
test chan-io-8.3 {PeekAhead: no cached data available} -constraints {stdio testchannel fileevent} -body {
# (bytesLeft == 0)
set f [openpipe w+ $path(cat)]
chan configure $f -translation {auto binary}
chan puts -nonewline $f "abcdefghijklmno\r"
chan flush $f
list [chan gets $f line] $line [testchannel queuedcr $f]
} -cleanup {
chan close $f
} -result {15 abcdefghijklmno 1}
set a "123456789012345678901234567890"
append a "123456789012345678901234567890"
append a "1234567890123456789012345678901"
test chan-io-8.4 {PeekAhead: cached data available in this buffer} -body {
# not (bytesLeft == 0)
set f [open $path(test1) w+]
chan configure $f -translation binary
chan puts $f "${a}\r\nabcdef"
chan close $f
set f [open $path(test1)]
chan configure $f -encoding binary -translation auto
# "${a}\r" was converted in one operation (because ENCODING_LINESIZE is
# 30). To check if "\n" follows, calls PeekAhead and determines that
# cached data is available in buffer w/o having to call driver.
chan gets $f
} -cleanup {
chan close $f
} -result $a
unset a
test chan-io-8.5 {PeekAhead: don't peek if last read was short} -constraints {stdio testchannel fileevent} -body {
# (bufPtr->nextAdded < bufPtr->length)
set f [openpipe w+ $path(cat)]
chan configure $f -translation {auto binary}
chan puts -nonewline $f "abcdefghijklmno\r"
chan flush $f
# here
list [chan gets $f line] $line [testchannel queuedcr $f]
} -cleanup {
chan close $f
} -result {15 abcdefghijklmno 1}
test chan-io-8.6 {PeekAhead: change to non-blocking mode} -constraints {stdio testchannel fileevent} -body {
# ((chanPtr->flags & CHANNEL_NONBLOCKING) == 0)
set f [openpipe w+ $path(cat)]
chan configure $f -translation {auto binary} -buffersize 16
chan puts -nonewline $f "abcdefghijklmno\r"
chan flush $f
# here
list [chan gets $f line] $line [testchannel queuedcr $f]
} -cleanup {
chan close $f
} -result {15 abcdefghijklmno 1}
test chan-io-8.7 {PeekAhead: cleanup} -setup {
set x ""
} -constraints {stdio testchannel fileevent} -body {
# Make sure bytes are removed from buffer.
set f [openpipe w+ $path(cat)]
chan configure $f -translation {auto binary} -buffering none
chan puts -nonewline $f "abcdefghijklmno\r"
# here
lappend x [chan gets $f line] $line [testchannel queuedcr $f]
chan puts -nonewline $f "\x1a"
lappend x [chan gets $f line] $line
} -cleanup {
chan close $f
} -result {15 abcdefghijklmno 1 -1 {}}
test chan-io-9.1 {CommonGetsCleanup} emptyTest {
} {}
test chan-io-10.1 {Tcl_ReadChars: CheckChannelErrors} emptyTest {
# no test, need to cause an async error.
} {}
test chan-io-10.2 {Tcl_ReadChars: loop until enough copied} -body {
# one time
# for (copied = 0; (unsigned) toRead > 0; )
set f [open $path(test1) w]
chan puts $f abcdefghijklmnop
chan close $f
set f [open $path(test1)]
chan read $f 5
} -cleanup {
chan close $f
} -result {abcde}
test chan-io-10.3 {Tcl_ReadChars: loop until enough copied} -body {
# multiple times
# for (copied = 0; (unsigned) toRead > 0; )
set f [open $path(test1) w]
chan puts $f abcdefghijklmnopqrstuvwxyz
chan close $f
set f [open $path(test1)]
chan configure $f -buffersize 16
# here
chan read $f 19
} -cleanup {
chan close $f
} -result {abcdefghijklmnopqrs}
test chan-io-10.4 {Tcl_ReadChars: no more in channel buffer} -body {
# (copiedNow < 0)
set f [open $path(test1) w]
chan puts -nonewline $f abcdefghijkl
chan close $f
set f [open $path(test1)]
# here
chan read $f 1000
} -cleanup {
chan close $f
} -result {abcdefghijkl}
test chan-io-10.5 {Tcl_ReadChars: stop on EOF} -body {
# (chanPtr->flags & CHANNEL_EOF)
set f [open $path(test1) w]
chan puts -nonewline $f abcdefghijkl
chan close $f
set f [open $path(test1)]
# here
chan read $f 1000
} -cleanup {
chan close $f
} -result {abcdefghijkl}
test chan-io-11.1 {ReadBytes: want to read a lot} -body {
# ((unsigned) toRead > (unsigned) srcLen)
set f [open $path(test1) w]
chan puts -nonewline $f abcdefghijkl
chan close $f
set f [open $path(test1)]
chan configure $f -encoding binary
# here
chan read $f 1000
} -cleanup {
chan close $f
} -result {abcdefghijkl}
test chan-io-11.2 {ReadBytes: want to read all} -body {
# ((unsigned) toRead > (unsigned) srcLen)
set f [open $path(test1) w]
chan puts -nonewline $f abcdefghijkl
chan close $f
set f [open $path(test1)]
chan configure $f -encoding binary
# here
chan read $f
} -cleanup {
chan close $f
} -result {abcdefghijkl}
test chan-io-11.3 {ReadBytes: allocate more space} -body {
# (toRead > length - offset - 1)
set f [open $path(test1) w]
chan puts -nonewline $f abcdefghijklmnopqrstuvwxyz
chan close $f
set f [open $path(test1)]
chan configure $f -buffersize 16 -encoding binary
# here
chan read $f
} -cleanup {
chan close $f
} -result {abcdefghijklmnopqrstuvwxyz}
test chan-io-11.4 {ReadBytes: EOF char found} -body {
# (TranslateInputEOL() != 0)
set f [open $path(test1) w]
chan puts $f abcdefghijklmnopqrstuvwxyz
chan close $f
set f [open $path(test1)]
chan configure $f -eofchar m -encoding binary
# here
list [chan read $f] [chan eof $f] [chan read $f] [chan eof $f]
} -cleanup {
chan close $f
} -result {abcdefghijkl 1 {} 1}
test chan-io-12.1 {ReadChars: want to read a lot} -body {
# ((unsigned) toRead > (unsigned) srcLen)
set f [open $path(test1) w]
chan puts -nonewline $f abcdefghijkl
chan close $f
set f [open $path(test1)]
# here
chan read $f 1000
} -cleanup {
chan close $f
} -result {abcdefghijkl}
test chan-io-12.2 {ReadChars: want to read all} -body {
# ((unsigned) toRead > (unsigned) srcLen)
set f [open $path(test1) w]
chan puts -nonewline $f abcdefghijkl
chan close $f
set f [open $path(test1)]
# here
chan read $f
} -cleanup {
chan close $f
} -result {abcdefghijkl}
test chan-io-12.3 {ReadChars: allocate more space} -body {
# (toRead > length - offset - 1)
set f [open $path(test1) w]
chan puts -nonewline $f abcdefghijklmnopqrstuvwxyz
chan close $f
set f [open $path(test1)]
chan configure $f -buffersize 16
# here
chan read $f
} -cleanup {
chan close $f
} -result {abcdefghijklmnopqrstuvwxyz}
test chan-io-12.4 {ReadChars: split-up char} -setup {
variable x {}
} -constraints {stdio testchannel fileevent} -body {
# (srcRead == 0)
set f [openpipe w+ $path(cat)]
chan configure $f -encoding binary -buffering none -buffersize 16
chan puts -nonewline $f "123456789012345\x96"
chan configure $f -encoding shiftjis -blocking 0
chan event $f read [namespace code {
lappend x [chan read $f] [testchannel inputbuffered $f]
}]
chan configure $f -encoding shiftjis
vwait [namespace which -variable x]
chan configure $f -encoding binary -blocking 1
chan puts -nonewline $f "\x7b"
after 500 ;# Give the cat process time to catch up
chan configure $f -encoding shiftjis -blocking 0
vwait [namespace which -variable x]
return $x
} -cleanup {
chan close $f
} -result [list "123456789012345" 1 "\u672c" 0]
test chan-io-12.5 {ReadChars: chan events on partial characters} -setup {
variable x {}
} -constraints {stdio fileevent} -body {
set path(test1) [makeFile {
chan configure stdout -encoding binary -buffering none
chan gets stdin; chan puts -nonewline "\xe7"
chan gets stdin; chan puts -nonewline "\x89"
chan gets stdin; chan puts -nonewline "\xa6"
} test1]
set f [openpipe r+ $path(test1)]
chan event $f readable [namespace code {
lappend x [chan read $f]
if {[chan eof $f]} {
lappend x eof
}
}]
chan puts $f "go1"
chan flush $f
chan configure $f -blocking 0 -encoding utf-8
vwait [namespace which -variable x]
after 500 [namespace code { lappend x timeout }]
vwait [namespace which -variable x]
chan puts $f "go2"
chan flush $f
vwait [namespace which -variable x]
after 500 [namespace code { lappend x timeout }]
vwait [namespace which -variable x]
chan puts $f "go3"
chan flush $f
vwait [namespace which -variable x]
vwait [namespace which -variable x]
lappend x [catch {chan close $f} msg] $msg
} -result "{} timeout {} timeout \u7266 {} eof 0 {}"
test chan-io-13.1 {TranslateInputEOL: cr mode} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "abcd\rdef\r"
chan close $f
set f [open $path(test1)]
chan configure $f -translation cr
chan read $f
} -cleanup {
chan close $f
} -result "abcd\ndef\n"
test chan-io-13.2 {TranslateInputEOL: crlf mode} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "abcd\r\ndef\r\n"
chan close $f
set f [open $path(test1)]
chan configure $f -translation crlf
chan read $f
} -cleanup {
chan close $f
} -result "abcd\ndef\n"
test chan-io-13.3 {TranslateInputEOL: crlf mode: naked cr} -body {
# (src >= srcMax)
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "abcd\r\ndef\r"
chan close $f
set f [open $path(test1)]
chan configure $f -translation crlf
chan read $f
} -cleanup {
chan close $f
} -result "abcd\ndef\r"
test chan-io-13.4 {TranslateInputEOL: crlf mode: cr followed by not \n} -body {
# (src >= srcMax)
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "abcd\r\ndef\rfgh"
chan close $f
set f [open $path(test1)]
chan configure $f -translation crlf
chan read $f
} -cleanup {
chan close $f
} -result "abcd\ndef\rfgh"
test chan-io-13.5 {TranslateInputEOL: crlf mode: naked lf} -body {
# (src >= srcMax)
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "abcd\r\ndef\nfgh"
chan close $f
set f [open $path(test1)]
chan configure $f -translation crlf
chan read $f
} -cleanup {
chan close $f
} -result "abcd\ndef\nfgh"
test chan-io-13.6 {TranslateInputEOL: auto mode: saw cr in last segment} -setup {
variable x {}
variable y {}
} -constraints {stdio testchannel fileevent} -body {
# (chanPtr->flags & INPUT_SAW_CR)
# This test may fail on slower machines.
set f [openpipe w+ $path(cat)]
chan configure $f -blocking 0 -buffering none -translation {auto lf}
chan event $f read [namespace code {
lappend x [chan read $f] [testchannel queuedcr $f]
}]
chan puts -nonewline $f "abcdefghj\r"
after 500 [namespace code {set y ok}]
vwait [namespace which -variable y]
chan puts -nonewline $f "\n01234"
after 500 [namespace code {set y ok}]
vwait [namespace which -variable y]
return $x
} -cleanup {
chan close $f
} -result [list "abcdefghj\n" 1 "01234" 0]
test chan-io-13.7 {TranslateInputEOL: auto mode: naked \r} -constraints testchannel -body {
# (src >= srcMax)
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "abcd\r"
chan close $f
set f [open $path(test1)]
chan configure $f -translation auto
list [chan read $f] [testchannel queuedcr $f]
} -cleanup {
chan close $f
} -result [list "abcd\n" 1]
test chan-io-13.8 {TranslateInputEOL: auto mode: \r\n} -body {
# (*src == '\n')
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "abcd\r\ndef"
chan close $f
set f [open $path(test1)]
chan configure $f -translation auto
chan read $f
} -cleanup {
chan close $f
} -result "abcd\ndef"
test chan-io-13.9 {TranslateInputEOL: auto mode: \r followed by not \n} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "abcd\rdef"
chan close $f
set f [open $path(test1)]
chan configure $f -translation auto
chan read $f
} -cleanup {
chan close $f
} -result "abcd\ndef"
test chan-io-13.10 {TranslateInputEOL: auto mode: \n} -body {
# not (*src == '\r')
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "abcd\ndef"
chan close $f
set f [open $path(test1)]
chan configure $f -translation auto
chan read $f
} -cleanup {
chan close $f
} -result "abcd\ndef"
test chan-io-13.11 {TranslateInputEOL: EOF char} -body {
# (*chanPtr->inEofChar != '\0')
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "abcd\ndefgh"
chan close $f
set f [open $path(test1)]
chan configure $f -translation auto -eofchar e
chan read $f
} -cleanup {
chan close $f
} -result "abcd\nd"
test chan-io-13.12 {TranslateInputEOL: find EOF char in src} -body {
# (*chanPtr->inEofChar != '\0')
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "\r\n\r\n\r\nab\r\n\r\ndef\r\n\r\n\r\n"
chan close $f
set f [open $path(test1)]
chan configure $f -translation auto -eofchar e
chan read $f
} -cleanup {
chan close $f
} -result "\n\n\nab\n\nd"
# Test standard handle management. The functions tested are Tcl_SetStdChannel
# and Tcl_GetStdChannel. Incidentally we are also testing channel table
# management.
if {[testConstraint testchannel]} {
set consoleFileNames [lsort [testchannel open]]
} else {
# just to avoid an error
set consoleFileNames [list]
}
test chan-io-14.1 {Tcl_SetStdChannel and Tcl_GetStdChannel} {testchannel} {
set result ""
lappend result [chan configure stdin -buffering]
lappend result [chan configure stdout -buffering]
lappend result [chan configure stderr -buffering]
lappend result [lsort [testchannel open]]
} [list line line none $consoleFileNames]
test chan-io-14.2 {Tcl_SetStdChannel and Tcl_GetStdChannel} -setup {
interp create x
set result ""
} -body {
lappend result [x eval {chan configure stdin -buffering}]
lappend result [x eval {chan configure stdout -buffering}]
lappend result [x eval {chan configure stderr -buffering}]
} -cleanup {
interp delete x
} -result {line line none}
set path(test3) [makeFile {} test3]
test chan-io-14.3 {Tcl_SetStdChannel & Tcl_GetStdChannel} -constraints exec -body {
set f [open $path(test1) w]
chan puts -nonewline $f {
chan close stdin
chan close stdout
chan close stderr
set f [}
chan puts $f [list open $path(test1) r]]
chan puts $f "set f2 \[[list open $path(test2) w]]"
chan puts $f "set f3 \[[list open $path(test3) w]]"
chan puts $f { chan puts stdout [chan gets stdin]
chan puts stdout out
chan puts stderr err
chan close $f
chan close $f2
chan close $f3
}
chan close $f
set result [exec [interpreter] $path(test1)]
set f [open $path(test2) r]
set f2 [open $path(test3) r]
lappend result [chan read $f] [chan read $f2]
} -cleanup {
chan close $f
chan close $f2
} -result {{
out
} {err
}}
# This test relies on the fact that stdout is used before stderr.
test chan-io-14.4 {Tcl_SetStdChannel & Tcl_GetStdChannel} -constraints {exec} -body {
set f [open $path(test1) w]
chan puts -nonewline $f { chan close stdin
chan close stdout
chan close stderr
set f [}
chan puts $f [list open $path(test1) r]]
chan puts $f "set f2 \[[list open $path(test2) w]]"
chan puts $f "set f3 \[[list open $path(test3) w]]"
chan puts $f {
chan puts stdout [chan gets stdin]
chan puts stdout $f2
chan puts stderr $f3
chan close $f
chan close $f2
chan close $f3
}
chan close $f
set result [exec [interpreter] $path(test1)]
set f [open $path(test2) r]
set f2 [open $path(test3) r]
lappend result [chan read $f] [chan read $f2]
} -cleanup {
chan close $f
chan close $f2
} -result {{ chan close stdin
stdout
} {stderr
}}
catch {interp delete z}
test chan-io-14.5 {Tcl_GetChannel: stdio name translation} -setup {
interp create z
} -body {
chan eof stdin
catch {z eval chan flush stdin} msg1
catch {z eval chan close stdin} msg2
catch {z eval chan flush stdin} msg3
list $msg1 $msg2 $msg3
} -cleanup {
interp delete z
} -result {{channel "stdin" wasn't opened for writing} {} {can not find channel named "stdin"}}
test chan-io-14.6 {Tcl_GetChannel: stdio name translation} -setup {
interp create z
} -body {
chan eof stdout
catch {z eval chan flush stdout} msg1
catch {z eval chan close stdout} msg2
catch {z eval chan flush stdout} msg3
list $msg1 $msg2 $msg3
} -cleanup {
interp delete z
} -result {{} {} {can not find channel named "stdout"}}
test chan-io-14.7 {Tcl_GetChannel: stdio name translation} -setup {
interp create z
} -body {
chan eof stderr
catch {z eval chan flush stderr} msg1
catch {z eval chan close stderr} msg2
catch {z eval chan flush stderr} msg3
list $msg1 $msg2 $msg3
} -cleanup {
interp delete z
} -result {{} {} {can not find channel named "stderr"}}
set path(script) [makeFile {} script]
test chan-io-14.8 {reuse of stdio special channels} -setup {
file delete $path(script)
file delete $path(test1)
} -constraints stdio -body {
set f [open $path(script) w]
chan puts -nonewline $f {
chan close stderr
set f [}
chan puts $f [list open $path(test1) w]]
chan puts -nonewline $f {
chan puts stderr hello
chan close $f
set f [}
chan puts $f [list open $path(test1) r]]
chan puts $f {
chan puts [chan gets $f]
}
chan close $f
set f [openpipe r $path(script)]
chan gets $f
} -cleanup {
chan close $f
} -result hello
test chan-io-14.9 {reuse of stdio special channels} -setup {
file delete $path(script)
file delete $path(test1)
} -constraints {stdio fileevent} -body {
set f [open $path(script) w]
chan puts $f {
array set path [lindex $argv 0]
set f [open $path(test1) w]
chan puts $f hello
chan close $f
chan close stderr
set f [open "|[list [info nameofexecutable] $path(cat) $path(test1)]" r]
chan puts [chan gets $f]
}
chan close $f
set f [openpipe r $path(script) [array get path]]
chan gets $f
} -cleanup {
chan close $f
# Added delay to give Windows time to stop the spawned process and clean
# up its grip on the file test1. Added delete as proper test cleanup.
# The failing tests were 18.1 and 18.2 as first re-users of file "test1".
after [expr {[testConstraint win] ? 10000 : 500}]
file delete $path(script)
file delete $path(test1)
} -result hello
test chan-io-15.1 {Tcl_CreateChan CloseHandler} emptyTest {
} {}
test chan-io-16.1 {Tcl_DeleteChan CloseHandler} emptyTest {
} {}
# Test channel table management. The functions tested are GetChannelTable,
# DeleteChannelTable, Tcl_RegisterChannel, Tcl_UnregisterChannel,
# Tcl_GetChannel and Tcl_CreateChannel.
#
# These functions use "eof stdin" to ensure that the standard channels are
# added to the channel table of the interpreter.
test chan-io-17.1 {GetChannelTable, DeleteChannelTable on std handles} -setup {
set l ""
} -constraints {testchannel} -body {
set l1 [testchannel refcount stdin]
chan eof stdin
interp create x
lappend l [expr {[testchannel refcount stdin] - $l1}]
x eval {chan eof stdin}
lappend l [expr {[testchannel refcount stdin] - $l1}]
interp delete x
lappend l [expr {[testchannel refcount stdin] - $l1}]
} -result {0 1 0}
test chan-io-17.2 {GetChannelTable, DeleteChannelTable on std handles} -setup {
set l ""
} -constraints {testchannel} -body {
set l1 [testchannel refcount stdout]
chan eof stdin
interp create x
lappend l [expr {[testchannel refcount stdout] - $l1}]
x eval {chan eof stdout}
lappend l [expr {[testchannel refcount stdout] - $l1}]
interp delete x
lappend l [expr {[testchannel refcount stdout] - $l1}]
} -result {0 1 0}
test chan-io-17.3 {GetChannelTable, DeleteChannelTable on std handles} -setup {
set l ""
} -constraints {testchannel} -body {
set l1 [testchannel refcount stderr]
chan eof stdin
interp create x
lappend l [expr {[testchannel refcount stderr] - $l1}]
x eval {chan eof stderr}
lappend l [expr {[testchannel refcount stderr] - $l1}]
interp delete x
lappend l [expr {[testchannel refcount stderr] - $l1}]
} -result {0 1 0}
test chan-io-18.1 {Tcl_RegisterChannel, Tcl_UnregisterChannel} -setup {
file delete -force $path(test1)
set l ""
} -constraints {testchannel} -body {
set f [open $path(test1) w]
lappend l [lindex [testchannel info $f] 15]
chan close $f
if {[catch {lindex [testchannel info $f] 15} msg]} {
lappend l $msg
} else {
lappend l "very broken: $f found after being chan closed"
}
string equal $l [list 1 "can not find channel named \"$f\""]
} -result 1
test chan-io-18.2 {Tcl_RegisterChannel, Tcl_UnregisterChannel} -setup {
file delete -force $path(test1)
set l ""
} -constraints {testchannel} -body {
set f [open $path(test1) w]
lappend l [lindex [testchannel info $f] 15]
interp create x
interp share "" $f x
lappend l [lindex [testchannel info $f] 15]
x eval chan close $f
lappend l [lindex [testchannel info $f] 15]
interp delete x
lappend l [lindex [testchannel info $f] 15]
chan close $f
if {[catch {lindex [testchannel info $f] 15} msg]} {
lappend l $msg
} else {
lappend l "very broken: $f found after being chan closed"
}
string equal $l [list 1 2 1 1 "can not find channel named \"$f\""]
} -result 1
test chan-io-18.3 {Tcl_RegisterChannel, Tcl_UnregisterChannel} -setup {
file delete $path(test1)
set l ""
} -constraints {testchannel} -body {
set f [open $path(test1) w]
lappend l [lindex [testchannel info $f] 15]
interp create x
interp share "" $f x
lappend l [lindex [testchannel info $f] 15]
interp delete x
lappend l [lindex [testchannel info $f] 15]
chan close $f
if {[catch {lindex [testchannel info $f] 15} msg]} {
lappend l $msg
} else {
lappend l "very broken: $f found after being chan closed"
}
string equal $l [list 1 2 1 "can not find channel named \"$f\""]
} -result 1
test chan-io-19.1 {Tcl_GetChannel->Tcl_GetStdChannel, standard handles} {
chan eof stdin
} 0
test chan-io-19.2 {testing Tcl_GetChannel, user opened handle} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan eof $f
} -cleanup {
chan close $f
} -result 0
test chan-io-19.3 {Tcl_GetChannel, channel not found} -body {
chan eof file34
} -returnCodes error -result {can not find channel named "file34"}
test chan-io-19.4 {Tcl_CreateChannel, insertion into channel table} -setup {
file delete $path(test1)
set l ""
} -constraints {testchannel} -body {
set f [open $path(test1) w]
lappend l [chan eof $f]
chan close $f
if {[catch {lindex [testchannel info $f] 15} msg]} {
lappend l $msg
} else {
lappend l "very broken: $f found after being chan closed"
}
string equal $l [list 0 "can not find channel named \"$f\""]
} -result 1
test chan-io-20.1 {Tcl_CreateChannel: initial settings} -setup {
set old [encoding system]
} -body {
set a [open $path(test2) w]
encoding system ascii
set f [open $path(test1) w]
chan configure $f -encoding
} -cleanup {
encoding system $old
chan close $f
chan close $a
} -result {ascii}
test chan-io-20.2 {Tcl_CreateChannel: initial settings} -constraints {win} -body {
set f [open $path(test1) w+]
list [chan configure $f -eofchar] [chan configure $f -translation]
} -cleanup {
chan close $f
} -result [list [list \x1a ""] {auto crlf}]
test chan-io-20.3 {Tcl_CreateChannel: initial settings} -constraints {unix} -body {
set f [open $path(test1) w+]
list [chan configure $f -eofchar] [chan configure $f -translation]
} -cleanup {
chan close $f
} -result {{{} {}} {auto lf}}
test chan-io-20.5 {Tcl_CreateChannel: install channel in empty slot} -setup {
set path(stdout) [makeFile {} stdout]
} -constraints {stdio notWinCI} -body {
set f [open $path(script) w]
chan puts -nonewline $f {
chan close stdout
set f1 [}
chan puts $f [list open $path(stdout) w]]
chan puts $f {
chan configure $f1 -buffersize 777
chan puts stderr [chan configure stdout -buffersize]
}
chan close $f
set f [openpipe r $path(script)]
chan close $f
} -cleanup {
removeFile $path(stdout)
} -returnCodes error -result {777}
test chan-io-21.1 {Chan CloseChannelsOnExit} emptyTest {
} {}
# Test management of attributes associated with a channel, such as its default
# translation, its name and type, etc. The functions tested in this group are
# Tcl_GetChannelName, Tcl_GetChannelType and Tcl_GetChannelFile.
# Tcl_GetChannelInstanceData not tested because files do not use the instance
# data.
test chan-io-22.1 {Tcl_GetChannelMode} emptyTest {
# Not used anywhere in Tcl.
} {}
test chan-io-23.1 {Tcl_GetChannelName} -constraints {testchannel} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
set n [testchannel name $f]
expr {$n eq $f ? "ok" : "$n != $f"}
} -cleanup {
chan close $f
} -result ok
test chan-io-24.1 {Tcl_GetChannelType} -constraints {testchannel} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
testchannel type $f
} -cleanup {
chan close $f
} -result "file"
test chan-io-25.1 {Tcl_GetChannelHandle, input} -setup {
set l ""
} -constraints {testchannel} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -eofchar {}
chan puts $f "1234567890\n098765432"
chan close $f
set f [open $path(test1) r]
chan gets $f
lappend l [testchannel inputbuffered $f]
lappend l [chan tell $f]
} -cleanup {
chan close $f
} -result {10 11}
test chan-io-25.2 {Tcl_GetChannelHandle, output} -setup {
file delete $path(test1)
set l ""
} -constraints {testchannel} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f hello
lappend l [testchannel outputbuffered $f]
lappend l [chan tell $f]
chan flush $f
lappend l [testchannel outputbuffered $f]
lappend l [chan tell $f]
} -cleanup {
chan close $f
file delete $path(test1)
} -result {6 6 0 6}
test chan-io-26.1 {Tcl_GetChannelInstanceData} -body {
# "pid" command uses Tcl_GetChannelInstanceData
# Don't care what pid is (but must be a number), just want to exercise it.
set f [openpipe r << exit]
pid $f
} -constraints stdio -cleanup {
chan close $f
} -match regexp -result {^\d+$}
# Test flushing. The functions tested here are FlushChannel.
test chan-io-27.1 {FlushChannel, no output buffered} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan flush $f
file size $path(test1)
} -cleanup {
chan close $f
} -result 0
test chan-io-27.2 {FlushChannel, some output buffered} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -eofchar {}
chan puts $f hello
lappend l [file size $path(test1)]
chan flush $f
lappend l [file size $path(test1)]
chan close $f
lappend l [file size $path(test1)]
} -result {0 6 6}
test chan-io-27.3 {FlushChannel, implicit flush on chan close} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -eofchar {}
chan puts $f hello
lappend l [file size $path(test1)]
chan close $f
lappend l [file size $path(test1)]
} -result {0 6}
test chan-io-27.4 {FlushChannel, implicit flush when buffer fills} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -eofchar {}
chan configure $f -buffersize 60
lappend l [file size $path(test1)]
for {set i 0} {$i < 12} {incr i} {
chan puts $f hello
}
lappend l [file size $path(test1)]
chan flush $f
lappend l [file size $path(test1)]
} -cleanup {
chan close $f
} -result {0 60 72}
test chan-io-27.5 {FlushChannel, implicit flush when buffer fills and on chan close} -setup {
file delete $path(test1)
set l ""
} -constraints {unixOrWin} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -buffersize 60 -eofchar {}
lappend l [file size $path(test1)]
for {set i 0} {$i < 12} {incr i} {
chan puts $f hello
}
lappend l [file size $path(test1)]
chan close $f
lappend l [file size $path(test1)]
} -result {0 60 72}
set path(pipe) [makeFile {} pipe]
set path(output) [makeFile {} output]
test chan-io-27.6 {FlushChannel, async flushing, async chan close} -setup {
file delete $path(pipe)
file delete $path(output)
} -constraints {stdio asyncPipeChan Close} -body {
set f [open $path(pipe) w]
chan puts $f "set f \[[list open $path(output) w]]"
chan puts $f {
chan configure $f -translation lf -buffering none -eofchar {}
while {![chan eof stdin]} {
after 20
chan puts -nonewline $f [chan read stdin 1024]
}
chan close $f
}
chan close $f
set x 01234567890123456789012345678901
for {set i 0} {$i < 11} {incr i} {
set x "$x$x"
}
set f [open $path(output) w]
chan close $f
set f [openpipe w $path(pipe)]
chan configure $f -blocking off
chan puts -nonewline $f $x
chan close $f
set counter 0
while {([file size $path(output)] < 65536) && ($counter < 1000)} {
after 20 [list incr [namespace which -variable counter]]
vwait [namespace which -variable counter]
}
if {$counter == 1000} {
set result "file size only [file size $path(output)]"
} else {
set result ok
}
} -result ok
# Tests closing a channel. The functions tested are Chan CloseChannel and
# Tcl_Chan Close.
test chan-io-28.1 {Chan CloseChannel called when all references are dropped} -setup {
file delete $path(test1)
set l ""
} -constraints {testchannel} -body {
set f [open $path(test1) w]
interp create x
interp share "" $f x
lappend l [testchannel refcount $f]
x eval chan close $f
interp delete x
lappend l [testchannel refcount $f]
} -cleanup {
chan close $f
} -result {2 1}
test chan-io-28.2 {Chan CloseChannel called when all references are dropped} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
interp create x
interp share "" $f x
chan puts -nonewline $f abc
chan close $f
x eval chan puts $f def
x eval chan close $f
interp delete x
set f [open $path(test1) r]
chan gets $f
} -cleanup {
chan close $f
} -result abcdef
test chan-io-28.3 {Chan CloseChannel, not called before output queue is empty} -setup {
file delete $path(pipe)
file delete $path(output)
} -constraints {stdio asyncPipeChan Close nonPortable} -body {
set f [open $path(pipe) w]
chan puts $f {
# Need to not have eof char appended on chan close, because the other
# side of the pipe already chan closed, so that writing would cause an
# error "invalid file".
chan configure stdout -eofchar {}
chan configure stderr -eofchar {}
set f [open $path(output) w]
chan configure $f -translation lf -buffering none
for {set x 0} {$x < 20} {incr x} {
after 20
chan puts -nonewline $f [chan read stdin 1024]
}
chan close $f
}
chan close $f
set x 01234567890123456789012345678901
for {set i 0} {$i < 11} {incr i} {
set x "$x$x"
}
set f [open $path(output) w]
chan close $f
set f [openpipe r+ $path(pipe)]
chan configure $f -blocking off -eofchar {}
chan puts -nonewline $f $x
chan close $f
set counter 0
while {([file size $path(output)] < 20480) && ($counter < 1000)} {
after 20 [list incr [namespace which -variable counter]]
vwait [namespace which -variable counter]
}
if {$counter == 1000} {
set result probably_broken
} else {
set result ok
}
} -result ok
test chan-io-28.4 {Tcl_Chan Close} -constraints {testchannel} -setup {
file delete $path(test1)
set l ""
} -body {
lappend l [lsort [testchannel open]]
set f [open $path(test1) w]
lappend l [lsort [testchannel open]]
chan close $f
lappend l [lsort [testchannel open]]
set x [list $consoleFileNames \
[lsort [list {*}$consoleFileNames $f]] \
$consoleFileNames]
expr {$l eq $x ? "ok" : "{$l} != {$x}"}
} -result ok
test chan-io-28.5 {Tcl_Chan Close vs standard handles} -setup {
file delete $path(script)
} -constraints {stdio unix testchannel} -body {
set f [open $path(script) w]
chan puts $f {
chan close stdin
chan puts [testchannel open]
}
chan close $f
set f [openpipe r $path(script)]
set l [chan gets $f]
chan close $f
lsort $l
} -result {file1 file2}
test chan-io-28.6 {Tcl_CloseEx (half-close) pipe} -setup {
set cat [makeFile {
fconfigure stdout -buffering line
while {[gets stdin line] >= 0} {puts $line}
puts DONE
exit 0
} cat.tcl]
variable done
} -body {
set ff [openpipe r+ $cat]
puts $ff Hey
close $ff w
set timer [after 1000 [namespace code {set done Failed}]]
set acc {}
fileevent $ff readable [namespace code {
if {[gets $ff line] < 0} {
set done Succeeded
} else {
lappend acc $line
}
}]
vwait [namespace which -variable done]
after cancel $timer
close $ff r
list $done $acc
} -cleanup {
removeFile cat.tcl
} -result {Succeeded {Hey DONE}}
test chan-io-28.7 {Tcl_CloseEx (half-close) socket} -setup {
set echo [makeFile {
proc accept {s args} {set ::sok $s}
set s [socket -server accept 0]
puts [lindex [fconfigure $s -sockname] 2]
flush stdout
vwait ::sok
fconfigure $sok -buffering line
while {[gets $sok line]>=0} {puts $sok $line}
puts $sok DONE
exit 0
} echo.tcl]
variable done
unset -nocomplain done
set done ""
set timer ""
set ff [openpipe r $echo]
gets $ff port
} -body {
set s [socket 127.0.0.1 $port]
puts $s Hey
close $s w
set timer [after 1000 [namespace code {set done Failed}]]
set acc {}
fileevent $s readable [namespace code {
if {[gets $s line]<0} {
set done Succeeded
} else {
lappend acc $line
}
}]
vwait [namespace which -variable done]
list $done $acc
} -cleanup {
catch {close $s}
close $ff
after cancel $timer
removeFile echo.tcl
} -result {Succeeded {Hey DONE}}
test chan-io-29.1 {Tcl_WriteChars, channel not writable} -body {
chan puts stdin hello
} -returnCodes error -result {channel "stdin" wasn't opened for writing}
test chan-io-29.2 {Tcl_WriteChars, empty string} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -eofchar {}
chan puts -nonewline $f ""
chan close $f
file size $path(test1)
} -result 0
test chan-io-29.3 {Tcl_WriteChars, nonempty string} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -eofchar {}
chan puts -nonewline $f hello
chan close $f
file size $path(test1)
} -result 5
test chan-io-29.4 {Tcl_WriteChars, buffering in full buffering mode} -setup {
file delete $path(test1)
set l ""
} -constraints {testchannel} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -buffering full -eofchar {}
chan puts $f hello
lappend l [testchannel outputbuffered $f]
lappend l [file size $path(test1)]
chan flush $f
lappend l [testchannel outputbuffered $f]
lappend l [file size $path(test1)]
} -cleanup {
chan close $f
} -result {6 0 0 6}
test chan-io-29.5 {Tcl_WriteChars, buffering in line buffering mode} -setup {
file delete $path(test1)
set l ""
} -constraints {testchannel} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -buffering line -eofchar {}
chan puts -nonewline $f hello
lappend l [testchannel outputbuffered $f]
lappend l [file size $path(test1)]
chan puts $f hello
lappend l [testchannel outputbuffered $f]
lappend l [file size $path(test1)]
} -cleanup {
chan close $f
} -result {5 0 0 11}
test chan-io-29.6 {Tcl_WriteChars, buffering in no buffering mode} -setup {
file delete $path(test1)
set l ""
} -constraints {testchannel} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -buffering none -eofchar {}
chan puts -nonewline $f hello
lappend l [testchannel outputbuffered $f]
lappend l [file size $path(test1)]
chan puts $f hello
lappend l [testchannel outputbuffered $f]
lappend l [file size $path(test1)]
} -cleanup {
chan close $f
} -result {0 5 0 11}
test chan-io-29.7 {Tcl_Flush, full buffering} -setup {
file delete $path(test1)
set l ""
} -constraints {testchannel} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -buffering full -eofchar {}
chan puts -nonewline $f hello
lappend l [testchannel outputbuffered $f]
lappend l [file size $path(test1)]
chan puts $f hello
lappend l [testchannel outputbuffered $f]
lappend l [file size $path(test1)]
chan flush $f
lappend l [testchannel outputbuffered $f]
lappend l [file size $path(test1)]
} -cleanup {
chan close $f
} -result {5 0 11 0 0 11}
test chan-io-29.8 {Tcl_Flush, full buffering} -setup {
file delete $path(test1)
set l ""
} -constraints {testchannel} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -buffering line
chan puts -nonewline $f hello
lappend l [testchannel outputbuffered $f]
lappend l [file size $path(test1)]
chan flush $f
lappend l [testchannel outputbuffered $f]
lappend l [file size $path(test1)]
chan puts $f hello
lappend l [testchannel outputbuffered $f]
lappend l [file size $path(test1)]
chan flush $f
lappend l [testchannel outputbuffered $f]
lappend l [file size $path(test1)]
} -cleanup {
chan close $f
} -result {5 0 0 5 0 11 0 11}
test chan-io-29.9 {Tcl_Flush, channel not writable} -body {
chan flush stdin
} -returnCodes error -result {channel "stdin" wasn't opened for writing}
test chan-io-29.10 {Tcl_WriteChars, looping and buffering} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -translation lf -eofchar {}
set f2 [open $path(longfile) r]
for {set x 0} {$x < 10} {incr x} {
chan puts $f1 [chan gets $f2]
}
chan close $f2
chan close $f1
file size $path(test1)
} -result 387
test chan-io-29.11 {Tcl_WriteChars, no newline, implicit flush} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -eofchar {}
set f2 [open $path(longfile) r]
for {set x 0} {$x < 10} {incr x} {
chan puts -nonewline $f1 [chan gets $f2]
}
chan close $f1
chan close $f2
file size $path(test1)
} -result 377
test chan-io-29.12 {Tcl_WriteChars on a pipe} -setup {
file delete $path(test1)
file delete $path(pipe)
} -constraints stdio -body {
set f1 [open $path(pipe) w]
chan puts $f1 "set f1 \[[list open $path(longfile) r]]"
chan puts $f1 {
for {set x 0} {$x < 10} {incr x} {
chan puts [chan gets $f1]
}
}
chan close $f1
set f1 [openpipe r $path(pipe)]
set f2 [open $path(longfile) r]
set y ok
for {set x 0} {$x < 10} {incr x} {
set l1 [chan gets $f1]
set l2 [chan gets $f2]
if {$l1 ne $l2} {
set y broken:$x
}
}
return $y
} -cleanup {
chan close $f1
chan close $f2
} -result ok
test chan-io-29.13 {Tcl_WriteChars to a pipe, line buffered} -setup {
file delete $path(test1)
file delete $path(pipe)
} -constraints stdio -body {
set f1 [open $path(pipe) w]
chan puts $f1 {
chan puts [chan gets stdin]
chan puts [chan gets stdin]
}
chan close $f1
set y ok
set f1 [openpipe r+ $path(pipe)]
chan configure $f1 -buffering line
set f2 [open $path(longfile) r]
set line [chan gets $f2]
chan puts $f1 $line
set backline [chan gets $f1]
if {$line ne $backline} {
set y broken1
}
set line [chan gets $f2]
chan puts $f1 $line
set backline [chan gets $f1]
if {$line ne $backline} {
set y broken2
}
return $y
} -cleanup {
chan close $f1
chan close $f2
} -result ok
test chan-io-29.14 {Tcl_WriteChars, buffering and implicit flush at chan close} -setup {
file delete $path(test3)
} -body {
set f [open $path(test3) w]
chan puts -nonewline $f "Text1"
chan puts -nonewline $f " Text 2"
chan puts $f " Text 3"
chan close $f
set f [open $path(test3) r]
chan gets $f
} -cleanup {
chan close $f
} -result {Text1 Text 2 Text 3}
test chan-io-29.15 {Tcl_Flush, channel not open for writing} -setup {
file delete $path(test1)
set fd [open $path(test1) w]
chan close $fd
} -body {
set fd [open $path(test1) r]
chan flush $fd
} -returnCodes error -cleanup {
catch {chan close $fd}
} -match glob -result {channel "*" wasn't opened for writing}
test chan-io-29.16 {Tcl_Flush on pipe opened only for reading} -setup {
set fd [openpipe r cat longfile]
} -constraints stdio -body {
chan flush $fd
} -returnCodes error -cleanup {
catch {chan close $fd}
} -match glob -result {channel "*" wasn't opened for writing}
test chan-io-29.17 {Tcl_WriteChars buffers, then Tcl_Flush flushes} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -translation lf
chan puts $f1 hello
chan puts $f1 hello
chan puts $f1 hello
chan flush $f1
file size $path(test1)
} -cleanup {
chan close $f1
} -result 18
test chan-io-29.18 {Tcl_WriteChars and Tcl_Flush intermixed} -setup {
file delete $path(test1)
set x ""
set f1 [open $path(test1) w]
} -body {
chan configure $f1 -translation lf
chan puts $f1 hello
chan puts $f1 hello
chan puts $f1 hello
chan flush $f1
lappend x [file size $path(test1)]
chan puts $f1 hello
chan flush $f1
lappend x [file size $path(test1)]
chan puts $f1 hello
chan flush $f1
lappend x [file size $path(test1)]
} -cleanup {
chan close $f1
} -result {18 24 30}
test chan-io-29.19 {Explicit and implicit flushes} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -translation lf -eofchar {}
set x ""
chan puts $f1 hello
chan puts $f1 hello
chan puts $f1 hello
chan flush $f1
lappend x [file size $path(test1)]
chan puts $f1 hello
chan flush $f1
lappend x [file size $path(test1)]
chan puts $f1 hello
chan close $f1
lappend x [file size $path(test1)]
} -result {18 24 30}
test chan-io-29.20 {Implicit flush when buffer is full} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -translation lf -eofchar {}
set line "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
for {set x 0} {$x < 100} {incr x} {
chan puts $f1 $line
}
set z ""
lappend z [file size $path(test1)]
for {set x 0} {$x < 100} {incr x} {
chan puts $f1 $line
}
lappend z [file size $path(test1)]
chan close $f1
lappend z [file size $path(test1)]
} -result {4096 12288 12600}
test chan-io-29.21 {Tcl_Flush to pipe} -setup {
file delete $path(pipe)
} -constraints stdio -body {
set f1 [open $path(pipe) w]
chan puts $f1 {set x [chan read stdin 6]}
chan puts $f1 {set cnt [string length $x]}
chan puts $f1 {chan puts "read $cnt characters"}
chan close $f1
set f1 [openpipe r+ $path(pipe)]
chan puts $f1 hello
chan flush $f1
chan gets $f1
} -cleanup {
catch {chan close $f1}
} -result "read 6 characters"
test chan-io-29.22 {Tcl_Flush called at other end of pipe} -setup {
file delete $path(pipe)
} -constraints stdio -body {
set f1 [open $path(pipe) w]
chan puts $f1 {
chan configure stdout -buffering full
chan puts hello
chan puts hello
chan flush stdout
chan gets stdin
chan puts bye
chan flush stdout
}
chan close $f1
set f1 [openpipe r+ $path(pipe)]
set x ""
lappend x [chan gets $f1]
lappend x [chan gets $f1]
chan puts $f1 hello
chan flush $f1
lappend x [chan gets $f1]
} -cleanup {
chan close $f1
} -result {hello hello bye}
test chan-io-29.23 {Tcl_Flush and line buffering at end of pipe} -setup {
file delete $path(pipe)
} -constraints stdio -body {
set f1 [open $path(pipe) w]
chan puts $f1 {
chan puts hello
chan puts hello
chan gets stdin
chan puts bye
}
chan close $f1
set f1 [openpipe r+ $path(pipe)]
set x ""
lappend x [chan gets $f1]
lappend x [chan gets $f1]
chan puts $f1 hello
chan flush $f1
lappend x [chan gets $f1]
} -cleanup {
chan close $f1
} -result {hello hello bye}
test chan-io-29.24 {Tcl_WriteChars and Tcl_Flush move end of file} -setup {
variable x {}
} -body {
set f [open $path(test3) w]
chan puts $f "Line 1"
chan puts $f "Line 2"
set f2 [open $path(test3)]
lappend x [chan read -nonewline $f2]
chan close $f2
chan flush $f
set f2 [open $path(test3)]
lappend x [chan read -nonewline $f2]
} -cleanup {
chan close $f2
chan close $f
} -result "{} {Line 1\nLine 2}"
test chan-io-29.25 {Implicit flush with Tcl_Flush to command pipelines} -setup {
file delete $path(test3)
} -constraints {stdio fileevent} -body {
set f [openpipe w $path(cat) | [interpreter] $path(cat) > $path(test3)]
chan puts $f "Line 1"
chan puts $f "Line 2"
chan close $f
after 100
set f [open $path(test3) r]
chan read $f
} -cleanup {
chan close $f
} -result "Line 1\nLine 2\n"
test chan-io-29.26 {Tcl_Flush, Tcl_Write on bidirectional pipelines} -constraints {stdio unixExecs} -body {
set f [open "|[list cat -u]" r+]
chan puts $f "Line1"
chan flush $f
chan gets $f
} -cleanup {
chan close $f
} -result {Line1}
test chan-io-29.27 {Tcl_Flush on chan closed pipeline} -setup {
file delete $path(pipe)
set f [open $path(pipe) w]
chan puts $f {exit}
chan close $f
} -constraints stdio -body {
set f [openpipe r+ $path(pipe)]
chan gets $f
chan puts $f output
after 50
#
# The flush below will get a SIGPIPE. This is an expected part of the test
# and indicates that the test operates correctly. If you run this test
# under a debugger, the signal will by intercepted unless you disable the
# debugger's signal interception.
#
if {[catch {chan flush $f} msg]} {
set x [list 1 $msg $::errorCode]
catch {chan close $f}
} elseif {[catch {chan close $f} msg]} {
set x [list 1 $msg $::errorCode]
} else {
set x {this was supposed to fail and did not}
}
string tolower $x
} -match glob -result {1 {error flushing "*": broken pipe} {posix epipe {broken pipe}}}
test chan-io-29.28 {Tcl_WriteChars, lf mode} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -eofchar {}
chan puts $f hello\nthere\nand\nhere
chan flush $f
file size $path(test1)
} -cleanup {
chan close $f
} -result 21
test chan-io-29.29 {Tcl_WriteChars, cr mode} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr -eofchar {}
chan puts $f hello\nthere\nand\nhere
chan close $f
file size $path(test1)
} -result 21
test chan-io-29.30 {Tcl_WriteChars, crlf mode} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf -eofchar {}
chan puts $f hello\nthere\nand\nhere
chan close $f
file size $path(test1)
} -result 25
test chan-io-29.31 {Tcl_WriteChars, background flush} -setup {
file delete $path(pipe)
file delete $path(output)
} -constraints stdio -body {
set f [open $path(pipe) w]
chan puts $f "set f \[[list open $path(output) w]]"
chan puts $f {chan configure $f -translation lf}
set x [list while {![chan eof stdin]}]
set x "$x {"
chan puts $f $x
chan puts $f { chan puts -nonewline $f [chan read stdin 4096]}
chan puts $f { chan flush $f}
chan puts $f "}"
chan puts $f {chan close $f}
chan close $f
set x 01234567890123456789012345678901
for {set i 0} {$i < 11} {incr i} {
set x "$x$x"
}
set f [open $path(output) w]
chan close $f
set f [openpipe r+ $path(pipe)]
chan configure $f -blocking off
chan puts -nonewline $f $x
chan close $f
set counter 0
while {([file size $path(output)] < 65536) && ($counter < 1000)} {
after 10 [list incr [namespace which -variable counter]]
vwait [namespace which -variable counter]
}
if {$counter == 1000} {
set result "file size only [file size $path(output)]"
} else {
set result ok
}
# allow a little time for the background process to chan close.
# otherwise, the following test fails on the [file delete $path(output)]
# on Windows because a process still has the file open.
after 100 set v 1; vwait v
return $result
} -result ok
test chan-io-29.32 {Tcl_WriteChars, background flush to slow reader} -setup {
file delete $path(pipe)
file delete $path(output)
} -constraints {stdio asyncPipeChan Close} -body {
set f [open $path(pipe) w]
chan puts $f "set f \[[list open $path(output) w]]"
chan puts $f {chan configure $f -translation lf}
set x [list while {![chan eof stdin]}]
set x "$x \{"
chan puts $f $x
chan puts $f { after 20}
chan puts $f { chan puts -nonewline $f [chan read stdin 1024]}
chan puts $f { chan flush $f}
chan puts $f "\}"
chan puts $f {chan close $f}
chan close $f
set x 01234567890123456789012345678901
for {set i 0} {$i < 11} {incr i} {
set x "$x$x"
}
set f [open $path(output) w]
chan close $f
set f [openpipe r+ $path(pipe)]
chan configure $f -blocking off
chan puts -nonewline $f $x
chan close $f
set counter 0
while {([file size $path(output)] < 65536) && ($counter < 1000)} {
after 20 [list incr [namespace which -variable counter]]
vwait [namespace which -variable counter]
}
if {$counter == 1000} {
set result "file size only [file size $path(output)]"
} else {
set result ok
}
} -result ok
test chan-io-29.33 {Tcl_Flush, implicit flush on exit} -setup {
set f [open $path(script) w]
chan puts $f "set f \[[list open $path(test1) w]]"
chan puts $f {chan configure $f -translation lf
chan puts $f hello
chan puts $f bye
chan puts $f strange
}
chan close $f
} -constraints exec -body {
exec [interpreter] $path(script)
set f [open $path(test1) r]
chan read $f
} -cleanup {
chan close $f
} -result "hello\nbye\nstrange\n"
test chan-io-29.34 {Tcl_Chan Close, async flush on chan close, using sockets} -setup {
variable c 0
variable x running
set l abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
proc writelots {s l} {
for {set i 0} {$i < 2000} {incr i} {
chan puts $s $l
}
}
} -constraints {socket tempNotMac fileevent notWinCI} -body {
proc accept {s a p} {
variable x
chan event $s readable [namespace code [list readit $s]]
chan configure $s -blocking off
set x accepted
}
proc readit {s} {
variable c
variable x
set l [chan gets $s]
if {[chan eof $s]} {
chan close $s
set x done
} elseif {([string length $l] > 0) || ![chan blocked $s]} {
incr c
}
}
set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
set cs [socket 127.0.0.1 [lindex [chan configure $ss -sockname] 2]]
vwait [namespace which -variable x]
chan configure $cs -blocking off
writelots $cs $l
chan close $cs
chan close $ss
vwait [namespace which -variable x]
set c
} -result 2000
test chan-io-29.35 {Tcl_Chan Close vs chan event vs multiple interpreters} -setup {
catch {interp delete x}
catch {interp delete y}
} -constraints {socket tempNotMac fileevent} -body {
# On Mac, this test screws up sockets such that subsequent tests using
# port 2828 either cause errors or panic().
interp create x
interp create y
set s [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
proc accept {s a p} {
chan puts $s hello
chan close $s
}
set c [socket 127.0.0.1 [lindex [chan configure $s -sockname] 2]]
interp share {} $c x
interp share {} $c y
chan close $c
x eval {
proc readit {s} {
chan gets $s
if {[chan eof $s]} {
chan close $s
}
}
}
y eval {
proc readit {s} {
chan gets $s
if {[chan eof $s]} {
chan close $s
}
}
}
x eval "chan event $c readable \{readit $c\}"
y eval "chan event $c readable \{readit $c\}"
y eval [list chan close $c]
update
} -cleanup {
chan close $s
interp delete x
interp delete y
} -result ""
# Test end of line translations. Procedures tested are Tcl_Write, Tcl_Read.
test chan-io-30.1 {Tcl_Write lf, Tcl_Read lf} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation lf
chan read $f
} -cleanup {
chan close $f
} -result "hello\nthere\nand\nhere\n"
test chan-io-30.2 {Tcl_Write lf, Tcl_Read cr} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation cr
chan read $f
} -cleanup {
chan close $f
} -result "hello\nthere\nand\nhere\n"
test chan-io-30.3 {Tcl_Write lf, Tcl_Read crlf} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation crlf
chan read $f
} -cleanup {
chan close $f
} -result "hello\nthere\nand\nhere\n"
test chan-io-30.4 {Tcl_Write cr, Tcl_Read cr} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation cr
chan read $f
} -cleanup {
chan close $f
} -result "hello\nthere\nand\nhere\n"
test chan-io-30.5 {Tcl_Write cr, Tcl_Read lf} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation lf
chan read $f
} -cleanup {
chan close $f
} -result "hello\rthere\rand\rhere\r"
test chan-io-30.6 {Tcl_Write cr, Tcl_Read crlf} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation crlf
chan read $f
} -cleanup {
chan close $f
} -result "hello\rthere\rand\rhere\r"
test chan-io-30.7 {Tcl_Write crlf, Tcl_Read crlf} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation crlf
chan read $f
} -cleanup {
chan close $f
} -result "hello\nthere\nand\nhere\n"
test chan-io-30.8 {Tcl_Write crlf, Tcl_Read lf} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation lf
chan read $f
} -cleanup {
chan close $f
} -result "hello\r\nthere\r\nand\r\nhere\r\n"
test chan-io-30.9 {Tcl_Write crlf, Tcl_Read cr} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation cr
chan read $f
} -cleanup {
chan close $f
} -result "hello\n\nthere\n\nand\n\nhere\n\n"
test chan-io-30.10 {Tcl_Write lf, Tcl_Read auto} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
list [chan read $f] [chan configure $f -translation]
} -cleanup {
chan close $f
} -result {{hello
there
and
here
} auto}
test chan-io-30.11 {Tcl_Write cr, Tcl_Read auto} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
list [chan read $f] [chan configure $f -translation]
} -cleanup {
chan close $f
} -result {{hello
there
and
here
} auto}
test chan-io-30.12 {Tcl_Write crlf, Tcl_Read auto} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
list [chan read $f] [chan configure $f -translation]
} -cleanup {
chan close $f
} -result {{hello
there
and
here
} auto}
test chan-io-30.13 {Tcl_Write crlf on block boundary, Tcl_Read auto} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
set line "123456789ABCDE" ;# 14 char plus crlf
chan puts -nonewline $f x ;# shift crlf across block boundary
for {set i 0} {$i < 700} {incr i} {
chan puts $f $line
}
chan close $f
set f [open $path(test1) r]
chan configure $f -translation auto
string length [chan read $f]
} -cleanup {
chan close $f
} -result [expr {700*15 + 1}]
test chan-io-30.14 {Tcl_Write crlf on block boundary, Tcl_Read crlf} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
set line "123456789ABCDE" ;# 14 char plus crlf
chan puts -nonewline $f x ;# shift crlf across block boundary
for {set i 0} {$i < 700} {incr i} {
chan puts $f $line
}
chan close $f
set f [open $path(test1) r]
chan configure $f -translation crlf
string length [chan read $f]
} -cleanup {
chan close $f
} -result [expr {700*15 + 1}]
test chan-io-30.15 {Tcl_Write mixed, Tcl_Read auto} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f hello\nthere\nand\rhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation auto
chan read $f
} -cleanup {
chan close $f
} -result {hello
there
and
here
}
test chan-io-30.16 {Tcl_Write ^Z at end, Tcl_Read auto} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f hello\nthere\nand\rhere\n\x1a
chan close $f
set f [open $path(test1) r]
chan configure $f -eofchar \x1a -translation auto
chan read $f
} -cleanup {
chan close $f
} -result {hello
there
and
here
}
test chan-io-30.17 {Tcl_Write, implicit ^Z at end, Tcl_Read auto} -setup {
file delete $path(test1)
} -constraints {win} -body {
set f [open $path(test1) w]
chan configure $f -eofchar \x1a -translation lf
chan puts $f hello\nthere\nand\rhere
chan close $f
set f [open $path(test1) r]
chan configure $f -eofchar \x1a -translation auto
chan read $f
} -cleanup {
chan close $f
} -result {hello
there
and
here
}
test chan-io-30.18 {Tcl_Write, ^Z in middle, Tcl_Read auto} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
set s [format "abc\ndef\n%cghi\nqrs" 26]
chan puts $f $s
chan close $f
set f [open $path(test1) r]
chan configure $f -eofchar \x1a -translation auto
set l ""
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {abc def 0 {} 1 {} 1}
test chan-io-30.19 {Tcl_Write, ^Z no newline in middle, Tcl_Read auto} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
set s [format "abc\ndef\n%cghi\nqrs" 26]
chan puts $f $s
chan close $f
set f [open $path(test1) r]
chan configure $f -eofchar \x1a -translation auto
set l ""
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {abc def 0 {} 1 {} 1}
test chan-io-30.20 {Tcl_Write, ^Z in middle ignored, Tcl_Read lf} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -eofchar {}
chan puts $f [format "abc\ndef\n%cghi\nqrs" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation lf -eofchar {}
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result "abc def 0 \x1aghi 0 qrs 0 {} 1"
test chan-io-30.21 {Tcl_Write, ^Z in middle ignored, Tcl_Read cr} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -eofchar {}
chan puts $f [format "abc\ndef\n%cghi\nqrs" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation cr -eofchar {}
set x [chan gets $f]
lappend l [string equal $x "abc\ndef\n\x1aghi\nqrs\n"]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {1 1 {} 1}
test chan-io-30.22 {Tcl_Write, ^Z in middle ignored, Tcl_Read crlf} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -eofchar {}
chan puts $f [format "abc\ndef\n%cghi\nqrs" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation crlf -eofchar {}
set x [chan gets $f]
lappend l [string equal $x "abc\ndef\n\x1aghi\nqrs\n"]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {1 1 {} 1}
test chan-io-30.23 {Tcl_Write lf, ^Z in middle, Tcl_Read auto} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f [format abc\ndef\n%cqrs\ntuv 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation auto -eofchar \x1a
list [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {8 1}
test chan-io-30.24 {Tcl_Write lf, ^Z in middle, Tcl_Read lf} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
set c [format abc\ndef\n%cqrs\ntuv 26]
chan puts $f $c
chan close $f
set f [open $path(test1) r]
chan configure $f -translation lf -eofchar \x1a
list [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {8 1}
test chan-io-30.25 {Tcl_Write cr, ^Z in middle, Tcl_Read auto} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr
set c [format abc\ndef\n%cqrs\ntuv 26]
chan puts $f $c
chan close $f
set f [open $path(test1) r]
chan configure $f -translation auto -eofchar \x1a
list [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {8 1}
test chan-io-30.26 {Tcl_Write cr, ^Z in middle, Tcl_Read cr} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr
set c [format abc\ndef\n%cqrs\ntuv 26]
chan puts $f $c
chan close $f
set f [open $path(test1) r]
chan configure $f -translation cr -eofchar \x1a
list [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {8 1}
test chan-io-30.27 {Tcl_Write crlf, ^Z in middle, Tcl_Read auto} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
set c [format abc\ndef\n%cqrs\ntuv 26]
chan puts $f $c
chan close $f
set f [open $path(test1) r]
chan configure $f -translation auto -eofchar \x1a
list [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {8 1}
test chan-io-30.28 {Tcl_Write crlf, ^Z in middle, Tcl_Read crlf} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
set c [format abc\ndef\n%cqrs\ntuv 26]
chan puts $f $c
chan close $f
set f [open $path(test1) r]
chan configure $f -translation crlf -eofchar \x1a
list [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {8 1}
# Test end of line translations. Functions tested are Tcl_Write and
# Tcl_Gets.
test chan-io-31.1 {Tcl_Write lf, Tcl_Gets auto} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
} -cleanup {
chan close $f
} -result {hello 6 auto there 12 auto}
test chan-io-31.2 {Tcl_Write cr, Tcl_Gets auto} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
} -cleanup {
chan close $f
} -result {hello 6 auto there 12 auto}
test chan-io-31.3 {Tcl_Write crlf, Tcl_Gets auto} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
} -cleanup {
chan close $f
} -result {hello 7 auto there 14 auto}
test chan-io-31.4 {Tcl_Write lf, Tcl_Gets lf} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation lf
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
} -cleanup {
chan close $f
} -result {hello 6 lf there 12 lf}
test chan-io-31.5 {Tcl_Write lf, Tcl_Gets cr} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation cr
lappend l [string length [chan gets $f]]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {21 21 cr 1 {} 21 cr 1}
test chan-io-31.6 {Tcl_Write lf, Tcl_Gets crlf} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation crlf
lappend l [string length [chan gets $f]]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {21 21 crlf 1 {} 21 crlf 1}
test chan-io-31.7 {Tcl_Write cr, Tcl_Gets cr} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation cr
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {hello 6 cr 0 there 12 cr 0}
test chan-io-31.8 {Tcl_Write cr, Tcl_Gets lf} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation lf
lappend l [string length [chan gets $f]]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {21 21 lf 1 {} 21 lf 1}
test chan-io-31.9 {Tcl_Write cr, Tcl_Gets crlf} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation crlf
lappend l [string length [chan gets $f]]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {21 21 crlf 1 {} 21 crlf 1}
test chan-io-31.10 {Tcl_Write crlf, Tcl_Gets crlf} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation crlf
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {hello 7 crlf 0 there 14 crlf 0}
test chan-io-31.11 {Tcl_Write crlf, Tcl_Gets cr} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation cr
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan eof $f]
lappend l [string length [chan gets $f]]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {hello 6 cr 0 6 13 cr 0}
test chan-io-31.12 {Tcl_Write crlf, Tcl_Gets lf} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
chan puts $f hello\nthere\nand\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation lf
lappend l [string length [chan gets $f]]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan eof $f]
lappend l [string length [chan gets $f]]
lappend l [chan tell $f]
lappend l [chan configure $f -translation]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {6 7 lf 0 6 14 lf 0}
test chan-io-31.13 {binary mode is synonym of lf mode} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation binary
chan configure $f -translation
} -cleanup {
chan close $f
} -result lf
#
# Test chan-io-9.14 has been removed because "auto" output translation mode is
# not supoprted.
#
test chan-io-31.14 {Tcl_Write mixed, Tcl_Gets auto} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f hello\nthere\rand\r\nhere
chan close $f
set f [open $path(test1) r]
chan configure $f -translation auto
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {hello there and here 0 {} 1}
test chan-io-31.15 {Tcl_Write mixed, Tcl_Gets auto} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f hello\nthere\rand\r\nhere\r
chan close $f
set f [open $path(test1) r]
chan configure $f -translation auto
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {hello there and here 0 {} 1}
test chan-io-31.16 {Tcl_Write mixed, Tcl_Gets auto} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f hello\nthere\rand\r\nhere\n
chan close $f
set f [open $path(test1) r]
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {hello there and here 0 {} 1}
test chan-io-31.17 {Tcl_Write mixed, Tcl_Gets auto} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f hello\nthere\rand\r\nhere\r\n
chan close $f
set f [open $path(test1) r]
chan configure $f -translation auto
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {hello there and here 0 {} 1}
test chan-io-31.18 {Tcl_Write ^Z at end, Tcl_Gets auto} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f [format "hello\nthere\nand\rhere\n\%c" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -eofchar \x1a -translation auto
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {hello there and here 0 {} 1}
test chan-io-31.19 {Tcl_Write, implicit ^Z at end, Tcl_Gets auto} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -eofchar \x1a -translation lf
chan puts $f hello\nthere\nand\rhere
chan close $f
set f [open $path(test1) r]
chan configure $f -eofchar \x1a -translation auto
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {hello there and here 0 {} 1}
test chan-io-31.20 {Tcl_Write, ^Z in middle, Tcl_Gets auto, eofChar} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -eofchar \x1a
chan configure $f -translation auto
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {abc def 0 {} 1}
test chan-io-31.21 {Tcl_Write, no newline ^Z in middle, Tcl_Gets auto, eofChar} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -eofchar \x1a -translation auto
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {abc def 0 {} 1}
test chan-io-31.22 {Tcl_Write, ^Z in middle ignored, Tcl_Gets lf} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -eofchar {}
chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation lf -eofchar {}
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result "abc def 0 \x1aqrs 0 tuv 0 {} 1"
test chan-io-31.23 {Tcl_Write, ^Z in middle ignored, Tcl_Gets cr} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr -eofchar {}
chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation cr -eofchar {}
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result "abc def 0 \x1aqrs 0 tuv 0 {} 1"
test chan-io-31.24 {Tcl_Write, ^Z in middle ignored, Tcl_Gets crlf} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf -eofchar {}
chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation crlf -eofchar {}
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result "abc def 0 \x1aqrs 0 tuv 0 {} 1"
test chan-io-31.25 {Tcl_Write lf, ^Z in middle, Tcl_Gets auto} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation auto -eofchar \x1a
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {abc def 0 {} 1}
test chan-io-31.26 {Tcl_Write lf, ^Z in middle, Tcl_Gets lf} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation lf -eofchar \x1a
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {abc def 0 {} 1}
test chan-io-31.27 {Tcl_Write cr, ^Z in middle, Tcl_Gets auto} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr -eofchar {}
chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation auto -eofchar \x1a
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {abc def 0 {} 1}
test chan-io-31.28 {Tcl_Write cr, ^Z in middle, Tcl_Gets cr} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr -eofchar {}
chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation cr -eofchar \x1a
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {abc def 0 {} 1}
test chan-io-31.29 {Tcl_Write crlf, ^Z in middle, Tcl_Gets auto} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf -eofchar {}
chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation auto -eofchar \x1a
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {abc def 0 {} 1}
test chan-io-31.30 {Tcl_Write crlf, ^Z in middle, Tcl_Gets crlf} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf -eofchar {}
chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation crlf -eofchar \x1a
lappend l [chan gets $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {abc def 0 {} 1}
test chan-io-31.31 {Tcl_Write crlf on block boundary, Tcl_Gets crlf} -setup {
file delete $path(test1)
set c ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
set line "123456789ABCDE" ;# 14 char plus crlf
chan puts -nonewline $f x ;# shift crlf across block boundary
for {set i 0} {$i < 700} {incr i} {
chan puts $f $line
}
chan close $f
set f [open $path(test1) r]
chan configure $f -translation crlf
while {[chan gets $f line] >= 0} {
append c $line\n
}
chan close $f
string length $c
} -result [expr {700*15 + 1}]
test chan-io-31.32 {Tcl_Write crlf on block boundary, Tcl_Gets auto} -setup {
file delete $path(test1)
set c ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
set line "123456789ABCDE" ;# 14 char plus crlf
chan puts -nonewline $f x ;# shift crlf across block boundary
for {set i 0} {$i < 700} {incr i} {
chan puts $f $line
}
chan close $f
set f [open $path(test1) r]
chan configure $f -translation auto
while {[chan gets $f line] >= 0} {
append c $line\n
}
chan close $f
string length $c
} -result [expr {700*15 + 1}]
# Test Tcl_Read and buffering.
test chan-io-32.1 {Tcl_Read, channel not readable} -body {
read stdout
} -returnCodes error -result {channel "stdout" wasn't opened for reading}
test chan-io-32.2 {Tcl_Read, zero byte count} {
chan read stdin 0
} ""
test chan-io-32.3 {Tcl_Read, negative byte count} -setup {
set f [open $path(longfile) r]
} -body {
chan read $f -1
} -returnCodes error -cleanup {
chan close $f
} -result {expected non-negative integer but got "-1"}
test chan-io-32.4 {Tcl_Read, positive byte count} -body {
set f [open $path(longfile) r]
string length [chan read $f 1024]
} -cleanup {
chan close $f
} -result 1024
test chan-io-32.5 {Tcl_Read, multiple buffers} -body {
set f [open $path(longfile) r]
chan configure $f -buffersize 100
string length [chan read $f 1024]
} -cleanup {
chan close $f
} -result 1024
test chan-io-32.6 {Tcl_Read, very large read} {
set f1 [open $path(longfile) r]
set z [chan read $f1 1000000]
chan close $f1
set l [string length $z]
set x ok
set z [file size $path(longfile)]
if {$z != $l} {
set x "$z != $l"
}
set x
} ok
test chan-io-32.7 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
set f1 [open $path(longfile) r]
chan configure $f1 -blocking off
set z [chan read $f1 20]
chan close $f1
set l [string length $z]
set x ok
if {$l != 20} {
set x "$l != 20"
}
set x
} ok
test chan-io-32.8 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
set f1 [open $path(longfile) r]
chan configure $f1 -blocking off
set z [chan read $f1 1000000]
chan close $f1
set x ok
set l [string length $z]
set z [file size $path(longfile)]
if {$z != $l} {
set x "$z != $l"
}
set x
} ok
test chan-io-32.9 {Tcl_Read, read to end of file} {
set f1 [open $path(longfile) r]
set z [chan read $f1]
chan close $f1
set l [string length $z]
set x ok
set z [file size $path(longfile)]
if {$z != $l} {
set x "$z != $l"
}
set x
} ok
test chan-io-32.10 {Tcl_Read from a pipe} -setup {
file delete $path(pipe)
} -constraints stdio -body {
set f1 [open $path(pipe) w]
chan puts $f1 {chan puts [chan gets stdin]}
chan close $f1
set f1 [openpipe r+ $path(pipe)]
chan puts $f1 hello
chan flush $f1
chan read $f1
} -cleanup {
chan close $f1
} -result "hello\n"
test chan-io-32.11 {Tcl_Read from a pipe} -setup {
file delete $path(pipe)
set x ""
} -constraints stdio -body {
set f1 [open $path(pipe) w]
chan puts $f1 {chan puts [chan gets stdin]}
chan puts $f1 {chan puts [chan gets stdin]}
chan close $f1
set f1 [openpipe r+ $path(pipe)]
chan puts $f1 hello
chan flush $f1
lappend x [chan read $f1 6]
chan puts $f1 hello
chan flush $f1
lappend x [chan read $f1]
} -cleanup {
chan close $f1
} -result {{hello
} {hello
}}
test chan-io-32.12 {Tcl_Read, -nonewline} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan puts $f1 hello
chan puts $f1 bye
chan close $f1
set f1 [open $path(test1) r]
chan read -nonewline $f1
} -cleanup {
chan close $f1
} -result {hello
bye}
test chan-io-32.13 {Tcl_Read, -nonewline} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan puts $f1 hello
chan puts $f1 bye
chan close $f1
set f1 [open $path(test1) r]
set c [chan read -nonewline $f1]
list [string length $c] $c
} -cleanup {
chan close $f1
} -result {9 {hello
bye}}
test chan-io-32.14 {Tcl_Read, reading in small chunks} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan puts $f "Two lines: this one"
chan puts $f "and this one"
chan close $f
set f [open $path(test1)]
list [chan read $f 1] [chan read $f 2] [chan read $f]
} -cleanup {
chan close $f
} -result {T wo { lines: this one
and this one
}}
test chan-io-32.15 {Tcl_Read, asking for more input than available} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan puts $f "Two lines: this one"
chan puts $f "and this one"
chan close $f
set f [open $path(test1)]
chan read $f 100
} -cleanup {
chan close $f
} -result {Two lines: this one
and this one
}
test chan-io-32.16 {Tcl_Read, read to end of file with -nonewline} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan puts $f "Two lines: this one"
chan puts $f "and this one"
chan close $f
set f [open $path(test1)]
chan read -nonewline $f
} -cleanup {
chan close $f
} -result {Two lines: this one
and this one}
# Test Tcl_Gets.
test chan-io-33.1 {Tcl_Gets, reading what was written} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan puts $f1 "first line"
chan close $f1
set f1 [open $path(test1) r]
chan gets $f1
} -cleanup {
chan close $f1
} -result {first line}
test chan-io-33.2 {Tcl_Gets into variable} {
set f1 [open $path(longfile) r]
set c [chan gets $f1 x]
set l [string length x]
set z ok
if {$l != $l} {
set z broken
}
chan close $f1
set z
} ok
test chan-io-33.3 {Tcl_Gets from pipe} -setup {
file delete $path(pipe)
} -constraints stdio -body {
set f1 [open $path(pipe) w]
chan puts $f1 {chan puts [chan gets stdin]}
chan close $f1
set f1 [openpipe r+ $path(pipe)]
chan puts $f1 hello
chan flush $f1
chan gets $f1
} -cleanup {
chan close $f1
} -result hello
test chan-io-33.4 {Tcl_Gets with long line} -setup {
file delete $path(test3)
} -body {
set f [open $path(test3) w]
chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
chan puts $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
chan close $f
set f [open $path(test3)]
chan gets $f
} -cleanup {
chan close $f
} -result {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
test chan-io-33.5 {Tcl_Gets with long line} -setup {
set f [open $path(test3) w]
puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
puts $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
close $f
} -body {
set f [open $path(test3)]
set x [chan gets $f y]
chan close $f
list $x $y
} -result {260 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
test chan-io-33.6 {Tcl_Gets and end of file} -setup {
file delete $path(test3)
set x {}
} -body {
set f [open $path(test3) w]
chan puts -nonewline $f "Test1\nTest2"
chan close $f
set f [open $path(test3)]
set y {}
lappend x [chan gets $f y] $y
set y {}
lappend x [chan gets $f y] $y
set y {}
lappend x [chan gets $f y] $y
} -cleanup {
chan close $f
} -result {5 Test1 5 Test2 -1 {}}
test chan-io-33.7 {Tcl_Gets and bad variable} -setup {
set f [open $path(test3) w]
chan puts $f "Line 1"
chan puts $f "Line 2"
chan close $f
catch {unset x}
set f [open $path(test3) r]
} -body {
set x 24
chan gets $f x(0)
} -returnCodes error -cleanup {
chan close $f
} -result {can't set "x(0)": variable isn't array}
test chan-io-33.8 {Tcl_Gets, exercising double buffering} {
set f [open $path(test3) w]
chan configure $f -translation lf -eofchar {}
set x ""
for {set y 0} {$y < 99} {incr y} {set x "a$x"}
for {set y 0} {$y < 100} {incr y} {chan puts $f $x}
chan close $f
set f [open $path(test3) r]
chan configure $f -translation lf
for {set y 0} {$y < 100} {incr y} {chan gets $f}
chan close $f
set y
} 100
test chan-io-33.9 {Tcl_Gets, exercising double buffering} {
set f [open $path(test3) w]
chan configure $f -translation lf -eofchar {}
set x ""
for {set y 0} {$y < 99} {incr y} {set x "a$x"}
for {set y 0} {$y < 200} {incr y} {chan puts $f $x}
chan close $f
set f [open $path(test3) r]
chan configure $f -translation lf
for {set y 0} {$y < 200} {incr y} {chan gets $f}
chan close $f
set y
} 200
test chan-io-33.10 {Tcl_Gets, exercising double buffering} {
set f [open $path(test3) w]
chan configure $f -translation lf -eofchar {}
set x ""
for {set y 0} {$y < 99} {incr y} {set x "a$x"}
for {set y 0} {$y < 300} {incr y} {chan puts $f $x}
chan close $f
set f [open $path(test3) r]
chan configure $f -translation lf
for {set y 0} {$y < 300} {incr y} {chan gets $f}
chan close $f
set y
} 300
# Test Tcl_Seek and Tcl_Tell.
test chan-io-34.1 {Tcl_Seek to current position at start of file} -body {
set f1 [open $path(longfile) r]
chan seek $f1 0 current
chan tell $f1
} -cleanup {
chan close $f1
} -result 0
test chan-io-34.2 {Tcl_Seek to offset from start} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -translation lf -eofchar {}
chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
chan close $f1
set f1 [open $path(test1) r]
chan seek $f1 10 start
chan tell $f1
} -cleanup {
chan close $f1
} -result 10
test chan-io-34.3 {Tcl_Seek to end of file} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -translation lf -eofchar {}
chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
chan close $f1
set f1 [open $path(test1) r]
chan seek $f1 0 end
chan tell $f1
} -cleanup {
chan close $f1
} -result 54
test chan-io-34.4 {Tcl_Seek to offset from end of file} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -translation lf -eofchar {}
chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
chan close $f1
set f1 [open $path(test1) r]
chan seek $f1 -10 end
chan tell $f1
} -cleanup {
chan close $f1
} -result 44
test chan-io-34.5 {Tcl_Seek to offset from current position} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -translation lf -eofchar {}
chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
chan close $f1
set f1 [open $path(test1) r]
chan seek $f1 10 current
chan seek $f1 10 current
chan tell $f1
} -cleanup {
chan close $f1
} -result 20
test chan-io-34.6 {Tcl_Seek to offset from end of file} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -translation lf -eofchar {}
chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
chan close $f1
set f1 [open $path(test1) r]
chan seek $f1 -10 end
list [chan tell $f1] [chan read $f1]
} -cleanup {
chan close $f1
} -result {44 {rstuvwxyz
}}
test chan-io-34.7 {Tcl_Seek to offset from end of file, then to current position} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -translation lf -eofchar {}
chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
chan close $f1
set f1 [open $path(test1) r]
chan seek $f1 -10 end
set c1 [chan tell $f1]
set r1 [chan read $f1 5]
chan seek $f1 0 current
list $c1 $r1 [chan tell $f1]
} -cleanup {
chan close $f1
} -result {44 rstuv 49}
test chan-io-34.8 {Tcl_Seek on pipes: not supported} -setup {
set pipe [openpipe]
} -constraints stdio -body {
chan seek $pipe 0 current
} -returnCodes error -cleanup {
chan close $pipe
} -match glob -result {error during seek on "*": invalid argument}
test chan-io-34.9 {Tcl_Seek, testing buffered input flushing} -setup {
file delete $path(test3)
} -body {
set f [open $path(test3) w]
chan configure $f -eofchar {}
chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
chan close $f
set f [open $path(test3) RDWR]
set x [chan read $f 1]
chan seek $f 3
lappend x [chan read $f 1]
chan seek $f 0 start
lappend x [chan read $f 1]
chan seek $f 10 current
lappend x [chan read $f 1]
chan seek $f -2 end
lappend x [chan read $f 1]
chan seek $f 50 end
lappend x [chan read $f 1]
chan seek $f 1
lappend x [chan read $f 1]
} -cleanup {
chan close $f
} -result {a d a l Y {} b}
set path(test3) [makeFile {} test3]
test chan-io-34.10 {Tcl_Seek testing flushing of buffered input} {
set f [open $path(test3) w]
chan configure $f -translation lf
chan puts $f xyz\n123
chan close $f
set f [open $path(test3) r+]
chan configure $f -translation lf
set x [chan gets $f]
chan seek $f 0 current
chan puts $f 456
chan close $f
list $x [viewFile test3]
} "xyz {xyz
456}"
test chan-io-34.11 {Tcl_Seek testing flushing of buffered output} {
set f [open $path(test3) w]
chan puts $f xyz\n123
chan close $f
set f [open $path(test3) w+]
chan puts $f xyzzy
chan seek $f 2
set x [chan gets $f]
chan close $f
list $x [viewFile test3]
} "zzy xyzzy"
test chan-io-34.12 {Tcl_Seek testing combination of write, seek back and read} {
set f [open $path(test3) w]
chan configure $f -translation lf -eofchar {}
chan puts $f xyz\n123
chan close $f
set f [open $path(test3) a+]
chan configure $f -translation lf -eofchar {}
chan puts $f xyzzy
chan flush $f
set x [chan tell $f]
chan seek $f -4 cur
set y [chan gets $f]
chan close $f
list $x [viewFile test3] $y
} {14 {xyz
123
xyzzy} zzy}
test chan-io-34.13 {Tcl_Tell at start of file} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan tell $f1
} -cleanup {
chan close $f1
} -result 0
test chan-io-34.14 {Tcl_Tell after seek to end of file} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -translation lf -eofchar {}
chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
chan close $f1
set f1 [open $path(test1) r]
chan seek $f1 0 end
chan tell $f1
} -cleanup {
chan close $f1
} -result 54
test chan-io-34.15 {Tcl_Tell combined with seeking} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -translation lf -eofchar {}
chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
chan close $f1
set f1 [open $path(test1) r]
chan seek $f1 10 start
set c1 [chan tell $f1]
chan seek $f1 10 current
list $c1 [chan tell $f1]
} -cleanup {
chan close $f1
} -result {10 20}
test chan-io-34.16 {Tcl_Tell on pipe: always -1} -constraints stdio -body {
set f1 [openpipe]
chan tell $f1
} -cleanup {
chan close $f1
} -result -1
test chan-io-34.17 {Tcl_Tell on pipe: always -1} stdio {
set f1 [openpipe]
chan puts $f1 {chan puts hello}
chan flush $f1
set c [chan tell $f1]
chan gets $f1
chan close $f1
set c
} -1
test chan-io-34.18 {Tcl_Tell combined with seeking and reading} -setup {
file delete $path(test2)
} -body {
set f [open $path(test2) w]
chan configure $f -translation lf -eofchar {}
chan puts -nonewline $f "line1\nline2\nline3\nline4\nline5\n"
chan close $f
set f [open $path(test2)]
chan configure $f -translation lf
set x [chan tell $f]
chan read $f 3
lappend x [chan tell $f]
chan seek $f 2
lappend x [chan tell $f]
chan seek $f 10 current
lappend x [chan tell $f]
chan seek $f 0 end
lappend x [chan tell $f]
} -cleanup {
chan close $f
} -result {0 3 2 12 30}
test chan-io-34.19 {Tcl_Tell combined with opening in append mode} -body {
set f [open $path(test3) w]
chan configure $f -translation lf -eofchar {}
chan puts $f "abcdefghijklmnopqrstuvwxyz"
chan puts $f "abcdefghijklmnopqrstuvwxyz"
chan close $f
set f [open $path(test3) a]
chan tell $f
} -cleanup {
chan close $f
} -result 54
test chan-io-34.20 {Tcl_Tell combined with writing} -setup {
set l ""
} -body {
set f [open $path(test3) w]
chan seek $f 29 start
lappend l [chan tell $f]
chan puts -nonewline $f a
chan seek $f 39 start
lappend l [chan tell $f]
chan puts -nonewline $f a
lappend l [chan tell $f]
chan seek $f 407 end
lappend l [chan tell $f]
} -cleanup {
chan close $f
} -result {29 39 40 447}
test chan-io-34.21 {Tcl_Seek and Tcl_Tell on large files} -setup {
file delete $path(test3)
set l ""
} -constraints {largefileSupport} -body {
set f [open $path(test3) w]
chan configure $f -encoding binary
lappend l [chan tell $f]
chan puts -nonewline $f abcdef
lappend l [chan tell $f]
chan flush $f
lappend l [chan tell $f]
# 4GB offset!
chan seek $f 0x100000000
lappend l [chan tell $f]
chan puts -nonewline $f abcdef
lappend l [chan tell $f]
chan close $f
lappend l [file size $path(test3)]
# truncate...
chan close [open $path(test3) w]
lappend l [file size $path(test3)]
} -result {0 6 6 4294967296 4294967302 4294967302 0}
# Test Tcl_Eof
test chan-io-35.1 {Tcl_Eof} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan puts $f hello
chan puts $f hello
chan close $f
set f [open $path(test1)]
set x [chan eof $f]
lappend x [chan eof $f]
chan gets $f
lappend x [chan eof $f]
chan gets $f
lappend x [chan eof $f]
chan gets $f
lappend x [chan eof $f]
lappend x [chan eof $f]
} -cleanup {
chan close $f
} -result {0 0 0 0 1 1}
test chan-io-35.2 {Tcl_Eof with pipe} -constraints stdio -setup {
file delete $path(pipe)
} -body {
set f1 [open $path(pipe) w]
chan puts $f1 {chan gets stdin}
chan puts $f1 {chan puts hello}
chan close $f1
set f1 [openpipe r+ $path(pipe)]
chan puts $f1 hello
set x [chan eof $f1]
chan flush $f1
lappend x [chan eof $f1]
chan gets $f1
lappend x [chan eof $f1]
chan gets $f1
lappend x [chan eof $f1]
} -cleanup {
chan close $f1
} -result {0 0 0 1}
test chan-io-35.3 {Tcl_Eof with pipe} -constraints stdio -setup {
file delete $path(pipe)
} -body {
set f1 [open $path(pipe) w]
chan puts $f1 {chan gets stdin}
chan puts $f1 {chan puts hello}
chan close $f1
set f1 [openpipe r+ $path(pipe)]
chan puts $f1 hello
set x [chan eof $f1]
chan flush $f1
lappend x [chan eof $f1]
chan gets $f1
lappend x [chan eof $f1]
chan gets $f1
lappend x [chan eof $f1]
chan gets $f1
lappend x [chan eof $f1]
chan gets $f1
lappend x [chan eof $f1]
} -cleanup {
chan close $f1
} -result {0 0 0 1 1 1}
test chan-io-35.4 {Tcl_Eof, eof detection on nonblocking file} -setup {
file delete $path(test1)
set l ""
} -constraints {nonBlockFiles} -body {
chan close [open $path(test1) w]
set f [open $path(test1) r]
chan configure $f -blocking off
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {{} 1}
test chan-io-35.5 {Tcl_Eof, eof detection on nonblocking pipe} -setup {
file delete $path(pipe)
set l ""
} -constraints stdio -body {
set f [open $path(pipe) w]
chan puts $f {
exit
}
chan close $f
set f [openpipe r $path(pipe)]
lappend l [chan gets $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {{} 1}
test chan-io-35.6 {Tcl_Eof, eof char, lf write, auto read} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -eofchar \x1a
chan puts $f abc\ndef
chan close $f
set s [file size $path(test1)]
set f [open $path(test1) r]
chan configure $f -translation auto -eofchar \x1a
list $s [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {9 8 1}
test chan-io-35.7 {Tcl_Eof, eof char, lf write, lf read} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -eofchar \x1a
chan puts $f abc\ndef
chan close $f
set s [file size $path(test1)]
set f [open $path(test1) r]
chan configure $f -translation lf -eofchar \x1a
list $s [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {9 8 1}
test chan-io-35.8 {Tcl_Eof, eof char, cr write, auto read} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr -eofchar \x1a
chan puts $f abc\ndef
chan close $f
set s [file size $path(test1)]
set f [open $path(test1) r]
chan configure $f -translation auto -eofchar \x1a
list $s [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {9 8 1}
test chan-io-35.9 {Tcl_Eof, eof char, cr write, cr read} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr -eofchar \x1a
chan puts $f abc\ndef
chan close $f
set s [file size $path(test1)]
set f [open $path(test1) r]
chan configure $f -translation cr -eofchar \x1a
list $s [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {9 8 1}
test chan-io-35.10 {Tcl_Eof, eof char, crlf write, auto read} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf -eofchar \x1a
chan puts $f abc\ndef
chan close $f
set s [file size $path(test1)]
set f [open $path(test1) r]
chan configure $f -translation auto -eofchar \x1a
list $s [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {11 8 1}
test chan-io-35.11 {Tcl_Eof, eof char, crlf write, crlf read} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf -eofchar \x1a
chan puts $f abc\ndef
chan close $f
set s [file size $path(test1)]
set f [open $path(test1) r]
chan configure $f -translation crlf -eofchar \x1a
list $s [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {11 8 1}
test chan-io-35.12 {Tcl_Eof, eof char in middle, lf write, auto read} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -eofchar {}
chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
chan close $f
set c [file size $path(test1)]
set f [open $path(test1) r]
chan configure $f -translation auto -eofchar \x1a
list $c [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {17 8 1}
test chan-io-35.13 {Tcl_Eof, eof char in middle, lf write, lf read} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf -eofchar {}
chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
chan close $f
set c [file size $path(test1)]
set f [open $path(test1) r]
chan configure $f -translation lf -eofchar \x1a
list $c [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {17 8 1}
test chan-io-35.14 {Tcl_Eof, eof char in middle, cr write, auto read} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr -eofchar {}
chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
chan close $f
set c [file size $path(test1)]
set f [open $path(test1) r]
chan configure $f -translation auto -eofchar \x1a
list $c [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {17 8 1}
test chan-io-35.15 {Tcl_Eof, eof char in middle, cr write, cr read} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation cr -eofchar {}
chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
chan close $f
set c [file size $path(test1)]
set f [open $path(test1) r]
chan configure $f -translation cr -eofchar \x1a
list $c [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {17 8 1}
test chan-io-35.16 {Tcl_Eof, eof char in middle, crlf write, auto read} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf -eofchar {}
chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
chan close $f
set c [file size $path(test1)]
set f [open $path(test1) r]
chan configure $f -translation auto -eofchar \x1a
list $c [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {21 8 1}
test chan-io-35.17 {Tcl_Eof, eof char in middle, crlf write, crlf read} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf -eofchar {}
chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
chan close $f
set c [file size $path(test1)]
set f [open $path(test1) r]
chan configure $f -translation crlf -eofchar \x1a
list $c [string length [chan read $f]] [chan eof $f]
} -cleanup {
chan close $f
} -result {21 8 1}
# Test Tcl_InputBlocked
test chan-io-36.1 {Tcl_InputBlocked on nonblocking pipe} -setup {
set x ""
} -constraints stdio -body {
set f1 [openpipe]
chan puts $f1 {chan puts hello_from_pipe}
chan flush $f1
chan gets $f1
chan configure $f1 -blocking off -buffering full
chan puts $f1 {chan puts hello}
lappend x [chan gets $f1]
lappend x [chan blocked $f1]
chan flush $f1
after 200
lappend x [chan gets $f1]
lappend x [chan blocked $f1]
lappend x [chan gets $f1]
lappend x [chan blocked $f1]
} -cleanup {
chan close $f1
} -result {{} 1 hello 0 {} 1}
test chan-io-36.2 {Tcl_InputBlocked on blocking pipe} -setup {
set x ""
} -constraints stdio -body {
set f1 [openpipe]
chan configure $f1 -buffering line
chan puts $f1 {chan puts hello_from_pipe}
lappend x [chan gets $f1]
lappend x [chan blocked $f1]
chan puts $f1 {exit}
lappend x [chan gets $f1]
lappend x [chan blocked $f1]
lappend x [chan eof $f1]
} -cleanup {
chan close $f1
} -result {hello_from_pipe 0 {} 0 1}
test chan-io-36.3 {Tcl_InputBlocked vs files, short read} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan puts $f abcdefghijklmnop
chan close $f
set f [open $path(test1) r]
lappend l [chan blocked $f]
lappend l [chan read $f 3]
lappend l [chan blocked $f]
lappend l [chan read -nonewline $f]
lappend l [chan blocked $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {0 abc 0 defghijklmnop 0 1}
test chan-io-36.4 {Tcl_InputBlocked vs files, event driven read} -setup {
file delete $path(test1)
set l ""
variable x
} -constraints {fileevent} -body {
set f [open $path(test1) w]
chan puts $f abcdefghijklmnop
chan close $f
set f [open $path(test1) r]
chan event $f readable [namespace code {
lappend l [chan read $f 3]
if {[chan eof $f]} {lappend l eof; chan close $f; set x done}
}]
vwait [namespace which -variable x]
return $l
} -result {abc def ghi jkl mno {p
} eof}
test chan-io-36.5 {Tcl_InputBlocked vs files, short read, nonblocking} -setup {
file delete $path(test1)
set l ""
} -constraints {nonBlockFiles} -body {
set f [open $path(test1) w]
chan puts $f abcdefghijklmnop
chan close $f
set f [open $path(test1) r]
chan configure $f -blocking off
lappend l [chan blocked $f]
lappend l [chan read $f 3]
lappend l [chan blocked $f]
lappend l [chan read -nonewline $f]
lappend l [chan blocked $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result {0 abc 0 defghijklmnop 0 1}
test chan-io-36.6 {Tcl_InputBlocked vs files, event driven read} -setup {
file delete $path(test1)
set l ""
variable x
} -constraints {nonBlockFiles fileevent} -body {
set f [open $path(test1) w]
chan puts $f abcdefghijklmnop
chan close $f
set f [open $path(test1) r]
chan configure $f -blocking off
chan event $f readable [namespace code {
lappend l [chan read $f 3]
if {[chan eof $f]} {lappend l eof; chan close $f; set x done}
}]
vwait [namespace which -variable x]
return $l
} -result {abc def ghi jkl mno {p
} eof}
# Test Tcl_InputBuffered
test chan-io-37.1 {Tcl_InputBuffered} -setup {
set l ""
} -constraints {testchannel} -body {
set f [open $path(longfile) r]
chan configure $f -buffersize 4096
chan read $f 3
lappend l [testchannel inputbuffered $f]
lappend l [chan tell $f]
} -cleanup {
chan close $f
} -result {4093 3}
test chan-io-37.2 {Tcl_InputBuffered, test input flushing on seek} -setup {
set l ""
} -constraints {testchannel} -body {
set f [open $path(longfile) r]
chan configure $f -buffersize 4096
chan read $f 3
lappend l [testchannel inputbuffered $f]
lappend l [chan tell $f]
chan seek $f 0 current
lappend l [testchannel inputbuffered $f]
lappend l [chan tell $f]
} -cleanup {
chan close $f
} -result {4093 3 0 3}
# Test Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize
test chan-io-38.1 {Tcl_GetChannelBufferSize, default buffer size} -body {
set f [open $path(longfile) r]
chan configure $f -buffersize
} -cleanup {
chan close $f
} -result 4096
test chan-io-38.2 {Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize} -setup {
set l ""
} -body {
set f [open $path(longfile) r]
lappend l [chan configure $f -buffersize]
chan configure $f -buffersize 10000
lappend l [chan configure $f -buffersize]
chan configure $f -buffersize 1
lappend l [chan configure $f -buffersize]
chan configure $f -buffersize -1
lappend l [chan configure $f -buffersize]
chan configure $f -buffersize 0
lappend l [chan configure $f -buffersize]
chan configure $f -buffersize 100000
lappend l [chan configure $f -buffersize]
chan configure $f -buffersize 10000000
lappend l [chan configure $f -buffersize]
} -cleanup {
chan close $f
} -result {4096 10000 1 1 1 100000 1048576}
test chan-io-38.3 {Tcl_SetChannelBufferSize, changing buffersize between reads} {
# This test crashes the interp if Bug #427196 is not fixed
set chan [open [info script] r]
chan configure $chan -buffersize 10
set var [chan read $chan 2]
chan configure $chan -buffersize 32
append var [chan read $chan]
chan close $chan
} {}
# Test Tcl_SetChannelOption, Tcl_GetChannelOption
test chan-io-39.1 {Tcl_GetChannelOption} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -blocking
} -cleanup {
chan close $f1
} -result 1
#
# Test 17.2 was removed.
#
test chan-io-39.2 {Tcl_GetChannelOption} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -buffering
} -cleanup {
chan close $f1
} -result full
test chan-io-39.3 {Tcl_GetChannelOption} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -buffering line
chan configure $f1 -buffering
} -cleanup {
chan close $f1
} -result line
test chan-io-39.4 {Tcl_GetChannelOption, Tcl_SetChannelOption} -setup {
file delete $path(test1)
set l ""
} -body {
set f1 [open $path(test1) w]
lappend l [chan configure $f1 -buffering]
chan configure $f1 -buffering line
lappend l [chan configure $f1 -buffering]
chan configure $f1 -buffering none
lappend l [chan configure $f1 -buffering]
chan configure $f1 -buffering line
lappend l [chan configure $f1 -buffering]
chan configure $f1 -buffering full
lappend l [chan configure $f1 -buffering]
} -cleanup {
chan close $f1
} -result {full line none line full}
test chan-io-39.5 {Tcl_GetChannelOption, invariance} -setup {
file delete $path(test1)
set l ""
} -body {
set f1 [open $path(test1) w]
lappend l [chan configure $f1 -buffering]
lappend l [list [catch {chan configure $f1 -buffering green} msg] $msg]
lappend l [chan configure $f1 -buffering]
} -cleanup {
chan close $f1
} -result {full {1 {bad value for -buffering: must be one of full, line, or none}} full}
test chan-io-39.6 {Tcl_SetChannelOption, multiple options} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -translation lf -buffering line
chan puts $f1 hello
chan puts $f1 bye
file size $path(test1)
} -cleanup {
chan close $f1
} -result 10
test chan-io-39.7 {Tcl_SetChannelOption, buffering, translation} -setup {
file delete $path(test1)
set x ""
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -translation lf
chan puts $f1 hello
chan puts $f1 bye
chan configure $f1 -buffering line
lappend x [file size $path(test1)]
chan puts $f1 really_bye
lappend x [file size $path(test1)]
} -cleanup {
chan close $f1
} -result {0 21}
test chan-io-39.8 {Tcl_SetChannelOption, different buffering options} -setup {
file delete $path(test1)
set l ""
} -body {
set f1 [open $path(test1) w]
chan configure $f1 -translation lf -buffering none -eofchar {}
chan puts -nonewline $f1 hello
lappend l [file size $path(test1)]
chan puts -nonewline $f1 hello
lappend l [file size $path(test1)]
chan configure $f1 -buffering full
chan puts -nonewline $f1 hello
lappend l [file size $path(test1)]
chan configure $f1 -buffering none
lappend l [file size $path(test1)]
chan puts -nonewline $f1 hello
lappend l [file size $path(test1)]
chan close $f1
lappend l [file size $path(test1)]
} -result {5 10 10 10 20 20}
test chan-io-39.9 {Tcl_SetChannelOption, blocking mode} -setup {
file delete $path(test1)
set x ""
} -constraints {nonBlockFiles} -body {
set f1 [open $path(test1) w]
chan close $f1
set f1 [open $path(test1) r]
lappend x [chan configure $f1 -blocking]
chan configure $f1 -blocking off
lappend x [chan configure $f1 -blocking]
lappend x [chan gets $f1]
lappend x [chan read $f1 1000]
lappend x [chan blocked $f1]
lappend x [chan eof $f1]
} -cleanup {
chan close $f1
} -result {1 0 {} {} 0 1}
test chan-io-39.10 {Tcl_SetChannelOption, blocking mode} -setup {
file delete $path(pipe)
set x ""
} -constraints stdio -body {
set f1 [open $path(pipe) w]
chan puts $f1 {
chan gets stdin
after 100
chan puts hi
chan gets stdin
}
chan close $f1
set f1 [openpipe r+ $path(pipe)]
chan configure $f1 -blocking off -buffering line
lappend x [chan configure $f1 -blocking]
lappend x [chan gets $f1]
lappend x [chan blocked $f1]
chan configure $f1 -blocking on
chan puts $f1 hello
chan configure $f1 -blocking off
lappend x [chan gets $f1]
lappend x [chan blocked $f1]
chan configure $f1 -blocking on
chan puts $f1 bye
chan configure $f1 -blocking off
lappend x [chan gets $f1]
lappend x [chan blocked $f1]
chan configure $f1 -blocking on
lappend x [chan configure $f1 -blocking]
lappend x [chan gets $f1]
lappend x [chan blocked $f1]
lappend x [chan eof $f1]
lappend x [chan gets $f1]
lappend x [chan eof $f1]
} -cleanup {
chan close $f1
} -result {0 {} 1 {} 1 {} 1 1 hi 0 0 {} 1}
test chan-io-39.11 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size clipped to lower bound} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -buffersize -10
chan configure $f -buffersize
} -cleanup {
chan close $f
} -result 1
test chan-io-39.12 {Tcl_SetChannelOption, Tcl_GetChannelOption buffer size clipped to upper bound} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -buffersize 10000000
chan configure $f -buffersize
} -cleanup {
chan close $f
} -result 1048576
test chan-io-39.13 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -buffersize 40000
chan configure $f -buffersize
} -cleanup {
chan close $f
} -result 40000
test chan-io-39.14 {Tcl_SetChannelOption: -encoding, binary & utf-8} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -encoding {}
chan puts -nonewline $f \xe7\x89\xa6
chan close $f
set f [open $path(test1) r]
chan configure $f -encoding utf-8
chan read $f
} -cleanup {
chan close $f
} -result \u7266
test chan-io-39.15 {Tcl_SetChannelOption: -encoding, binary & utf-8} -setup {
file delete $path(test1)
} -body {
set f [open $path(test1) w]
chan configure $f -encoding binary
chan puts -nonewline $f \xe7\x89\xa6
chan close $f
set f [open $path(test1) r]
chan configure $f -encoding utf-8
chan read $f
} -cleanup {
chan close $f
} -result \u7266
test chan-io-39.16 {Tcl_SetChannelOption: -encoding, errors} -setup {
file delete $path(test1)
set f [open $path(test1) w]
} -body {
chan configure $f -encoding foobar
} -returnCodes error -cleanup {
chan close $f
} -result {unknown encoding "foobar"}
test chan-io-39.17 {Tcl_SetChannelOption: -encoding, clearing CHANNEL_NEED_MORE_DATA} -setup {
variable x {}
} -constraints {stdio fileevent} -body {
set f [openpipe r+ $path(cat)]
chan configure $f -encoding binary
chan puts -nonewline $f "\xe7"
chan flush $f
chan configure $f -encoding utf-8 -blocking 0
chan event $f readable [namespace code { lappend x [chan read $f] }]
vwait [namespace which -variable x]
after 300 [namespace code { lappend x timeout }]
vwait [namespace which -variable x]
chan configure $f -encoding utf-8
vwait [namespace which -variable x]
after 300 [namespace code { lappend x timeout }]
vwait [namespace which -variable x]
chan configure $f -encoding binary
vwait [namespace which -variable x]
after 300 [namespace code { lappend x timeout }]
vwait [namespace which -variable x]
return $x
} -cleanup {
chan close $f
} -result "{} timeout {} timeout \xe7 timeout"
test chan-io-39.18 {Tcl_SetChannelOption, setting read mode independently} \
-constraints {socket} -body {
proc accept {s a p} {chan close $s}
set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
set port [lindex [chan configure $s1 -sockname] 2]
set s2 [socket 127.0.0.1 $port]
update
chan configure $s2 -translation {auto lf}
chan configure $s2 -translation
} -cleanup {
chan close $s1
chan close $s2
} -result {auto lf}
test chan-io-39.19 {Tcl_SetChannelOption, setting read mode independently} \
-constraints {socket} -body {
proc accept {s a p} {chan close $s}
set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
set port [lindex [chan configure $s1 -sockname] 2]
set s2 [socket 127.0.0.1 $port]
update
chan configure $s2 -translation {auto crlf}
chan configure $s2 -translation
} -cleanup {
chan close $s1
chan close $s2
} -result {auto crlf}
test chan-io-39.20 {Tcl_SetChannelOption, setting read mode independently} \
-constraints {socket} -body {
proc accept {s a p} {chan close $s}
set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
set port [lindex [chan configure $s1 -sockname] 2]
set s2 [socket 127.0.0.1 $port]
update
chan configure $s2 -translation {auto cr}
chan configure $s2 -translation
} -cleanup {
chan close $s1
chan close $s2
} -result {auto cr}
test chan-io-39.21 {Tcl_SetChannelOption, setting read mode independently} \
-constraints {socket} -body {
proc accept {s a p} {chan close $s}
set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
set port [lindex [chan configure $s1 -sockname] 2]
set s2 [socket 127.0.0.1 $port]
update
chan configure $s2 -translation {auto auto}
chan configure $s2 -translation
} -cleanup {
chan close $s1
chan close $s2
} -result {auto crlf}
test chan-io-39.22 {Tcl_SetChannelOption, invariance} -setup {
file delete $path(test1)
set l ""
} -constraints {unix} -body {
set f1 [open $path(test1) w+]
lappend l [chan configure $f1 -eofchar]
chan configure $f1 -eofchar {ON GO}
lappend l [chan configure $f1 -eofchar]
chan configure $f1 -eofchar D
lappend l [chan configure $f1 -eofchar]
} -cleanup {
chan close $f1
} -result {{{} {}} {O G} {D D}}
test chan-io-39.22a {Tcl_SetChannelOption, invariance} -setup {
file delete $path(test1)
set l [list]
} -body {
set f1 [open $path(test1) w+]
chan configure $f1 -eofchar {ON GO}
lappend l [chan configure $f1 -eofchar]
chan configure $f1 -eofchar D
lappend l [chan configure $f1 -eofchar]
lappend l [list [catch {chan configure $f1 -eofchar {1 2 3}} msg] $msg]
} -cleanup {
chan close $f1
} -result {{O G} {D D} {1 {bad value for -eofchar: should be a list of zero, one, or two elements}}}
test chan-io-39.23 {Tcl_GetChannelOption, server socket is not readable or\
writeable, it should still have valid -eofchar and -translation options} -setup {
set l [list]
} -body {
set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
lappend l [chan configure $sock -eofchar] \
[chan configure $sock -translation]
} -cleanup {
chan close $sock
} -result {{{}} auto}
test chan-io-39.24 {Tcl_SetChannelOption, server socket is not readable or\
writable so we can't change -eofchar or -translation} -setup {
set l [list]
} -body {
set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
chan configure $sock -eofchar D -translation lf
lappend l [chan configure $sock -eofchar] \
[chan configure $sock -translation]
} -cleanup {
chan close $sock
} -result {{{}} auto}
test chan-io-40.1 {POSIX open access modes: RDWR} -setup {
file delete $path(test3)
} -body {
set f [open $path(test3) w]
chan puts $f xyzzy
chan close $f
set f [open $path(test3) RDWR]
chan puts -nonewline $f "ab"
chan seek $f 0 current
set x [chan gets $f]
chan close $f
set f [open $path(test3) r]
lappend x [chan gets $f]
} -cleanup {
chan close $f
} -result {zzy abzzy}
test chan-io-40.2 {POSIX open access modes: CREAT} -setup {
file delete $path(test3)
} -constraints {unix} -body {
set f [open $path(test3) {WRONLY CREAT} 0o600]
file stat $path(test3) stats
set x [format 0o%03o [expr {$stats(mode) & 0o777}]]
chan puts $f "line 1"
chan close $f
set f [open $path(test3) r]
lappend x [chan gets $f]
} -cleanup {
chan close $f
} -result {0o600 {line 1}}
test chan-io-40.3 {POSIX open access modes: CREAT} -setup {
file delete $path(test3)
} -constraints {unix umask} -body {
# This test only works if your umask is 2, like ouster's.
chan close [open $path(test3) {WRONLY CREAT}]
file stat $path(test3) stats
format "0o%03o" [expr {$stats(mode) & 0o777}]
} -result [format 0o%03o [expr {0o666 & ~ $umaskValue}]]
test chan-io-40.4 {POSIX open access modes: CREAT} -setup {
file delete $path(test3)
} -body {
set f [open $path(test3) w]
chan configure $f -eofchar {}
chan puts $f xyzzy
chan close $f
set f [open $path(test3) {WRONLY CREAT}]
chan configure $f -eofchar {}
chan puts -nonewline $f "ab"
chan close $f
set f [open $path(test3) r]
chan gets $f
} -cleanup {
chan close $f
} -result abzzy
test chan-io-40.5 {POSIX open access modes: APPEND} -setup {
file delete $path(test3)
set x ""
} -body {
set f [open $path(test3) w]
chan configure $f -translation lf -eofchar {}
chan puts $f xyzzy
chan close $f
set f [open $path(test3) {WRONLY APPEND}]
chan configure $f -translation lf
chan puts $f "new line"
chan seek $f 0
chan puts $f "abc"
chan close $f
set f [open $path(test3) r]
chan configure $f -translation lf
chan seek $f 6 current
lappend x [chan gets $f]
lappend x [chan gets $f]
} -cleanup {
chan close $f
} -result {{new line} abc}
test chan-io-40.6 {POSIX open access modes: EXCL} -match regexp -setup {
file delete $path(test3)
} -body {
set f [open $path(test3) w]
chan puts $f xyzzy
chan close $f
open $path(test3) {WRONLY CREAT EXCL}
} -returnCodes error -result {(?i)couldn't open ".*test3": file (already )?exists}
test chan-io-40.7 {POSIX open access modes: EXCL} -setup {
file delete $path(test3)
} -body {
set f [open $path(test3) {WRONLY CREAT EXCL}]
chan configure $f -eofchar {}
chan puts $f "A test line"
chan close $f
viewFile test3
} -result {A test line}
test chan-io-40.8 {POSIX open access modes: TRUNC} -setup {
file delete $path(test3)
} -body {
set f [open $path(test3) w]
chan puts $f xyzzy
chan close $f
set f [open $path(test3) {WRONLY TRUNC}]
chan puts $f abc
chan close $f
set f [open $path(test3) r]
chan gets $f
} -cleanup {
chan close $f
} -result abc
test chan-io-40.9 {POSIX open access modes: NONBLOCK} -setup {
file delete $path(test3)
} -constraints {nonPortable unix} -body {
set f [open $path(test3) {WRONLY NONBLOCK CREAT}]
chan puts $f "NONBLOCK test"
chan close $f
set f [open $path(test3) r]
chan gets $f
} -cleanup {
chan close $f
} -result {NONBLOCK test}
test chan-io-40.10 {POSIX open access modes: RDONLY} -body {
set f [open $path(test1) w]
chan puts $f "two lines: this one"
chan puts $f "and this"
chan close $f
set f [open $path(test1) RDONLY]
list [chan gets $f] [catch {chan puts $f Test} msg] $msg
} -cleanup {
chan close $f
} -match glob -result {{two lines: this one} 1 {channel "*" wasn't opened for writing}}
test chan-io-40.11 {POSIX open access modes: RDONLY} -match regexp -body {
file delete $path(test3)
open $path(test3) RDONLY
} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
test chan-io-40.12 {POSIX open access modes: WRONLY} -match regexp -body {
file delete $path(test3)
open $path(test3) WRONLY
} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
test chan-io-40.13 {POSIX open access modes: WRONLY} -body {
makeFile xyzzy test3
set f [open $path(test3) WRONLY]
chan configure $f -eofchar {}
chan puts -nonewline $f "ab"
chan seek $f 0 current
set x [list [catch {chan gets $f} msg] $msg]
chan close $f
lappend x [viewFile test3]
} -match glob -result {1 {channel "*" wasn't opened for reading} abzzy}
test chan-io-40.14 {POSIX open access modes: RDWR} -match regexp -body {
file delete $path(test3)
open $path(test3) RDWR
} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
test chan-io-40.15 {POSIX open access modes: RDWR} {
makeFile xyzzy test3
set f [open $path(test3) RDWR]
chan puts -nonewline $f "ab"
chan seek $f 0 current
set x [chan gets $f]
chan close $f
lappend x [viewFile test3]
} {zzy abzzy}
test chan-io-40.16 {tilde substitution in open} -constraints makeFileInHome -setup {
makeFile {Some text} _test_ ~
} -body {
file exists [file join $::env(HOME) _test_]
} -cleanup {
removeFile _test_ ~
} -result 1
test chan-io-40.17 {tilde substitution in open} -setup {
set home $::env(HOME)
} -body {
unset ::env(HOME)
open ~/foo
} -returnCodes error -cleanup {
set ::env(HOME) $home
} -result {couldn't find HOME environment variable to expand path}
test chan-io-41.1 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
chan event foo
} -returnCodes error -result {wrong # args: should be "chan event channelId event ?script?"}
test chan-io-41.2 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
chan event foo bar baz q
} -returnCodes error -result {wrong # args: should be "chan event channelId event ?script?"}
test chan-io-41.3 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
chan event gorp readable
} -returnCodes error -result {can not find channel named "gorp"}
test chan-io-41.4 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
chan event gorp writable
} -returnCodes error -result {can not find channel named "gorp"}
test chan-io-41.5 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
chan event gorp who-knows
} -returnCodes error -result {bad event name "who-knows": must be readable or writable}
#
# Test chan event on a file
#
set path(foo) [makeFile {} foo]
set f [open $path(foo) w+]
test chan-io-42.1 {Tcl_FileeventCmd: creating, deleting, querying} {fileevent} {
list [chan event $f readable] [chan event $f writable]
} {{} {}}
test chan-io-42.2 {Tcl_FileeventCmd: replacing} {fileevent} {
set result {}
chan event $f r "first script"
lappend result [chan event $f readable]
chan event $f r "new script"
lappend result [chan event $f readable]
chan event $f r "yet another"
lappend result [chan event $f readable]
chan event $f r ""
lappend result [chan event $f readable]
} {{first script} {new script} {yet another} {}}
test chan-io-42.3 {Tcl_FileeventCmd: replacing, with NULL chars in script} {fileevent} {
set result {}
chan event $f r "first scr\0ipt"
lappend result [string length [chan event $f readable]]
chan event $f r "new scr\0ipt"
lappend result [string length [chan event $f readable]]
chan event $f r "yet ano\0ther"
lappend result [string length [chan event $f readable]]
chan event $f r ""
lappend result [chan event $f readable]
} {13 11 12 {}}
test chan-io-43.1 {Tcl_FileeventCmd: creating, deleting, querying} {stdio unixExecs fileevent} {
set result {}
chan event $f readable "script 1"
lappend result [chan event $f readable] [chan event $f writable]
chan event $f writable "write script"
lappend result [chan event $f readable] [chan event $f writable]
chan event $f readable {}
lappend result [chan event $f readable] [chan event $f writable]
chan event $f writable {}
lappend result [chan event $f readable] [chan event $f writable]
} {{script 1} {} {script 1} {write script} {} {write script} {} {}}
test chan-io-43.2 {Tcl_FileeventCmd: deleting when many present} -setup {
set f2 [open "|[list cat -u]" r+]
set f3 [open "|[list cat -u]" r+]
set result {}
} -constraints {stdio unixExecs fileevent} -body {
lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
chan event $f r "chan read f"
chan event $f2 r "chan read f2"
chan event $f3 r "chan read f3"
lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
chan event $f2 r {}
lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
chan event $f3 r {}
lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
chan event $f r {}
lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
} -cleanup {
catch {chan close $f2}
catch {chan close $f3}
} -result {{} {} {} {chan read f} {chan read f2} {chan read f3} {chan read f} {} {chan read f3} {chan read f} {} {} {} {} {}}
test chan-io-44.1 {FileEventProc procedure: normal read event} -setup {
set f2 [open "|[list cat -u]" r+]
set f3 [open "|[list cat -u]" r+]
} -constraints {stdio unixExecs fileevent} -body {
chan event $f2 readable [namespace code {
set x [chan gets $f2]; chan event $f2 readable {}
}]
chan puts $f2 text; chan flush $f2
variable x initial
vwait [namespace which -variable x]
return $x
} -cleanup {
catch {chan close $f2}
catch {chan close $f3}
} -result {text}
test chan-io-44.2 {FileEventProc procedure: error in read event} -setup {
set f2 [open "|[list cat -u]" r+]
set f3 [open "|[list cat -u]" r+]
proc myHandler {msg options} {
variable x $msg
}
set handler [interp bgerror {}]
interp bgerror {} [namespace which myHandler]
} -constraints {stdio unixExecs fileevent} -body {
chan event $f2 readable {error bogus}
chan puts $f2 text; chan flush $f2
variable x initial
vwait [namespace which -variable x]
list $x [chan event $f2 readable]
} -cleanup {
interp bgerror {} $handler
catch {chan close $f2}
catch {chan close $f3}
} -result {bogus {}}
test chan-io-44.3 {FileEventProc procedure: normal write event} -setup {
set f2 [open "|[list cat -u]" r+]
set f3 [open "|[list cat -u]" r+]
} -constraints {stdio unixExecs fileevent} -body {
chan event $f2 writable [namespace code {
lappend x "triggered"
incr count -1
if {$count <= 0} {
chan event $f2 writable {}
}
}]
variable x initial
set count 3
vwait [namespace which -variable x]
vwait [namespace which -variable x]
vwait [namespace which -variable x]
return $x
} -cleanup {
catch {chan close $f2}
catch {chan close $f3}
} -result {initial triggered triggered triggered}
test chan-io-44.4 {FileEventProc procedure: eror in write event} -setup {
set f2 [open "|[list cat -u]" r+]
set f3 [open "|[list cat -u]" r+]
proc myHandler {msg options} {
variable x $msg
}
set handler [interp bgerror {}]
interp bgerror {} [namespace which myHandler]
} -constraints {stdio unixExecs fileevent} -body {
chan event $f2 writable {error bad-write}
variable x initial
vwait [namespace which -variable x]
list $x [chan event $f2 writable]
} -cleanup {
interp bgerror {} $handler
catch {chan close $f2}
catch {chan close $f3}
} -result {bad-write {}}
test chan-io-44.5 {FileEventProc procedure: end of file} -constraints {
stdio unixExecs fileevent
} -body {
set f4 [openpipe r $path(cat) << foo]
chan event $f4 readable [namespace code {
if {[chan gets $f4 line] < 0} {
lappend x eof
chan event $f4 readable {}
} else {
lappend x $line
}
}]
variable x initial
vwait [namespace which -variable x]
vwait [namespace which -variable x]
set x
} -cleanup {
chan close $f4
} -result {initial foo eof}
chan close $f
makeFile "foo bar" foo
test chan-io-45.1 {DeleteFileEvent, cleanup on chan close} {fileevent} {
set f [open $path(foo) r]
chan event $f readable [namespace code {
lappend x "binding triggered: \"[chan gets $f]\""
chan event $f readable {}
}]
chan close $f
set x initial
after 100 [namespace code {
set y done
}]
variable y
vwait [namespace which -variable y]
set x
} {initial}
test chan-io-45.2 {DeleteFileEvent, cleanup on chan close} {fileevent} {
set f [open $path(foo) r]
set f2 [open $path(foo) r]
chan event $f readable [namespace code {
lappend x "f triggered: \"[chan gets $f]\""
chan event $f readable {}
}]
chan event $f2 readable [namespace code {
lappend x "f2 triggered: \"[chan gets $f2]\""
chan event $f2 readable {}
}]
chan close $f
variable x initial
vwait [namespace which -variable x]
chan close $f2
set x
} {initial {f2 triggered: "foo bar"}}
test chan-io-45.3 {DeleteFileEvent, cleanup on chan close} {fileevent} {
set f [open $path(foo) r]
set f2 [open $path(foo) r]
set f3 [open $path(foo) r]
chan event $f readable {f script}
chan event $f2 readable {f2 script}
chan event $f3 readable {f3 script}
set x {}
chan close $f2
lappend x [catch {chan event $f readable} msg] $msg \
[catch {chan event $f2 readable}] \
[catch {chan event $f3 readable} msg] $msg
chan close $f3
lappend x [catch {chan event $f readable} msg] $msg \
[catch {chan event $f2 readable}] \
[catch {chan event $f3 readable}]
chan close $f
lappend x [catch {chan event $f readable}] \
[catch {chan event $f2 readable}] \
[catch {chan event $f3 readable}]
} {0 {f script} 1 0 {f3 script} 0 {f script} 1 1 1 1 1}
# Execute these tests only if the "testfevent" command is present.
test chan-io-46.1 {Tcl event loop vs multiple interpreters} {testfevent fileevent notOSX} {
testfevent create
set script "set f \[[list open $path(foo) r]]\n"
append script {
set x "no event"
chan event $f readable [namespace code {
set x "f triggered: [chan gets $f]"
chan event $f readable {}
}]
}
set timer [after 10 lappend x timeout]
testfevent cmd $script
vwait x
after cancel $timer
testfevent cmd {chan close $f}
list [testfevent cmd {set x}] [testfevent cmd {info commands after}]
} {{f triggered: foo bar} after}
test chan-io-46.2 {Tcl event loop vs multiple interpreters} testfevent {
testfevent create
testfevent cmd {
variable x 0
after 100 {set x triggered}
vwait [namespace which -variable x]
set x
}
} {triggered}
test chan-io-46.3 {Tcl event loop vs multiple interpreters} testfevent {
testfevent create
testfevent cmd {
set x 0
after 10 {lappend x timer}
after 30
set result $x
update idletasks
lappend result $x
update
lappend result $x
}
} {0 0 {0 timer}}
test chan-io-47.1 {chan event vs multiple interpreters} -setup {
set f [open $path(foo) r]
set f2 [open $path(foo) r]
set f3 [open $path(foo) r]
set x {}
} -constraints {testfevent fileevent} -body {
chan event $f readable {script 1}
testfevent create
testfevent share $f2
testfevent cmd "chan event $f2 readable {script 2}"
chan event $f3 readable {sript 3}
lappend x [chan event $f2 readable]
testfevent delete
lappend x [chan event $f readable] [chan event $f2 readable] \
[chan event $f3 readable]
} -cleanup {
chan close $f
chan close $f2
chan close $f3
} -result {{} {script 1} {} {sript 3}}
test chan-io-47.2 {deleting chan event on interpreter delete} -setup {
set f [open $path(foo) r]
set f2 [open $path(foo) r]
set f3 [open $path(foo) r]
set f4 [open $path(foo) r]
} -constraints {testfevent fileevent} -body {
chan event $f readable {script 1}
testfevent create
testfevent share $f2
testfevent share $f3
testfevent cmd "chan event $f2 readable {script 2}
chan event $f3 readable {script 3}"
chan event $f4 readable {script 4}
testfevent delete
list [chan event $f readable] [chan event $f2 readable] \
[chan event $f3 readable] [chan event $f4 readable]
} -cleanup {
chan close $f
chan close $f2
chan close $f3
chan close $f4
} -result {{script 1} {} {} {script 4}}
test chan-io-47.3 {deleting chan event on interpreter delete} -setup {
set f [open $path(foo) r]
set f2 [open $path(foo) r]
set f3 [open $path(foo) r]
set f4 [open $path(foo) r]
} -constraints {testfevent fileevent} -body {
testfevent create
testfevent share $f3
testfevent share $f4
chan event $f readable {script 1}
chan event $f2 readable {script 2}
testfevent cmd "chan event $f3 readable {script 3}
chan event $f4 readable {script 4}"
testfevent delete
list [chan event $f readable] [chan event $f2 readable] \
[chan event $f3 readable] [chan event $f4 readable]
} -cleanup {
chan close $f
chan close $f2
chan close $f3
chan close $f4
} -result {{script 1} {script 2} {} {}}
test chan-io-47.4 {file events on shared files and multiple interpreters} -setup {
set f [open $path(foo) r]
set f2 [open $path(foo) r]
} -constraints {testfevent fileevent} -body {
testfevent create
testfevent share $f
testfevent cmd "chan event $f readable {script 1}"
chan event $f readable {script 2}
chan event $f2 readable {script 3}
list [chan event $f2 readable] [testfevent cmd "chan event $f readable"] \
[chan event $f readable]
} -cleanup {
testfevent delete
chan close $f
chan close $f2
} -result {{script 3} {script 1} {script 2}}
test chan-io-47.5 {file events on shared files, deleting file events} -setup {
set f [open $path(foo) r]
} -body {
testfevent create
testfevent share $f
testfevent cmd "chan event $f readable {script 1}"
chan event $f readable {script 2}
testfevent cmd "chan event $f readable {}"
list [testfevent cmd "chan event $f readable"] [chan event $f readable]
} -constraints {testfevent fileevent} -cleanup {
testfevent delete
chan close $f
} -result {{} {script 2}}
test chan-io-47.6 {file events on shared files, deleting file events} -setup {
set f [open $path(foo) r]
} -body {
testfevent create
testfevent share $f
testfevent cmd "chan event $f readable {script 1}"
chan event $f readable {script 2}
chan event $f readable {}
list [testfevent cmd "chan event $f readable"] [chan event $f readable]
} -constraints {testfevent fileevent} -cleanup {
testfevent delete
chan close $f
} -result {{script 1} {}}
unset path(foo)
removeFile foo
set path(bar) [makeFile {} bar]
test chan-io-48.1 {testing readability conditions} {fileevent} {
set f [open $path(bar) w]
chan puts $f abcdefg
chan puts $f abcdefg
chan puts $f abcdefg
chan puts $f abcdefg
chan puts $f abcdefg
chan close $f
set f [open $path(bar) r]
chan event $f readable [namespace code {
lappend l called
if {[chan eof $f]} {
chan close $f
set x done
} else {
chan gets $f
}
}]
set l ""
variable x not_done
vwait [namespace which -variable x]
list $x $l
} {done {called called called called called called called}}
test chan-io-48.2 {testing readability conditions} {nonBlockFiles fileevent} {
set f [open $path(bar) w]
chan puts $f abcdefg
chan puts $f abcdefg
chan puts $f abcdefg
chan puts $f abcdefg
chan puts $f abcdefg
chan close $f
set f [open $path(bar) r]
chan event $f readable [namespace code {
lappend l called
if {[chan eof $f]} {
chan close $f
set x done
} else {
chan gets $f
}
}]
chan configure $f -blocking off
set l ""
variable x not_done
vwait [namespace which -variable x]
list $x $l
} {done {called called called called called called called}}
set path(my_script) [makeFile {} my_script]
test chan-io-48.3 {testing readability conditions} -setup {
set l ""
} -constraints {stdio unix nonBlockFiles fileevent} -body {
set f [open $path(bar) w]
chan puts $f abcdefg
chan puts $f abcdefg
chan puts $f abcdefg
chan puts $f abcdefg
chan puts $f abcdefg
chan close $f
set f [open $path(my_script) w]
chan puts $f {
proc copy_slowly {f} {
while {![chan eof $f]} {
chan puts [chan gets $f]
after 200
}
chan close $f
}
}
chan close $f
set f [openpipe]
chan event $f readable [namespace code {
if {[chan eof $f]} {
set x done
} else {
chan gets $f
lappend l [chan blocked $f]
chan gets $f
lappend l [chan blocked $f]
}
}]
chan configure $f -buffering line
chan configure $f -blocking off
variable x not_done
chan puts $f [list source $path(my_script)]
chan puts $f "set f \[[list open $path(bar) r]]"
chan puts $f {copy_slowly $f}
chan puts $f {exit}
vwait [namespace which -variable x]
list $x $l
} -cleanup {
chan close $f
} -result {done {0 1 0 1 0 1 0 1 0 1 0 1 0 0}}
unset path(bar)
removeFile bar
test chan-io-48.4 {lf write, testing readability, ^Z termination, auto read mode} -setup {
file delete $path(test1)
set c 0
set l ""
} -constraints {fileevent} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f [format "abc\ndef\n%c" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation auto -eofchar \x1a
chan event $f readable [namespace code {
if {[chan eof $f]} {
set x done
chan close $f
} else {
lappend l [chan gets $f]
incr c
}
}]
variable x
vwait [namespace which -variable x]
list $c $l
} -result {3 {abc def {}}}
test chan-io-48.5 {lf write, testing readability, ^Z in middle, auto read mode} -setup {
file delete $path(test1)
set c 0
set l ""
} -constraints {fileevent} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -eofchar \x1a -translation auto
chan event $f readable [namespace code {
if {[chan eof $f]} {
set x done
chan close $f
} else {
lappend l [chan gets $f]
incr c
}
}]
variable x
vwait [namespace which -variable x]
list $c $l
} -result {3 {abc def {}}}
test chan-io-48.6 {cr write, testing readability, ^Z termination, auto read mode} -setup {
file delete $path(test1)
set c 0
set l ""
} -constraints {fileevent} -body {
set f [open $path(test1) w]
chan configure $f -translation cr
chan puts -nonewline $f [format "abc\ndef\n%c" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation auto -eofchar \x1a
chan event $f readable [namespace code {
if {[chan eof $f]} {
set x done
chan close $f
} else {
lappend l [chan gets $f]
incr c
}
}]
variable x
vwait [namespace which -variable x]
list $c $l
} -result {3 {abc def {}}}
test chan-io-48.7 {cr write, testing readability, ^Z in middle, auto read mode} -setup {
file delete $path(test1)
set c 0
set l ""
} -constraints {fileevent} -body {
set f [open $path(test1) w]
chan configure $f -translation cr
chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -eofchar \x1a -translation auto
chan event $f readable [namespace code {
if {[chan eof $f]} {
set x done
chan close $f
} else {
lappend l [chan gets $f]
incr c
}
}]
variable x
vwait [namespace which -variable x]
list $c $l
} -result {3 {abc def {}}}
test chan-io-48.8 {crlf write, testing readability, ^Z termination, auto read mode} -setup {
file delete $path(test1)
set c 0
set l ""
} -constraints {fileevent} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
chan puts -nonewline $f [format "abc\ndef\n%c" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation auto -eofchar \x1a
chan event $f readable [namespace code {
if {[chan eof $f]} {
set x done
chan close $f
} else {
lappend l [chan gets $f]
incr c
}
}]
variable x
vwait [namespace which -variable x]
list $c $l
} -result {3 {abc def {}}}
test chan-io-48.9 {crlf write, testing readability, ^Z in middle, auto read mode} -setup {
file delete $path(test1)
set c 0
set l ""
} -constraints {fileevent} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -eofchar \x1a -translation auto
chan event $f readable [namespace code {
if {[chan eof $f]} {
set x done
chan close $f
} else {
lappend l [chan gets $f]
incr c
}
}]
variable x
vwait [namespace which -variable x]
list $c $l
} -result {3 {abc def {}}}
test chan-io-48.10 {lf write, testing readability, ^Z in middle, lf read mode} -setup {
file delete $path(test1)
set c 0
set l ""
} -constraints {fileevent} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -eofchar \x1a -translation lf
chan event $f readable [namespace code {
if {[chan eof $f]} {
set x done
chan close $f
} else {
lappend l [chan gets $f]
incr c
}
}]
variable x
vwait [namespace which -variable x]
list $c $l
} -result {3 {abc def {}}}
test chan-io-48.11 {lf write, testing readability, ^Z termination, lf read mode} -setup {
file delete $path(test1)
set c 0
set l ""
} -constraints {fileevent} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f [format "abc\ndef\n%c" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation lf -eofchar \x1a
chan event $f readable [namespace code {
if {[chan eof $f]} {
set x done
chan close $f
} else {
lappend l [chan gets $f]
incr c
}
}]
variable x
vwait [namespace which -variable x]
list $c $l
} -result {3 {abc def {}}}
test chan-io-48.12 {cr write, testing readability, ^Z in middle, cr read mode} -setup {
file delete $path(test1)
set c 0
set l ""
} -constraints {fileevent} -body {
set f [open $path(test1) w]
chan configure $f -translation cr
chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -eofchar \x1a -translation cr
chan event $f readable [namespace code {
if {[chan eof $f]} {
set x done
chan close $f
} else {
lappend l [chan gets $f]
incr c
}
}]
variable x
vwait [namespace which -variable x]
list $c $l
} -result {3 {abc def {}}}
test chan-io-48.13 {cr write, testing readability, ^Z termination, cr read mode} -setup {
file delete $path(test1)
set c 0
set l ""
} -constraints {fileevent} -body {
set f [open $path(test1) w]
chan configure $f -translation cr
chan puts -nonewline $f [format "abc\ndef\n%c" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation cr -eofchar \x1a
chan event $f readable [namespace code {
if {[chan eof $f]} {
set x done
chan close $f
} else {
lappend l [chan gets $f]
incr c
}
}]
variable x
vwait [namespace which -variable x]
list $c $l
} -result {3 {abc def {}}}
test chan-io-48.14 {crlf write, testing readability, ^Z in middle, crlf read mode} -setup {
file delete $path(test1)
set c 0
set l ""
} -constraints {fileevent} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -eofchar \x1a -translation crlf
chan event $f readable [namespace code {
if {[chan eof $f]} {
set x done
chan close $f
} else {
lappend l [chan gets $f]
incr c
}
}]
variable x
vwait [namespace which -variable x]
list $c $l
} -result {3 {abc def {}}}
test chan-io-48.15 {crlf write, testing readability, ^Z termi, crlf read mode} -setup {
file delete $path(test1)
set c 0
set l ""
} -constraints {fileevent} -body {
set f [open $path(test1) w]
chan configure $f -translation crlf
chan puts -nonewline $f [format "abc\ndef\n%c" 26]
chan close $f
set f [open $path(test1) r]
chan configure $f -translation crlf -eofchar \x1a
chan event $f readable [namespace code {
if {[chan eof $f]} {
set x done
chan close $f
} else {
lappend l [chan gets $f]
incr c
}
}]
variable x
vwait [namespace which -variable x]
list $c $l
} -result {3 {abc def {}}}
test chan-io-49.1 {testing crlf reading, leftover cr disgorgment} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "a\rb\rc\r\n"
chan close $f
set f [open $path(test1) r]
lappend l [file size $path(test1)]
chan configure $f -translation crlf
lappend l [chan read $f 1]
lappend l [chan tell $f]
lappend l [chan read $f 1]
lappend l [chan tell $f]
lappend l [chan read $f 1]
lappend l [chan tell $f]
lappend l [chan read $f 1]
lappend l [chan tell $f]
lappend l [chan read $f 1]
lappend l [chan tell $f]
lappend l [chan read $f 1]
lappend l [chan tell $f]
lappend l [chan eof $f]
lappend l [chan read $f 1]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result "7 a 1 [list \r] 2 b 3 [list \r] 4 c 5 {
} 7 0 {} 1"
test chan-io-49.2 {testing crlf reading, leftover cr disgorgment} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "a\rb\rc\r\n"
chan close $f
set f [open $path(test1) r]
lappend l [file size $path(test1)]
chan configure $f -translation crlf
lappend l [chan read $f 2]
lappend l [chan tell $f]
lappend l [chan read $f 2]
lappend l [chan tell $f]
lappend l [chan read $f 2]
lappend l [chan tell $f]
lappend l [chan eof $f]
lappend l [chan read $f 2]
lappend l [chan tell $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result "7 [list a\r] 2 [list b\r] 4 [list c\n] 7 0 {} 7 1"
test chan-io-49.3 {testing crlf reading, leftover cr disgorgment} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "a\rb\rc\r\n"
chan close $f
set f [open $path(test1) r]
lappend l [file size $path(test1)]
chan configure $f -translation crlf
lappend l [chan read $f 3]
lappend l [chan tell $f]
lappend l [chan read $f 3]
lappend l [chan tell $f]
lappend l [chan eof $f]
lappend l [chan read $f 3]
lappend l [chan tell $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result "7 [list a\rb] 3 [list \rc\n] 7 0 {} 7 1"
test chan-io-49.4 {testing crlf reading, leftover cr disgorgment} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "a\rb\rc\r\n"
chan close $f
set f [open $path(test1) r]
lappend l [file size $path(test1)]
chan configure $f -translation crlf
lappend l [chan read $f 3]
lappend l [chan tell $f]
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan eof $f]
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result "7 [list a\rb] 3 [list \rc] 7 0 {} 7 1"
test chan-io-49.5 {testing crlf reading, leftover cr disgorgment} -setup {
file delete $path(test1)
set l ""
} -body {
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts -nonewline $f "a\rb\rc\r\n"
chan close $f
set f [open $path(test1) r]
lappend l [file size $path(test1)]
chan configure $f -translation crlf
lappend l [set x [chan gets $f]]
lappend l [chan tell $f]
lappend l [chan gets $f]
lappend l [chan tell $f]
lappend l [chan eof $f]
} -cleanup {
chan close $f
} -result [list 7 a\rb\rc 7 {} 7 1]
test chan-io-50.1 {testing handler deletion} -setup {
file delete $path(test1)
} -constraints testchannelevent -body {
set f [open $path(test1) w]
chan close $f
set f [open $path(test1) r]
variable z not_called
set timer [after 50 lappend z timeout]
testservicemode 0
testchannelevent $f add readable [namespace code {
variable z called
testchannelevent $f delete 0
}]
testservicemode 1
vwait z
after cancel $timer
set z
} -cleanup {
chan close $f
} -result called
test chan-io-50.2 {testing handler deletion with multiple handlers} -setup {
file delete $path(test1)
chan close [open $path(test1) w]
set z ""
} -constraints {testchannelevent testservicemode} -body {
proc delhandler {f i} {
variable z
lappend z "called delhandler $f $i"
testchannelevent $f delete 0
}
set z ""
set timer [after 50 lappend z timeout]
testservicemode 0
set f [open $path(test1) r]
testchannelevent $f add readable [namespace code [list delhandler $f 1]]
testchannelevent $f add readable [namespace code [list delhandler $f 0]]
testservicemode 1
vwait z
after cancel $timer
string equal $z \
[list [list called delhandler $f 0] [list called delhandler $f 1]]
} -cleanup {
chan close $f
} -result 1
test chan-io-50.3 {testing handler deletion with multiple handlers} -setup {
file delete $path(test1)
chan close [open $path(test1) w]
} -constraints {testchannelevent testservicemode} -body {
proc notcalled {f i} {
variable z
lappend z "notcalled was called!! $f $i"
}
proc delhandler {f i} {
variable z
testchannelevent $f delete 1
lappend z "delhandler $f $i called"
testchannelevent $f delete 0
lappend z "delhandler $f $i deleted myself"
}
set z ""
set timer [after 50 lappend z timeout]
testservicemode 0
set f [open $path(test1) r]
testchannelevent $f add readable [namespace code [list notcalled $f 1]]
testchannelevent $f add readable [namespace code [list delhandler $f 0]]
testservicemode 1
vwait z
after cancel $timer
string equal $z \
[list [list delhandler $f 0 called] \
[list delhandler $f 0 deleted myself]]
} -cleanup {
chan close $f
} -result 1
test chan-io-50.4 {testing handler deletion vs reentrant calls} -setup {
file delete $path(test1)
set f [open $path(test1) w]
chan close $f
} -constraints testchannelevent -body {
set f [open $path(test1) r]
testchannelevent $f add readable [namespace code {
if {$u eq "recursive"} {
testchannelevent $f delete 0
lappend z "delrecursive deleting recursive"
} else {
lappend z "delrecursive calling recursive"
set u recursive
update
}
}]
variable u toplevel
variable z ""
set timer [after 50 lappend z timeout]
vwait z
after cancel $timer
set z
} -cleanup {
chan close $f
update
} -result {{delrecursive calling recursive} {delrecursive deleting recursive}}
test chan-io-50.5 {testing handler deletion vs reentrant calls} -setup {
file delete $path(test1)
set f [open $path(test1) w]
chan close $f
update
} -constraints {testchannelevent testservicemode notOSX} -body {
proc notcalled {f} {
variable z
lappend z "notcalled was called!! $f"
}
proc del {f} {
variable u
variable z
if {$u eq "recursive"} {
testchannelevent $f delete 1
testchannelevent $f delete 0
lappend z "del deleted notcalled"
lappend z "del deleted myself"
} else {
set u recursive
lappend z "del calling recursive"
set timer [after 50 lappend z timeout]
set mode [testservicemode 1]
vwait z
after cancel $timer
testservicemode $mode
lappend z "del after update"
}
}
set z ""
set u toplevel
set timer [after 50 lappend z timeout]
testservicemode 0
set f [open $path(test1) r]
testchannelevent $f add readable [namespace code [list notcalled $f]]
testchannelevent $f add readable [namespace code [list del $f]]
testservicemode 1
vwait z
after cancel $timer
set z
} -cleanup {
chan close $f
update
} -result [list {del calling recursive} {del deleted notcalled} \
{del deleted myself} {del after update}]
test chan-io-50.6 {testing handler deletion vs reentrant calls} -setup {
file delete $path(test1)
set f [open $path(test1) w]
chan close $f
} -constraints {testchannelevent testservicemode} -body {
proc first {f} {
variable u
variable z
if {$u eq "toplevel"} {
lappend z "first called"
set mode [testservicemode 1]
set timer [after 50 lappend z timeout]
set u first
vwait z
after cancel $timer
testservicemode $mode
lappend z "first after update"
} else {
lappend z "first called not toplevel"
}
}
proc second {f} {
variable u
variable z
if {$u eq "first"} {
lappend z "second called, first time"
set u second
testchannelevent $f delete 0
} elseif {$u eq "second"} {
lappend z "second called, second time"
testchannelevent $f delete 0
} else {
lappend z "second called, cannot happen!"
testchannelevent $f removeall
}
}
set z ""
set u toplevel
set timer [after 50 lappend z timeout]
testservicemode 0
set f [open $path(test1) r]
testchannelevent $f add readable [namespace code [list second $f]]
testchannelevent $f add readable [namespace code [list first $f]]
testservicemode 1
vwait z
after cancel $timer
set z
} -cleanup {
chan close $f
} -result [list {first called} {first called not toplevel} \
{second called, first time} {second called, second time} \
{first after update}]
test chan-io-51.1 {Test old socket deletion on Macintosh} -setup {
set x 0
set result ""
variable wait ""
} -constraints {socket} -body {
proc accept {s a p} {
variable x
chan configure $s -blocking off
chan puts $s "sock[incr x]"
chan close $s
variable wait done
}
set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
set port [lindex [chan configure $ss -sockname] 2]
set cs [socket 127.0.0.1 $port]
vwait [namespace which -variable wait]
lappend result [chan gets $cs]
chan close $cs
set cs [socket 127.0.0.1 $port]
vwait [namespace which -variable wait]
lappend result [chan gets $cs]
chan close $cs
set cs [socket 127.0.0.1 $port]
vwait [namespace which -variable wait]
lappend result [chan gets $cs]
chan close $cs
set cs [socket 127.0.0.1 $port]
vwait [namespace which -variable wait]
lappend result [chan gets $cs]
} -cleanup {
chan close $cs
chan close $ss
} -result {sock1 sock2 sock3 sock4}
test chan-io-52.1 {TclCopyChannel} -constraints {fcopy} -setup {
file delete $path(test1)
} -body {
set f1 [open $thisScript]
set f2 [open $path(test1) w]
chan copy $f1 $f2 -command " # "
chan copy $f1 $f2
} -returnCodes error -cleanup {
chan close $f1
chan close $f2
} -match glob -result {channel "*" is busy}
test chan-io-52.2 {TclCopyChannel} -constraints {fcopy} -setup {
file delete $path(test1)
} -body {
set f1 [open $thisScript]
set f2 [open $path(test1) w]
set f3 [open $thisScript]
chan copy $f1 $f2 -command " # "
chan copy $f3 $f2
} -returnCodes error -cleanup {
chan close $f1
chan close $f2
chan close $f3
} -match glob -result {channel "*" is busy}
test chan-io-52.3 {TclCopyChannel} -constraints {fcopy} -setup {
file delete $path(test1)
} -body {
set f1 [open $thisScript]
set f2 [open $path(test1) w]
chan configure $f1 -translation lf -blocking 0
chan configure $f2 -translation cr -blocking 0
set s0 [chan copy $f1 $f2]
set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
chan close $f1
chan close $f2
set s1 [file size $thisScript]
set s2 [file size $path(test1)]
if {($s1 == $s2) && ($s0 == $s1)} {
lappend result ok
}
return $result
} -result {0 0 ok}
test chan-io-52.4 {TclCopyChannel} -constraints {fcopy} -setup {
file delete $path(test1)
} -body {
set f1 [open $thisScript]
set f2 [open $path(test1) w]
chan configure $f1 -translation lf -blocking 0
chan configure $f2 -translation cr -blocking 0
chan copy $f1 $f2 -size 40
set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
chan close $f1
chan close $f2
lappend result [file size $path(test1)]
} -result {0 0 40}
test chan-io-52.5 {TclCopyChannel, all} -constraints {fcopy} -setup {
file delete $path(test1)
} -body {
set f1 [open $thisScript]
set f2 [open $path(test1) w]
chan configure $f1 -translation lf -blocking 0
chan configure $f2 -translation lf -blocking 0
chan copy $f1 $f2 -size -1 ;# -1 means 'copy all', same as if no -size specified.
set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
chan close $f1
chan close $f2
if {[file size $thisScript] == [file size $path(test1)]} {
lappend result ok
}
return $result
} -result {0 0 ok}
test chan-io-52.5a {TclCopyChannel, all, other negative value} -setup {
file delete $path(test1)
} -constraints {fcopy} -body {
set f1 [open $thisScript]
set f2 [open $path(test1) w]
chan configure $f1 -translation lf -blocking 0
chan configure $f2 -translation lf -blocking 0
chan copy $f1 $f2 -size -2 ;# < 0 behaves like -1, copy all
set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
chan close $f1
chan close $f2
if {[file size $thisScript] == [file size $path(test1)]} {
lappend result ok
}
return $result
} -result {0 0 ok}
test chan-io-52.5b {TclCopyChannel, all, wrap to negative value} -setup {
file delete $path(test1)
} -constraints {fcopy} -body {
set f1 [open $thisScript]
set f2 [open $path(test1) w]
chan configure $f1 -translation lf -blocking 0
chan configure $f2 -translation lf -blocking 0
chan copy $f1 $f2 -size 3221176172 ;# Wrapped to < 0, behaves like -1, copy all
set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
chan close $f1
chan close $f2
if {[file size $thisScript] == [file size $path(test1)]} {
lappend result ok
}
return $result
} -result {0 0 ok}
test chan-io-52.6 {TclCopyChannel} -setup {
file delete $path(test1)
} -constraints {fcopy} -body {
set f1 [open $thisScript]
set f2 [open $path(test1) w]
chan configure $f1 -translation lf -blocking 0
chan configure $f2 -translation lf -blocking 0
set s0 [chan copy $f1 $f2 -size [expr {[file size $thisScript] + 5}]]
set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
chan close $f1
chan close $f2
set s1 [file size $thisScript]
set s2 [file size $path(test1)]
if {($s1 == $s2) && ($s0 == $s1)} {
lappend result ok
}
return $result
} -result {0 0 ok}
test chan-io-52.7 {TclCopyChannel} -constraints {fcopy} -setup {
file delete $path(test1)
} -body {
set f1 [open $thisScript]
set f2 [open $path(test1) w]
chan configure $f1 -translation lf -blocking 0
chan configure $f2 -translation lf -blocking 0
chan copy $f1 $f2
set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
if {[file size $thisScript] == [file size $path(test1)]} {
lappend result ok
}
return $result
} -cleanup {
chan close $f1
chan close $f2
} -result {0 0 ok}
test chan-io-52.8 {TclCopyChannel} -setup {
file delete $path(test1)
file delete $path(pipe)
} -constraints {stdio fcopy} -body {
set f1 [open $path(pipe) w]
chan configure $f1 -translation lf
chan puts $f1 "
chan puts ready
chan gets stdin
set f1 \[open [list $thisScript] r\]
chan configure \$f1 -translation lf
chan puts \[chan read \$f1 100\]
chan close \$f1
"
chan close $f1
set f1 [openpipe r+ $path(pipe)]
chan configure $f1 -translation lf
chan gets $f1
chan puts $f1 ready
chan flush $f1
set f2 [open $path(test1) w]
chan configure $f2 -translation lf
set s0 [chan copy $f1 $f2 -size 40]
catch {chan close $f1}
chan close $f2
list $s0 [file size $path(test1)]
} -result {40 40}
# Empty files, to register them with the test facility
set path(kyrillic.txt) [makeFile {} kyrillic.txt]
set path(utf8-fcopy.txt) [makeFile {} utf8-fcopy.txt]
set path(utf8-rp.txt) [makeFile {} utf8-rp.txt]
# Create kyrillic file, use lf translation to avoid os eol issues
set out [open $path(kyrillic.txt) w]
chan configure $out -encoding koi8-r -translation lf
chan puts $out "\u0410\u0410"
chan close $out
test chan-io-52.9 {TclCopyChannel & encodings} {fcopy} {
# Copy kyrillic to UTF-8, using chan copy.
set in [open $path(kyrillic.txt) r]
set out [open $path(utf8-fcopy.txt) w]
chan configure $in -encoding koi8-r -translation lf
chan configure $out -encoding utf-8 -translation lf
chan copy $in $out
chan close $in
chan close $out
# Do the same again, but differently (read/chan puts).
set in [open $path(kyrillic.txt) r]
set out [open $path(utf8-rp.txt) w]
chan configure $in -encoding koi8-r -translation lf
chan configure $out -encoding utf-8 -translation lf
chan puts -nonewline $out [chan read $in]
chan close $in
chan close $out
list [file size $path(kyrillic.txt)] \
[file size $path(utf8-fcopy.txt)] \
[file size $path(utf8-rp.txt)]
} {3 5 5}
test chan-io-52.10 {TclCopyChannel & encodings} {fcopy} {
# encoding to binary (=> implies that the internal utf-8 is written)
set in [open $path(kyrillic.txt) r]
set out [open $path(utf8-fcopy.txt) w]
chan configure $in -encoding koi8-r -translation lf
# -translation binary is also -encoding binary
chan configure $out -translation binary
chan copy $in $out
chan close $in
chan close $out
file size $path(utf8-fcopy.txt)
} 5
test chan-io-52.11 {TclCopyChannel & encodings} -setup {
set f [open $path(utf8-fcopy.txt) w]
fconfigure $f -encoding utf-8 -translation lf
puts $f "\u0410\u0410"
close $f
} -constraints {fcopy} -body {
# binary to encoding => the input has to be in utf-8 to make sense to the
# encoder
set in [open $path(utf8-fcopy.txt) r]
set out [open $path(kyrillic.txt) w]
# -translation binary is also -encoding binary
chan configure $in -translation binary
chan configure $out -encoding koi8-r -translation lf
chan copy $in $out
chan close $in
chan close $out
file size $path(kyrillic.txt)
} -result 3
test chan-io-53.1 {CopyData} -setup {
file delete $path(test1)
} -constraints {fcopy} -body {
set f1 [open $thisScript]
set f2 [open $path(test1) w]
chan configure $f1 -translation lf -blocking 0
chan configure $f2 -translation cr -blocking 0
chan copy $f1 $f2 -size 0
set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
chan close $f1
chan close $f2
lappend result [file size $path(test1)]
} -result {0 0 0}
test chan-io-53.2 {CopyData} -setup {
file delete $path(test1)
} -constraints {fcopy} -body {
set f1 [open $thisScript]
set f2 [open $path(test1) w]
chan configure $f1 -translation lf -blocking 0
chan configure $f2 -translation cr -blocking 0
chan copy $f1 $f2 -command [namespace code {set s0}]
set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
variable s0
vwait [namespace which -variable s0]
chan close $f1
chan close $f2
set s1 [file size $thisScript]
set s2 [file size $path(test1)]
if {($s1 == $s2) && ($s0 == $s1)} {
lappend result ok
}
return $result
} -result {0 0 ok}
test chan-io-53.3 {CopyData: background read underflow} -setup {
file delete $path(test1)
file delete $path(pipe)
} -constraints {stdio unix fcopy} -body {
set f1 [open $path(pipe) w]
chan puts -nonewline $f1 {
chan puts ready
chan flush stdout ;# Don't assume line buffered!
chan copy stdin stdout -command { set x }
vwait x
set f [}
chan puts $f1 [list open $path(test1) w]]
chan puts $f1 {
chan configure $f -translation lf
chan puts $f "done"
chan close $f
}
chan close $f1
set f1 [openpipe r+ $path(pipe)]
set result [chan gets $f1]
chan puts $f1 line1
chan flush $f1
lappend result [chan gets $f1]
chan puts $f1 line2
chan flush $f1
lappend result [chan gets $f1]
chan close $f1
after 500
set f [open $path(test1)]
lappend result [chan read $f]
} -cleanup {
chan close $f
} -result "ready line1 line2 {done\n}"
test chan-io-53.4 {CopyData: background write overflow} -setup {
set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n
variable x
for {set x 0} {$x < 12} {incr x} {
append big $big
}
file delete $path(test1)
file delete $path(pipe)
} -constraints {stdio unix fileevent fcopy} -body {
set f1 [open $path(pipe) w]
chan puts $f1 {
chan puts ready
chan copy stdin stdout -command { set x }
vwait x
set f [open $path(test1) w]
chan configure $f -translation lf
chan puts $f "done"
chan close $f
}
chan close $f1
set f1 [openpipe r+ $path(pipe)]
set result [chan gets $f1]
chan configure $f1 -blocking 0
chan puts $f1 $big
chan flush $f1
after 500
set result ""
chan event $f1 read [namespace code {
append result [chan read $f1 1024]
if {[string length $result] >= [string length $big]} {
set x done
}
}]
vwait [namespace which -variable x]
return $x
} -cleanup {
set big {}
chan close $f1
} -result done
set result {}
proc FcopyTestAccept {sock args} {
after 1000 "chan close $sock"
}
proc FcopyTestDone {bytes {error {}}} {
variable fcopyTestDone
if {[string length $error]} {
set fcopyTestDone 1
} else {
set fcopyTestDone 0
}
}
test chan-io-53.5 {CopyData: error during chan copy} {socket fcopy} {
variable fcopyTestDone
set listen [socket -server [namespace code FcopyTestAccept] -myaddr 127.0.0.1 0]
set in [open $thisScript] ;# 126 K
set out [socket 127.0.0.1 [lindex [chan configure $listen -sockname] 2]]
catch {unset fcopyTestDone}
chan close $listen ;# This means the socket open never really succeeds
chan copy $in $out -command [namespace code FcopyTestDone]
variable fcopyTestDone
if {![info exists fcopyTestDone]} {
vwait [namespace which -variable fcopyTestDone] ;# The error occurs here in the b.g.
}
chan close $in
chan close $out
set fcopyTestDone ;# 1 for error condition
} 1
test chan-io-53.6 {CopyData: error during chan copy} -setup {
variable fcopyTestDone
file delete $path(pipe)
file delete $path(test1)
catch {unset fcopyTestDone}
} -constraints {stdio fcopy} -body {
set f1 [open $path(pipe) w]
chan puts $f1 "exit 1"
chan close $f1
set in [openpipe r+ $path(pipe)]
set out [open $path(test1) w]
chan copy $in $out -command [namespace code FcopyTestDone]
variable fcopyTestDone
if {![info exists fcopyTestDone]} {
vwait [namespace which -variable fcopyTestDone]
}
return $fcopyTestDone ;# 0 for plain end of file
} -cleanup {
catch {chan close $in}
chan close $out
} -result 0
proc doFcopy {in out {bytes 0} {error {}}} {
variable fcopyTestDone
variable fcopyTestCount
incr fcopyTestCount $bytes
if {[string length $error]} {
set fcopyTestDone 1
} elseif {[chan eof $in]} {
set fcopyTestDone 0
} else {
# Delay next chan copy to wait for size>0 input bytes
after 100 [list chan copy $in $out -size 1000 \
-command [namespace code [list doFcopy $in $out]]]
}
}
test chan-io-53.7 {CopyData: Flooding chan copy from pipe} -setup {
variable fcopyTestDone
file delete $path(pipe)
catch {unset fcopyTestDone}
} -constraints {stdio fcopy} -body {
set fcopyTestCount 0
set f1 [open $path(pipe) w]
chan puts $f1 {
# Write 10 bytes / 10 msec
proc Write {count} {
chan puts -nonewline "1234567890"
if {[incr count -1]} {
after 10 [list Write $count]
} else {
set ::ready 1
}
}
chan configure stdout -buffering none
Write 345 ;# 3450 bytes ~3.45 sec
vwait ready
exit 0
}
chan close $f1
set in [openpipe r+ $path(pipe) &]
set out [open $path(test1) w]
doFcopy $in $out
variable fcopyTestDone
if {![info exists fcopyTestDone]} {
vwait [namespace which -variable fcopyTestDone]
}
# -1=error 0=script error N=number of bytes
expr {($fcopyTestDone == 0) ? $fcopyTestCount : -1}
} -cleanup {
catch {chan close $in}
chan close $out
} -result {3450}
test chan-io-53.8 {CopyData: async callback and error handling, Bug 1932639} -setup {
# copy progress callback. errors out intentionally
proc cmd args {
lappend ::RES "CMD $args"
error !STOP
}
# capture callback error here
proc ::bgerror args {
lappend ::RES "bgerror/OK $args"
set ::forever has-been-reached
return
}
# Files we use for our channels
set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
set bar [makeFile {} bar]
# Channels to copy between
set f [open $foo r] ; fconfigure $f -translation binary
set g [open $bar w] ; fconfigure $g -translation binary -buffering none
} -constraints {stdio fcopy} -body {
# Record input size, so that result is always defined
lappend ::RES [file size $bar]
# Run the copy. Should not invoke -command now.
chan copy $f $g -size 2 -command [namespace code cmd]
# Check that -command was not called synchronously
set sbs [file size $bar]
lappend ::RES [expr {($sbs > 0) ? "sync/FAIL" : "sync/OK"}] $sbs
# Now let the async part happen. Should capture the error in cmd via
# bgerror. If not break the event loop via timer.
set token [after 1000 {
lappend ::RES {bgerror/FAIL timeout}
set ::forever has-been-reached
}]
vwait ::forever
catch {after cancel $token}
# Report
set ::RES
} -cleanup {
chan close $f
chan close $g
catch {unset ::RES}
catch {unset ::forever}
rename ::bgerror {}
removeFile foo
removeFile bar
} -result {0 sync/OK 0 {CMD 2} {bgerror/OK !STOP}}
test chan-io-53.8a {CopyData: async callback and error handling, Bug 1932639, at eof} -setup {
# copy progress callback.
proc cmd args {
lappend ::RES "CMD $args"
set ::forever has-been-reached
return
}
# Files we use for our channels
set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
set bar [makeFile {} bar]
# Channels to copy between
set f [open $foo r] ; chan configure $f -translation binary
set g [open $bar w] ; chan configure $g -translation binary -buffering none
} -constraints {stdio fcopy} -body {
# Initialize and force eof on the input.
chan seek $f 0 end ; chan read $f 1
set ::RES [chan eof $f]
# Run the copy. Should not invoke -command now.
chan copy $f $g -size 2 -command [namespace code cmd]
# Check that -command was not called synchronously
lappend ::RES [expr {([llength $::RES] > 1) ? "sync/FAIL" : "sync/OK"}]
# Now let the async part happen. Should capture the eof in cmd
# If not break the event loop via timer.
set token [after 1000 {
lappend ::RES {cmd/FAIL timeout}
set ::forever has-been-reached
}]
vwait ::forever
catch {after cancel $token}
# Report
return $::RES
} -cleanup {
chan close $f
chan close $g
catch {unset ::RES}
catch {unset ::forever}
removeFile foo
removeFile bar
} -result {1 sync/OK {CMD 0}}
test chan-io-53.9 {CopyData: -size and event interaction, Bug 780533} -setup {
set out [makeFile {} out]
set err [makeFile {} err]
set pipe [open "|[list [info nameofexecutable] 2> $err]" r+]
chan configure $pipe -translation binary -buffering line
chan puts $pipe {
chan configure stdout -translation binary -buffering line
chan puts stderr Waiting...
after 1000
foreach x {a b c} {
chan puts stderr Looping...
chan puts $x
after 500
}
proc bye args {
if {[chan gets stdin line]<0} {
chan puts stderr "CHILD: EOF detected, exiting"
exit
} else {
chan puts stderr "CHILD: ignoring line: $line"
}
}
chan puts stderr Now-sleeping-forever
chan event stdin readable bye
vwait forever
}
proc ::done args {
set ::forever OK
return
}
set ::forever {}
set out [open $out w]
} -constraints {stdio fcopy} -body {
chan copy $pipe $out -size 6 -command ::done
set token [after 5000 {
set ::forever {fcopy hangs}
}]
vwait ::forever
catch {after cancel $token}
set ::forever
} -cleanup {
chan close $pipe
rename ::done {}
if {[testConstraint win]} {
after 1000; # Allow Windows time to figure out that the
# process is gone
}
catch {close $out}
catch {removeFile out}
catch {removeFile err}
catch {unset ::forever}
} -result OK
test chan-io-53.10 {Bug 1350564, multi-directional fcopy} -setup {
set err [makeFile {} err]
set pipe [open "|[list [info nameofexecutable] 2> $err]" r+]
chan configure $pipe -translation binary -buffering line
chan puts $pipe {
chan configure stderr -buffering line
# Kill server when pipe closed by invoker.
proc bye args {
if {![chan eof stdin]} { chan gets stdin ; return }
chan puts stderr BYE
exit
}
# Server code. Bi-directional copy between 2 sockets.
proc geof {sok} {
chan puts stderr DONE/$sok
chan close $sok
}
proc new {sok args} {
chan puts stderr NEW/$sok
global l srv
chan configure $sok -translation binary -buffering none
lappend l $sok
if {[llength $l] == 2} {
chan close $srv
foreach {a b} $l break
chan copy $a $b -command [list geof $a]
chan copy $b $a -command [list geof $b]
chan puts stderr 2COPY
}
chan puts stderr ...
}
chan puts stderr SRV
set l {}
set srv [socket -server new 9999]
chan puts stderr WAITING
chan event stdin readable bye
chan puts OK
vwait forever
}
# wait for OK from server.
chan gets $pipe
# Now the two clients.
proc done {sock} {
if {[chan eof $sock]} { chan close $sock ; return }
lappend ::forever [chan gets $sock]
return
}
set a [socket 127.0.0.1 9999]
set b [socket 127.0.0.1 9999]
chan configure $a -translation binary -buffering none
chan configure $b -translation binary -buffering none
chan event $a readable [namespace code "done $a"]
chan event $b readable [namespace code "done $b"]
} -constraints {stdio fcopy} -body {
# Now pass data through the server in both directions.
set ::forever {}
chan puts $a AB
vwait ::forever
chan puts $b BA
vwait ::forever
set ::forever
} -cleanup {
catch {chan close $a}
catch {chan close $b}
chan close $pipe
if {[testConstraint win]} {
after 1000 ;# Give Windows time to kill the process
}
removeFile err
catch {unset ::forever}
} -result {AB BA}
test chan-io-54.1 {Recursive channel events} {socket fileevent} {
# This test checks to see if file events are delivered during recursive
# event loops when there is buffered data on the channel.
proc accept {s a p} {
variable as
chan configure $s -translation lf
chan puts $s "line 1\nline2\nline3"
chan flush $s
set as $s
}
proc readit {s next} {
variable x
variable result
lappend result $next
if {$next == 1} {
chan event $s readable [namespace code [list readit $s 2]]
vwait [namespace which -variable x]
}
incr x
}
set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
# We need to delay on some systems until the creation of the server socket
# completes.
set done 0
for {set i 0} {$i < 10} {incr i} {
if {![catch {
set cs [socket 127.0.0.1 [lindex [chan configure $ss -sockname] 2]]
}]} {
set done 1
break
}
after 100
}
if {$done == 0} {
chan close $ss
error "failed to connect to server"
}
variable result {}
variable x 0
variable as
vwait [namespace which -variable as]
chan configure $cs -translation lf
lappend result [chan gets $cs]
chan configure $cs -blocking off
chan event $cs readable [namespace code [list readit $cs 1]]
set a [after 2000 [namespace code { set x failure }]]
vwait [namespace which -variable x]
after cancel $a
chan close $as
chan close $ss
chan close $cs
list $result $x
} {{{line 1} 1 2} 2}
test chan-io-54.2 {Testing for busy-wait in recursive channel events} -setup {
set accept {}
set after {}
variable done 0
} -constraints {socket fileevent} -body {
variable s [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
proc accept {s a p} {
variable counter 0
variable accept $s
chan configure $s -blocking off -buffering line -translation lf
chan event $s readable [namespace code "doit $s"]
}
proc doit {s} {
variable counter
variable after
incr counter
if {[chan gets $s] eq ""} {
chan event $s readable [namespace code "doit1 $s"]
set after [after 1000 [namespace code {
chan puts $writer hello
chan flush $writer
set done 1
}]]
}
}
proc doit1 {s} {
variable counter
variable accept
incr counter
chan gets $s
chan close $s
set accept {}
}
proc producer {} {
variable s
variable writer
set writer [socket 127.0.0.1 [lindex [chan configure $s -sockname] 2]]
chan configure $writer -buffering line
chan puts -nonewline $writer hello
chan flush $writer
}
producer
vwait [namespace which -variable done]
chan close $writer
chan close $s
after cancel $after
set counter
} -cleanup {
if {$accept ne {}} {chan close $accept}
} -result 1
set path(fooBar) [makeFile {} fooBar]
test chan-io-55.1 {ChannelEventScriptInvoker: deletion} -constraints {
fileevent
} -setup {
variable x
proc eventScript {fd} {
variable x
chan close $fd
error "planned error"
set x whoops
}
proc myHandler args {
variable x got_error
}
set handler [interp bgerror {}]
interp bgerror {} [namespace which myHandler]
} -body {
set f [open $path(fooBar) w]
chan event $f writable [namespace code [list eventScript $f]]
variable x not_done
vwait [namespace which -variable x]
set x
} -cleanup {
interp bgerror {} $handler
} -result {got_error}
test chan-io-56.1 {ChannelTimerProc} {testchannelevent} {
set f [open $path(fooBar) w]
chan puts $f "this is a test"
chan close $f
set f [open $path(fooBar) r]
testchannelevent $f add readable [namespace code {
chan read $f 1
incr x
}]
variable x 0
vwait [namespace which -variable x]
vwait [namespace which -variable x]
set result $x
testchannelevent $f set 0 none
after idle [namespace code {set y done}]
variable y
vwait [namespace which -variable y]
chan close $f
lappend result $y
} {2 done}
test chan-io-57.1 {buffered data and file events, gets} -setup {
variable s2
} -constraints {fileevent} -body {
proc accept {sock args} {
variable s2
set s2 $sock
}
set server [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
set s [socket 127.0.0.1 [lindex [chan configure $server -sockname] 2]]
vwait [namespace which -variable s2]
update
chan event $s2 readable [namespace code {lappend result readable}]
chan puts $s "12\n34567890"
chan flush $s
variable result [chan gets $s2]
after 1000 [namespace code {lappend result timer}]
vwait [namespace which -variable result]
lappend result [chan gets $s2]
vwait [namespace which -variable result]
set result
} -cleanup {
chan close $s
chan close $s2
chan close $server
} -result {12 readable 34567890 timer}
test chan-io-57.2 {buffered data and file events, read} -setup {
variable s2
} -constraints {fileevent} -body {
proc accept {sock args} {
variable s2
set s2 $sock
}
set server [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
set s [socket 127.0.0.1 [lindex [chan configure $server -sockname] 2]]
vwait [namespace which -variable s2]
update
chan event $s2 readable [namespace code {lappend result readable}]
chan puts -nonewline $s "1234567890"
chan flush $s
variable result [chan read $s2 1]
after 1000 [namespace code {lappend result timer}]
vwait [namespace which -variable result]
lappend result [chan read $s2 9]
vwait [namespace which -variable result]
set result
} -cleanup {
chan close $s
chan close $s2
chan close $server
} -result {1 readable 234567890 timer}
test chan-io-58.1 {Tcl_NotifyChannel and error when closing} {stdio unixOrWin fileevent} {
set out [open $path(script) w]
chan puts $out {
chan puts "normal message from pipe"
chan puts stderr "error message from pipe"
exit 1
}
proc readit {pipe} {
variable x
variable result
if {[chan eof $pipe]} {
set x [catch {chan close $pipe} line]
lappend result catch $line
} else {
chan gets $pipe line
lappend result chan gets $line
}
}
chan close $out
set pipe [openpipe r $path(script)]
chan event $pipe readable [namespace code [list readit $pipe]]
variable x ""
set result ""
vwait [namespace which -variable x]
list $x $result
} {1 {chan gets {normal message from pipe} chan gets {} catch {error message from pipe}}}
test chan-io-59.1 {Thread reference of channels} {testmainthread testchannel} {
# TIP #10
# More complicated tests (like that the reference changes as a channel is
# moved from thread to thread) can be done only in the extension which
# fully implements the moving of channels between threads, i.e. 'Threads'.
set f [open $path(longfile) r]
set result [testchannel mthread $f]
chan close $f
string equal $result [testmainthread]
} {1}
test chan-io-60.1 {writing illegal utf sequences} {fileevent testbytestring} {
# This test will hang in older revisions of the core.
set out [open $path(script) w]
chan puts $out "catch {load $::tcltestlib Tcltest}"
chan puts $out {
chan puts [testbytestring \xe2]
exit 1
}
proc readit {pipe} {
variable x
variable result
if {[chan eof $pipe]} {
set x [catch {chan close $pipe} line]
lappend result catch $line
} else {
chan gets $pipe line
lappend result gets $line
}
}
chan close $out
set pipe [openpipe r $path(script)]
chan event $pipe readable [namespace code [list readit $pipe]]
variable x ""
set result ""
vwait [namespace which -variable x]
# cut of the remainder of the error stack, especially the filename
set result [lreplace $result 3 3 [lindex [split [lindex $result 3] \n] 0]]
list $x $result
} {1 {gets {} catch {error writing "stdout": invalid argument}}}
test chan-io-61.1 {Reset eof state after changing the eof char} -setup {
set datafile [makeFile {} eofchar]
set f [open $datafile w]
chan configure $f -translation binary
chan puts -nonewline $f [string repeat "Ho hum\n" 11]
chan puts $f =
set line [string repeat "Ge gla " 4]
chan puts -nonewline $f [string repeat [string trimright $line]\n 834]
chan close $f
} -body {
set f [open $datafile r]
chan configure $f -eofchar =
set res {}
lappend res [chan read $f; chan tell $f]
chan configure $f -eofchar {}
lappend res [chan read $f 1]
lappend res [chan read $f; chan tell $f]
# Any seek zaps the internals into a good state.
#chan seek $f 0 start
#chan seek $f 0 current
#lappend res [chan read $f; chan tell $f]
} -cleanup {
chan close $f
removeFile eofchar
} -result {77 = 23431}
# Test the cutting and splicing of channels, this is incidentially the
# attach/detach facility of package Thread, but __without any safeguards__. It
# can also be used to emulate transfer of channels between threads, and is
# used for that here.
test chan-io-70.0 {Cutting & Splicing channels} -setup {
set f [makeFile {... dummy ...} cutsplice]
set res {}
} -constraints {testchannel} -body {
set c [open $f r]
lappend res [catch {chan seek $c 0 start}]
testchannel cut $c
lappend res [catch {chan seek $c 0 start}]
testchannel splice $c
lappend res [catch {chan seek $c 0 start}]
} -cleanup {
chan close $c
removeFile cutsplice
} -result {0 1 0}
test chan-io-70.1 {Transfer channel} -setup {
set f [makeFile {... dummy ...} cutsplice]
set res {}
} -constraints {testchannel thread} -body {
set c [open $f r]
lappend res [catch {chan seek $c 0 start}]
testchannel cut $c
lappend res [catch {chan seek $c 0 start}]
set tid [thread::create -preserved]
thread::send $tid [list set c $c]
thread::send $tid {load {} Tcltest}
lappend res [thread::send $tid {
testchannel splice $c
set res [catch {chan seek $c 0 start}]
chan close $c
set res
}]
} -cleanup {
thread::release $tid
removeFile cutsplice
} -result {0 1 0}
# ### ### ### ######### ######### #########
foreach {n msg expected} {
0 {} {}
1 {{message only}} {{message only}}
2 {-options x} {-options x}
3 {-options {x y} {the message}} {-options {x y} {the message}}
4 {-code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
5 {-code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
6 {-code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
7 {-code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
8 {-code error -level 0 -f ba snarf} {-code error -level 0 -f ba snarf}
9 {-code ok -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
10 {-code error -level 5 -f ba snarf} {-code error -level 0 -f ba snarf}
11 {-code ok -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
12 {-code boss -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
13 {-code boss -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
14 {-code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
15 {-code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
16 {-code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
17 {-code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
18 {-code error -level 0 -f ba} {-code error -level 0 -f ba}
19 {-code ok -level 0 -f ba} {-code 1 -level 0 -f ba}
20 {-code error -level 5 -f ba} {-code error -level 0 -f ba}
21 {-code ok -level 5 -f ba} {-code 1 -level 0 -f ba}
22 {-code boss -level 0 -f ba} {-code 1 -level 0 -f ba}
23 {-code boss -level 5 -f ba} {-code 1 -level 0 -f ba}
24 {-code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
25 {-code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
26 {-code error -level X -f ba snarf} {-code error -level 0 -f ba snarf}
27 {-code ok -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
28 {-code boss -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
29 {-code 1 -level X -f ba} {-code 1 -level 0 -f ba}
30 {-code 0 -level X -f ba} {-code 1 -level 0 -f ba}
31 {-code error -level X -f ba} {-code error -level 0 -f ba}
32 {-code ok -level X -f ba} {-code 1 -level 0 -f ba}
33 {-code boss -level X -f ba} {-code 1 -level 0 -f ba}
34 {-code 1 -code 1 -level 0 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
35 {-code 1 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
36 {-code 1 -code 1 -level 5 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
37 {-code 1 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
38 {-code 1 -code error -level 0 -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
39 {-code 1 -code ok -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
40 {-code 1 -code error -level 5 -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
41 {-code 1 -code ok -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
42 {-code 1 -code boss -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
43 {-code 1 -code boss -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
44 {-code 1 -code 1 -level 0 -f ba} {-code 1 -code 1 -level 0 -f ba}
45 {-code 1 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
46 {-code 1 -code 1 -level 5 -f ba} {-code 1 -code 1 -level 0 -f ba}
47 {-code 1 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
48 {-code 1 -code error -level 0 -f ba} {-code 1 -code error -level 0 -f ba}
49 {-code 1 -code ok -level 0 -f ba} {-code 1 -level 0 -f ba}
50 {-code 1 -code error -level 5 -f ba} {-code 1 -code error -level 0 -f ba}
51 {-code 1 -code ok -level 5 -f ba} {-code 1 -level 0 -f ba}
52 {-code 1 -code boss -level 0 -f ba} {-code 1 -level 0 -f ba}
53 {-code 1 -code boss -level 5 -f ba} {-code 1 -level 0 -f ba}
54 {-code 1 -code 1 -level X -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
55 {-code 1 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
56 {-code 1 -code error -level X -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
57 {-code 1 -code ok -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
58 {-code 1 -code boss -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
59 {-code 1 -code 1 -level X -f ba} {-code 1 -code 1 -level 0 -f ba}
60 {-code 1 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
61 {-code 1 -code error -level X -f ba} {-code 1 -code error -level 0 -f ba}
62 {-code 1 -code ok -level X -f ba} {-code 1 -level 0 -f ba}
63 {-code 1 -code boss -level X -f ba} {-code 1 -level 0 -f ba}
64 {-code 0 -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
65 {-code 0 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
66 {-code 0 -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
67 {-code 0 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
68 {-code 0 -code error -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
69 {-code 0 -code ok -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
70 {-code 0 -code error -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
71 {-code 0 -code ok -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
72 {-code 0 -code boss -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
73 {-code 0 -code boss -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
74 {-code 0 -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
75 {-code 0 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
76 {-code 0 -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
77 {-code 0 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
78 {-code 0 -code error -level 0 -f ba} {-code 1 -level 0 -f ba}
79 {-code 0 -code ok -level 0 -f ba} {-code 1 -level 0 -f ba}
80 {-code 0 -code error -level 5 -f ba} {-code 1 -level 0 -f ba}
81 {-code 0 -code ok -level 5 -f ba} {-code 1 -level 0 -f ba}
82 {-code 0 -code boss -level 0 -f ba} {-code 1 -level 0 -f ba}
83 {-code 0 -code boss -level 5 -f ba} {-code 1 -level 0 -f ba}
84 {-code 0 -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
85 {-code 0 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
86 {-code 0 -code error -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
87 {-code 0 -code ok -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
88 {-code 0 -code boss -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
89 {-code 0 -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
90 {-code 0 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
91 {-code 0 -code error -level X -f ba} {-code 1 -level 0 -f ba}
92 {-code 0 -code ok -level X -f ba} {-code 1 -level 0 -f ba}
93 {-code 0 -code boss -level X -f ba} {-code 1 -level 0 -f ba}
94 {-code 1 -code 1 -level 0 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
95 {-code 0 -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
96 {-code 1 -code 1 -level 5 -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
97 {-code 0 -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
98 {-code error -code 1 -level 0 -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
99 {-code ok -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
a0 {-code error -code 1 -level 5 -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
a1 {-code ok -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
a2 {-code boss -code 1 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
a3 {-code boss -code 1 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
a4 {-code 1 -code 1 -level 0 -f ba} {-code 1 -code 1 -level 0 -f ba}
a5 {-code 0 -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
a6 {-code 1 -code 1 -level 5 -f ba} {-code 1 -code 1 -level 0 -f ba}
a7 {-code 0 -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
a8 {-code error -code 1 -level 0 -f ba} {-code error -code 1 -level 0 -f ba}
a9 {-code ok -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
b0 {-code error -code 1 -level 5 -f ba} {-code error -code 1 -level 0 -f ba}
b1 {-code ok -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
b2 {-code boss -code 1 -level 0 -f ba} {-code 1 -level 0 -f ba}
b3 {-code boss -code 1 -level 5 -f ba} {-code 1 -level 0 -f ba}
b4 {-code 1 -code 1 -level X -f ba snarf} {-code 1 -code 1 -level 0 -f ba snarf}
b5 {-code 0 -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
b6 {-code error -code 1 -level X -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
b7 {-code ok -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
b8 {-code boss -code 1 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
b9 {-code 1 -code 1 -level X -f ba} {-code 1 -code 1 -level 0 -f ba}
c0 {-code 0 -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
c1 {-code error -code 1 -level X -f ba} {-code error -code 1 -level 0 -f ba}
c2 {-code ok -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
c3 {-code boss -code 1 -level X -f ba} {-code 1 -level 0 -f ba}
c4 {-code 1 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
c5 {-code 0 -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
c6 {-code 1 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
c7 {-code 0 -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
c8 {-code error -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
c9 {-code ok -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
d0 {-code error -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
d1 {-code ok -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
d2 {-code boss -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
d3 {-code boss -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
d4 {-code 1 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
d5 {-code 0 -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
d6 {-code 1 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
d7 {-code 0 -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
d8 {-code error -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
d9 {-code ok -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
e0 {-code error -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
e1 {-code ok -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
e2 {-code boss -code 0 -level 0 -f ba} {-code 1 -level 0 -f ba}
e3 {-code boss -code 0 -level 5 -f ba} {-code 1 -level 0 -f ba}
e4 {-code 1 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
e5 {-code 0 -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
e6 {-code error -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
e7 {-code ok -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
e8 {-code boss -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
e9 {-code 1 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
f0 {-code 0 -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
f1 {-code error -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
f2 {-code ok -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
f3 {-code boss -code 0 -level X -f ba} {-code 1 -level 0 -f ba}
} {
test chan-io-71.$n {Tcl_SetChannelError} -setup {
set f [makeFile {... dummy ...} cutsplice]
} -constraints {testchannel} -body {
set c [open $f r]
testchannel setchannelerror $c [lrange $msg 0 end]
} -cleanup {
chan close $c
removeFile cutsplice
} -result [lrange $expected 0 end]
test chan-io-72.$n {Tcl_SetChannelErrorInterp} -setup {
set f [makeFile {... dummy ...} cutsplice]
} -constraints {testchannel} -body {
set c [open $f r]
testchannel setchannelerrorinterp $c [lrange $msg 0 end]
} -cleanup {
chan close $c
removeFile cutsplice
} -result [lrange $expected 0 end]
}
test chan-io-73.1 {channel Tcl_Obj SetChannelFromAny} -body {
# Test for Bug 1847044 - don't spoil type unless we have a valid channel
chan close [lreplace [list a] 0 end]
} -returnCodes error -match glob -result *
# ### ### ### ######### ######### #########
# cleanup
foreach file [list fooBar longfile script output test1 pipe my_script \
test2 test3 cat kyrillic.txt utf8-fcopy.txt utf8-rp.txt] {
removeFile $file
}
cleanupTests
}
namespace delete ::tcl::test::io