os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/tests/io.test
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 # -*- tcl -*-
     2 # Functionality covered: operation of all IO commands, and all procedures
     3 # defined in generic/tclIO.c.
     4 #
     5 # This file contains a collection of tests for one or more of the Tcl
     6 # built-in commands.  Sourcing this file into Tcl runs the tests and
     7 # generates output for errors.  No output means no errors were found.
     8 #
     9 # Copyright (c) 1991-1994 The Regents of the University of California.
    10 # Copyright (c) 1994-1997 Sun Microsystems, Inc.
    11 # Copyright (c) 1998-1999 by Scriptics Corporation.
    12 #
    13 # See the file "license.terms" for information on usage and redistribution
    14 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    15 #
    16 # RCS: @(#) $Id: io.test,v 1.40.2.12 2007/02/12 19:25:42 andreas_kupries Exp $
    17 
    18 if {[catch {package require tcltest 2}]} {
    19     puts stderr "Skipping tests in [info script].  tcltest 2 required."
    20     return
    21 }
    22 namespace eval ::tcl::test::io {
    23 
    24     namespace import ::tcltest::cleanupTests
    25     namespace import ::tcltest::interpreter
    26     namespace import ::tcltest::makeFile
    27     namespace import ::tcltest::removeFile
    28     namespace import ::tcltest::test
    29     namespace import ::tcltest::testConstraint
    30     namespace import ::tcltest::viewFile
    31 
    32 testConstraint testchannel [llength [info commands testchannel]]
    33 testConstraint exec [llength [info commands exec]]
    34 testConstraint openpipe 1
    35 testConstraint fileevent [llength [info commands fileevent]]
    36 testConstraint fcopy [llength [info commands fcopy]]
    37 
    38 # You need a *very* special environment to do some tests.  In
    39 # particular, many file systems do not support large-files...
    40 testConstraint largefileSupport 0
    41 
    42 # set up a long data file for some of the following tests
    43 
    44 set path(longfile) [makeFile {} longfile]
    45 set f [open $path(longfile) w]
    46 fconfigure $f -eofchar {} -translation lf
    47 for { set i 0 } { $i < 100 } { incr i} {
    48     puts $f "#123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
    49 \#123456789abcdef01
    50 \#"
    51     }
    52 close $f
    53 
    54 set path(cat) [makeFile {
    55     set f stdin
    56     if {$argv != ""} {
    57 	set f [open [lindex $argv 0]]
    58     }
    59     fconfigure $f -encoding binary -translation lf -blocking 0 -eofchar \x1a
    60     fconfigure stdout -encoding binary -translation lf -buffering none
    61     fileevent $f readable "foo $f"
    62     proc foo {f} {
    63 	set x [read $f]
    64 	catch {puts -nonewline $x}
    65 	if {[eof $f]} {
    66 	    close $f
    67 	    exit 0
    68 	}
    69     }
    70     vwait forever
    71 } cat]
    72 
    73 set thisScript [file join [pwd] [info script]]
    74 
    75 proc contents {file} {
    76     set f [open $file]
    77     fconfigure $f -translation binary
    78     set a [read $f]
    79     close $f
    80     return $a
    81 }
    82 
    83 test io-1.5 {Tcl_WriteChars: CheckChannelErrors} {emptyTest} {
    84     # no test, need to cause an async error.
    85 } {}
    86 
    87 set path(test1) [makeFile {} test1]
    88 
    89 test io-1.6 {Tcl_WriteChars: WriteBytes} {
    90     set f [open $path(test1) w]
    91     fconfigure $f -encoding binary
    92     puts -nonewline $f "a\u4e4d\0"
    93     close $f
    94     contents $path(test1)
    95 } "a\x4d\x00"
    96 test io-1.7 {Tcl_WriteChars: WriteChars} {
    97     set f [open $path(test1) w]
    98     fconfigure $f -encoding shiftjis
    99     puts -nonewline $f "a\u4e4d\0"
   100     close $f
   101     contents $path(test1)
   102 } "a\x93\xe1\x00"
   103 
   104 set path(test2) [makeFile {} test2]
   105 
   106 test io-1.8 {Tcl_WriteChars: WriteChars} {
   107     # This test written for SF bug #506297.
   108     #
   109     # Executing this test without the fix for the referenced bug
   110     # applied to tcl will cause tcl, more specifically WriteChars, to
   111     # go into an infinite loop.
   112 
   113     set f [open $path(test2) w] 
   114     fconfigure      $f -encoding iso2022-jp 
   115     puts -nonewline $f [format %s%c [string repeat " " 4] 12399] 
   116     close           $f 
   117     contents $path(test2)
   118 } "    \x1b\$B\$O\x1b(B"
   119 
   120 test io-1.9 {Tcl_WriteChars: WriteChars} {
   121     # When closing a channel with an encoding that appends
   122     # escape bytes, check for the case where the escape
   123     # bytes overflow the current IO buffer. The bytes
   124     # should be moved into a new buffer.
   125 
   126     set data "1234567890 [format %c 12399]"
   127 
   128     set sizes [list]
   129 
   130     # With default buffer size
   131     set f [open $path(test2) w]
   132     fconfigure      $f -encoding iso2022-jp
   133     puts -nonewline $f $data
   134     close           $f
   135     lappend sizes [file size $path(test2)]
   136 
   137     # With buffer size equal to the length
   138     # of the data, the escape bytes would
   139     # go into the next buffer.
   140 
   141     set f [open $path(test2) w]
   142     fconfigure      $f -encoding iso2022-jp -buffersize 16
   143     puts -nonewline $f $data
   144     close           $f
   145     lappend sizes [file size $path(test2)]
   146 
   147     # With buffer size that is large enough
   148     # to hold 1 byte of escaped data, but
   149     # not all 3. This should not write
   150     # the escape bytes to the first buffer
   151     # and then again to the second buffer.
   152 
   153     set f [open $path(test2) w]
   154     fconfigure      $f -encoding iso2022-jp -buffersize 17
   155     puts -nonewline $f $data
   156     close           $f
   157     lappend sizes [file size $path(test2)]
   158 
   159     # With buffer size that can hold 2 out of
   160     # 3 bytes of escaped data.
   161 
   162     set f [open $path(test2) w]
   163     fconfigure      $f -encoding iso2022-jp -buffersize 18
   164     puts -nonewline $f $data
   165     close           $f
   166     lappend sizes [file size $path(test2)]
   167 
   168     # With buffer size that can hold all the
   169     # data and escape bytes.
   170 
   171     set f [open $path(test2) w]
   172     fconfigure      $f -encoding iso2022-jp -buffersize 19
   173     puts -nonewline $f $data
   174     close           $f
   175     lappend sizes [file size $path(test2)]
   176 
   177     set sizes
   178 } {19 19 19 19 19}
   179 
   180 test io-2.1 {WriteBytes} {
   181     # loop until all bytes are written
   182     
   183     set f [open $path(test1) w]
   184     fconfigure $f  -encoding binary -buffersize 16 -translation crlf
   185     puts $f "abcdefghijklmnopqrstuvwxyz"
   186     close $f
   187     contents $path(test1)
   188 } "abcdefghijklmnopqrstuvwxyz\r\n"
   189 test io-2.2 {WriteBytes: savedLF > 0} {
   190     # After flushing buffer, there was a \n left over from the last
   191     # \n -> \r\n expansion.  It gets stuck at beginning of this buffer.
   192 
   193     set f [open $path(test1) w]
   194     fconfigure $f -encoding binary -buffersize 16 -translation crlf
   195     puts -nonewline $f "123456789012345\n12"
   196     set x [list [contents $path(test1)]]
   197     close $f
   198     lappend x [contents $path(test1)]
   199 } [list "123456789012345\r" "123456789012345\r\n12"]
   200 test io-2.3 {WriteBytes: flush on line} {
   201     # Tcl "line" buffering has weird behavior: if current buffer contains
   202     # a \n, entire buffer gets flushed.  Logical behavior would be to flush
   203     # only up to the \n.
   204     
   205     set f [open $path(test1) w]
   206     fconfigure $f -encoding binary -buffering line -translation crlf
   207     puts -nonewline $f "\n12"
   208     set x [contents $path(test1)]
   209     close $f
   210     set x
   211 } "\r\n12"
   212 test io-2.4 {WriteBytes: reset sawLF after each buffer} {
   213     set f [open $path(test1) w]
   214      fconfigure $f -encoding binary -buffering line -translation lf \
   215 	     -buffersize 16
   216     puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
   217     set x [list [contents $path(test1)]]
   218     close $f
   219     lappend x [contents $path(test1)]
   220 } [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]
   221 
   222 test io-3.1 {WriteChars: compatibility with WriteBytes} {
   223     # loop until all bytes are written
   224     
   225     set f [open $path(test1) w]
   226     fconfigure $f -encoding ascii -buffersize 16 -translation crlf
   227     puts $f "abcdefghijklmnopqrstuvwxyz"
   228     close $f
   229     contents $path(test1)
   230 } "abcdefghijklmnopqrstuvwxyz\r\n"
   231 test io-3.2 {WriteChars: compatibility with WriteBytes: savedLF > 0} {
   232     # After flushing buffer, there was a \n left over from the last
   233     # \n -> \r\n expansion.  It gets stuck at beginning of this buffer.
   234 
   235     set f [open $path(test1) w]
   236     fconfigure $f -encoding ascii -buffersize 16 -translation crlf
   237     puts -nonewline $f "123456789012345\n12"
   238     set x [list [contents $path(test1)]]
   239     close $f
   240     lappend x [contents $path(test1)]
   241 } [list "123456789012345\r" "123456789012345\r\n12"]
   242 test io-3.3 {WriteChars: compatibility with WriteBytes: flush on line} {
   243     # Tcl "line" buffering has weird behavior: if current buffer contains
   244     # a \n, entire buffer gets flushed.  Logical behavior would be to flush
   245     # only up to the \n.
   246     
   247     set f [open $path(test1) w]
   248     fconfigure $f -encoding ascii -buffering line -translation crlf
   249     puts -nonewline $f "\n12"
   250     set x [contents $path(test1)]
   251     close $f
   252     set x
   253 } "\r\n12"
   254 test io-3.4 {WriteChars: loop over stage buffer} {
   255     # stage buffer maps to more than can be queued at once.
   256 
   257     set f [open $path(test1) w]
   258     fconfigure $f -encoding jis0208 -buffersize 16 
   259     puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
   260     set x [list [contents $path(test1)]]
   261     close $f
   262     lappend x [contents $path(test1)]
   263 } [list "!)!)!)!)!)!)!)!)" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
   264 test io-3.5 {WriteChars: saved != 0} {
   265     # Bytes produced by UtfToExternal from end of last channel buffer
   266     # had to be moved to beginning of next channel buffer to preserve
   267     # requested buffersize.
   268 
   269     set f [open $path(test1) w]
   270     fconfigure $f -encoding jis0208 -buffersize 17 
   271     puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
   272     set x [list [contents $path(test1)]]
   273     close $f
   274     lappend x [contents $path(test1)]
   275 } [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
   276 test io-3.6 {WriteChars: (stageRead + dstWrote == 0)} {
   277     # One incomplete UTF-8 character at end of staging buffer.  Backup
   278     # in src to the beginning of that UTF-8 character and try again.
   279     #
   280     # Translate the first 16 bytes, produce 14 bytes of output, 2 left over
   281     # (first two bytes of \uff21 in UTF-8).  Given those two bytes try
   282     # translating them again, find that no bytes are read produced, and break
   283     # to outer loop where those two bytes will have the remaining 4 bytes
   284     # (the last byte of \uff21 plus the all of \uff22) appended.
   285 
   286     set f [open $path(test1) w]
   287     fconfigure $f -encoding shiftjis -buffersize 16
   288     puts -nonewline $f "12345678901234\uff21\uff22"
   289     set x [list [contents $path(test1)]]
   290     close $f
   291     lappend x [contents $path(test1)]
   292 } [list "12345678901234\x82\x60" "12345678901234\x82\x60\x82\x61"]
   293 test io-3.7 {WriteChars: (bufPtr->nextAdded > bufPtr->length)} {
   294     # When translating UTF-8 to external, the produced bytes went past end
   295     # of the channel buffer.  This is done purpose -- we then truncate the
   296     # bytes at the end of the partial character to preserve the requested
   297     # blocksize on flush.  The truncated bytes are moved to the beginning
   298     # of the next channel buffer.
   299 
   300     set f [open $path(test1) w]
   301     fconfigure $f -encoding jis0208 -buffersize 17 
   302     puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
   303     set x [list [contents $path(test1)]]
   304     close $f
   305     lappend x [contents $path(test1)]
   306 } [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
   307 test io-3.8 {WriteChars: reset sawLF after each buffer} {
   308     set f [open $path(test1) w]
   309     fconfigure $f -encoding ascii -buffering line -translation lf \
   310 	     -buffersize 16
   311     puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
   312     set x [list [contents $path(test1)]]
   313     close $f
   314     lappend x [contents $path(test1)]
   315 } [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]
   316 
   317 test io-4.1 {TranslateOutputEOL: lf} {
   318     # search for \n
   319 
   320     set f [open $path(test1) w]
   321     fconfigure $f -buffering line -translation lf
   322     puts $f "abcde"
   323     set x [list [contents $path(test1)]]
   324     close $f
   325     lappend x [contents $path(test1)]
   326 } [list "abcde\n" "abcde\n"]
   327 test io-4.2 {TranslateOutputEOL: cr} {
   328     # search for \n, replace with \r
   329 
   330     set f [open $path(test1) w]
   331     fconfigure $f -buffering line -translation cr
   332     puts $f "abcde"
   333     set x [list [contents $path(test1)]]
   334     close $f
   335     lappend x [contents $path(test1)]
   336 } [list "abcde\r" "abcde\r"]
   337 test io-4.3 {TranslateOutputEOL: crlf} {
   338     # simple case: search for \n, replace with \r
   339 
   340     set f [open $path(test1) w]
   341     fconfigure $f -buffering line -translation crlf
   342     puts $f "abcde"
   343     set x [list [contents $path(test1)]]
   344     close $f
   345     lappend x [contents $path(test1)]
   346 } [list "abcde\r\n" "abcde\r\n"]
   347 test io-4.4 {TranslateOutputEOL: crlf} {
   348     # keep storing more bytes in output buffer until output buffer is full.
   349     # We have 13 bytes initially that would turn into 18 bytes.  Fill
   350     # dest buffer while (dstEnd < dstMax).
   351 
   352     set f [open $path(test1) w]
   353     fconfigure $f -translation crlf -buffersize 16
   354     puts -nonewline $f "1234567\n\n\n\n\nA"
   355     set x [list [contents $path(test1)]]
   356     close $f
   357     lappend x [contents $path(test1)]
   358 } [list "1234567\r\n\r\n\r\n\r\n\r" "1234567\r\n\r\n\r\n\r\n\r\nA"]
   359 test io-4.5 {TranslateOutputEOL: crlf} {
   360     # Check for overflow of the destination buffer
   361 
   362     set f [open $path(test1) w]
   363     fconfigure $f -translation crlf -buffersize 12
   364     puts -nonewline $f "12345678901\n456789012345678901234"
   365     close $f
   366     set x [contents $path(test1)]
   367 } "12345678901\r\n456789012345678901234"
   368 
   369 test io-5.1 {CheckFlush: not full} {
   370     set f [open $path(test1) w]
   371     fconfigure $f 
   372     puts -nonewline $f "12345678901234567890"
   373     set x [list [contents $path(test1)]]
   374     close $f
   375     lappend x [contents $path(test1)]
   376 } [list "" "12345678901234567890"]
   377 test io-5.2 {CheckFlush: full} {
   378     set f [open $path(test1) w]
   379     fconfigure $f -buffersize 16
   380     puts -nonewline $f "12345678901234567890"
   381     set x [list [contents $path(test1)]]
   382     close $f
   383     lappend x [contents $path(test1)]
   384 } [list "1234567890123456" "12345678901234567890"]
   385 test io-5.3 {CheckFlush: not line} {
   386     set f [open $path(test1) w]
   387     fconfigure $f -buffering line
   388     puts -nonewline $f "12345678901234567890"
   389     set x [list [contents $path(test1)]]
   390     close $f
   391     lappend x [contents $path(test1)]
   392 } [list "" "12345678901234567890"]
   393 test io-5.4 {CheckFlush: line} {
   394     set f [open $path(test1) w]
   395     fconfigure $f -buffering line -translation lf -encoding ascii
   396     puts -nonewline $f "1234567890\n1234567890"
   397     set x [list [contents $path(test1)]]
   398     close $f
   399     lappend x [contents $path(test1)]
   400 } [list "1234567890\n1234567890" "1234567890\n1234567890"]
   401 test io-5.5 {CheckFlush: none} {
   402     set f [open $path(test1) w]
   403     fconfigure $f -buffering none
   404     puts -nonewline $f "1234567890"
   405     set x [list [contents $path(test1)]]
   406     close $f
   407     lappend x [contents $path(test1)]
   408 } [list "1234567890" "1234567890"]
   409 
   410 test io-6.1 {Tcl_GetsObj: working} {
   411     set f [open $path(test1) w]
   412     puts $f "foo\nboo"
   413     close $f
   414     set f [open $path(test1)]
   415     set x [gets $f]
   416     close $f
   417     set x
   418 } {foo}
   419 test io-6.2 {Tcl_GetsObj: CheckChannelErrors() != 0} {
   420     # no test, need to cause an async error.
   421 } {}
   422 test io-6.3 {Tcl_GetsObj: how many have we used?} {
   423     # if (bufPtr != NULL) {oldRemoved = bufPtr->nextRemoved}
   424 
   425     set f [open $path(test1) w]
   426     fconfigure $f -translation crlf
   427     puts $f "abc\ndefg"
   428     close $f
   429     set f [open $path(test1)]
   430     set x [list [tell $f] [gets $f line] [tell $f] [gets $f line] $line]
   431     close $f
   432     set x
   433 } {0 3 5 4 defg}
   434 test io-6.4 {Tcl_GetsObj: encoding == NULL} {
   435     set f [open $path(test1) w]
   436     fconfigure $f -translation binary
   437     puts $f "\x81\u1234\0"
   438     close $f
   439     set f [open $path(test1)]
   440     fconfigure $f -translation binary
   441     set x [list [gets $f line] $line]
   442     close $f
   443     set x
   444 } [list 3 "\x81\x34\x00"]
   445 test io-6.5 {Tcl_GetsObj: encoding != NULL} {
   446     set f [open $path(test1) w]
   447     fconfigure $f -translation binary
   448     puts $f "\x88\xea\x92\x9a"
   449     close $f
   450     set f [open $path(test1)]
   451     fconfigure $f -encoding shiftjis
   452     set x [list [gets $f line] $line]
   453     close $f
   454     set x
   455 } [list 2 "\u4e00\u4e01"]
   456 set a "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
   457 append a $a
   458 append a $a
   459 test io-6.6 {Tcl_GetsObj: loop test} {
   460     # if (dst >= dstEnd) 
   461 
   462     set f [open $path(test1) w]
   463     puts $f $a
   464     puts $f hi
   465     close $f
   466     set f [open $path(test1)]
   467     set x [list [gets $f line] $line]
   468     close $f
   469     set x
   470 } [list 256 $a]
   471 test io-6.7 {Tcl_GetsObj: error in input} {stdio openpipe} {
   472     # if (FilterInputBytes(chanPtr, &gs) != 0)
   473 
   474     set f [open "|[list [interpreter] $path(cat)]" w+]
   475     puts -nonewline $f "hi\nwould"
   476     flush $f
   477     gets $f
   478     fconfigure $f -blocking 0
   479     set x [gets $f line]
   480     close $f
   481     set x
   482 } {-1}
   483 test io-6.8 {Tcl_GetsObj: remember if EOF is seen} {
   484     set f [open $path(test1) w]
   485     puts $f "abcdef\x1aghijk\nwombat"
   486     close $f
   487     set f [open $path(test1)]
   488     fconfigure $f -eofchar \x1a
   489     set x [list [gets $f line] $line [gets $f line] $line]
   490     close $f
   491     set x
   492 } {6 abcdef -1 {}}
   493 test io-6.9 {Tcl_GetsObj: remember if EOF is seen} {
   494     set f [open $path(test1) w]
   495     puts $f "abcdefghijk\nwom\u001abat"
   496     close $f
   497     set f [open $path(test1)]
   498     fconfigure $f -eofchar \x1a
   499     set x [list [gets $f line] $line [gets $f line] $line]
   500     close $f
   501     set x
   502 } {11 abcdefghijk 3 wom}
   503 
   504 # Comprehensive tests
   505 
   506 test io-6.10 {Tcl_GetsObj: lf mode: no chars} {
   507     set f [open $path(test1) w]
   508     close $f
   509     set f [open $path(test1)]
   510     fconfigure $f -translation lf
   511     set x [list [gets $f line] $line]
   512     close $f
   513     set x
   514 } {-1 {}}
   515 test io-6.11 {Tcl_GetsObj: lf mode: lone \n} {
   516     set f [open $path(test1) w]
   517     fconfigure $f -translation lf
   518     puts -nonewline $f "\n"
   519     close $f
   520     set f [open $path(test1)]
   521     fconfigure $f -translation lf
   522     set x [list [gets $f line] $line [gets $f line] $line]
   523     close $f
   524     set x
   525 } {0 {} -1 {}}
   526 test io-6.12 {Tcl_GetsObj: lf mode: lone \r} {
   527     set f [open $path(test1) w]
   528     fconfigure $f -translation lf
   529     puts -nonewline $f "\r"
   530     close $f
   531     set f [open $path(test1)]
   532     fconfigure $f -translation lf
   533     set x [list [gets $f line] $line [gets $f line] $line]
   534     close $f
   535     set x
   536 } [list 1 "\r" -1 ""]
   537 test io-6.13 {Tcl_GetsObj: lf mode: 1 char} {
   538     set f [open $path(test1) w]
   539     fconfigure $f -translation lf
   540     puts -nonewline $f a
   541     close $f
   542     set f [open $path(test1)]
   543     fconfigure $f -translation lf
   544     set x [list [gets $f line] $line [gets $f line] $line]
   545     close $f
   546     set x
   547 } {1 a -1 {}}
   548 test io-6.14 {Tcl_GetsObj: lf mode: 1 char followed by EOL} {
   549     set f [open $path(test1) w]
   550     fconfigure $f -translation lf
   551     puts -nonewline $f "a\n"
   552     close $f
   553     set f [open $path(test1)]
   554     fconfigure $f -translation lf
   555     set x [list [gets $f line] $line [gets $f line] $line]
   556     close $f
   557     set x
   558 } {1 a -1 {}}
   559 test io-6.15 {Tcl_GetsObj: lf mode: several chars} {
   560     set f [open $path(test1) w]
   561     fconfigure $f -translation lf
   562     puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
   563     close $f
   564     set f [open $path(test1)]
   565     fconfigure $f -translation lf
   566     set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line [gets $f line] $line]
   567     close $f
   568     set x
   569 } [list 4 "abcd" 10 "efgh\rijkl\r" 4 "mnop" -1 ""]
   570 test io-6.16 {Tcl_GetsObj: cr mode: no chars} {
   571     set f [open $path(test1) w]
   572     close $f
   573     set f [open $path(test1)]
   574     fconfigure $f -translation cr
   575     set x [list [gets $f line] $line]
   576     close $f
   577     set x
   578 } {-1 {}}
   579 test io-6.17 {Tcl_GetsObj: cr mode: lone \n} {
   580     set f [open $path(test1) w]
   581     fconfigure $f -translation lf
   582     puts -nonewline $f "\n"
   583     close $f
   584     set f [open $path(test1)]
   585     fconfigure $f -translation cr
   586     set x [list [gets $f line] $line [gets $f line] $line]
   587     close $f
   588     set x
   589 } [list 1 "\n" -1 ""]
   590 test io-6.18 {Tcl_GetsObj: cr mode: lone \r} {
   591     set f [open $path(test1) w]
   592     fconfigure $f -translation lf
   593     puts -nonewline $f "\r"
   594     close $f
   595     set f [open $path(test1)]
   596     fconfigure $f -translation cr
   597     set x [list [gets $f line] $line [gets $f line] $line]
   598     close $f
   599     set x
   600 } {0 {} -1 {}}
   601 test io-6.19 {Tcl_GetsObj: cr mode: 1 char} {
   602     set f [open $path(test1) w]
   603     fconfigure $f -translation lf
   604     puts -nonewline $f a
   605     close $f
   606     set f [open $path(test1)]
   607     fconfigure $f -translation cr
   608     set x [list [gets $f line] $line [gets $f line] $line]
   609     close $f
   610     set x
   611 } {1 a -1 {}}
   612 test io-6.20 {Tcl_GetsObj: cr mode: 1 char followed by EOL} {
   613     set f [open $path(test1) w]
   614     fconfigure $f -translation lf
   615     puts -nonewline $f "a\r"
   616     close $f
   617     set f [open $path(test1)]
   618     fconfigure $f -translation cr
   619     set x [list [gets $f line] $line [gets $f line] $line]
   620     close $f
   621     set x
   622 } {1 a -1 {}}
   623 test io-6.21 {Tcl_GetsObj: cr mode: several chars} {
   624     set f [open $path(test1) w]
   625     fconfigure $f -translation lf
   626     puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
   627     close $f
   628     set f [open $path(test1)]
   629     fconfigure $f -translation cr
   630     set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line [gets $f line] $line]
   631     close $f
   632     set x
   633 } [list 9 "abcd\nefgh" 4 "ijkl" 5 "\nmnop" -1 ""]
   634 test io-6.22 {Tcl_GetsObj: crlf mode: no chars} {
   635     set f [open $path(test1) w]
   636     close $f
   637     set f [open $path(test1)]
   638     fconfigure $f -translation crlf
   639     set x [list [gets $f line] $line]
   640     close $f
   641     set x
   642 } {-1 {}}
   643 test io-6.23 {Tcl_GetsObj: crlf mode: lone \n} {
   644     set f [open $path(test1) w]
   645     fconfigure $f -translation lf
   646     puts -nonewline $f "\n"
   647     close $f
   648     set f [open $path(test1)]
   649     fconfigure $f -translation crlf
   650     set x [list [gets $f line] $line [gets $f line] $line]
   651     close $f
   652     set x
   653 } [list 1 "\n" -1 ""]
   654 test io-6.24 {Tcl_GetsObj: crlf mode: lone \r} {
   655     set f [open $path(test1) w]
   656     fconfigure $f -translation lf
   657     puts -nonewline $f "\r"
   658     close $f
   659     set f [open $path(test1)]
   660     fconfigure $f -translation crlf
   661     set x [list [gets $f line] $line [gets $f line] $line]
   662     close $f
   663     set x
   664 } [list 1 "\r" -1 ""]
   665 test io-6.25 {Tcl_GetsObj: crlf mode: \r\r} {
   666     set f [open $path(test1) w]
   667     fconfigure $f -translation lf
   668     puts -nonewline $f "\r\r"
   669     close $f
   670     set f [open $path(test1)]
   671     fconfigure $f -translation crlf
   672     set x [list [gets $f line] $line [gets $f line] $line]
   673     close $f
   674     set x
   675 } [list 2 "\r\r" -1 ""]
   676 test io-6.26 {Tcl_GetsObj: crlf mode: \r\n} {
   677     set f [open $path(test1) w]
   678     fconfigure $f -translation lf
   679     puts -nonewline $f "\r\n"
   680     close $f
   681     set f [open $path(test1)]
   682     fconfigure $f -translation crlf
   683     set x [list [gets $f line] $line [gets $f line] $line]
   684     close $f
   685     set x
   686 } [list 0 "" -1 ""]
   687 test io-6.27 {Tcl_GetsObj: crlf mode: 1 char} {
   688     set f [open $path(test1) w]
   689     fconfigure $f -translation lf
   690     puts -nonewline $f a
   691     close $f
   692     set f [open $path(test1)]
   693     fconfigure $f -translation crlf
   694     set x [list [gets $f line] $line [gets $f line] $line]
   695     close $f
   696     set x
   697 } {1 a -1 {}}
   698 test io-6.28 {Tcl_GetsObj: crlf mode: 1 char followed by EOL} {
   699     set f [open $path(test1) w]
   700     fconfigure $f -translation lf
   701     puts -nonewline $f "a\r\n"
   702     close $f
   703     set f [open $path(test1)]
   704     fconfigure $f -translation crlf
   705     set x [list [gets $f line] $line [gets $f line] $line]
   706     close $f
   707     set x
   708 } {1 a -1 {}}
   709 test io-6.29 {Tcl_GetsObj: crlf mode: several chars} {
   710     set f [open $path(test1) w]
   711     fconfigure $f -translation lf
   712     puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
   713     close $f
   714     set f [open $path(test1)]
   715     fconfigure $f -translation crlf
   716     set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
   717     close $f
   718     set x
   719 } [list 14 "abcd\nefgh\rijkl" 4 "mnop" -1 ""]
   720 test io-6.30 {Tcl_GetsObj: crlf mode: buffer exhausted} {testchannel} {
   721     # if (eol >= dstEnd)
   722 
   723     set f [open $path(test1) w]
   724     fconfigure $f -translation lf
   725     puts -nonewline $f "123456789012345\r\nabcdefghijklmnoprstuvwxyz"
   726     close $f
   727     set f [open $path(test1)]
   728     fconfigure $f -translation crlf -buffersize 16
   729     set x [list [gets $f line] $line [testchannel inputbuffered $f]]
   730     close $f
   731     set x
   732 } [list 15 "123456789012345" 15]
   733 test io-6.31 {Tcl_GetsObj: crlf mode: buffer exhausted, blocked} {stdio testchannel openpipe fileevent} {
   734     # (FilterInputBytes() != 0)
   735 
   736     set f [open "|[list [interpreter] $path(cat)]" w+]
   737     fconfigure $f -translation {crlf lf} -buffering none
   738     puts -nonewline $f "bbbbbbbbbbbbbb\r\n123456789012345\r"
   739     fconfigure $f -buffersize 16
   740     set x [gets $f]
   741     fconfigure $f -blocking 0
   742     lappend x [gets $f line] $line [fblocked $f] [testchannel inputbuffered $f]
   743     close $f
   744     set x
   745 } [list "bbbbbbbbbbbbbb" -1 "" 1 16]
   746 test io-6.32 {Tcl_GetsObj: crlf mode: buffer exhausted, more data} {testchannel} {
   747     # not (FilterInputBytes() != 0)
   748 
   749     set f [open $path(test1) w]
   750     fconfigure $f -translation lf
   751     puts -nonewline $f "123456789012345\r\n123"
   752     close $f
   753     set f [open $path(test1)]
   754     fconfigure $f -translation crlf -buffersize 16
   755     set x [list [gets $f line] $line [tell $f] [testchannel inputbuffered $f]]
   756     close $f
   757     set x
   758 } [list 15 "123456789012345" 17 3]
   759 test io-6.33 {Tcl_GetsObj: crlf mode: buffer exhausted, at eof} {
   760     # eol still equals dstEnd
   761     
   762     set f [open $path(test1) w]
   763     fconfigure $f -translation lf
   764     puts -nonewline $f "123456789012345\r"
   765     close $f
   766     set f [open $path(test1)]
   767     fconfigure $f -translation crlf -buffersize 16
   768     set x [list [gets $f line] $line [eof $f]]
   769     close $f
   770     set x
   771 } [list 16 "123456789012345\r" 1]
   772 test io-6.34 {Tcl_GetsObj: crlf mode: buffer exhausted, not followed by \n} {
   773     # not (*eol == '\n') 
   774     
   775     set f [open $path(test1) w]
   776     fconfigure $f -translation lf
   777     puts -nonewline $f "123456789012345\rabcd\r\nefg"
   778     close $f
   779     set f [open $path(test1)]
   780     fconfigure $f -translation crlf -buffersize 16
   781     set x [list [gets $f line] $line [tell $f]]
   782     close $f
   783     set x
   784 } [list 20 "123456789012345\rabcd" 22]
   785 test io-6.35 {Tcl_GetsObj: auto mode: no chars} {
   786     set f [open $path(test1) w]
   787     close $f
   788     set f [open $path(test1)]
   789     fconfigure $f -translation auto
   790     set x [list [gets $f line] $line]
   791     close $f
   792     set x
   793 } {-1 {}}
   794 test io-6.36 {Tcl_GetsObj: auto mode: lone \n} {
   795     set f [open $path(test1) w]
   796     fconfigure $f -translation lf
   797     puts -nonewline $f "\n"
   798     close $f
   799     set f [open $path(test1)]
   800     fconfigure $f -translation auto
   801     set x [list [gets $f line] $line [gets $f line] $line]
   802     close $f
   803     set x
   804 } [list 0 "" -1 ""]
   805 test io-6.37 {Tcl_GetsObj: auto mode: lone \r} {
   806     set f [open $path(test1) w]
   807     fconfigure $f -translation lf
   808     puts -nonewline $f "\r"
   809     close $f
   810     set f [open $path(test1)]
   811     fconfigure $f -translation auto
   812     set x [list [gets $f line] $line [gets $f line] $line]
   813     close $f
   814     set x
   815 } [list 0 "" -1 ""]
   816 test io-6.38 {Tcl_GetsObj: auto mode: \r\r} {
   817     set f [open $path(test1) w]
   818     fconfigure $f -translation lf
   819     puts -nonewline $f "\r\r"
   820     close $f
   821     set f [open $path(test1)]
   822     fconfigure $f -translation auto
   823     set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
   824     close $f
   825     set x
   826 } [list 0 "" 0 "" -1 ""]
   827 test io-6.39 {Tcl_GetsObj: auto mode: \r\n} {
   828     set f [open $path(test1) w]
   829     fconfigure $f -translation lf
   830     puts -nonewline $f "\r\n"
   831     close $f
   832     set f [open $path(test1)]
   833     fconfigure $f -translation auto
   834     set x [list [gets $f line] $line [gets $f line] $line]
   835     close $f
   836     set x
   837 } [list 0 "" -1 ""]
   838 test io-6.40 {Tcl_GetsObj: auto mode: 1 char} {
   839     set f [open $path(test1) w]
   840     fconfigure $f -translation lf
   841     puts -nonewline $f a
   842     close $f
   843     set f [open $path(test1)]
   844     fconfigure $f -translation auto
   845     set x [list [gets $f line] $line [gets $f line] $line]
   846     close $f
   847     set x
   848 } {1 a -1 {}}
   849 test io-6.41 {Tcl_GetsObj: auto mode: 1 char followed by EOL} {
   850     set f [open $path(test1) w]
   851     fconfigure $f -translation lf
   852     puts -nonewline $f "a\r\n"
   853     close $f
   854     set f [open $path(test1)]
   855     fconfigure $f -translation auto
   856     set x [list [gets $f line] $line [gets $f line] $line]
   857     close $f
   858     set x
   859 } {1 a -1 {}}
   860 test io-6.42 {Tcl_GetsObj: auto mode: several chars} {
   861     set f [open $path(test1) w]
   862     fconfigure $f -translation lf
   863     puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
   864     close $f
   865     set f [open $path(test1)]
   866     fconfigure $f -translation auto
   867     set x [list [gets $f line] $line [gets $f line] $line]
   868     lappend x [gets $f line] $line [gets $f line] $line [gets $f line] $line
   869     close $f
   870     set x
   871 } [list 4 "abcd" 4 "efgh" 4 "ijkl" 4 "mnop" -1 ""]
   872 test io-6.43 {Tcl_GetsObj: input saw cr} {stdio testchannel openpipe fileevent} {
   873     # if (chanPtr->flags & INPUT_SAW_CR)
   874 
   875     set f [open "|[list [interpreter] $path(cat)]" w+]
   876     fconfigure $f -translation {auto lf} -buffering none
   877     puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
   878     fconfigure $f -buffersize 16
   879     set x [list [gets $f]]
   880     fconfigure $f -blocking 0
   881     lappend x [gets $f line] $line [testchannel queuedcr $f] 
   882     fconfigure $f -blocking 1
   883     puts -nonewline $f "\nabcd\refg\x1a"
   884     lappend x [gets $f line] $line [testchannel queuedcr $f]
   885     lappend x [gets $f line] $line
   886     close $f
   887     set x
   888 } [list "bbbbbbbbbbbbbbb" 15 "123456789abcdef" 1 4 "abcd" 0 3 "efg"]
   889 test io-6.44 {Tcl_GetsObj: input saw cr, not followed by cr} {stdio testchannel openpipe fileevent} {
   890     # not (*eol == '\n') 
   891 
   892     set f [open "|[list [interpreter] $path(cat)]" w+]
   893     fconfigure $f -translation {auto lf} -buffering none
   894     puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
   895     fconfigure $f -buffersize 16
   896     set x [list [gets $f]]
   897     fconfigure $f -blocking 0
   898     lappend x [gets $f line] $line [testchannel queuedcr $f] 
   899     fconfigure $f -blocking 1
   900     puts -nonewline $f "abcd\refg\x1a"
   901     lappend x [gets $f line] $line [testchannel queuedcr $f]
   902     lappend x [gets $f line] $line
   903     close $f
   904     set x
   905 } [list "bbbbbbbbbbbbbbb" 15 "123456789abcdef" 1 4 "abcd" 0 3 "efg"]
   906 test io-6.45 {Tcl_GetsObj: input saw cr, skip right number of bytes} {stdio testchannel openpipe fileevent} {
   907     # Tcl_ExternalToUtf()
   908 
   909     set f [open "|[list [interpreter] $path(cat)]" w+]
   910     fconfigure $f -translation {auto lf} -buffering none
   911     fconfigure $f -encoding unicode
   912     puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
   913     fconfigure $f -buffersize 16
   914     gets $f
   915     fconfigure $f -blocking 0
   916     set x [list [gets $f line] $line [testchannel queuedcr $f]]
   917     fconfigure $f -blocking 1
   918     puts -nonewline $f "\nabcd\refg"
   919     lappend x [gets $f line] $line [testchannel queuedcr $f]
   920     close $f
   921     set x
   922 } [list 15 "123456789abcdef" 1 4 "abcd" 0]
   923 test io-6.46 {Tcl_GetsObj: input saw cr, followed by just \n should give eof} {stdio testchannel openpipe fileevent} {
   924     # memmove()
   925 
   926     set f [open "|[list [interpreter] $path(cat)]" w+]
   927     fconfigure $f -translation {auto lf} -buffering none
   928     puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
   929     fconfigure $f -buffersize 16
   930     gets $f
   931     fconfigure $f -blocking 0
   932     set x [list [gets $f line] $line [testchannel queuedcr $f]]
   933     fconfigure $f -blocking 1
   934     puts -nonewline $f "\n\x1a"
   935     lappend x [gets $f line] $line [testchannel queuedcr $f]
   936     close $f
   937     set x
   938 } [list 15 "123456789abcdef" 1 -1 "" 0]
   939 test io-6.47 {Tcl_GetsObj: auto mode: \r at end of buffer, peek for \n} {testchannel} {
   940     # (eol == dstEnd)
   941 
   942     set f [open $path(test1) w]
   943     fconfigure $f -translation lf
   944     puts -nonewline $f "123456789012345\r\nabcdefghijklmnopq"
   945     close $f
   946     set f [open $path(test1)]
   947     fconfigure $f -translation auto -buffersize 16
   948     set x [list [gets $f] [testchannel inputbuffered $f]]
   949     close $f
   950     set x
   951 } [list "123456789012345" 15]    
   952 test io-6.48 {Tcl_GetsObj: auto mode: \r at end of buffer, no more avail} {testchannel} {
   953     # PeekAhead() did not get any, so (eol >= dstEnd)
   954     
   955     set f [open $path(test1) w]
   956     fconfigure $f -translation lf
   957     puts -nonewline $f "123456789012345\r"
   958     close $f
   959     set f [open $path(test1)]
   960     fconfigure $f -translation auto -buffersize 16
   961     set x [list [gets $f] [testchannel queuedcr $f]]
   962     close $f
   963     set x
   964 } [list "123456789012345" 1]
   965 test io-6.49 {Tcl_GetsObj: auto mode: \r followed by \n} {testchannel} {
   966     # if (*eol == '\n') {skip++}
   967     
   968     set f [open $path(test1) w]
   969     fconfigure $f -translation lf
   970     puts -nonewline $f "123456\r\n78901"
   971     close $f
   972     set f [open $path(test1)]
   973     set x [list [gets $f] [testchannel queuedcr $f] [tell $f] [gets $f]]
   974     close $f
   975     set x
   976 } [list "123456" 0 8 "78901"]
   977 test io-6.50 {Tcl_GetsObj: auto mode: \r not followed by \n} {testchannel} {
   978     # not (*eol == '\n') 
   979     
   980     set f [open $path(test1) w]
   981     fconfigure $f -translation lf
   982     puts -nonewline $f "123456\r78901"
   983     close $f
   984     set f [open $path(test1)]
   985     set x [list [gets $f] [testchannel queuedcr $f] [tell $f] [gets $f]]
   986     close $f
   987     set x
   988 } [list "123456" 0 7 "78901"]
   989 test io-6.51 {Tcl_GetsObj: auto mode: \n} {
   990     # else if (*eol == '\n') {goto gotoeol;}
   991     
   992     set f [open $path(test1) w]
   993     fconfigure $f -translation lf
   994     puts -nonewline $f "123456\n78901"
   995     close $f
   996     set f [open $path(test1)]
   997     set x [list [gets $f] [tell $f] [gets $f]]
   998     close $f
   999     set x
  1000 } [list "123456" 7 "78901"]
  1001 test io-6.52 {Tcl_GetsObj: saw EOF character} {testchannel} {
  1002     # if (eof != NULL)
  1003 
  1004     set f [open $path(test1) w]
  1005     fconfigure $f -translation lf
  1006     puts -nonewline $f "123456\x1ak9012345\r"
  1007     close $f
  1008     set f [open $path(test1)]
  1009     fconfigure $f -eofchar \x1a
  1010     set x [list [gets $f] [testchannel queuedcr $f] [tell $f] [gets $f]]
  1011     close $f
  1012     set x
  1013 } [list "123456" 0 6 ""]
  1014 test io-6.53 {Tcl_GetsObj: device EOF} {
  1015     # didn't produce any bytes
  1016 
  1017     set f [open $path(test1) w]
  1018     close $f
  1019     set f [open $path(test1)]
  1020     set x [list [gets $f line] $line [eof $f]]
  1021     close $f
  1022     set x
  1023 } {-1 {} 1}
  1024 test io-6.54 {Tcl_GetsObj: device EOF} {
  1025     # got some bytes before EOF.
  1026 
  1027     set f [open $path(test1) w]
  1028     puts -nonewline $f abc
  1029     close $f
  1030     set f [open $path(test1)]
  1031     set x [list [gets $f line] $line [eof $f]]
  1032     close $f
  1033     set x
  1034 } {3 abc 1}
  1035 test io-6.55 {Tcl_GetsObj: overconverted} {
  1036     # Tcl_ExternalToUtf(), make sure state updated
  1037 
  1038     set f [open $path(test1) w]
  1039     fconfigure $f -encoding iso2022-jp
  1040     puts $f "there\u4e00ok\n\u4e01more bytes\nhere"
  1041     close $f
  1042     set f [open $path(test1)]
  1043     fconfigure $f -encoding iso2022-jp
  1044     set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
  1045     close $f
  1046     set x
  1047 } [list 8 "there\u4e00ok" 11 "\u4e01more bytes" 4 "here"]
  1048 test io-6.56 {Tcl_GetsObj: incomplete lines should disable file events} {stdio openpipe fileevent} {
  1049     update
  1050     set f [open "|[list [interpreter] $path(cat)]" w+]
  1051     fconfigure $f -buffering none
  1052     puts -nonewline $f "foobar"
  1053     fconfigure $f -blocking 0
  1054     variable x {}
  1055     after 500 [namespace code { lappend x timeout }]
  1056     fileevent $f readable [namespace code { lappend x [gets $f] }]
  1057     vwait [namespace which -variable x]
  1058     vwait [namespace which -variable x]
  1059     fconfigure $f -blocking 1
  1060     puts -nonewline $f "baz\n"
  1061     after 500 [namespace code { lappend x timeout }]
  1062     fconfigure $f -blocking 0
  1063     vwait [namespace which -variable x]
  1064     vwait [namespace which -variable x]
  1065     close $f
  1066     set x
  1067 } {{} timeout foobarbaz timeout}
  1068 
  1069 test io-7.1 {FilterInputBytes: split up character at end of buffer} {
  1070     # (result == TCL_CONVERT_MULTIBYTE)
  1071 
  1072     set f [open $path(test1) w]
  1073     fconfigure $f -encoding shiftjis
  1074     puts $f "1234567890123\uff10\uff11\uff12\uff13\uff14\nend"
  1075     close $f
  1076     set f [open $path(test1)]
  1077     fconfigure $f -encoding shiftjis -buffersize 16
  1078     set x [gets $f]
  1079     close $f
  1080     set x
  1081 } "1234567890123\uff10\uff11\uff12\uff13\uff14"
  1082 test io-7.2 {FilterInputBytes: split up character in middle of buffer} {
  1083     # (bufPtr->nextAdded < bufPtr->bufLength)
  1084     
  1085     set f [open $path(test1) w]
  1086     fconfigure $f -encoding binary
  1087     puts -nonewline $f "1234567890\n123\x82\x4f\x82\x50\x82"
  1088     close $f
  1089     set f [open $path(test1)]
  1090     fconfigure $f -encoding shiftjis
  1091     set x [list [gets $f line] $line [eof $f]]
  1092     close $f
  1093     set x
  1094 } [list 10 "1234567890" 0]
  1095 test io-7.3 {FilterInputBytes: split up character at EOF} {testchannel} {
  1096     set f [open $path(test1) w]
  1097     fconfigure $f -encoding binary
  1098     puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
  1099     close $f
  1100     set f [open $path(test1)]
  1101     fconfigure $f -encoding shiftjis
  1102     set x [list [gets $f line] $line]
  1103     lappend x [tell $f] [testchannel inputbuffered $f] [eof $f]
  1104     lappend x [gets $f line] $line
  1105     close $f
  1106     set x
  1107 } [list 15 "1234567890123\uff10\uff11" 18 0 1 -1 ""]
  1108 test io-7.4 {FilterInputBytes: recover from split up character} {stdio openpipe fileevent} {
  1109     set f [open "|[list [interpreter] $path(cat)]" w+]
  1110     fconfigure $f -encoding binary -buffering none
  1111     puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
  1112     fconfigure $f -encoding shiftjis -blocking 0
  1113     fileevent $f read [namespace code "ready $f"]
  1114     variable x {}
  1115     proc ready {f} {
  1116 	variable x
  1117 	lappend x [gets $f line] $line [fblocked $f]
  1118     }
  1119     vwait [namespace which -variable x]
  1120     fconfigure $f -encoding binary -blocking 1
  1121     puts $f "\x51\x82\x52"
  1122     fconfigure $f -encoding shiftjis
  1123     vwait [namespace which -variable x]
  1124     close $f
  1125     set x
  1126 } [list -1 "" 1 17 "1234567890123\uff10\uff11\uff12\uff13" 0]
  1127 
  1128 test io-8.1 {PeekAhead: only go to device if no more cached data} {testchannel} {
  1129     # (bufPtr->nextPtr == NULL)
  1130 
  1131     set f [open $path(test1) w]
  1132     fconfigure $f -encoding ascii -translation lf
  1133     puts -nonewline $f "123456789012345\r\n2345678"
  1134     close $f
  1135     set f [open $path(test1)]
  1136     fconfigure $f -encoding ascii -translation auto -buffersize 16
  1137     # here
  1138     gets $f
  1139     set x [testchannel inputbuffered $f]
  1140     close $f
  1141     set x
  1142 } "7"
  1143 test io-8.2 {PeekAhead: only go to device if no more cached data} {stdio testchannel openpipe fileevent} {
  1144     # not (bufPtr->nextPtr == NULL)
  1145 
  1146     set f [open "|[list [interpreter] $path(cat)]" w+]
  1147     fconfigure $f -translation lf -encoding ascii -buffering none
  1148     puts -nonewline $f "123456789012345\r\nbcdefghijklmnopqrstuvwxyz"
  1149     variable x {}
  1150     fileevent $f read [namespace code "ready $f"]
  1151     proc ready {f} {
  1152 	variable x
  1153 	lappend x [gets $f line] $line [testchannel inputbuffered $f]
  1154     }
  1155     fconfigure $f -encoding unicode -buffersize 16 -blocking 0
  1156     vwait [namespace which -variable x]
  1157     fconfigure $f -translation auto -encoding ascii -blocking 1
  1158     # here
  1159     vwait [namespace which -variable x]
  1160     close $f
  1161     set x
  1162 } [list -1 "" 42 15 "123456789012345" 25]
  1163 test io-8.3 {PeekAhead: no cached data available} {stdio testchannel openpipe fileevent} {
  1164     # (bytesLeft == 0)
  1165 
  1166     set f [open "|[list [interpreter] $path(cat)]" w+]
  1167     fconfigure $f -translation {auto binary}
  1168     puts -nonewline $f "abcdefghijklmno\r"
  1169     flush $f
  1170     set x [list [gets $f line] $line [testchannel queuedcr $f]]
  1171     close $f
  1172     set x
  1173 } [list 15 "abcdefghijklmno" 1]
  1174 set a "123456789012345678901234567890"
  1175 append a "123456789012345678901234567890"
  1176 append a "1234567890123456789012345678901"
  1177 test io-8.4 {PeekAhead: cached data available in this buffer} {
  1178     # not (bytesLeft == 0)
  1179 
  1180     set f [open $path(test1) w+]
  1181     fconfigure $f -translation binary
  1182     puts $f "${a}\r\nabcdef"
  1183     close $f
  1184     set f [open $path(test1)]
  1185     fconfigure $f -encoding binary -translation auto
  1186 
  1187     # "${a}\r" was converted in one operation (because ENCODING_LINESIZE
  1188     # is 30).  To check if "\n" follows, calls PeekAhead and determines
  1189     # that cached data is available in buffer w/o having to call driver.
  1190 
  1191     set x [gets $f]
  1192     close $f
  1193     set x    
  1194 } $a
  1195 unset a
  1196 test io-8.5 {PeekAhead: don't peek if last read was short} {stdio testchannel openpipe fileevent} {
  1197     # (bufPtr->nextAdded < bufPtr->length)
  1198 
  1199     set f [open "|[list [interpreter] $path(cat)]" w+]
  1200     fconfigure $f -translation {auto binary}
  1201     puts -nonewline $f "abcdefghijklmno\r"
  1202     flush $f
  1203     # here
  1204     set x [list [gets $f line] $line [testchannel queuedcr $f]]
  1205     close $f
  1206     set x
  1207 } {15 abcdefghijklmno 1}
  1208 test io-8.6 {PeekAhead: change to non-blocking mode} {stdio testchannel openpipe fileevent} {
  1209     # ((chanPtr->flags & CHANNEL_NONBLOCKING) == 0) 
  1210 
  1211     set f [open "|[list [interpreter] $path(cat)]" w+]
  1212     fconfigure $f -translation {auto binary} -buffersize 16
  1213     puts -nonewline $f "abcdefghijklmno\r"
  1214     flush $f
  1215     # here
  1216     set x [list [gets $f line] $line [testchannel queuedcr $f]]
  1217     close $f
  1218     set x
  1219 } {15 abcdefghijklmno 1}
  1220 test io-8.7 {PeekAhead: cleanup} {stdio testchannel openpipe fileevent} {
  1221     # Make sure bytes are removed from buffer.
  1222 
  1223     set f [open "|[list [interpreter] $path(cat)]" w+]
  1224     fconfigure $f -translation {auto binary} -buffering none
  1225     puts -nonewline $f "abcdefghijklmno\r"
  1226     # here
  1227     set x [list [gets $f line] $line [testchannel queuedcr $f]]
  1228     puts -nonewline $f "\x1a"
  1229     lappend x [gets $f line] $line
  1230     close $f
  1231     set x
  1232 } {15 abcdefghijklmno 1 -1 {}}
  1233     
  1234 
  1235 test io-9.1 {CommonGetsCleanup} {
  1236 } {}
  1237 
  1238 test io-10.1 {Tcl_ReadChars: CheckChannelErrors} {
  1239     # no test, need to cause an async error.
  1240 } {}
  1241 test io-10.2 {Tcl_ReadChars: loop until enough copied} {
  1242     # one time
  1243     # for (copied = 0; (unsigned) toRead > 0; )
  1244 
  1245     set f [open $path(test1) w]
  1246     puts $f abcdefghijklmnop
  1247     close $f
  1248 
  1249     set f [open $path(test1)]
  1250     set x [read $f 5]
  1251     close $f
  1252     set x
  1253 } {abcde}
  1254 test io-10.3 {Tcl_ReadChars: loop until enough copied} {
  1255     # multiple times
  1256     # for (copied = 0; (unsigned) toRead > 0; )
  1257 
  1258     set f [open $path(test1) w]
  1259     puts $f abcdefghijklmnopqrstuvwxyz
  1260     close $f
  1261 
  1262     set f [open $path(test1)]
  1263     fconfigure $f -buffersize 16
  1264     # here
  1265     set x [read $f 19]
  1266     close $f
  1267     set x
  1268 } {abcdefghijklmnopqrs}
  1269 test io-10.4 {Tcl_ReadChars: no more in channel buffer} {
  1270     # (copiedNow < 0)
  1271 
  1272     set f [open $path(test1) w]
  1273     puts -nonewline $f abcdefghijkl
  1274     close $f
  1275 
  1276     set f [open $path(test1)]
  1277     # here
  1278     set x [read $f 1000]
  1279     close $f
  1280     set x
  1281 } {abcdefghijkl}
  1282 test io-10.5 {Tcl_ReadChars: stop on EOF} {
  1283     # (chanPtr->flags & CHANNEL_EOF)
  1284 
  1285     set f [open $path(test1) w]
  1286     puts -nonewline $f abcdefghijkl
  1287     close $f
  1288 
  1289     set f [open $path(test1)]
  1290     # here
  1291     set x [read $f 1000]
  1292     close $f
  1293     set x
  1294 } {abcdefghijkl}
  1295 
  1296 test io-11.1 {ReadBytes: want to read a lot} {
  1297     # ((unsigned) toRead > (unsigned) srcLen)
  1298 
  1299     set f [open $path(test1) w]
  1300     puts -nonewline $f abcdefghijkl
  1301     close $f
  1302     set f [open $path(test1)]
  1303     fconfigure $f -encoding binary
  1304     # here
  1305     set x [read $f 1000]
  1306     close $f
  1307     set x
  1308 } {abcdefghijkl}
  1309 test io-11.2 {ReadBytes: want to read all} {
  1310     # ((unsigned) toRead > (unsigned) srcLen)
  1311 
  1312     set f [open $path(test1) w]
  1313     puts -nonewline $f abcdefghijkl
  1314     close $f
  1315     set f [open $path(test1)]
  1316     fconfigure $f -encoding binary
  1317     # here
  1318     set x [read $f]
  1319     close $f
  1320     set x
  1321 } {abcdefghijkl}
  1322 test io-11.3 {ReadBytes: allocate more space} {
  1323     # (toRead > length - offset - 1)
  1324 
  1325     set f [open $path(test1) w]
  1326     puts -nonewline $f abcdefghijklmnopqrstuvwxyz
  1327     close $f
  1328     set f [open $path(test1)]
  1329     fconfigure $f -buffersize 16 -encoding binary
  1330     # here
  1331     set x [read $f]
  1332     close $f
  1333     set x
  1334 } {abcdefghijklmnopqrstuvwxyz}
  1335 test io-11.4 {ReadBytes: EOF char found} {
  1336     # (TranslateInputEOL() != 0)
  1337 
  1338     set f [open $path(test1) w]
  1339     puts $f abcdefghijklmnopqrstuvwxyz
  1340     close $f
  1341     set f [open $path(test1)]
  1342     fconfigure $f -eofchar m -encoding binary
  1343     # here
  1344     set x [list [read $f] [eof $f] [read $f] [eof $f]]
  1345     close $f
  1346     set x
  1347 } [list "abcdefghijkl" 1 "" 1]
  1348     
  1349 test io-12.1 {ReadChars: want to read a lot} {
  1350     # ((unsigned) toRead > (unsigned) srcLen)
  1351 
  1352     set f [open $path(test1) w]
  1353     puts -nonewline $f abcdefghijkl
  1354     close $f
  1355     set f [open $path(test1)]
  1356     # here
  1357     set x [read $f 1000]
  1358     close $f
  1359     set x
  1360 } {abcdefghijkl}
  1361 test io-12.2 {ReadChars: want to read all} {
  1362     # ((unsigned) toRead > (unsigned) srcLen)
  1363 
  1364     set f [open $path(test1) w]
  1365     puts -nonewline $f abcdefghijkl
  1366     close $f
  1367     set f [open $path(test1)]
  1368     # here
  1369     set x [read $f]
  1370     close $f
  1371     set x
  1372 } {abcdefghijkl}
  1373 test io-12.3 {ReadChars: allocate more space} {
  1374     # (toRead > length - offset - 1)
  1375 
  1376     set f [open $path(test1) w]
  1377     puts -nonewline $f abcdefghijklmnopqrstuvwxyz
  1378     close $f
  1379     set f [open $path(test1)]
  1380     fconfigure $f -buffersize 16
  1381     # here
  1382     set x [read $f]
  1383     close $f
  1384     set x
  1385 } {abcdefghijklmnopqrstuvwxyz}
  1386 test io-12.4 {ReadChars: split-up char} {stdio testchannel openpipe fileevent} {
  1387     # (srcRead == 0)
  1388 
  1389     set f [open "|[list [interpreter] $path(cat)]" w+]
  1390     fconfigure $f -encoding binary -buffering none -buffersize 16
  1391     puts -nonewline $f "123456789012345\x96"
  1392     fconfigure $f -encoding shiftjis -blocking 0
  1393 
  1394     fileevent $f read [namespace code "ready $f"]
  1395     proc ready {f} {
  1396 	variable x
  1397 	lappend x [read $f] [testchannel inputbuffered $f]
  1398     }
  1399     variable x {}
  1400 
  1401     fconfigure $f -encoding shiftjis
  1402     vwait [namespace which -variable x]
  1403     fconfigure $f -encoding binary -blocking 1
  1404     puts -nonewline $f "\x7b"
  1405     after 500			;# Give the cat process time to catch up
  1406     fconfigure $f -encoding shiftjis -blocking 0
  1407     vwait [namespace which -variable x]
  1408     close $f
  1409     set x
  1410 } [list "123456789012345" 1 "\u672c" 0]
  1411 test io-12.5 {ReadChars: fileevents on partial characters} {stdio openpipe fileevent} {
  1412     set path(test1) [makeFile {
  1413 	fconfigure stdout -encoding binary -buffering none
  1414 	gets stdin; puts -nonewline "\xe7"
  1415 	gets stdin; puts -nonewline "\x89"
  1416 	gets stdin; puts -nonewline "\xa6"
  1417     } test1]
  1418     set f [open "|[list [interpreter] $path(test1)]" r+]
  1419     fileevent $f readable [namespace code {
  1420 	lappend x [read $f]
  1421 	if {[eof $f]} {
  1422 	    lappend x eof
  1423 	}
  1424     }]
  1425     puts $f "go1"
  1426     flush $f
  1427     fconfigure $f -blocking 0 -encoding utf-8
  1428     variable x {}
  1429     vwait [namespace which -variable x]
  1430     after 500 [namespace code { lappend x timeout }]
  1431     vwait [namespace which -variable x]
  1432     puts $f "go2"
  1433     flush $f
  1434     vwait [namespace which -variable x]
  1435     after 500 [namespace code { lappend x timeout }]
  1436     vwait [namespace which -variable x]
  1437     puts $f "go3"
  1438     flush $f
  1439     vwait [namespace which -variable x]
  1440     vwait [namespace which -variable x]
  1441     lappend x [catch {close $f} msg] $msg
  1442     set x
  1443 } "{} timeout {} timeout \u7266 {} eof 0 {}"
  1444 
  1445 test io-13.1 {TranslateInputEOL: cr mode} {} {
  1446     set f [open $path(test1) w]
  1447     fconfigure $f -translation lf
  1448     puts -nonewline $f "abcd\rdef\r"
  1449     close $f
  1450     set f [open $path(test1)]
  1451     fconfigure $f -translation cr
  1452     set x [read $f]
  1453     close $f
  1454     set x
  1455 } "abcd\ndef\n"
  1456 test io-13.2 {TranslateInputEOL: crlf mode} {
  1457     set f [open $path(test1) w]
  1458     fconfigure $f -translation lf
  1459     puts -nonewline $f "abcd\r\ndef\r\n"
  1460     close $f
  1461     set f [open $path(test1)]
  1462     fconfigure $f -translation crlf
  1463     set x [read $f]
  1464     close $f
  1465     set x
  1466 } "abcd\ndef\n"
  1467 test io-13.3 {TranslateInputEOL: crlf mode: naked cr} {
  1468     # (src >= srcMax) 
  1469 
  1470     set f [open $path(test1) w]
  1471     fconfigure $f -translation lf
  1472     puts -nonewline $f "abcd\r\ndef\r"
  1473     close $f
  1474     set f [open $path(test1)]
  1475     fconfigure $f -translation crlf
  1476     set x [read $f]
  1477     close $f
  1478     set x
  1479 } "abcd\ndef\r"
  1480 test io-13.4 {TranslateInputEOL: crlf mode: cr followed by not \n} {
  1481     # (src >= srcMax) 
  1482 
  1483     set f [open $path(test1) w]
  1484     fconfigure $f -translation lf
  1485     puts -nonewline $f "abcd\r\ndef\rfgh"
  1486     close $f
  1487     set f [open $path(test1)]
  1488     fconfigure $f -translation crlf
  1489     set x [read $f]
  1490     close $f
  1491     set x
  1492 } "abcd\ndef\rfgh"
  1493 test io-13.5 {TranslateInputEOL: crlf mode: naked lf} {
  1494     # (src >= srcMax) 
  1495 
  1496     set f [open $path(test1) w]
  1497     fconfigure $f -translation lf
  1498     puts -nonewline $f "abcd\r\ndef\nfgh"
  1499     close $f
  1500     set f [open $path(test1)]
  1501     fconfigure $f -translation crlf
  1502     set x [read $f]
  1503     close $f
  1504     set x
  1505 } "abcd\ndef\nfgh"
  1506 test io-13.6 {TranslateInputEOL: auto mode: saw cr in last segment} {stdio testchannel openpipe fileevent} {
  1507     # (chanPtr->flags & INPUT_SAW_CR)
  1508     # This test may fail on slower machines.
  1509 
  1510     set f [open "|[list [interpreter] $path(cat)]" w+]
  1511     fconfigure $f -blocking 0 -buffering none -translation {auto lf}
  1512 
  1513     fileevent $f read [namespace code "ready $f"]
  1514     proc ready {f} {
  1515 	variable x
  1516 	lappend x [read $f] [testchannel queuedcr $f]
  1517     }
  1518     variable x {}
  1519     variable y {}
  1520 
  1521     puts -nonewline $f "abcdefghj\r"
  1522     after 500 [namespace code {set y ok}]
  1523     vwait [namespace which -variable y]
  1524 
  1525     puts -nonewline $f "\n01234"
  1526     after 500 [namespace code {set y ok}]
  1527     vwait [namespace which -variable y]
  1528 
  1529     close $f
  1530     set x
  1531 } [list "abcdefghj\n" 1 "01234" 0]
  1532 test io-13.7 {TranslateInputEOL: auto mode: naked \r} {testchannel openpipe} {
  1533     # (src >= srcMax)
  1534 
  1535     set f [open $path(test1) w]
  1536     fconfigure $f -translation lf
  1537     puts -nonewline $f "abcd\r"
  1538     close $f
  1539     set f [open $path(test1)]
  1540     fconfigure $f -translation auto
  1541     set x [list [read $f] [testchannel queuedcr $f]]
  1542     close $f
  1543     set x
  1544 } [list "abcd\n" 1]
  1545 test io-13.8 {TranslateInputEOL: auto mode: \r\n} {
  1546     # (*src == '\n')
  1547 
  1548     set f [open $path(test1) w]
  1549     fconfigure $f -translation lf
  1550     puts -nonewline $f "abcd\r\ndef"
  1551     close $f
  1552     set f [open $path(test1)]
  1553     fconfigure $f -translation auto
  1554     set x [read $f]
  1555     close $f
  1556     set x
  1557 } "abcd\ndef"
  1558 test io-13.9 {TranslateInputEOL: auto mode: \r followed by not \n} {
  1559     set f [open $path(test1) w]
  1560     fconfigure $f -translation lf
  1561     puts -nonewline $f "abcd\rdef"
  1562     close $f
  1563     set f [open $path(test1)]
  1564     fconfigure $f -translation auto
  1565     set x [read $f]
  1566     close $f
  1567     set x
  1568 } "abcd\ndef"
  1569 test io-13.10 {TranslateInputEOL: auto mode: \n} {
  1570     # not (*src == '\r') 
  1571 
  1572     set f [open $path(test1) w]
  1573     fconfigure $f -translation lf
  1574     puts -nonewline $f "abcd\ndef"
  1575     close $f
  1576     set f [open $path(test1)]
  1577     fconfigure $f -translation auto
  1578     set x [read $f]
  1579     close $f
  1580     set x
  1581 } "abcd\ndef"
  1582 test io-13.11 {TranslateInputEOL: EOF char} {
  1583     # (*chanPtr->inEofChar != '\0')
  1584 
  1585     set f [open $path(test1) w]
  1586     fconfigure $f -translation lf
  1587     puts -nonewline $f "abcd\ndefgh"
  1588     close $f
  1589     set f [open $path(test1)]
  1590     fconfigure $f -translation auto -eofchar e
  1591     set x [read $f]
  1592     close $f
  1593     set x
  1594 } "abcd\nd"
  1595 test io-13.12 {TranslateInputEOL: find EOF char in src} {
  1596     # (*chanPtr->inEofChar != '\0')
  1597 
  1598     set f [open $path(test1) w]
  1599     fconfigure $f -translation lf
  1600     puts -nonewline $f "\r\n\r\n\r\nab\r\n\r\ndef\r\n\r\n\r\n"
  1601     close $f
  1602     set f [open $path(test1)]
  1603     fconfigure $f -translation auto -eofchar e
  1604     set x [read $f]
  1605     close $f
  1606     set x
  1607 } "\n\n\nab\n\nd"
  1608     
  1609 # Test standard handle management. The functions tested are
  1610 # Tcl_SetStdChannel and Tcl_GetStdChannel. Incidentally we are
  1611 # also testing channel table management.
  1612 
  1613 if {[info commands testchannel] != ""} {
  1614     if {$tcl_platform(platform) == "macintosh"} {
  1615 	set consoleFileNames [list console0 console1 console2]
  1616     } else {
  1617 	set consoleFileNames [lsort [testchannel open]]
  1618     }
  1619 } else {
  1620     # just to avoid an error
  1621     set consoleFileNames [list]
  1622 }
  1623 
  1624 test io-14.1 {Tcl_SetStdChannel and Tcl_GetStdChannel} {testchannel} {
  1625     set l ""
  1626     lappend l [fconfigure stdin -buffering]
  1627     lappend l [fconfigure stdout -buffering]
  1628     lappend l [fconfigure stderr -buffering]
  1629     lappend l [lsort [testchannel open]]
  1630     set l
  1631 } [list line line none $consoleFileNames]
  1632 test io-14.2 {Tcl_SetStdChannel and Tcl_GetStdChannel} {
  1633     interp create x
  1634     set l ""
  1635     lappend l [x eval {fconfigure stdin -buffering}]
  1636     lappend l [x eval {fconfigure stdout -buffering}]
  1637     lappend l [x eval {fconfigure stderr -buffering}]
  1638     interp delete x
  1639     set l
  1640 } {line line none}
  1641 
  1642 set path(test3) [makeFile {} test3]
  1643 
  1644 test io-14.3 {Tcl_SetStdChannel & Tcl_GetStdChannel} {exec openpipe} {
  1645     set f [open $path(test1) w]
  1646     puts -nonewline $f {
  1647 	close stdin
  1648 	close stdout
  1649 	close stderr
  1650 	set f  [}
  1651     puts $f [list open $path(test1) r]]
  1652     puts $f "set f2 \[[list open $path(test2) w]]"
  1653     puts $f "set f3 \[[list open $path(test3) w]]"
  1654     puts $f {	puts stdout [gets stdin]
  1655 	puts stdout out
  1656 	puts stderr err
  1657 	close $f
  1658 	close $f2
  1659 	close $f3
  1660     }
  1661     close $f
  1662     set result [exec [interpreter] $path(test1)]
  1663     set f  [open $path(test2) r]
  1664     set f2 [open $path(test3) r]
  1665     lappend result [read $f] [read $f2]
  1666     close $f
  1667     close $f2
  1668     set result
  1669 } {{
  1670 out
  1671 } {err
  1672 }}
  1673 # This test relies on the fact that the smallest available fd is used first.
  1674 test io-14.4 {Tcl_SetStdChannel & Tcl_GetStdChannel} {exec unixOnly} {
  1675     set f [open $path(test1) w]
  1676     puts -nonewline $f { close stdin
  1677 	close stdout
  1678 	close stderr
  1679 	set f  [}
  1680     puts $f [list open $path(test1) r]]
  1681     puts $f "set f2 \[[list open $path(test2) w]]"
  1682     puts $f "set f3 \[[list open $path(test3) w]]"
  1683     puts $f {	puts stdout [gets stdin]
  1684 	puts stdout $f2
  1685 	puts stderr $f3
  1686 	close $f
  1687 	close $f2
  1688 	close $f3
  1689     }
  1690     close $f
  1691     set result [exec [interpreter] $path(test1)]
  1692     set f  [open $path(test2) r]
  1693     set f2 [open $path(test3) r]
  1694     lappend result [read $f] [read $f2]
  1695     close $f
  1696     close $f2
  1697     set result
  1698 } {{ close stdin
  1699 file1
  1700 } {file2
  1701 }}
  1702 catch {interp delete z}
  1703 test io-14.5 {Tcl_GetChannel: stdio name translation} {
  1704     interp create z
  1705     eof stdin
  1706     catch {z eval flush stdin} msg1
  1707     catch {z eval close stdin} msg2
  1708     catch {z eval flush stdin} msg3
  1709     set result [list $msg1 $msg2 $msg3]
  1710     interp delete z
  1711     set result
  1712 } {{channel "stdin" wasn't opened for writing} {} {can not find channel named "stdin"}}
  1713 test io-14.6 {Tcl_GetChannel: stdio name translation} {
  1714     interp create z
  1715     eof stdout
  1716     catch {z eval flush stdout} msg1
  1717     catch {z eval close stdout} msg2
  1718     catch {z eval flush stdout} msg3
  1719     set result [list $msg1 $msg2 $msg3]
  1720     interp delete z
  1721     set result
  1722 } {{} {} {can not find channel named "stdout"}}
  1723 test io-14.7 {Tcl_GetChannel: stdio name translation} {
  1724     interp create z
  1725     eof stderr
  1726     catch {z eval flush stderr} msg1
  1727     catch {z eval close stderr} msg2
  1728     catch {z eval flush stderr} msg3
  1729     set result [list $msg1 $msg2 $msg3]
  1730     interp delete z
  1731     set result
  1732 } {{} {} {can not find channel named "stderr"}}
  1733 
  1734 set path(script) [makeFile {} script]
  1735 
  1736 test io-14.8 {reuse of stdio special channels} {stdio openpipe} {
  1737     file delete $path(script)
  1738     file delete $path(test1)
  1739     set f [open $path(script) w]
  1740     puts -nonewline $f {
  1741 	close stderr
  1742 	set f [}
  1743     puts $f [list open $path(test1) w]]
  1744     puts -nonewline $f {
  1745 	puts stderr hello
  1746 	close $f
  1747 	set f [}
  1748     puts $f [list open $path(test1) r]]
  1749     puts $f {
  1750 	puts [gets $f]
  1751     }
  1752     close $f
  1753     set f [open "|[list [interpreter] $path(script)]" r]
  1754     set c [gets $f]
  1755     close $f
  1756     set c
  1757 } hello
  1758 
  1759 test io-14.9 {reuse of stdio special channels} {stdio openpipe fileevent} {
  1760     file delete $path(script)
  1761     file delete $path(test1)
  1762     set f [open $path(script) w]
  1763     puts $f {
  1764         array set path [lindex $argv 0]
  1765 	set f [open $path(test1) w]
  1766 	puts $f hello
  1767 	close $f
  1768 	close stderr
  1769 	set f [open "|[list [info nameofexecutable] $path(cat) $path(test1)]" r]
  1770 	puts [gets $f]
  1771     }
  1772     close $f
  1773     set f [open "|[list [interpreter] $path(script) [array get path]]" r]
  1774     set c [gets $f]
  1775     close $f
  1776     # Added delay to give Windows time to stop the spawned process and clean
  1777     # up its grip on the file test1. Added delete as proper test cleanup.
  1778     # The failing tests were 18.1 and 18.2 as first re-users of file "test1".
  1779     after 10000
  1780     file delete $path(script)
  1781     file delete $path(test1)
  1782     set c
  1783 } hello
  1784 
  1785 test io-15.1 {Tcl_CreateCloseHandler} {
  1786 } {}
  1787 
  1788 test io-16.1 {Tcl_DeleteCloseHandler} {
  1789 } {}
  1790 
  1791 # Test channel table management. The functions tested are
  1792 # GetChannelTable, DeleteChannelTable, Tcl_RegisterChannel,
  1793 # Tcl_UnregisterChannel, Tcl_GetChannel and Tcl_CreateChannel.
  1794 #
  1795 # These functions use "eof stdin" to ensure that the standard
  1796 # channels are added to the channel table of the interpreter.
  1797 
  1798 test io-17.1 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} {
  1799     set l1 [testchannel refcount stdin]
  1800     eof stdin
  1801     interp create x
  1802     set l ""
  1803     lappend l [expr [testchannel refcount stdin] - $l1]
  1804     x eval {eof stdin}
  1805     lappend l [expr [testchannel refcount stdin] - $l1]
  1806     interp delete x
  1807     lappend l [expr [testchannel refcount stdin] - $l1]
  1808     set l
  1809 } {0 1 0}
  1810 test io-17.2 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} {
  1811     set l1 [testchannel refcount stdout]
  1812     eof stdin
  1813     interp create x
  1814     set l ""
  1815     lappend l [expr [testchannel refcount stdout] - $l1]
  1816     x eval {eof stdout}
  1817     lappend l [expr [testchannel refcount stdout] - $l1]
  1818     interp delete x
  1819     lappend l [expr [testchannel refcount stdout] - $l1]
  1820     set l
  1821 } {0 1 0}
  1822 test io-17.3 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} {
  1823     set l1 [testchannel refcount stderr]
  1824     eof stdin
  1825     interp create x
  1826     set l ""
  1827     lappend l [expr [testchannel refcount stderr] - $l1]
  1828     x eval {eof stderr}
  1829     lappend l [expr [testchannel refcount stderr] - $l1]
  1830     interp delete x
  1831     lappend l [expr [testchannel refcount stderr] - $l1]
  1832     set l
  1833 } {0 1 0}
  1834 
  1835 test io-18.1 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {testchannel} {
  1836     file delete $path(test1)
  1837     set l ""
  1838     set f [open $path(test1) w]
  1839     lappend l [lindex [testchannel info $f] 15]
  1840     close $f
  1841     if {[catch {lindex [testchannel info $f] 15} msg]} {
  1842 	lappend l $msg
  1843     } else {
  1844 	lappend l "very broken: $f found after being closed"
  1845     }
  1846     string compare [string tolower $l] \
  1847 	[list 1 [format "can not find channel named \"%s\"" $f]]
  1848 } 0
  1849 test io-18.2 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {testchannel} {
  1850     file delete $path(test1)
  1851     set l ""
  1852     set f [open $path(test1) w]
  1853     lappend l [lindex [testchannel info $f] 15]
  1854     interp create x
  1855     interp share "" $f x
  1856     lappend l [lindex [testchannel info $f] 15]
  1857     x eval close $f
  1858     lappend l [lindex [testchannel info $f] 15]
  1859     interp delete x
  1860     lappend l [lindex [testchannel info $f] 15]
  1861     close $f
  1862     if {[catch {lindex [testchannel info $f] 15} msg]} {
  1863 	lappend l $msg
  1864     } else {
  1865 	lappend l "very broken: $f found after being closed"
  1866     }
  1867     string compare [string tolower $l] \
  1868 	[list 1 2 1 1 [format "can not find channel named \"%s\"" $f]]
  1869 } 0
  1870 test io-18.3 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {testchannel} {
  1871     file delete $path(test1)
  1872     set l ""
  1873     set f [open $path(test1) w]
  1874     lappend l [lindex [testchannel info $f] 15]
  1875     interp create x
  1876     interp share "" $f x
  1877     lappend l [lindex [testchannel info $f] 15]
  1878     interp delete x
  1879     lappend l [lindex [testchannel info $f] 15]
  1880     close $f
  1881     if {[catch {lindex [testchannel info $f] 15} msg]} {
  1882 	lappend l $msg
  1883     } else {
  1884 	lappend l "very broken: $f found after being closed"
  1885     }
  1886     string compare [string tolower $l] \
  1887 	[list 1 2 1 [format "can not find channel named \"%s\"" $f]]
  1888 } 0
  1889 
  1890 test io-19.1 {Tcl_GetChannel->Tcl_GetStdChannel, standard handles} {
  1891     eof stdin
  1892 } 0
  1893 test io-19.2 {testing Tcl_GetChannel, user opened handle} {
  1894     file delete $path(test1)
  1895     set f [open $path(test1) w]
  1896     set x [eof $f]
  1897     close $f
  1898     set x
  1899 } 0
  1900 test io-19.3 {Tcl_GetChannel, channel not found} {
  1901     list [catch {eof file34} msg] $msg
  1902 } {1 {can not find channel named "file34"}}
  1903 test io-19.4 {Tcl_CreateChannel, insertion into channel table} {testchannel} {
  1904     file delete $path(test1)
  1905     set f [open $path(test1) w]
  1906     set l ""
  1907     lappend l [eof $f]
  1908     close $f
  1909     if {[catch {lindex [testchannel info $f] 15} msg]} {
  1910 	lappend l $msg
  1911     } else {
  1912 	lappend l "very broken: $f found after being closed"
  1913     }
  1914     string compare [string tolower $l] \
  1915 	[list 0 [format "can not find channel named \"%s\"" $f]]
  1916 } 0
  1917 
  1918 test io-20.1 {Tcl_CreateChannel: initial settings} {
  1919 	set a [open $path(test2) w]
  1920     set old [encoding system]
  1921     encoding system ascii
  1922     set f [open $path(test1) w]
  1923     set x [fconfigure $f -encoding]
  1924     close $f
  1925     encoding system $old
  1926 	close $a
  1927     set x
  1928 } {ascii}    
  1929 test io-20.2 {Tcl_CreateChannel: initial settings} {pcOnly} {
  1930     set f [open $path(test1) w+]
  1931     set x [list [fconfigure $f -eofchar] [fconfigure $f -translation]]
  1932     close $f
  1933     set x
  1934 } [list [list \x1a ""] {auto crlf}]
  1935 test io-20.3 {Tcl_CreateChannel: initial settings} {unixOnly} {
  1936     set f [open $path(test1) w+]
  1937     set x [list [fconfigure $f -eofchar] [fconfigure $f -translation]]
  1938     close $f
  1939     set x
  1940 } {{{} {}} {auto lf}}
  1941 test io-20.4 {Tcl_CreateChannel: initial settings} {macOnly} {
  1942     set f [open $path(test1) w+]
  1943     set x [list [fconfigure $f -eofchar] [fconfigure $f -translation]]
  1944     close $f
  1945     set x
  1946 } {{{} {}} {auto cr}}
  1947 
  1948 set path(stdout) [makeFile {} stdout]
  1949 
  1950 test io-20.5 {Tcl_CreateChannel: install channel in empty slot} {stdio openpipe} {
  1951     set f [open $path(script) w]
  1952     puts -nonewline $f {
  1953 	close stdout
  1954 	set f1 [}
  1955     puts $f [list open $path(stdout) w]]
  1956     puts $f {
  1957 	fconfigure $f1 -buffersize 777
  1958 	puts stderr [fconfigure stdout -buffersize]
  1959     }
  1960     close $f
  1961     set f [open "|[list [interpreter] $path(script)]"]
  1962     catch {close $f} msg
  1963     set msg
  1964 } {777}
  1965 	
  1966 test io-21.1 {CloseChannelsOnExit} {
  1967 } {}
  1968     
  1969 # Test management of attributes associated with a channel, such as
  1970 # its default translation, its name and type, etc. The functions
  1971 # tested in this group are Tcl_GetChannelName,
  1972 # Tcl_GetChannelType and Tcl_GetChannelFile. Tcl_GetChannelInstanceData
  1973 # not tested because files do not use the instance data.
  1974 
  1975 test io-22.1 {Tcl_GetChannelMode} {
  1976     # Not used anywhere in Tcl.
  1977 } {}
  1978 
  1979 test io-23.1 {Tcl_GetChannelName} {testchannel} {
  1980     file delete $path(test1)
  1981     set f [open $path(test1) w]
  1982     set n [testchannel name $f]
  1983     close $f
  1984     string compare $n $f
  1985 } 0
  1986 
  1987 test io-24.1 {Tcl_GetChannelType} {testchannel} {
  1988     file delete $path(test1)
  1989     set f [open $path(test1) w]
  1990     set t [testchannel type $f]
  1991     close $f
  1992     string compare $t file
  1993 } 0
  1994 
  1995 test io-25.1 {Tcl_GetChannelHandle, input} {testchannel} {
  1996     set f [open $path(test1) w]
  1997     fconfigure $f -translation lf -eofchar {}
  1998     puts $f "1234567890\n098765432"
  1999     close $f
  2000     set f [open $path(test1) r]
  2001     gets $f
  2002     set l ""
  2003     lappend l [testchannel inputbuffered $f]
  2004     lappend l [tell $f]
  2005     close $f
  2006     set l
  2007 } {10 11}
  2008 test io-25.2 {Tcl_GetChannelHandle, output} {testchannel} {
  2009     file delete $path(test1)
  2010     set f [open $path(test1) w]
  2011     fconfigure $f -translation lf
  2012     puts $f hello
  2013     set l ""
  2014     lappend l [testchannel outputbuffered $f]
  2015     lappend l [tell $f]
  2016     flush $f
  2017     lappend l [testchannel outputbuffered $f]
  2018     lappend l [tell $f]
  2019     close $f
  2020     file delete $path(test1)
  2021     set l
  2022 } {6 6 0 6}
  2023 
  2024 test io-26.1 {Tcl_GetChannelInstanceData} {stdio openpipe} {
  2025     # "pid" command uses Tcl_GetChannelInstanceData
  2026     # Don't care what pid is (but must be a number), just want to exercise it.
  2027 
  2028     set f [open "|[list [interpreter] << exit]"]
  2029     expr [pid $f]
  2030     close $f
  2031 } {}    
  2032 
  2033 # Test flushing. The functions tested here are FlushChannel.
  2034 
  2035 test io-27.1 {FlushChannel, no output buffered} {
  2036     file delete $path(test1)
  2037     set f [open $path(test1) w]
  2038     flush $f
  2039     set s [file size $path(test1)]
  2040     close $f
  2041     set s
  2042 } 0
  2043 test io-27.2 {FlushChannel, some output buffered} {
  2044     file delete $path(test1)
  2045     set f [open $path(test1) w]
  2046     fconfigure $f -translation lf -eofchar {}
  2047     set l ""
  2048     puts $f hello
  2049     lappend l [file size $path(test1)]
  2050     flush $f
  2051     lappend l [file size $path(test1)]
  2052     close $f
  2053     lappend l [file size $path(test1)]
  2054     set l
  2055 } {0 6 6}
  2056 test io-27.3 {FlushChannel, implicit flush on close} {
  2057     file delete $path(test1)
  2058     set f [open $path(test1) w]
  2059     fconfigure $f -translation lf -eofchar {}
  2060     set l ""
  2061     puts $f hello
  2062     lappend l [file size $path(test1)]
  2063     close $f
  2064     lappend l [file size $path(test1)]
  2065     set l
  2066 } {0 6}
  2067 test io-27.4 {FlushChannel, implicit flush when buffer fills} {
  2068     file delete $path(test1)
  2069     set f [open $path(test1) w]
  2070     fconfigure $f -translation lf -eofchar {}
  2071     fconfigure $f -buffersize 60
  2072     set l ""
  2073     lappend l [file size $path(test1)]
  2074     for {set i 0} {$i < 12} {incr i} {
  2075 	puts $f hello
  2076     }
  2077     lappend l [file size $path(test1)]
  2078     flush $f
  2079     lappend l [file size $path(test1)]
  2080     close $f
  2081     set l
  2082 } {0 60 72}
  2083 test io-27.5 {FlushChannel, implicit flush when buffer fills and on close} \
  2084 	{unixOrPc} {
  2085     file delete $path(test1)
  2086     set f [open $path(test1) w]
  2087     fconfigure $f -translation lf -buffersize 60 -eofchar {}
  2088     set l ""
  2089     lappend l [file size $path(test1)]
  2090     for {set i 0} {$i < 12} {incr i} {
  2091 	puts $f hello
  2092     }
  2093     lappend l [file size $path(test1)]
  2094     close $f
  2095     lappend l [file size $path(test1)]
  2096     set l
  2097 } {0 60 72}
  2098 
  2099 set path(pipe)   [makeFile {} pipe]
  2100 set path(output) [makeFile {} output]
  2101 
  2102 test io-27.6 {FlushChannel, async flushing, async close} \
  2103 	{stdio asyncPipeClose openpipe} {
  2104     file delete $path(pipe)
  2105     file delete $path(output)
  2106     set f [open $path(pipe) w]
  2107     puts $f "set f \[[list open $path(output) w]]"
  2108     puts $f {
  2109 	fconfigure $f -translation lf -buffering none -eofchar {}
  2110 	while {![eof stdin]} {
  2111 	    after 20
  2112 	    puts -nonewline $f [read stdin 1024]
  2113 	}
  2114 	close $f
  2115     }
  2116     close $f
  2117     set x 01234567890123456789012345678901
  2118     for {set i 0} {$i < 11} {incr i} {
  2119         set x "$x$x"
  2120     }
  2121     set f [open $path(output) w]
  2122     close $f
  2123     set f [open "|[list [interpreter] $path(pipe)]" w]
  2124     fconfigure $f -blocking off
  2125     puts -nonewline $f $x
  2126     close $f
  2127     set counter 0
  2128     while {([file size $path(output)] < 65536) && ($counter < 1000)} {
  2129         incr counter
  2130         after 20
  2131         update
  2132     }
  2133     if {$counter == 1000} {
  2134         set result "file size only [file size $path(output)]"
  2135     } else {
  2136         set result ok
  2137     }
  2138 } ok
  2139 
  2140 # Tests closing a channel. The functions tested are CloseChannel and Tcl_Close.
  2141 
  2142 test io-28.1 {CloseChannel called when all references are dropped} {testchannel} {
  2143     file delete $path(test1)
  2144     set f [open $path(test1) w]
  2145     interp create x
  2146     interp share "" $f x
  2147     set l ""
  2148     lappend l [testchannel refcount $f]
  2149     x eval close $f
  2150     interp delete x
  2151     lappend l [testchannel refcount $f]
  2152     close $f
  2153     set l
  2154 } {2 1}
  2155 test io-28.2 {CloseChannel called when all references are dropped} {
  2156     file delete $path(test1)
  2157     set f [open $path(test1) w]
  2158     interp create x
  2159     interp share "" $f x
  2160     puts -nonewline $f abc
  2161     close $f
  2162     x eval puts $f def
  2163     x eval close $f
  2164     interp delete x
  2165     set f [open $path(test1) r]
  2166     set l [gets $f]
  2167     close $f
  2168     set l
  2169 } abcdef
  2170 test io-28.3 {CloseChannel, not called before output queue is empty} \
  2171 	{stdio asyncPipeClose nonPortable openpipe} {
  2172     file delete $path(pipe)
  2173     file delete $path(output)
  2174     set f [open $path(pipe) w]
  2175     puts $f {
  2176 
  2177 	# Need to not have eof char appended on close, because the other
  2178 	# side of the pipe already closed, so that writing would cause an
  2179 	# error "invalid file".
  2180 
  2181 	fconfigure stdout -eofchar {}
  2182 	fconfigure stderr -eofchar {}
  2183 
  2184 	set f [open $path(output) w]
  2185 	fconfigure $f -translation lf -buffering none
  2186 	for {set x 0} {$x < 20} {incr x} {
  2187 	    after 20
  2188 	    puts -nonewline $f [read stdin 1024]
  2189 	}
  2190 	close $f
  2191     }
  2192     close $f
  2193     set x 01234567890123456789012345678901
  2194     for {set i 0} {$i < 11} {incr i} {
  2195         set x "$x$x"
  2196     }
  2197     set f [open $path(output) w]
  2198     close $f
  2199     set f [open "|[list [interpreter] pipe]" r+]
  2200     fconfigure $f -blocking off -eofchar {}
  2201 
  2202     puts -nonewline $f $x
  2203     close $f
  2204     set counter 0
  2205     while {([file size $path(output)] < 20480) && ($counter < 1000)} {
  2206         incr counter
  2207         after 20
  2208         update
  2209     }
  2210     if {$counter == 1000} {
  2211         set result probably_broken
  2212     } else {
  2213         set result ok
  2214     }
  2215 } ok
  2216 test io-28.4 {Tcl_Close} {testchannel} {
  2217     file delete $path(test1)
  2218     set l ""
  2219     lappend l [lsort [testchannel open]]
  2220     set f [open $path(test1) w]
  2221     lappend l [lsort [testchannel open]]
  2222     close $f
  2223     lappend l [lsort [testchannel open]]
  2224     set x [list $consoleFileNames \
  2225 		[lsort [eval list $consoleFileNames $f]] \
  2226 		$consoleFileNames]
  2227     string compare $l $x
  2228 } 0
  2229 test io-28.5 {Tcl_Close vs standard handles} {stdio unixOnly testchannel openpipe} {
  2230     file delete $path(script)
  2231     set f [open $path(script) w]
  2232     puts $f {
  2233 	close stdin
  2234 	puts [testchannel open]
  2235     }
  2236     close $f
  2237     set f [open "|[list [interpreter] $path(script)]" r]
  2238     set l [gets $f]
  2239     close $f
  2240     set l
  2241 } {file1 file2}
  2242 
  2243 test io-29.1 {Tcl_WriteChars, channel not writable} {
  2244     list [catch {puts stdin hello} msg] $msg
  2245 } {1 {channel "stdin" wasn't opened for writing}}
  2246 test io-29.2 {Tcl_WriteChars, empty string} {
  2247     file delete $path(test1)
  2248     set f [open $path(test1) w]
  2249     fconfigure $f -eofchar {}
  2250     puts -nonewline $f ""
  2251     close $f
  2252     file size $path(test1)
  2253 } 0
  2254 test io-29.3 {Tcl_WriteChars, nonempty string} {
  2255     file delete $path(test1)
  2256     set f [open $path(test1) w]
  2257     fconfigure $f -eofchar {}
  2258     puts -nonewline $f hello
  2259     close $f
  2260     file size $path(test1)
  2261 } 5
  2262 test io-29.4 {Tcl_WriteChars, buffering in full buffering mode} {testchannel} {
  2263     file delete $path(test1)
  2264     set f [open $path(test1) w]
  2265     fconfigure $f -translation lf -buffering full -eofchar {}
  2266     puts $f hello
  2267     set l ""
  2268     lappend l [testchannel outputbuffered $f]
  2269     lappend l [file size $path(test1)]
  2270     flush $f
  2271     lappend l [testchannel outputbuffered $f]
  2272     lappend l [file size $path(test1)]
  2273     close $f
  2274     set l
  2275 } {6 0 0 6}
  2276 test io-29.5 {Tcl_WriteChars, buffering in line buffering mode} {testchannel} {
  2277     file delete $path(test1)
  2278     set f [open $path(test1) w]
  2279     fconfigure $f -translation lf -buffering line -eofchar {}
  2280     puts -nonewline $f hello
  2281     set l ""
  2282     lappend l [testchannel outputbuffered $f]
  2283     lappend l [file size $path(test1)]
  2284     puts $f hello
  2285     lappend l [testchannel outputbuffered $f]
  2286     lappend l [file size $path(test1)]
  2287     close $f
  2288     set l
  2289 } {5 0 0 11}
  2290 test io-29.6 {Tcl_WriteChars, buffering in no buffering mode} {testchannel} {
  2291     file delete $path(test1)
  2292     set f [open $path(test1) w]
  2293     fconfigure $f -translation lf -buffering none -eofchar {}
  2294     puts -nonewline $f hello
  2295     set l ""
  2296     lappend l [testchannel outputbuffered $f]
  2297     lappend l [file size $path(test1)]
  2298     puts $f hello
  2299     lappend l [testchannel outputbuffered $f]
  2300     lappend l [file size $path(test1)]
  2301     close $f
  2302     set l
  2303 } {0 5 0 11}
  2304 
  2305 test io-29.7 {Tcl_Flush, full buffering} {testchannel} {
  2306     file delete $path(test1)
  2307     set f [open $path(test1) w]
  2308     fconfigure $f -translation lf -buffering full -eofchar {}
  2309     puts -nonewline $f hello
  2310     set l ""
  2311     lappend l [testchannel outputbuffered $f]
  2312     lappend l [file size $path(test1)]
  2313     puts $f hello
  2314     lappend l [testchannel outputbuffered $f]
  2315     lappend l [file size $path(test1)]
  2316     flush $f
  2317     lappend l [testchannel outputbuffered $f]
  2318     lappend l [file size $path(test1)]
  2319     close $f
  2320     set l
  2321 } {5 0 11 0 0 11}
  2322 test io-29.8 {Tcl_Flush, full buffering} {testchannel} {
  2323     file delete $path(test1)
  2324     set f [open $path(test1) w]
  2325     fconfigure $f -translation lf -buffering line
  2326     puts -nonewline $f hello
  2327     set l ""
  2328     lappend l [testchannel outputbuffered $f]
  2329     lappend l [file size $path(test1)]
  2330     flush $f
  2331     lappend l [testchannel outputbuffered $f]
  2332     lappend l [file size $path(test1)]
  2333     puts $f hello
  2334     lappend l [testchannel outputbuffered $f]
  2335     lappend l [file size $path(test1)]
  2336     flush $f
  2337     lappend l [testchannel outputbuffered $f]
  2338     lappend l [file size $path(test1)]
  2339     close $f
  2340     set l
  2341 } {5 0 0 5 0 11 0 11}
  2342 test io-29.9 {Tcl_Flush, channel not writable} {
  2343     list [catch {flush stdin} msg] $msg
  2344 } {1 {channel "stdin" wasn't opened for writing}}
  2345 test io-29.10 {Tcl_WriteChars, looping and buffering} {
  2346     file delete $path(test1)
  2347     set f1 [open $path(test1) w]
  2348     fconfigure $f1 -translation lf -eofchar {}
  2349     set f2 [open $path(longfile) r]
  2350     for {set x 0} {$x < 10} {incr x} {
  2351 	puts $f1 [gets $f2]
  2352     }
  2353     close $f2
  2354     close $f1
  2355     file size $path(test1)
  2356 } 387
  2357 test io-29.11 {Tcl_WriteChars, no newline, implicit flush} {
  2358     file delete $path(test1)
  2359     set f1 [open $path(test1) w]
  2360     fconfigure $f1 -eofchar {}
  2361     set f2 [open $path(longfile) r]
  2362     for {set x 0} {$x < 10} {incr x} {
  2363 	puts -nonewline $f1 [gets $f2]
  2364     }
  2365     close $f1
  2366     close $f2
  2367     file size $path(test1)
  2368 } 377
  2369 test io-29.12 {Tcl_WriteChars on a pipe} {stdio openpipe} {
  2370     file delete $path(test1)
  2371     file delete $path(pipe)
  2372     set f1 [open $path(pipe) w]
  2373     puts $f1 "set f1 \[[list open $path(longfile) r]]"
  2374     puts $f1 {
  2375 	for {set x 0} {$x < 10} {incr x} {
  2376 	    puts [gets $f1]
  2377 	}
  2378     }
  2379     close $f1
  2380     set f1 [open "|[list [interpreter] $path(pipe)]" r]
  2381     set f2 [open $path(longfile) r]
  2382     set y ok
  2383     for {set x 0} {$x < 10} {incr x} {
  2384 	set l1 [gets $f1]
  2385 	set l2 [gets $f2]
  2386 	if {"$l1" != "$l2"} {
  2387 	    set y broken
  2388 	}
  2389     }
  2390     close $f1
  2391     close $f2
  2392     set y
  2393 } ok
  2394 test io-29.13 {Tcl_WriteChars to a pipe, line buffered} {stdio openpipe} {
  2395     file delete $path(test1)
  2396     file delete $path(pipe)
  2397     set f1 [open $path(pipe) w]
  2398     puts $f1 {
  2399 	puts [gets stdin]
  2400 	puts [gets stdin]
  2401     }
  2402     close $f1
  2403     set y ok
  2404     set f1 [open "|[list [interpreter] $path(pipe)]" r+]
  2405     fconfigure $f1 -buffering line
  2406     set f2 [open $path(longfile) r]
  2407     set line [gets $f2]
  2408     puts $f1 $line
  2409     set backline [gets $f1]
  2410     if {"$line" != "$backline"} {
  2411 	set y broken
  2412     }
  2413     set line [gets $f2]
  2414     puts $f1 $line
  2415     set backline [gets $f1]
  2416     if {"$line" != "$backline"} {
  2417 	set y broken
  2418     }
  2419     close $f1
  2420     close $f2
  2421     set y
  2422 } ok
  2423 test io-29.14 {Tcl_WriteChars, buffering and implicit flush at close} {
  2424     file delete $path(test3)
  2425     set f [open $path(test3) w]
  2426     puts -nonewline $f "Text1"
  2427     puts -nonewline $f " Text 2"
  2428     puts $f " Text 3"
  2429     close $f
  2430     set f [open $path(test3) r]
  2431     set x [gets $f]
  2432     close $f
  2433     set x
  2434 } {Text1 Text 2 Text 3}
  2435 test io-29.15 {Tcl_Flush, channel not open for writing} {
  2436     file delete $path(test1)
  2437     set fd [open $path(test1) w]
  2438     close $fd
  2439     set fd [open $path(test1) r]
  2440     set x [list [catch {flush $fd} msg] $msg]
  2441     close $fd
  2442     string compare $x \
  2443 	[list 1 "channel \"$fd\" wasn't opened for writing"]
  2444 } 0
  2445 test io-29.16 {Tcl_Flush on pipe opened only for reading} {stdio openpipe} {
  2446     set fd [open "|[list [interpreter] cat longfile]" r]
  2447     set x [list [catch {flush $fd} msg] $msg]
  2448     catch {close $fd}
  2449     string compare $x \
  2450 	[list 1 "channel \"$fd\" wasn't opened for writing"]
  2451 } 0
  2452 test io-29.17 {Tcl_WriteChars buffers, then Tcl_Flush flushes} {
  2453     file delete $path(test1)
  2454     set f1 [open $path(test1) w]
  2455     fconfigure $f1 -translation lf
  2456     puts $f1 hello
  2457     puts $f1 hello
  2458     puts $f1 hello
  2459     flush $f1
  2460     set x [file size $path(test1)]
  2461     close $f1
  2462     set x
  2463 } 18
  2464 test io-29.18 {Tcl_WriteChars and Tcl_Flush intermixed} {
  2465     file delete $path(test1)
  2466     set x ""
  2467     set f1 [open $path(test1) w]
  2468     fconfigure $f1 -translation lf
  2469     puts $f1 hello
  2470     puts $f1 hello
  2471     puts $f1 hello
  2472     flush $f1
  2473     lappend x [file size $path(test1)]
  2474     puts $f1 hello
  2475     flush $f1
  2476     lappend x [file size $path(test1)]
  2477     puts $f1 hello
  2478     flush $f1
  2479     lappend x [file size $path(test1)]
  2480     close $f1
  2481     set x
  2482 } {18 24 30}
  2483 test io-29.19 {Explicit and implicit flushes} {
  2484     file delete $path(test1)
  2485     set f1 [open $path(test1) w]
  2486     fconfigure $f1 -translation lf -eofchar {}
  2487     set x ""
  2488     puts $f1 hello
  2489     puts $f1 hello
  2490     puts $f1 hello
  2491     flush $f1
  2492     lappend x [file size $path(test1)]
  2493     puts $f1 hello
  2494     flush $f1
  2495     lappend x [file size $path(test1)]
  2496     puts $f1 hello
  2497     close $f1
  2498     lappend x [file size $path(test1)]
  2499     set x
  2500 } {18 24 30}
  2501 test io-29.20 {Implicit flush when buffer is full} {
  2502     file delete $path(test1)
  2503     set f1 [open $path(test1) w]
  2504     fconfigure $f1 -translation lf -eofchar {}
  2505     set line "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  2506     for {set x 0} {$x < 100} {incr x} {
  2507       puts $f1 $line
  2508     }
  2509     set z ""
  2510     lappend z [file size $path(test1)]
  2511     for {set x 0} {$x < 100} {incr x} {
  2512 	puts $f1 $line
  2513     }
  2514     lappend z [file size $path(test1)]
  2515     close $f1
  2516     lappend z [file size $path(test1)]
  2517     set z
  2518 } {4096 12288 12600}
  2519 test io-29.21 {Tcl_Flush to pipe} {stdio openpipe} {
  2520     file delete $path(pipe)
  2521     set f1 [open $path(pipe) w]
  2522     puts $f1 {set x [read stdin 6]}
  2523     puts $f1 {set cnt [string length $x]}
  2524     puts $f1 {puts "read $cnt characters"}
  2525     close $f1
  2526     set f1 [open "|[list [interpreter] $path(pipe)]" r+]
  2527     puts $f1 hello
  2528     flush $f1
  2529     set x [gets $f1]
  2530     catch {close $f1}
  2531     set x
  2532 } "read 6 characters"
  2533 test io-29.22 {Tcl_Flush called at other end of pipe} {stdio openpipe} {
  2534     file delete $path(pipe)
  2535     set f1 [open $path(pipe) w]
  2536     puts $f1 {
  2537 	fconfigure stdout -buffering full
  2538 	puts hello
  2539 	puts hello
  2540 	flush stdout
  2541 	gets stdin
  2542 	puts bye
  2543 	flush stdout
  2544     }
  2545     close $f1
  2546     set f1 [open "|[list [interpreter] $path(pipe)]" r+]
  2547     set x ""
  2548     lappend x [gets $f1]
  2549     lappend x [gets $f1]
  2550     puts $f1 hello
  2551     flush $f1
  2552     lappend x [gets $f1]
  2553     close $f1
  2554     set x
  2555 } {hello hello bye}
  2556 test io-29.23 {Tcl_Flush and line buffering at end of pipe} {stdio openpipe} {
  2557     file delete $path(pipe)
  2558     set f1 [open $path(pipe) w]
  2559     puts $f1 {
  2560 	puts hello
  2561 	puts hello
  2562 	gets stdin
  2563 	puts bye
  2564     }
  2565     close $f1
  2566     set f1 [open "|[list [interpreter] $path(pipe)]" r+]
  2567     set x ""
  2568     lappend x [gets $f1]
  2569     lappend x [gets $f1]
  2570     puts $f1 hello
  2571     flush $f1
  2572     lappend x [gets $f1]
  2573     close $f1
  2574     set x
  2575 } {hello hello bye}
  2576 test io-29.24 {Tcl_WriteChars and Tcl_Flush move end of file} {
  2577     set f [open $path(test3) w]
  2578     puts $f "Line 1"
  2579     puts $f "Line 2"
  2580     set f2 [open $path(test3)]
  2581     set x {}
  2582     lappend x [read -nonewline $f2]
  2583     close $f2
  2584     flush $f
  2585     set f2 [open $path(test3)]
  2586     lappend x [read -nonewline $f2]
  2587     close $f2
  2588     close $f
  2589     set x
  2590 } "{} {Line 1\nLine 2}"
  2591 test io-29.25 {Implicit flush with Tcl_Flush to command pipelines} {stdio openpipe fileevent} {
  2592     file delete $path(test3)
  2593     set f [open "|[list [interpreter] $path(cat) | [interpreter] $path(cat) > $path(test3)]" w]
  2594     puts $f "Line 1"
  2595     puts $f "Line 2"
  2596     close $f
  2597     after 100
  2598     set f [open $path(test3) r]
  2599     set x [read $f]
  2600     close $f
  2601     set x
  2602 } "Line 1\nLine 2\n"
  2603 test io-29.26 {Tcl_Flush, Tcl_Write on bidirectional pipelines} {stdio unixExecs openpipe} {
  2604     set f [open "|[list cat -u]" r+]
  2605     puts $f "Line1"
  2606     flush $f
  2607     set x [gets $f]
  2608     close $f
  2609     set x
  2610 } {Line1}
  2611 test io-29.27 {Tcl_Flush on closed pipeline} {stdio openpipe} {
  2612     file delete $path(pipe)
  2613     set f [open $path(pipe) w]
  2614     puts $f {exit}
  2615     close $f
  2616     set f [open "|[list [interpreter] $path(pipe)]" r+]
  2617     gets $f
  2618     puts $f output
  2619     after 50
  2620     #
  2621     # The flush below will get a SIGPIPE. This is an expected part of
  2622     # test and indicates that the test operates correctly. If you run
  2623     # this test under a debugger, the signal will by intercepted unless
  2624     # you disable the debugger's signal interception.
  2625     #
  2626     if {[catch {flush $f} msg]} {
  2627 	set x [list 1 $msg $errorCode]
  2628 	catch {close $f}
  2629     } else {
  2630 	if {[catch {close $f} msg]} {
  2631 	    set x [list 1 $msg $errorCode]
  2632 	} else {
  2633 	    set x {this was supposed to fail and did not}
  2634 	}
  2635     }
  2636     regsub {".*":} $x {"":} x
  2637     string tolower $x
  2638 } {1 {error flushing "": broken pipe} {posix epipe {broken pipe}}}
  2639 test io-29.28 {Tcl_WriteChars, lf mode} {
  2640     file delete $path(test1)
  2641     set f [open $path(test1) w]
  2642     fconfigure $f -translation lf -eofchar {}
  2643     puts $f hello\nthere\nand\nhere
  2644     flush $f
  2645     set s [file size $path(test1)]
  2646     close $f
  2647     set s
  2648 } 21
  2649 test io-29.29 {Tcl_WriteChars, cr mode} {
  2650     file delete $path(test1)
  2651     set f [open $path(test1) w]
  2652     fconfigure $f -translation cr -eofchar {}
  2653     puts $f hello\nthere\nand\nhere
  2654     close $f
  2655     file size $path(test1)
  2656 } 21
  2657 test io-29.30 {Tcl_WriteChars, crlf mode} {
  2658     file delete $path(test1)
  2659     set f [open $path(test1) w]
  2660     fconfigure $f -translation crlf -eofchar {}
  2661     puts $f hello\nthere\nand\nhere
  2662     close $f
  2663     file size $path(test1)
  2664 } 25
  2665 test io-29.31 {Tcl_WriteChars, background flush} {stdio openpipe} {
  2666     file delete $path(pipe)
  2667     file delete $path(output)
  2668     set f [open $path(pipe) w]
  2669     puts $f "set f \[[list open $path(output)  w]]"
  2670     puts $f {fconfigure $f -translation lf}
  2671     set x [list while {![eof stdin]}]
  2672     set x "$x {"
  2673     puts $f $x
  2674     puts $f {  puts -nonewline $f [read stdin 4096]}
  2675     puts $f {  flush $f}
  2676     puts $f "}"
  2677     puts $f {close $f}
  2678     close $f
  2679     set x 01234567890123456789012345678901
  2680     for {set i 0} {$i < 11} {incr i} {
  2681 	set x "$x$x"
  2682     }
  2683     set f [open $path(output) w]
  2684     close $f
  2685     set f [open "|[list [interpreter] $path(pipe)]" r+]
  2686     fconfigure $f -blocking off
  2687     puts -nonewline $f $x
  2688     close $f
  2689     set counter 0
  2690     while {([file size $path(output)] < 65536) && ($counter < 1000)} {
  2691 	incr counter
  2692 	after 5
  2693 	update
  2694     }
  2695     if {$counter == 1000} {
  2696 	set result "file size only [file size $path(output)]"
  2697     } else {
  2698 	set result ok
  2699     }
  2700 } ok
  2701 test io-29.32 {Tcl_WriteChars, background flush to slow reader} \
  2702 	{stdio asyncPipeClose openpipe} {
  2703     file delete $path(pipe)
  2704     file delete $path(output)
  2705     set f [open $path(pipe) w]
  2706     puts $f "set f \[[list open $path(output) w]]"
  2707     puts $f {fconfigure $f -translation lf}
  2708     set x [list while {![eof stdin]}]
  2709     set x "$x \{"
  2710     puts $f $x
  2711     puts $f {  after 20}
  2712     puts $f {  puts -nonewline $f [read stdin 1024]}
  2713     puts $f {  flush $f}
  2714     puts $f "\}"
  2715     puts $f {close $f}
  2716     close $f
  2717     set x 01234567890123456789012345678901
  2718     for {set i 0} {$i < 11} {incr i} {
  2719 	set x "$x$x"
  2720     }
  2721     set f [open $path(output) w]
  2722     close $f
  2723     set f [open "|[list [interpreter] $path(pipe)]" r+]
  2724     fconfigure $f -blocking off
  2725     puts -nonewline $f $x
  2726     close $f
  2727     set counter 0
  2728     while {([file size $path(output)] < 65536) && ($counter < 1000)} {
  2729 	incr counter
  2730 	after 20
  2731 	update
  2732     }
  2733     if {$counter == 1000} {
  2734 	set result "file size only [file size $path(output)]"
  2735     } else {
  2736 	set result ok
  2737     }
  2738 } ok
  2739 test io-29.33 {Tcl_Flush, implicit flush on exit} {exec} {
  2740     set f [open $path(script) w]
  2741     puts $f "set f \[[list open $path(test1) w]]"
  2742     puts $f {fconfigure $f -translation lf
  2743 	puts $f hello
  2744 	puts $f bye
  2745 	puts $f strange
  2746     }
  2747     close $f
  2748     exec [interpreter] $path(script)
  2749     set f [open $path(test1) r]
  2750     set r [read $f]
  2751     close $f
  2752     set r
  2753 } "hello\nbye\nstrange\n"
  2754 test io-29.34 {Tcl_Close, async flush on close, using sockets} {socket tempNotMac fileevent} {
  2755     variable c 0
  2756     variable x running
  2757     set l abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
  2758     proc writelots {s l} {
  2759 	for {set i 0} {$i < 2000} {incr i} {
  2760 	    puts $s $l
  2761 	}
  2762     }
  2763     proc accept {s a p} {
  2764 	variable x
  2765 	fileevent $s readable [namespace code [list readit $s]]
  2766 	fconfigure $s -blocking off
  2767 	set x accepted
  2768     }
  2769     proc readit {s} {
  2770 	variable c
  2771 	variable x
  2772 	set l [gets $s]
  2773 	
  2774 	if {[eof $s]} {
  2775 	    close $s
  2776 	    set x done
  2777 	} elseif {([string length $l] > 0) || ![fblocked $s]} {
  2778 	    incr c
  2779 	}
  2780     }
  2781     set ss [socket -server [namespace code accept] 0]
  2782     set cs [socket [info hostname] [lindex [fconfigure $ss -sockname] 2]]
  2783     vwait [namespace which -variable x]
  2784     fconfigure $cs -blocking off
  2785     writelots $cs $l
  2786     close $cs
  2787     close $ss
  2788     vwait [namespace which -variable x]
  2789     set c
  2790 } 2000
  2791 test io-29.35 {Tcl_Close vs fileevent vs multiple interpreters} {socket tempNotMac fileevent} {
  2792     # On Mac, this test screws up sockets such that subsequent tests using port 2828 
  2793     # either cause errors or panic().
  2794      
  2795     catch {interp delete x}
  2796     catch {interp delete y}
  2797     interp create x
  2798     interp create y
  2799     set s [socket -server [namespace code accept] 0]
  2800     proc accept {s a p} {
  2801 	puts $s hello
  2802 	close $s
  2803     }
  2804     set c [socket [info hostname] [lindex [fconfigure $s -sockname] 2]]
  2805     interp share {} $c x
  2806     interp share {} $c y
  2807     close $c
  2808     x eval {
  2809 	proc readit {s} {
  2810 	    gets $s
  2811 	    if {[eof $s]} {
  2812 		close $s
  2813 	    }
  2814 	}
  2815     }
  2816     y eval {
  2817 	proc readit {s} {
  2818 	    gets $s
  2819 	    if {[eof $s]} {
  2820 		close $s
  2821 	    }
  2822 	}
  2823     }
  2824     x eval "fileevent $c readable \{readit $c\}"
  2825     y eval "fileevent $c readable \{readit $c\}"
  2826     y eval [list close $c]
  2827     update
  2828     close $s
  2829     interp delete x
  2830     interp delete y
  2831 } ""
  2832 
  2833 # Test end of line translations. Procedures tested are Tcl_Write, Tcl_Read.
  2834 
  2835 test io-30.1 {Tcl_Write lf, Tcl_Read lf} {
  2836     file delete $path(test1)
  2837     set f [open $path(test1) w]
  2838     fconfigure $f -translation lf
  2839     puts $f hello\nthere\nand\nhere
  2840     close $f
  2841     set f [open $path(test1) r]
  2842     fconfigure $f -translation lf
  2843     set x [read $f]
  2844     close $f
  2845     set x
  2846 } "hello\nthere\nand\nhere\n"
  2847 test io-30.2 {Tcl_Write lf, Tcl_Read cr} {
  2848     file delete $path(test1)
  2849     set f [open $path(test1) w]
  2850     fconfigure $f -translation lf
  2851     puts $f hello\nthere\nand\nhere
  2852     close $f
  2853     set f [open $path(test1) r]
  2854     fconfigure $f -translation cr
  2855     set x [read $f]
  2856     close $f
  2857     set x
  2858 } "hello\nthere\nand\nhere\n"
  2859 test io-30.3 {Tcl_Write lf, Tcl_Read crlf} {
  2860     file delete $path(test1)
  2861     set f [open $path(test1) w]
  2862     fconfigure $f -translation lf
  2863     puts $f hello\nthere\nand\nhere
  2864     close $f
  2865     set f [open $path(test1) r]
  2866     fconfigure $f -translation crlf
  2867     set x [read $f]
  2868     close $f
  2869     set x
  2870 } "hello\nthere\nand\nhere\n"
  2871 test io-30.4 {Tcl_Write cr, Tcl_Read cr} {
  2872     file delete $path(test1)
  2873     set f [open $path(test1) w]
  2874     fconfigure $f -translation cr
  2875     puts $f hello\nthere\nand\nhere
  2876     close $f
  2877     set f [open $path(test1) r]
  2878     fconfigure $f -translation cr
  2879     set x [read $f]
  2880     close $f
  2881     set x
  2882 } "hello\nthere\nand\nhere\n"
  2883 test io-30.5 {Tcl_Write cr, Tcl_Read lf} {
  2884     file delete $path(test1)
  2885     set f [open $path(test1) w]
  2886     fconfigure $f -translation cr
  2887     puts $f hello\nthere\nand\nhere
  2888     close $f
  2889     set f [open $path(test1) r]
  2890     fconfigure $f -translation lf
  2891     set x [read $f]
  2892     close $f
  2893     set x
  2894 } "hello\rthere\rand\rhere\r"
  2895 test io-30.6 {Tcl_Write cr, Tcl_Read crlf} {
  2896     file delete $path(test1)
  2897     set f [open $path(test1) w]
  2898     fconfigure $f -translation cr
  2899     puts $f hello\nthere\nand\nhere
  2900     close $f
  2901     set f [open $path(test1) r]
  2902     fconfigure $f -translation crlf
  2903     set x [read $f]
  2904     close $f
  2905     set x 
  2906 } "hello\rthere\rand\rhere\r"
  2907 test io-30.7 {Tcl_Write crlf, Tcl_Read crlf} {
  2908     file delete $path(test1)
  2909     set f [open $path(test1) w]
  2910     fconfigure $f -translation crlf
  2911     puts $f hello\nthere\nand\nhere
  2912     close $f
  2913     set f [open $path(test1) r]
  2914     fconfigure $f -translation crlf
  2915     set x [read $f]
  2916     close $f
  2917     set x
  2918 } "hello\nthere\nand\nhere\n"
  2919 test io-30.8 {Tcl_Write crlf, Tcl_Read lf} {
  2920     file delete $path(test1)
  2921     set f [open $path(test1) w]
  2922     fconfigure $f -translation crlf
  2923     puts $f hello\nthere\nand\nhere
  2924     close $f
  2925     set f [open $path(test1) r]
  2926     fconfigure $f -translation lf
  2927     set x [read $f]
  2928     close $f
  2929     set x
  2930 } "hello\r\nthere\r\nand\r\nhere\r\n"
  2931 test io-30.9 {Tcl_Write crlf, Tcl_Read cr} {
  2932     file delete $path(test1)
  2933     set f [open $path(test1) w]
  2934     fconfigure $f -translation crlf
  2935     puts $f hello\nthere\nand\nhere
  2936     close $f
  2937     set f [open $path(test1) r]
  2938     fconfigure $f -translation cr
  2939     set x [read $f]
  2940     close $f
  2941     set x
  2942 } "hello\n\nthere\n\nand\n\nhere\n\n"
  2943 test io-30.10 {Tcl_Write lf, Tcl_Read auto} {
  2944     file delete $path(test1)
  2945     set f [open $path(test1) w]
  2946     fconfigure $f -translation lf
  2947     puts $f hello\nthere\nand\nhere
  2948     close $f
  2949     set f [open $path(test1) r]
  2950     set c [read $f]
  2951     set x [fconfigure $f -translation]
  2952     close $f
  2953     list $c $x
  2954 } {{hello
  2955 there
  2956 and
  2957 here
  2958 } auto}
  2959 test io-30.11 {Tcl_Write cr, Tcl_Read auto} {
  2960     file delete $path(test1)
  2961     set f [open $path(test1) w]
  2962     fconfigure $f -translation cr
  2963     puts $f hello\nthere\nand\nhere
  2964     close $f
  2965     set f [open $path(test1) r]
  2966     set c [read $f]
  2967     set x [fconfigure $f -translation]
  2968     close $f
  2969     list $c $x
  2970 } {{hello
  2971 there
  2972 and
  2973 here
  2974 } auto}
  2975 test io-30.12 {Tcl_Write crlf, Tcl_Read auto} {
  2976     file delete $path(test1)
  2977     set f [open $path(test1) w]
  2978     fconfigure $f -translation crlf
  2979     puts $f hello\nthere\nand\nhere
  2980     close $f
  2981     set f [open $path(test1) r]
  2982     set c [read $f]
  2983     set x [fconfigure $f -translation]
  2984     close $f
  2985     list $c $x
  2986 } {{hello
  2987 there
  2988 and
  2989 here
  2990 } auto}
  2991 
  2992 test io-30.13 {Tcl_Write crlf on block boundary, Tcl_Read auto} {
  2993     file delete $path(test1)
  2994     set f [open $path(test1) w]
  2995     fconfigure $f -translation crlf
  2996     set line "123456789ABCDE"	;# 14 char plus crlf
  2997     puts -nonewline $f x	;# shift crlf across block boundary
  2998     for {set i 0} {$i < 700} {incr i} {
  2999 	puts $f $line
  3000     }
  3001     close $f
  3002     set f [open $path(test1) r]
  3003     fconfigure $f -translation auto
  3004     set c [read $f]
  3005     close $f
  3006     string length $c
  3007 } [expr 700*15+1]
  3008 
  3009 test io-30.14 {Tcl_Write crlf on block boundary, Tcl_Read crlf} {
  3010     file delete $path(test1)
  3011     set f [open $path(test1) w]
  3012     fconfigure $f -translation crlf
  3013     set line "123456789ABCDE"	;# 14 char plus crlf
  3014     puts -nonewline $f x	;# shift crlf across block boundary
  3015     for {set i 0} {$i < 700} {incr i} {
  3016 	puts $f $line
  3017     }
  3018     close $f
  3019     set f [open $path(test1) r]
  3020     fconfigure $f -translation crlf
  3021     set c [read $f]
  3022     close $f
  3023     string length $c
  3024 } [expr 700*15+1]
  3025 
  3026 test io-30.15 {Tcl_Write mixed, Tcl_Read auto} {
  3027     file delete $path(test1)
  3028     set f [open $path(test1) w]
  3029     fconfigure $f -translation lf
  3030     puts $f hello\nthere\nand\rhere
  3031     close $f
  3032     set f [open $path(test1) r]
  3033     fconfigure $f -translation auto
  3034     set c [read $f]
  3035     close $f
  3036     set c
  3037 } {hello
  3038 there
  3039 and
  3040 here
  3041 }
  3042 test io-30.16 {Tcl_Write ^Z at end, Tcl_Read auto} {
  3043     file delete $path(test1)
  3044     set f [open $path(test1) w]
  3045     fconfigure $f -translation lf
  3046     puts -nonewline $f hello\nthere\nand\rhere\n\x1a
  3047     close $f
  3048     set f [open $path(test1) r]
  3049     fconfigure $f -eofchar \x1a -translation auto
  3050     set c [read $f]
  3051     close $f
  3052     set c
  3053 } {hello
  3054 there
  3055 and
  3056 here
  3057 }
  3058 test io-30.17 {Tcl_Write, implicit ^Z at end, Tcl_Read auto} {pcOnly} {
  3059     file delete $path(test1)
  3060     set f [open $path(test1) w]
  3061     fconfigure $f -eofchar \x1a -translation lf
  3062     puts $f hello\nthere\nand\rhere
  3063     close $f
  3064     set f [open $path(test1) r]
  3065     fconfigure $f -eofchar \x1a -translation auto
  3066     set c [read $f]
  3067     close $f
  3068     set c
  3069 } {hello
  3070 there
  3071 and
  3072 here
  3073 }
  3074 test io-30.18 {Tcl_Write, ^Z in middle, Tcl_Read auto} {
  3075     file delete $path(test1)
  3076     set f [open $path(test1) w]
  3077     fconfigure $f -translation lf
  3078     set s [format "abc\ndef\n%cghi\nqrs" 26]
  3079     puts $f $s
  3080     close $f
  3081     set f [open $path(test1) r]
  3082     fconfigure $f -eofchar \x1a -translation auto
  3083     set l ""
  3084     lappend l [gets $f]
  3085     lappend l [gets $f]
  3086     lappend l [eof $f]
  3087     lappend l [gets $f]
  3088     lappend l [eof $f]
  3089     lappend l [gets $f]
  3090     lappend l [eof $f]
  3091     close $f
  3092     set l
  3093 } {abc def 0 {} 1 {} 1}
  3094 test io-30.19 {Tcl_Write, ^Z no newline in middle, Tcl_Read auto} {
  3095     file delete $path(test1)
  3096     set f [open $path(test1) w]
  3097     fconfigure $f -translation lf
  3098     set s [format "abc\ndef\n%cghi\nqrs" 26]
  3099     puts $f $s
  3100     close $f
  3101     set f [open $path(test1) r]
  3102     fconfigure $f -eofchar \x1a -translation auto
  3103     set l ""
  3104     lappend l [gets $f]
  3105     lappend l [gets $f]
  3106     lappend l [eof $f]
  3107     lappend l [gets $f]
  3108     lappend l [eof $f]
  3109     lappend l [gets $f]
  3110     lappend l [eof $f]
  3111     close $f
  3112     set l
  3113 } {abc def 0 {} 1 {} 1}
  3114 test io-30.20 {Tcl_Write, ^Z in middle ignored, Tcl_Read lf} {
  3115     file delete $path(test1)
  3116     set f [open $path(test1) w]
  3117     fconfigure $f -translation lf -eofchar {}
  3118     set s [format "abc\ndef\n%cghi\nqrs" 26]
  3119     puts $f $s
  3120     close $f
  3121     set f [open $path(test1) r]
  3122     fconfigure $f -translation lf -eofchar {}
  3123     set l ""
  3124     lappend l [gets $f]
  3125     lappend l [gets $f]
  3126     lappend l [eof $f]
  3127     lappend l [gets $f]
  3128     lappend l [eof $f]
  3129     lappend l [gets $f]
  3130     lappend l [eof $f]
  3131     lappend l [gets $f]
  3132     lappend l [eof $f]
  3133     close $f
  3134     set l
  3135 } "abc def 0 \x1aghi 0 qrs 0 {} 1"
  3136 test io-30.21 {Tcl_Write, ^Z in middle ignored, Tcl_Read cr} {
  3137     file delete $path(test1)
  3138     set f [open $path(test1) w]
  3139     fconfigure $f -translation lf -eofchar {}
  3140     set s [format "abc\ndef\n%cghi\nqrs" 26]
  3141     puts $f $s
  3142     close $f
  3143     set f [open $path(test1) r]
  3144     fconfigure $f -translation cr -eofchar {}
  3145     set l ""
  3146     set x [gets $f]
  3147     lappend l [string compare $x "abc\ndef\n\x1aghi\nqrs\n"]
  3148     lappend l [eof $f]
  3149     lappend l [gets $f]
  3150     lappend l [eof $f]
  3151     close $f
  3152     set l
  3153 } {0 1 {} 1}
  3154 test io-30.22 {Tcl_Write, ^Z in middle ignored, Tcl_Read crlf} {
  3155     file delete $path(test1)
  3156     set f [open $path(test1) w]
  3157     fconfigure $f -translation lf -eofchar {}
  3158     set s [format "abc\ndef\n%cghi\nqrs" 26]
  3159     puts $f $s
  3160     close $f
  3161     set f [open $path(test1) r]
  3162     fconfigure $f -translation crlf -eofchar {}
  3163     set l ""
  3164     set x [gets $f]
  3165     lappend l [string compare $x "abc\ndef\n\x1aghi\nqrs\n"]
  3166     lappend l [eof $f]
  3167     lappend l [gets $f]
  3168     lappend l [eof $f]
  3169     close $f
  3170     set l
  3171 } {0 1 {} 1}
  3172 test io-30.23 {Tcl_Write lf, ^Z in middle, Tcl_Read auto} {
  3173     file delete $path(test1)
  3174     set f [open $path(test1) w]
  3175     fconfigure $f -translation lf
  3176     set c [format abc\ndef\n%cqrs\ntuv 26]
  3177     puts $f $c
  3178     close $f
  3179     set f [open $path(test1) r]
  3180     fconfigure $f -translation auto -eofchar \x1a
  3181     set c [string length [read $f]]
  3182     set e [eof $f]
  3183     close $f
  3184     list $c $e
  3185 } {8 1}
  3186 test io-30.24 {Tcl_Write lf, ^Z in middle, Tcl_Read lf} {
  3187     file delete $path(test1)
  3188     set f [open $path(test1) w]
  3189     fconfigure $f -translation lf
  3190     set c [format abc\ndef\n%cqrs\ntuv 26]
  3191     puts $f $c
  3192     close $f
  3193     set f [open $path(test1) r]
  3194     fconfigure $f -translation lf -eofchar \x1a
  3195     set c [string length [read $f]]
  3196     set e [eof $f]
  3197     close $f
  3198     list $c $e
  3199 } {8 1}
  3200 test io-30.25 {Tcl_Write cr, ^Z in middle, Tcl_Read auto} {
  3201     file delete $path(test1)
  3202     set f [open $path(test1) w]
  3203     fconfigure $f -translation cr
  3204     set c [format abc\ndef\n%cqrs\ntuv 26]
  3205     puts $f $c
  3206     close $f
  3207     set f [open $path(test1) r]
  3208     fconfigure $f -translation auto -eofchar \x1a
  3209     set c [string length [read $f]]
  3210     set e [eof $f]
  3211     close $f
  3212     list $c $e
  3213 } {8 1}
  3214 test io-30.26 {Tcl_Write cr, ^Z in middle, Tcl_Read cr} {
  3215     file delete $path(test1)
  3216     set f [open $path(test1) w]
  3217     fconfigure $f -translation cr
  3218     set c [format abc\ndef\n%cqrs\ntuv 26]
  3219     puts $f $c
  3220     close $f
  3221     set f [open $path(test1) r]
  3222     fconfigure $f -translation cr -eofchar \x1a
  3223     set c [string length [read $f]]
  3224     set e [eof $f]
  3225     close $f
  3226     list $c $e
  3227 } {8 1}
  3228 test io-30.27 {Tcl_Write crlf, ^Z in middle, Tcl_Read auto} {
  3229     file delete $path(test1)
  3230     set f [open $path(test1) w]
  3231     fconfigure $f -translation crlf
  3232     set c [format abc\ndef\n%cqrs\ntuv 26]
  3233     puts $f $c
  3234     close $f
  3235     set f [open $path(test1) r]
  3236     fconfigure $f -translation auto -eofchar \x1a
  3237     set c [string length [read $f]]
  3238     set e [eof $f]
  3239     close $f
  3240     list $c $e
  3241 } {8 1}
  3242 test io-30.28 {Tcl_Write crlf, ^Z in middle, Tcl_Read crlf} {
  3243     file delete $path(test1)
  3244     set f [open $path(test1) w]
  3245     fconfigure $f -translation crlf
  3246     set c [format abc\ndef\n%cqrs\ntuv 26]
  3247     puts $f $c
  3248     close $f
  3249     set f [open $path(test1) r]
  3250     fconfigure $f -translation crlf -eofchar \x1a
  3251     set c [string length [read $f]]
  3252     set e [eof $f]
  3253     close $f
  3254     list $c $e
  3255 } {8 1}
  3256 
  3257 # Test end of line translations. Functions tested are Tcl_Write and Tcl_Gets.
  3258 
  3259 test io-31.1 {Tcl_Write lf, Tcl_Gets auto} {
  3260     file delete $path(test1)
  3261     set f [open $path(test1) w]
  3262     fconfigure $f -translation lf
  3263     puts $f hello\nthere\nand\nhere
  3264     close $f
  3265     set f [open $path(test1) r]
  3266     set l ""
  3267     lappend l [gets $f]
  3268     lappend l [tell $f]
  3269     lappend l [fconfigure $f -translation]
  3270     lappend l [gets $f]
  3271     lappend l [tell $f]
  3272     lappend l [fconfigure $f -translation]
  3273     close $f
  3274     set l
  3275 } {hello 6 auto there 12 auto}
  3276 test io-31.2 {Tcl_Write cr, Tcl_Gets auto} {
  3277     file delete $path(test1)
  3278     set f [open $path(test1) w]
  3279     fconfigure $f -translation cr
  3280     puts $f hello\nthere\nand\nhere
  3281     close $f
  3282     set f [open $path(test1) r]
  3283     set l ""
  3284     lappend l [gets $f]
  3285     lappend l [tell $f]
  3286     lappend l [fconfigure $f -translation]
  3287     lappend l [gets $f]
  3288     lappend l [tell $f]
  3289     lappend l [fconfigure $f -translation]
  3290     close $f
  3291     set l
  3292 } {hello 6 auto there 12 auto}
  3293 test io-31.3 {Tcl_Write crlf, Tcl_Gets auto} {
  3294     file delete $path(test1)
  3295     set f [open $path(test1) w]
  3296     fconfigure $f -translation crlf
  3297     puts $f hello\nthere\nand\nhere
  3298     close $f
  3299     set f [open $path(test1) r]
  3300     set l ""
  3301     lappend l [gets $f]
  3302     lappend l [tell $f]
  3303     lappend l [fconfigure $f -translation]
  3304     lappend l [gets $f]
  3305     lappend l [tell $f]
  3306     lappend l [fconfigure $f -translation]
  3307     close $f
  3308     set l
  3309 } {hello 7 auto there 14 auto}
  3310 test io-31.4 {Tcl_Write lf, Tcl_Gets lf} {
  3311     file delete $path(test1)
  3312     set f [open $path(test1) w]
  3313     fconfigure $f -translation lf
  3314     puts $f hello\nthere\nand\nhere
  3315     close $f
  3316     set f [open $path(test1) r]
  3317     fconfigure $f -translation lf
  3318     set l ""
  3319     lappend l [gets $f]
  3320     lappend l [tell $f]
  3321     lappend l [fconfigure $f -translation]
  3322     lappend l [gets $f]
  3323     lappend l [tell $f]
  3324     lappend l [fconfigure $f -translation]
  3325     close $f
  3326     set l
  3327 } {hello 6 lf there 12 lf}
  3328 test io-31.5 {Tcl_Write lf, Tcl_Gets cr} {
  3329     file delete $path(test1)
  3330     set f [open $path(test1) w]
  3331     fconfigure $f -translation lf
  3332     puts $f hello\nthere\nand\nhere
  3333     close $f
  3334     set f [open $path(test1) r]
  3335     fconfigure $f -translation cr
  3336     set l ""
  3337     lappend l [string length [gets $f]]
  3338     lappend l [tell $f]
  3339     lappend l [fconfigure $f -translation]
  3340     lappend l [eof $f]
  3341     lappend l [gets $f]
  3342     lappend l [tell $f]
  3343     lappend l [fconfigure $f -translation]
  3344     lappend l [eof $f]
  3345     close $f
  3346     set l
  3347 } {21 21 cr 1 {} 21 cr 1}
  3348 test io-31.6 {Tcl_Write lf, Tcl_Gets crlf} {
  3349     file delete $path(test1)
  3350     set f [open $path(test1) w]
  3351     fconfigure $f -translation lf
  3352     puts $f hello\nthere\nand\nhere
  3353     close $f
  3354     set f [open $path(test1) r]
  3355     fconfigure $f -translation crlf
  3356     set l ""
  3357     lappend l [string length [gets $f]]
  3358     lappend l [tell $f]
  3359     lappend l [fconfigure $f -translation]
  3360     lappend l [eof $f]
  3361     lappend l [gets $f]
  3362     lappend l [tell $f]
  3363     lappend l [fconfigure $f -translation]
  3364     lappend l [eof $f]
  3365     close $f
  3366     set l
  3367 } {21 21 crlf 1 {} 21 crlf 1}
  3368 test io-31.7 {Tcl_Write cr, Tcl_Gets cr} {
  3369     file delete $path(test1)
  3370     set f [open $path(test1) w]
  3371     fconfigure $f -translation cr
  3372     puts $f hello\nthere\nand\nhere
  3373     close $f
  3374     set f [open $path(test1) r]
  3375     fconfigure $f -translation cr
  3376     set l ""
  3377     lappend l [gets $f]
  3378     lappend l [tell $f]
  3379     lappend l [fconfigure $f -translation]
  3380     lappend l [eof $f]
  3381     lappend l [gets $f]
  3382     lappend l [tell $f]
  3383     lappend l [fconfigure $f -translation]
  3384     lappend l [eof $f]
  3385     close $f
  3386     set l
  3387 } {hello 6 cr 0 there 12 cr 0}
  3388 test io-31.8 {Tcl_Write cr, Tcl_Gets lf} {
  3389     file delete $path(test1)
  3390     set f [open $path(test1) w]
  3391     fconfigure $f -translation cr
  3392     puts $f hello\nthere\nand\nhere
  3393     close $f
  3394     set f [open $path(test1) r]
  3395     fconfigure $f -translation lf
  3396     set l ""
  3397     lappend l [string length [gets $f]]
  3398     lappend l [tell $f]
  3399     lappend l [fconfigure $f -translation]
  3400     lappend l [eof $f]
  3401     lappend l [gets $f]
  3402     lappend l [tell $f]
  3403     lappend l [fconfigure $f -translation]
  3404     lappend l [eof $f]
  3405     close $f
  3406     set l
  3407 } {21 21 lf 1 {} 21 lf 1}
  3408 test io-31.9 {Tcl_Write cr, Tcl_Gets crlf} {
  3409     file delete $path(test1)
  3410     set f [open $path(test1) w]
  3411     fconfigure $f -translation cr
  3412     puts $f hello\nthere\nand\nhere
  3413     close $f
  3414     set f [open $path(test1) r]
  3415     fconfigure $f -translation crlf
  3416     set l ""
  3417     lappend l [string length [gets $f]]
  3418     lappend l [tell $f]
  3419     lappend l [fconfigure $f -translation]
  3420     lappend l [eof $f]
  3421     lappend l [gets $f]
  3422     lappend l [tell $f]
  3423     lappend l [fconfigure $f -translation]
  3424     lappend l [eof $f]
  3425     close $f
  3426     set l
  3427 } {21 21 crlf 1 {} 21 crlf 1}
  3428 test io-31.10 {Tcl_Write crlf, Tcl_Gets crlf} {
  3429     file delete $path(test1)
  3430     set f [open $path(test1) w]
  3431     fconfigure $f -translation crlf
  3432     puts $f hello\nthere\nand\nhere
  3433     close $f
  3434     set f [open $path(test1) r]
  3435     fconfigure $f -translation crlf
  3436     set l ""
  3437     lappend l [gets $f]
  3438     lappend l [tell $f]
  3439     lappend l [fconfigure $f -translation]
  3440     lappend l [eof $f]
  3441     lappend l [gets $f]
  3442     lappend l [tell $f]
  3443     lappend l [fconfigure $f -translation]
  3444     lappend l [eof $f]
  3445     close $f
  3446     set l
  3447 } {hello 7 crlf 0 there 14 crlf 0}
  3448 test io-31.11 {Tcl_Write crlf, Tcl_Gets cr} {
  3449     file delete $path(test1)
  3450     set f [open $path(test1) w]
  3451     fconfigure $f -translation crlf
  3452     puts $f hello\nthere\nand\nhere
  3453     close $f
  3454     set f [open $path(test1) r]
  3455     fconfigure $f -translation cr
  3456     set l ""
  3457     lappend l [gets $f]
  3458     lappend l [tell $f]
  3459     lappend l [fconfigure $f -translation]
  3460     lappend l [eof $f]
  3461     lappend l [string length [gets $f]]
  3462     lappend l [tell $f]
  3463     lappend l [fconfigure $f -translation]
  3464     lappend l [eof $f]
  3465     close $f
  3466     set l
  3467 } {hello 6 cr 0 6 13 cr 0}
  3468 test io-31.12 {Tcl_Write crlf, Tcl_Gets lf} {
  3469     file delete $path(test1)
  3470     set f [open $path(test1) w]
  3471     fconfigure $f -translation crlf
  3472     puts $f hello\nthere\nand\nhere
  3473     close $f
  3474     set f [open $path(test1) r]
  3475     fconfigure $f -translation lf
  3476     set l ""
  3477     lappend l [string length [gets $f]]
  3478     lappend l [tell $f]
  3479     lappend l [fconfigure $f -translation]
  3480     lappend l [eof $f]
  3481     lappend l [string length [gets $f]]
  3482     lappend l [tell $f]
  3483     lappend l [fconfigure $f -translation]
  3484     lappend l [eof $f]
  3485     close $f
  3486     set l
  3487 } {6 7 lf 0 6 14 lf 0}
  3488 test io-31.13 {binary mode is synonym of lf mode} {
  3489     file delete $path(test1)
  3490     set f [open $path(test1) w]
  3491     fconfigure $f -translation binary
  3492     set x [fconfigure $f -translation]
  3493     close $f
  3494     set x
  3495 } lf
  3496 #
  3497 # Test io-9.14 has been removed because "auto" output translation mode is
  3498 # not supoprted.
  3499 #
  3500 test io-31.14 {Tcl_Write mixed, Tcl_Gets auto} {
  3501     file delete $path(test1)
  3502     set f [open $path(test1) w]
  3503     fconfigure $f -translation lf
  3504     puts $f hello\nthere\rand\r\nhere
  3505     close $f
  3506     set f [open $path(test1) r]
  3507     fconfigure $f -translation auto
  3508     set l ""
  3509     lappend l [gets $f]
  3510     lappend l [gets $f]
  3511     lappend l [gets $f]
  3512     lappend l [gets $f]
  3513     lappend l [eof $f]
  3514     lappend l [gets $f]
  3515     lappend l [eof $f]
  3516     close $f
  3517     set l
  3518 } {hello there and here 0 {} 1}
  3519 test io-31.15 {Tcl_Write mixed, Tcl_Gets auto} {
  3520     file delete $path(test1)
  3521     set f [open $path(test1) w]
  3522     fconfigure $f -translation lf
  3523     puts -nonewline $f hello\nthere\rand\r\nhere\r
  3524     close $f
  3525     set f [open $path(test1) r]
  3526     fconfigure $f -translation auto
  3527     set l ""
  3528     lappend l [gets $f]
  3529     lappend l [gets $f]
  3530     lappend l [gets $f]
  3531     lappend l [gets $f]
  3532     lappend l [eof $f]
  3533     lappend l [gets $f]
  3534     lappend l [eof $f]
  3535     close $f
  3536     set l
  3537 } {hello there and here 0 {} 1}
  3538 test io-31.16 {Tcl_Write mixed, Tcl_Gets auto} {
  3539     file delete $path(test1)
  3540     set f [open $path(test1) w]
  3541     fconfigure $f -translation lf
  3542     puts -nonewline $f hello\nthere\rand\r\nhere\n
  3543     close $f
  3544     set f [open $path(test1) r]
  3545     set l ""
  3546     lappend l [gets $f]
  3547     lappend l [gets $f]
  3548     lappend l [gets $f]
  3549     lappend l [gets $f]
  3550     lappend l [eof $f]
  3551     lappend l [gets $f]
  3552     lappend l [eof $f]
  3553     close $f
  3554     set l
  3555 } {hello there and here 0 {} 1}
  3556 test io-31.17 {Tcl_Write mixed, Tcl_Gets auto} {
  3557     file delete $path(test1)
  3558     set f [open $path(test1) w]
  3559     fconfigure $f -translation lf
  3560     puts -nonewline $f hello\nthere\rand\r\nhere\r\n
  3561     close $f
  3562     set f [open $path(test1) r]
  3563     fconfigure $f -translation auto
  3564     set l ""
  3565     lappend l [gets $f]
  3566     lappend l [gets $f]
  3567     lappend l [gets $f]
  3568     lappend l [gets $f]
  3569     lappend l [eof $f]
  3570     lappend l [gets $f]
  3571     lappend l [eof $f]
  3572     close $f
  3573     set l
  3574 } {hello there and here 0 {} 1}
  3575 test io-31.18 {Tcl_Write ^Z at end, Tcl_Gets auto} {
  3576     file delete $path(test1)
  3577     set f [open $path(test1) w]
  3578     fconfigure $f -translation lf
  3579     set s [format "hello\nthere\nand\rhere\n\%c" 26]
  3580     puts $f $s
  3581     close $f
  3582     set f [open $path(test1) r]
  3583     fconfigure $f -eofchar \x1a -translation auto
  3584     set l ""
  3585     lappend l [gets $f]
  3586     lappend l [gets $f]
  3587     lappend l [gets $f]
  3588     lappend l [gets $f]
  3589     lappend l [eof $f]
  3590     lappend l [gets $f]
  3591     lappend l [eof $f]
  3592     close $f
  3593     set l
  3594 } {hello there and here 0 {} 1}
  3595 test io-31.19 {Tcl_Write, implicit ^Z at end, Tcl_Gets auto} {
  3596     file delete $path(test1)
  3597     set f [open $path(test1) w]
  3598     fconfigure $f -eofchar \x1a -translation lf
  3599     puts $f hello\nthere\nand\rhere
  3600     close $f
  3601     set f [open $path(test1) r]
  3602     fconfigure $f -eofchar \x1a -translation auto
  3603     set l ""
  3604     lappend l [gets $f]
  3605     lappend l [gets $f]
  3606     lappend l [gets $f]
  3607     lappend l [gets $f]
  3608     lappend l [eof $f]
  3609     lappend l [gets $f]
  3610     lappend l [eof $f]
  3611     close $f
  3612     set l
  3613 } {hello there and here 0 {} 1}
  3614 test io-31.20 {Tcl_Write, ^Z in middle, Tcl_Gets auto, eofChar} {
  3615     file delete $path(test1)
  3616     set f [open $path(test1) w]
  3617     fconfigure $f -translation lf
  3618     set s [format "abc\ndef\n%cqrs\ntuv" 26]
  3619     puts $f $s
  3620     close $f
  3621     set f [open $path(test1) r]
  3622     fconfigure $f -eofchar \x1a
  3623     fconfigure $f -translation auto
  3624     set l ""
  3625     lappend l [gets $f]
  3626     lappend l [gets $f]
  3627     lappend l [eof $f]
  3628     lappend l [gets $f]
  3629     lappend l [eof $f]
  3630     close $f
  3631     set l
  3632 } {abc def 0 {} 1}
  3633 test io-31.21 {Tcl_Write, no newline ^Z in middle, Tcl_Gets auto, eofChar} {
  3634     file delete $path(test1)
  3635     set f [open $path(test1) w]
  3636     fconfigure $f -translation lf
  3637     set s [format "abc\ndef\n%cqrs\ntuv" 26]
  3638     puts $f $s
  3639     close $f
  3640     set f [open $path(test1) r]
  3641     fconfigure $f -eofchar \x1a -translation auto
  3642     set l ""
  3643     lappend l [gets $f]
  3644     lappend l [gets $f]
  3645     lappend l [eof $f]
  3646     lappend l [gets $f]
  3647     lappend l [eof $f]
  3648     close $f
  3649     set l
  3650 } {abc def 0 {} 1}
  3651 test io-31.22 {Tcl_Write, ^Z in middle ignored, Tcl_Gets lf} {
  3652     file delete $path(test1)
  3653     set f [open $path(test1) w]
  3654     fconfigure $f -translation lf -eofchar {}
  3655     set s [format "abc\ndef\n%cqrs\ntuv" 26]
  3656     puts $f $s
  3657     close $f
  3658     set f [open $path(test1) r]
  3659     fconfigure $f -translation lf -eofchar {}
  3660     set l ""
  3661     lappend l [gets $f]
  3662     lappend l [gets $f]
  3663     lappend l [eof $f]
  3664     lappend l [gets $f]
  3665     lappend l [eof $f]
  3666     lappend l [gets $f]
  3667     lappend l [eof $f]
  3668     lappend l [gets $f]
  3669     lappend l [eof $f]
  3670     close $f
  3671     set l
  3672 } "abc def 0 \x1aqrs 0 tuv 0 {} 1"
  3673 test io-31.23 {Tcl_Write, ^Z in middle ignored, Tcl_Gets cr} {
  3674     file delete $path(test1)
  3675     set f [open $path(test1) w]
  3676     fconfigure $f -translation cr -eofchar {}
  3677     set s [format "abc\ndef\n%cqrs\ntuv" 26]
  3678     puts $f $s
  3679     close $f
  3680     set f [open $path(test1) r]
  3681     fconfigure $f -translation cr -eofchar {}
  3682     set l ""
  3683     lappend l [gets $f]
  3684     lappend l [gets $f]
  3685     lappend l [eof $f]
  3686     lappend l [gets $f]
  3687     lappend l [eof $f]
  3688     lappend l [gets $f]
  3689     lappend l [eof $f]
  3690     lappend l [gets $f]
  3691     lappend l [eof $f]
  3692     close $f
  3693     set l
  3694 } "abc def 0 \x1aqrs 0 tuv 0 {} 1"
  3695 test io-31.24 {Tcl_Write, ^Z in middle ignored, Tcl_Gets crlf} {
  3696     file delete $path(test1)
  3697     set f [open $path(test1) w]
  3698     fconfigure $f -translation crlf -eofchar {}
  3699     set s [format "abc\ndef\n%cqrs\ntuv" 26]
  3700     puts $f $s
  3701     close $f
  3702     set f [open $path(test1) r]
  3703     fconfigure $f -translation crlf -eofchar {}
  3704     set l ""
  3705     lappend l [gets $f]
  3706     lappend l [gets $f]
  3707     lappend l [eof $f]
  3708     lappend l [gets $f]
  3709     lappend l [eof $f]
  3710     lappend l [gets $f]
  3711     lappend l [eof $f]
  3712     lappend l [gets $f]
  3713     lappend l [eof $f]
  3714     close $f
  3715     set l
  3716 } "abc def 0 \x1aqrs 0 tuv 0 {} 1"
  3717 test io-31.25 {Tcl_Write lf, ^Z in middle, Tcl_Gets auto} {
  3718     file delete $path(test1)
  3719     set f [open $path(test1) w]
  3720     fconfigure $f -translation lf
  3721     set s [format "abc\ndef\n%cqrs\ntuv" 26]
  3722     puts $f $s
  3723     close $f
  3724     set f [open $path(test1) r]
  3725     fconfigure $f -translation auto -eofchar \x1a
  3726     set l ""
  3727     lappend l [gets $f]
  3728     lappend l [gets $f]
  3729     lappend l [eof $f]
  3730     lappend l [gets $f]
  3731     lappend l [eof $f]
  3732     close $f
  3733     set l
  3734 } {abc def 0 {} 1}
  3735 test io-31.26 {Tcl_Write lf, ^Z in middle, Tcl_Gets lf} {
  3736     file delete $path(test1)
  3737     set f [open $path(test1) w]
  3738     fconfigure $f -translation lf
  3739     set s [format "abc\ndef\n%cqrs\ntuv" 26]
  3740     puts $f $s
  3741     close $f
  3742     set f [open $path(test1) r]
  3743     fconfigure $f -translation lf -eofchar \x1a
  3744     set l ""
  3745     lappend l [gets $f]
  3746     lappend l [gets $f]
  3747     lappend l [eof $f]
  3748     lappend l [gets $f]
  3749     lappend l [eof $f]
  3750     close $f
  3751     set l
  3752 } {abc def 0 {} 1}
  3753 test io-31.27 {Tcl_Write cr, ^Z in middle, Tcl_Gets auto} {
  3754     file delete $path(test1)
  3755     set f [open $path(test1) w]
  3756     fconfigure $f -translation cr -eofchar {}
  3757     set s [format "abc\ndef\n%cqrs\ntuv" 26]
  3758     puts $f $s
  3759     close $f
  3760     set f [open $path(test1) r]
  3761     fconfigure $f -translation auto -eofchar \x1a
  3762     set l ""
  3763     lappend l [gets $f]
  3764     lappend l [gets $f]
  3765     lappend l [eof $f]
  3766     lappend l [gets $f]
  3767     lappend l [eof $f]
  3768     close $f
  3769     set l
  3770 } {abc def 0 {} 1}
  3771 test io-31.28 {Tcl_Write cr, ^Z in middle, Tcl_Gets cr} {
  3772     file delete $path(test1)
  3773     set f [open $path(test1) w]
  3774     fconfigure $f -translation cr -eofchar {}
  3775     set s [format "abc\ndef\n%cqrs\ntuv" 26]
  3776     puts $f $s
  3777     close $f
  3778     set f [open $path(test1) r]
  3779     fconfigure $f -translation cr -eofchar \x1a
  3780     set l ""
  3781     lappend l [gets $f]
  3782     lappend l [gets $f]
  3783     lappend l [eof $f]
  3784     lappend l [gets $f]
  3785     lappend l [eof $f]
  3786     close $f
  3787     set l
  3788 } {abc def 0 {} 1}
  3789 test io-31.29 {Tcl_Write crlf, ^Z in middle, Tcl_Gets auto} {
  3790     file delete $path(test1)
  3791     set f [open $path(test1) w]
  3792     fconfigure $f -translation crlf -eofchar {}
  3793     set s [format "abc\ndef\n%cqrs\ntuv" 26]
  3794     puts $f $s
  3795     close $f
  3796     set f [open $path(test1) r]
  3797     fconfigure $f -translation auto -eofchar \x1a
  3798     set l ""
  3799     lappend l [gets $f]
  3800     lappend l [gets $f]
  3801     lappend l [eof $f]
  3802     lappend l [gets $f]
  3803     lappend l [eof $f]
  3804     close $f
  3805     set l
  3806 } {abc def 0 {} 1}
  3807 test io-31.30 {Tcl_Write crlf, ^Z in middle, Tcl_Gets crlf} {
  3808     file delete $path(test1)
  3809     set f [open $path(test1) w]
  3810     fconfigure $f -translation crlf -eofchar {}
  3811     set s [format "abc\ndef\n%cqrs\ntuv" 26]
  3812     puts $f $s
  3813     close $f
  3814     set f [open $path(test1) r]
  3815     fconfigure $f -translation crlf -eofchar \x1a
  3816     set l ""
  3817     lappend l [gets $f]
  3818     lappend l [gets $f]
  3819     lappend l [eof $f]
  3820     lappend l [gets $f]
  3821     lappend l [eof $f]
  3822     close $f
  3823     set l
  3824 } {abc def 0 {} 1}
  3825 test io-31.31 {Tcl_Write crlf on block boundary, Tcl_Gets crlf} {
  3826     file delete $path(test1)
  3827     set f [open $path(test1) w]
  3828     fconfigure $f -translation crlf
  3829     set line "123456789ABCDE"	;# 14 char plus crlf
  3830     puts -nonewline $f x	;# shift crlf across block boundary
  3831     for {set i 0} {$i < 700} {incr i} {
  3832 	puts $f $line
  3833     }
  3834     close $f
  3835     set f [open $path(test1) r]
  3836     fconfigure $f -translation crlf 
  3837     set c ""
  3838     while {[gets $f line] >= 0} {
  3839 	append c $line\n
  3840     }
  3841     close $f
  3842     string length $c
  3843 } [expr 700*15+1]
  3844 test io-31.32 {Tcl_Write crlf on block boundary, Tcl_Gets auto} {
  3845     file delete $path(test1)
  3846     set f [open $path(test1) w]
  3847     fconfigure $f -translation crlf
  3848     set line "123456789ABCDE"	;# 14 char plus crlf
  3849     puts -nonewline $f x	;# shift crlf across block boundary
  3850     for {set i 0} {$i < 700} {incr i} {
  3851 	puts $f $line
  3852     }
  3853     close $f
  3854     set f [open $path(test1) r]
  3855     fconfigure $f -translation auto
  3856     set c ""
  3857     while {[gets $f line] >= 0} {
  3858 	append c $line\n
  3859     }
  3860     close $f
  3861     string length $c
  3862 } [expr 700*15+1]
  3863 
  3864 
  3865 # Test Tcl_Read and buffering.
  3866 
  3867 test io-32.1 {Tcl_Read, channel not readable} {
  3868     list [catch {read stdout} msg] $msg
  3869 } {1 {channel "stdout" wasn't opened for reading}}
  3870 test io-32.2 {Tcl_Read, zero byte count} {
  3871     read stdin 0
  3872 } ""
  3873 test io-32.3 {Tcl_Read, negative byte count} {
  3874     set f [open $path(longfile) r]
  3875     set l [list [catch {read $f -1} msg] $msg]
  3876     close $f
  3877     set l
  3878 } {1 {bad argument "-1": should be "nonewline"}}
  3879 test io-32.4 {Tcl_Read, positive byte count} {
  3880     set f [open $path(longfile) r]
  3881     set x [read $f 1024]
  3882     set s [string length $x]
  3883     unset x
  3884     close $f
  3885     set s
  3886 } 1024
  3887 test io-32.5 {Tcl_Read, multiple buffers} {
  3888     set f [open $path(longfile) r]
  3889     fconfigure $f -buffersize 100
  3890     set x [read $f 1024]
  3891     set s [string length $x]
  3892     unset x
  3893     close $f
  3894     set s
  3895 } 1024
  3896 test io-32.6 {Tcl_Read, very large read} {
  3897     set f1 [open $path(longfile) r]
  3898     set z [read $f1 1000000]
  3899     close $f1
  3900     set l [string length $z]
  3901     set x ok
  3902     set z [file size $path(longfile)]
  3903     if {$z != $l} {
  3904 	set x broken
  3905     }
  3906     set x
  3907 } ok
  3908 test io-32.7 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
  3909     set f1 [open $path(longfile) r]
  3910     fconfigure $f1 -blocking off
  3911     set z [read $f1 20]
  3912     close $f1
  3913     set l [string length $z]
  3914     set x ok
  3915     if {$l != 20} {
  3916 	set x broken
  3917     }
  3918     set x
  3919 } ok
  3920 test io-32.8 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
  3921     set f1 [open $path(longfile) r]
  3922     fconfigure $f1 -blocking off
  3923     set z [read $f1 1000000]
  3924     close $f1
  3925     set x ok
  3926     set l [string length $z]
  3927     set z [file size $path(longfile)]
  3928     if {$z != $l} {
  3929 	set x broken
  3930     }
  3931     set x
  3932 } ok
  3933 test io-32.9 {Tcl_Read, read to end of file} {
  3934     set f1 [open $path(longfile) r]
  3935     set z [read $f1]
  3936     close $f1
  3937     set l [string length $z]
  3938     set x ok
  3939     set z [file size $path(longfile)]
  3940     if {$z != $l} {
  3941 	set x broken
  3942     }
  3943     set x
  3944 } ok
  3945 test io-32.10 {Tcl_Read from a pipe} {stdio openpipe} {
  3946     file delete $path(pipe)
  3947     set f1 [open $path(pipe) w]
  3948     puts $f1 {puts [gets stdin]}
  3949     close $f1
  3950     set f1 [open "|[list [interpreter] $path(pipe)]" r+]
  3951     puts $f1 hello
  3952     flush $f1
  3953     set x [read $f1]
  3954     close $f1
  3955     set x
  3956 } "hello\n"
  3957 test io-32.11 {Tcl_Read from a pipe} {stdio openpipe} {
  3958     file delete $path(pipe)
  3959     set f1 [open $path(pipe) w]
  3960     puts $f1 {puts [gets stdin]}
  3961     puts $f1 {puts [gets stdin]}
  3962     close $f1
  3963     set f1 [open "|[list [interpreter] $path(pipe)]" r+]
  3964     puts $f1 hello
  3965     flush $f1
  3966     set x ""
  3967     lappend x [read $f1 6]
  3968     puts $f1 hello
  3969     flush $f1
  3970     lappend x [read $f1]
  3971     close $f1
  3972     set x
  3973 } {{hello
  3974 } {hello
  3975 }}
  3976 test io-32.12 {Tcl_Read, -nonewline} {
  3977     file delete $path(test1)
  3978     set f1 [open $path(test1) w]
  3979     puts $f1 hello
  3980     puts $f1 bye
  3981     close $f1
  3982     set f1 [open $path(test1) r]
  3983     set c [read -nonewline $f1]
  3984     close $f1
  3985     set c
  3986 } {hello
  3987 bye}
  3988 test io-32.13 {Tcl_Read, -nonewline} {
  3989     file delete $path(test1)
  3990     set f1 [open $path(test1) w]
  3991     puts $f1 hello
  3992     puts $f1 bye
  3993     close $f1
  3994     set f1 [open $path(test1) r]
  3995     set c [read -nonewline $f1]
  3996     close $f1
  3997     list [string length $c] $c
  3998 } {9 {hello
  3999 bye}}
  4000 test io-32.14 {Tcl_Read, reading in small chunks} {
  4001     file delete $path(test1)
  4002     set f [open $path(test1) w]
  4003     puts $f "Two lines: this one"
  4004     puts $f "and this one"
  4005     close $f
  4006     set f [open $path(test1)]
  4007     set x [list [read $f 1] [read $f 2] [read $f]]
  4008     close $f
  4009     set x
  4010 } {T wo { lines: this one
  4011 and this one
  4012 }}
  4013 test io-32.15 {Tcl_Read, asking for more input than available} {
  4014     file delete $path(test1)
  4015     set f [open $path(test1) w]
  4016     puts $f "Two lines: this one"
  4017     puts $f "and this one"
  4018     close $f
  4019     set f [open $path(test1)]
  4020     set x [read $f 100]
  4021     close $f
  4022     set x
  4023 } {Two lines: this one
  4024 and this one
  4025 }
  4026 test io-32.16 {Tcl_Read, read to end of file with -nonewline} {
  4027     file delete $path(test1)
  4028     set f [open $path(test1) w]
  4029     puts $f "Two lines: this one"
  4030     puts $f "and this one"
  4031     close $f
  4032     set f [open $path(test1)]
  4033     set x [read -nonewline $f]
  4034     close $f
  4035     set x
  4036 } {Two lines: this one
  4037 and this one}
  4038 
  4039 # Test Tcl_Gets.
  4040 
  4041 test io-33.1 {Tcl_Gets, reading what was written} {
  4042     file delete $path(test1)
  4043     set f1 [open $path(test1) w]
  4044     set y "first line"
  4045     puts $f1 $y
  4046     close $f1
  4047     set f1 [open $path(test1) r]
  4048     set x [gets $f1]
  4049     set z ok
  4050     if {"$x" != "$y"} {
  4051 	set z broken
  4052     }
  4053     close $f1
  4054     set z
  4055 } ok
  4056 test io-33.2 {Tcl_Gets into variable} {
  4057     set f1 [open $path(longfile) r]
  4058     set c [gets $f1 x]
  4059     set l [string length x]
  4060     set z ok
  4061     if {$l != $l} {
  4062 	set z broken
  4063     }
  4064     close $f1
  4065     set z
  4066 } ok
  4067 test io-33.3 {Tcl_Gets from pipe} {stdio openpipe} {
  4068     file delete $path(pipe)
  4069     set f1 [open $path(pipe) w]
  4070     puts $f1 {puts [gets stdin]}
  4071     close $f1
  4072     set f1 [open "|[list [interpreter] $path(pipe)]" r+]
  4073     puts $f1 hello
  4074     flush $f1
  4075     set x [gets $f1]
  4076     close $f1
  4077     set z ok
  4078     if {"$x" != "hello"} {
  4079 	set z broken
  4080     }
  4081     set z
  4082 } ok
  4083 test io-33.4 {Tcl_Gets with long line} {
  4084     file delete $path(test3)
  4085     set f [open $path(test3) w]
  4086     puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
  4087     puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
  4088     puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
  4089     puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
  4090     puts $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
  4091     close $f
  4092     set f [open $path(test3)]
  4093     set x [gets $f]
  4094     close $f
  4095     set x
  4096 } {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
  4097 test io-33.5 {Tcl_Gets with long line} {
  4098     set f [open $path(test3)]
  4099     set x [gets $f y]
  4100     close $f
  4101     list $x $y
  4102 } {260 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
  4103 test io-33.6 {Tcl_Gets and end of file} {
  4104     file delete $path(test3)
  4105     set f [open $path(test3) w]
  4106     puts -nonewline $f "Test1\nTest2"
  4107     close $f
  4108     set f [open $path(test3)]
  4109     set x {}
  4110     set y {}
  4111     lappend x [gets $f y] $y
  4112     set y {}
  4113     lappend x [gets $f y] $y
  4114     set y {}
  4115     lappend x [gets $f y] $y
  4116     close $f
  4117     set x
  4118 } {5 Test1 5 Test2 -1 {}}
  4119 test io-33.7 {Tcl_Gets and bad variable} {
  4120     set f [open $path(test3) w]
  4121     puts $f "Line 1"
  4122     puts $f "Line 2"
  4123     close $f
  4124     catch {unset x}
  4125     set x 24
  4126     set f [open $path(test3) r]
  4127     set result [list [catch {gets $f x(0)} msg] $msg]
  4128     close $f
  4129     set result
  4130 } {1 {can't set "x(0)": variable isn't array}}
  4131 test io-33.8 {Tcl_Gets, exercising double buffering} {
  4132     set f [open $path(test3) w]
  4133     fconfigure $f -translation lf -eofchar {}
  4134     set x ""
  4135     for {set y 0} {$y < 99} {incr y} {set x "a$x"}
  4136     for {set y 0} {$y < 100} {incr y} {puts $f $x}
  4137     close $f
  4138     set f [open $path(test3) r]
  4139     fconfigure $f -translation lf
  4140     for {set y 0} {$y < 100} {incr y} {gets $f}
  4141     close $f
  4142     set y
  4143 } 100
  4144 test io-33.9 {Tcl_Gets, exercising double buffering} {
  4145     set f [open $path(test3) w]
  4146     fconfigure $f -translation lf -eofchar {}
  4147     set x ""
  4148     for {set y 0} {$y < 99} {incr y} {set x "a$x"}
  4149     for {set y 0} {$y < 200} {incr y} {puts $f $x}
  4150     close $f
  4151     set f [open $path(test3) r]
  4152     fconfigure $f -translation lf
  4153     for {set y 0} {$y < 200} {incr y} {gets $f}
  4154     close $f
  4155     set y
  4156 } 200
  4157 test io-33.10 {Tcl_Gets, exercising double buffering} {
  4158     set f [open $path(test3) w]
  4159     fconfigure $f -translation lf -eofchar {}
  4160     set x ""
  4161     for {set y 0} {$y < 99} {incr y} {set x "a$x"}
  4162     for {set y 0} {$y < 300} {incr y} {puts $f $x}
  4163     close $f
  4164     set f [open $path(test3) r]
  4165     fconfigure $f -translation lf
  4166     for {set y 0} {$y < 300} {incr y} {gets $f}
  4167     close $f
  4168     set y
  4169 } 300
  4170 
  4171 # Test Tcl_Seek and Tcl_Tell.
  4172 
  4173 test io-34.1 {Tcl_Seek to current position at start of file} {
  4174     set f1 [open $path(longfile) r]
  4175     seek $f1 0 current
  4176     set c [tell $f1]
  4177     close $f1
  4178     set c
  4179 } 0
  4180 test io-34.2 {Tcl_Seek to offset from start} {
  4181     file delete $path(test1)
  4182     set f1 [open $path(test1) w]
  4183     fconfigure $f1 -translation lf -eofchar {}
  4184     puts $f1 "abcdefghijklmnopqrstuvwxyz"
  4185     puts $f1 "abcdefghijklmnopqrstuvwxyz"
  4186     close $f1
  4187     set f1 [open $path(test1) r]
  4188     seek $f1 10 start
  4189     set c [tell $f1]
  4190     close $f1
  4191     set c
  4192 } 10
  4193 test io-34.3 {Tcl_Seek to end of file} {
  4194     file delete $path(test1)
  4195     set f1 [open $path(test1) w]
  4196     fconfigure $f1 -translation lf -eofchar {}
  4197     puts $f1 "abcdefghijklmnopqrstuvwxyz"
  4198     puts $f1 "abcdefghijklmnopqrstuvwxyz"
  4199     close $f1
  4200     set f1 [open $path(test1) r]
  4201     seek $f1 0 end
  4202     set c [tell $f1]
  4203     close $f1
  4204     set c
  4205 } 54
  4206 test io-34.4 {Tcl_Seek to offset from end of file} {
  4207     file delete $path(test1)
  4208     set f1 [open $path(test1) w]
  4209     fconfigure $f1 -translation lf -eofchar {}
  4210     puts $f1 "abcdefghijklmnopqrstuvwxyz"
  4211     puts $f1 "abcdefghijklmnopqrstuvwxyz"
  4212     close $f1
  4213     set f1 [open $path(test1) r]
  4214     seek $f1 -10 end
  4215     set c [tell $f1]
  4216     close $f1
  4217     set c
  4218 } 44
  4219 test io-34.5 {Tcl_Seek to offset from current position} {
  4220     file delete $path(test1)
  4221     set f1 [open $path(test1) w]
  4222     fconfigure $f1 -translation lf -eofchar {}
  4223     puts $f1 "abcdefghijklmnopqrstuvwxyz"
  4224     puts $f1 "abcdefghijklmnopqrstuvwxyz"
  4225     close $f1
  4226     set f1 [open $path(test1) r]
  4227     seek $f1 10 current
  4228     seek $f1 10 current
  4229     set c [tell $f1]
  4230     close $f1
  4231     set c
  4232 } 20
  4233 test io-34.6 {Tcl_Seek to offset from end of file} {
  4234     file delete $path(test1)
  4235     set f1 [open $path(test1) w]
  4236     fconfigure $f1 -translation lf -eofchar {}
  4237     puts $f1 "abcdefghijklmnopqrstuvwxyz"
  4238     puts $f1 "abcdefghijklmnopqrstuvwxyz"
  4239     close $f1
  4240     set f1 [open $path(test1) r]
  4241     seek $f1 -10 end
  4242     set c [tell $f1]
  4243     set r [read $f1]
  4244     close $f1
  4245     list $c $r
  4246 } {44 {rstuvwxyz
  4247 }}
  4248 test io-34.7 {Tcl_Seek to offset from end of file, then to current position} {
  4249     file delete $path(test1)
  4250     set f1 [open $path(test1) w]
  4251     fconfigure $f1 -translation lf -eofchar {}
  4252     puts $f1 "abcdefghijklmnopqrstuvwxyz"
  4253     puts $f1 "abcdefghijklmnopqrstuvwxyz"
  4254     close $f1
  4255     set f1 [open $path(test1) r]
  4256     seek $f1 -10 end
  4257     set c1 [tell $f1]
  4258     set r1 [read $f1 5]
  4259     seek $f1 0 current
  4260     set c2 [tell $f1]
  4261     close $f1
  4262     list $c1 $r1 $c2
  4263 } {44 rstuv 49}
  4264 test io-34.8 {Tcl_Seek on pipes: not supported} {stdio openpipe} {
  4265     set f1 [open "|[list [interpreter]]" r+]
  4266     set x [list [catch {seek $f1 0 current} msg] $msg]
  4267     close $f1
  4268     regsub {".*":} $x {"":} x
  4269     string tolower $x
  4270 } {1 {error during seek on "": invalid argument}}
  4271 test io-34.9 {Tcl_Seek, testing buffered input flushing} {
  4272     file delete $path(test3)
  4273     set f [open $path(test3) w]
  4274     fconfigure $f -eofchar {}
  4275     puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
  4276     close $f
  4277     set f [open $path(test3) RDWR]
  4278     set x [read $f 1]
  4279     seek $f 3
  4280     lappend x [read $f 1]
  4281     seek $f 0 start
  4282     lappend x [read $f 1]
  4283     seek $f 10 current
  4284     lappend x [read $f 1]
  4285     seek $f -2 end
  4286     lappend x [read $f 1]
  4287     seek $f 50 end
  4288     lappend x [read $f 1]
  4289     seek $f 1
  4290     lappend x [read $f 1]
  4291     close $f
  4292     set x
  4293 } {a d a l Y {} b}
  4294 
  4295 set path(test3) [makeFile {} test3]
  4296 
  4297 test io-34.10 {Tcl_Seek testing flushing of buffered input} {
  4298     set f [open $path(test3) w]
  4299     fconfigure $f -translation lf
  4300     puts $f xyz\n123
  4301     close $f
  4302     set f [open $path(test3) r+]
  4303     fconfigure $f -translation lf
  4304     set x [gets $f]
  4305     seek $f 0 current
  4306     puts $f 456
  4307     close $f
  4308     list $x [viewFile test3]
  4309 } "xyz {xyz
  4310 456}"
  4311 test io-34.11 {Tcl_Seek testing flushing of buffered output} {
  4312     set f [open $path(test3) w]
  4313     puts $f xyz\n123
  4314     close $f
  4315     set f [open $path(test3) w+]
  4316     puts $f xyzzy
  4317     seek $f 2
  4318     set x [gets $f]
  4319     close $f
  4320     list $x [viewFile test3]
  4321 } "zzy xyzzy"
  4322 test io-34.12 {Tcl_Seek testing combination of write, seek back and read} {
  4323     set f [open $path(test3) w]
  4324     fconfigure $f -translation lf -eofchar {}
  4325     puts $f xyz\n123
  4326     close $f
  4327     set f [open $path(test3) a+]
  4328     fconfigure $f -translation lf -eofchar {}
  4329     puts $f xyzzy
  4330     flush $f
  4331     set x [tell $f]
  4332     seek $f -4 cur
  4333     set y [gets $f]
  4334     close $f
  4335     list $x [viewFile test3] $y
  4336 } {14 {xyz
  4337 123
  4338 xyzzy} zzy}
  4339 test io-34.13 {Tcl_Tell at start of file} {
  4340     file delete $path(test1)
  4341     set f1 [open $path(test1) w]
  4342     set p [tell $f1]
  4343     close $f1
  4344     set p
  4345 } 0
  4346 test io-34.14 {Tcl_Tell after seek to end of file} {
  4347     file delete $path(test1)
  4348     set f1 [open $path(test1) w]
  4349     fconfigure $f1 -translation lf -eofchar {}
  4350     puts $f1 "abcdefghijklmnopqrstuvwxyz"
  4351     puts $f1 "abcdefghijklmnopqrstuvwxyz"
  4352     close $f1
  4353     set f1 [open $path(test1) r]
  4354     seek $f1 0 end
  4355     set c1 [tell $f1]
  4356     close $f1
  4357     set c1
  4358 } 54
  4359 test io-34.15 {Tcl_Tell combined with seeking} {
  4360     file delete $path(test1)
  4361     set f1 [open $path(test1) w]
  4362     fconfigure $f1 -translation lf -eofchar {}
  4363     puts $f1 "abcdefghijklmnopqrstuvwxyz"
  4364     puts $f1 "abcdefghijklmnopqrstuvwxyz"
  4365     close $f1
  4366     set f1 [open $path(test1) r]
  4367     seek $f1 10 start
  4368     set c1 [tell $f1]
  4369     seek $f1 10 current
  4370     set c2 [tell $f1]
  4371     close $f1
  4372     list $c1 $c2
  4373 } {10 20}
  4374 test io-34.16 {Tcl_tell on pipe: always -1} {stdio openpipe} {
  4375     set f1 [open "|[list [interpreter]]" r+]
  4376     set c [tell $f1]
  4377     close $f1
  4378     set c
  4379 } -1
  4380 test io-34.17 {Tcl_Tell on pipe: always -1} {stdio openpipe} {
  4381     set f1 [open "|[list [interpreter]]" r+]
  4382     puts $f1 {puts hello}
  4383     flush $f1
  4384     set c [tell $f1]
  4385     gets $f1
  4386     close $f1
  4387     set c
  4388 } -1
  4389 test io-34.18 {Tcl_Tell combined with seeking and reading} {
  4390     file delete $path(test2)
  4391     set f [open $path(test2) w]
  4392     fconfigure $f -translation lf -eofchar {}
  4393     puts -nonewline $f "line1\nline2\nline3\nline4\nline5\n"
  4394     close $f
  4395     set f [open $path(test2)]
  4396     fconfigure $f -translation lf
  4397     set x [tell $f]
  4398     read $f 3
  4399     lappend x [tell $f]
  4400     seek $f 2
  4401     lappend x [tell $f]
  4402     seek $f 10 current
  4403     lappend x [tell $f]
  4404     seek $f 0 end
  4405     lappend x [tell $f]
  4406     close $f
  4407     set x
  4408 } {0 3 2 12 30}
  4409 test io-34.19 {Tcl_Tell combined with opening in append mode} {
  4410     set f [open $path(test3) w]
  4411     fconfigure $f -translation lf -eofchar {}
  4412     puts $f "abcdefghijklmnopqrstuvwxyz"
  4413     puts $f "abcdefghijklmnopqrstuvwxyz"
  4414     close $f
  4415     set f [open $path(test3) a]
  4416     set c [tell $f]
  4417     close $f
  4418     set c
  4419 } 54
  4420 test io-34.20 {Tcl_Tell combined with writing} {
  4421     set f [open $path(test3) w]
  4422     set l ""
  4423     seek $f 29 start
  4424     lappend l [tell $f]
  4425     puts -nonewline $f a
  4426     seek $f 39 start
  4427     lappend l [tell $f]
  4428     puts -nonewline $f a
  4429     lappend l [tell $f]
  4430     seek $f 407 end
  4431     lappend l [tell $f]
  4432     close $f
  4433     set l
  4434 } {29 39 40 447}
  4435 test io-34.21 {Tcl_Seek and Tcl_Tell on large files} {largefileSupport} {
  4436     file delete $path(test3)
  4437     set f [open $path(test3) w]
  4438     fconfigure $f -encoding binary
  4439     set l ""
  4440     lappend l [tell $f]
  4441     puts -nonewline $f abcdef
  4442     lappend l [tell $f]
  4443     flush $f
  4444     lappend l [tell $f]
  4445     # 4GB offset!
  4446     seek $f 0x100000000
  4447     lappend l [tell $f]
  4448     puts -nonewline $f abcdef
  4449     lappend l [tell $f]
  4450     close $f
  4451     lappend l [file size $f]
  4452     # truncate...
  4453     close [open $path(test3) w]
  4454     lappend l [file size $f]
  4455     set l
  4456 } {0 6 6 4294967296 4294967302 4294967302 0}
  4457 
  4458 # Test Tcl_Eof
  4459 
  4460 test io-35.1 {Tcl_Eof} {
  4461     file delete $path(test1)
  4462     set f [open $path(test1) w]
  4463     puts $f hello
  4464     puts $f hello
  4465     close $f
  4466     set f [open $path(test1)]
  4467     set x [eof $f]
  4468     lappend x [eof $f]
  4469     gets $f
  4470     lappend x [eof $f]
  4471     gets $f
  4472     lappend x [eof $f]
  4473     gets $f
  4474     lappend x [eof $f]
  4475     lappend x [eof $f]
  4476     close $f
  4477     set x
  4478 } {0 0 0 0 1 1}
  4479 test io-35.2 {Tcl_Eof with pipe} {stdio openpipe} {
  4480     file delete $path(pipe)
  4481     set f1 [open $path(pipe) w]
  4482     puts $f1 {gets stdin}
  4483     puts $f1 {puts hello}
  4484     close $f1
  4485     set f1 [open "|[list [interpreter] $path(pipe)]" r+]
  4486     puts $f1 hello
  4487     set x [eof $f1]
  4488     flush $f1
  4489     lappend x [eof $f1]
  4490     gets $f1
  4491     lappend x [eof $f1]
  4492     gets $f1
  4493     lappend x [eof $f1]
  4494     close $f1
  4495     set x
  4496 } {0 0 0 1}
  4497 test io-35.3 {Tcl_Eof with pipe} {stdio openpipe} {
  4498     file delete $path(pipe)
  4499     set f1 [open $path(pipe) w]
  4500     puts $f1 {gets stdin}
  4501     puts $f1 {puts hello}
  4502     close $f1
  4503     set f1 [open "|[list [interpreter] $path(pipe)]" r+]
  4504     puts $f1 hello
  4505     set x [eof $f1]
  4506     flush $f1
  4507     lappend x [eof $f1]
  4508     gets $f1
  4509     lappend x [eof $f1]
  4510     gets $f1
  4511     lappend x [eof $f1]
  4512     gets $f1
  4513     lappend x [eof $f1]
  4514     gets $f1
  4515     lappend x [eof $f1]
  4516     close $f1
  4517     set x
  4518 } {0 0 0 1 1 1}
  4519 test io-35.4 {Tcl_Eof, eof detection on nonblocking file} {nonBlockFiles} {
  4520     file delete $path(test1)
  4521     set f [open $path(test1) w]
  4522     close $f
  4523     set f [open $path(test1) r]
  4524     fconfigure $f -blocking off
  4525     set l ""
  4526     lappend l [gets $f]
  4527     lappend l [eof $f]
  4528     close $f
  4529     set l
  4530 } {{} 1}
  4531 test io-35.5 {Tcl_Eof, eof detection on nonblocking pipe} {stdio openpipe} {
  4532     file delete $path(pipe)
  4533     set f [open $path(pipe) w]
  4534     puts $f {
  4535 	exit
  4536     }
  4537     close $f
  4538     set f [open "|[list [interpreter] $path(pipe)]" r]
  4539     set l ""
  4540     lappend l [gets $f]
  4541     lappend l [eof $f]
  4542     close $f
  4543     set l
  4544 } {{} 1}
  4545 test io-35.6 {Tcl_Eof, eof char, lf write, auto read} {
  4546     file delete $path(test1)
  4547     set f [open $path(test1) w]
  4548     fconfigure $f -translation lf -eofchar \x1a
  4549     puts $f abc\ndef
  4550     close $f
  4551     set s [file size $path(test1)]
  4552     set f [open $path(test1) r]
  4553     fconfigure $f -translation auto -eofchar \x1a
  4554     set l [string length [read $f]]
  4555     set e [eof $f]
  4556     close $f
  4557     list $s $l $e
  4558 } {9 8 1}
  4559 test io-35.7 {Tcl_Eof, eof char, lf write, lf read} {
  4560     file delete $path(test1)
  4561     set f [open $path(test1) w]
  4562     fconfigure $f -translation lf -eofchar \x1a
  4563     puts $f abc\ndef
  4564     close $f
  4565     set s [file size $path(test1)]
  4566     set f [open $path(test1) r]
  4567     fconfigure $f -translation lf -eofchar \x1a
  4568     set l [string length [read $f]]
  4569     set e [eof $f]
  4570     close $f
  4571     list $s $l $e
  4572 } {9 8 1}
  4573 test io-35.8 {Tcl_Eof, eof char, cr write, auto read} {
  4574     file delete $path(test1)
  4575     set f [open $path(test1) w]
  4576     fconfigure $f -translation cr -eofchar \x1a
  4577     puts $f abc\ndef
  4578     close $f
  4579     set s [file size $path(test1)]
  4580     set f [open $path(test1) r]
  4581     fconfigure $f -translation auto -eofchar \x1a
  4582     set l [string length [read $f]]
  4583     set e [eof $f]
  4584     close $f
  4585     list $s $l $e
  4586 } {9 8 1}
  4587 test io-35.9 {Tcl_Eof, eof char, cr write, cr read} {
  4588     file delete $path(test1)
  4589     set f [open $path(test1) w]
  4590     fconfigure $f -translation cr -eofchar \x1a
  4591     puts $f abc\ndef
  4592     close $f
  4593     set s [file size $path(test1)]
  4594     set f [open $path(test1) r]
  4595     fconfigure $f -translation cr -eofchar \x1a
  4596     set l [string length [read $f]]
  4597     set e [eof $f]
  4598     close $f
  4599     list $s $l $e
  4600 } {9 8 1}
  4601 test io-35.10 {Tcl_Eof, eof char, crlf write, auto read} {
  4602     file delete $path(test1)
  4603     set f [open $path(test1) w]
  4604     fconfigure $f -translation crlf -eofchar \x1a
  4605     puts $f abc\ndef
  4606     close $f
  4607     set s [file size $path(test1)]
  4608     set f [open $path(test1) r]
  4609     fconfigure $f -translation auto -eofchar \x1a
  4610     set l [string length [read $f]]
  4611     set e [eof $f]
  4612     close $f
  4613     list $s $l $e
  4614 } {11 8 1}
  4615 test io-35.11 {Tcl_Eof, eof char, crlf write, crlf read} {
  4616     file delete $path(test1)
  4617     set f [open $path(test1) w]
  4618     fconfigure $f -translation crlf -eofchar \x1a
  4619     puts $f abc\ndef
  4620     close $f
  4621     set s [file size $path(test1)]
  4622     set f [open $path(test1) r]
  4623     fconfigure $f -translation crlf -eofchar \x1a
  4624     set l [string length [read $f]]
  4625     set e [eof $f]
  4626     close $f
  4627     list $s $l $e
  4628 } {11 8 1}
  4629 test io-35.12 {Tcl_Eof, eof char in middle, lf write, auto read} {
  4630     file delete $path(test1)
  4631     set f [open $path(test1) w]
  4632     fconfigure $f -translation lf -eofchar {}
  4633     set i [format abc\ndef\n%cqrs\nuvw 26]
  4634     puts $f $i
  4635     close $f
  4636     set c [file size $path(test1)]
  4637     set f [open $path(test1) r]
  4638     fconfigure $f -translation auto -eofchar \x1a
  4639     set l [string length [read $f]]
  4640     set e [eof $f]
  4641     close $f
  4642     list $c $l $e
  4643 } {17 8 1}
  4644 test io-35.13 {Tcl_Eof, eof char in middle, lf write, lf read} {
  4645     file delete $path(test1)
  4646     set f [open $path(test1) w]
  4647     fconfigure $f -translation lf -eofchar {}
  4648     set i [format abc\ndef\n%cqrs\nuvw 26]
  4649     puts $f $i
  4650     close $f
  4651     set c [file size $path(test1)]
  4652     set f [open $path(test1) r]
  4653     fconfigure $f -translation lf -eofchar \x1a
  4654     set l [string length [read $f]]
  4655     set e [eof $f]
  4656     close $f
  4657     list $c $l $e
  4658 } {17 8 1}
  4659 test io-35.14 {Tcl_Eof, eof char in middle, cr write, auto read} {
  4660     file delete $path(test1)
  4661     set f [open $path(test1) w]
  4662     fconfigure $f -translation cr -eofchar {}
  4663     set i [format abc\ndef\n%cqrs\nuvw 26]
  4664     puts $f $i
  4665     close $f
  4666     set c [file size $path(test1)]
  4667     set f [open $path(test1) r]
  4668     fconfigure $f -translation auto -eofchar \x1a
  4669     set l [string length [read $f]]
  4670     set e [eof $f]
  4671     close $f
  4672     list $c $l $e
  4673 } {17 8 1}
  4674 test io-35.15 {Tcl_Eof, eof char in middle, cr write, cr read} {
  4675     file delete $path(test1)
  4676     set f [open $path(test1) w]
  4677     fconfigure $f -translation cr -eofchar {}
  4678     set i [format abc\ndef\n%cqrs\nuvw 26]
  4679     puts $f $i
  4680     close $f
  4681     set c [file size $path(test1)]
  4682     set f [open $path(test1) r]
  4683     fconfigure $f -translation cr -eofchar \x1a
  4684     set l [string length [read $f]]
  4685     set e [eof $f]
  4686     close $f
  4687     list $c $l $e
  4688 } {17 8 1}
  4689 test io-35.16 {Tcl_Eof, eof char in middle, crlf write, auto read} {
  4690     file delete $path(test1)
  4691     set f [open $path(test1) w]
  4692     fconfigure $f -translation crlf -eofchar {}
  4693     set i [format abc\ndef\n%cqrs\nuvw 26]
  4694     puts $f $i
  4695     close $f
  4696     set c [file size $path(test1)]
  4697     set f [open $path(test1) r]
  4698     fconfigure $f -translation auto -eofchar \x1a
  4699     set l [string length [read $f]]
  4700     set e [eof $f]
  4701     close $f
  4702     list $c $l $e
  4703 } {21 8 1}
  4704 test io-35.17 {Tcl_Eof, eof char in middle, crlf write, crlf read} {
  4705     file delete $path(test1)
  4706     set f [open $path(test1) w]
  4707     fconfigure $f -translation crlf -eofchar {}
  4708     set i [format abc\ndef\n%cqrs\nuvw 26]
  4709     puts $f $i
  4710     close $f
  4711     set c [file size $path(test1)]
  4712     set f [open $path(test1) r]
  4713     fconfigure $f -translation crlf -eofchar \x1a
  4714     set l [string length [read $f]]
  4715     set e [eof $f]
  4716     close $f
  4717     list $c $l $e
  4718 } {21 8 1}
  4719 
  4720 # Test Tcl_InputBlocked
  4721 
  4722 test io-36.1 {Tcl_InputBlocked on nonblocking pipe} {stdio openpipe} {
  4723     set f1 [open "|[list [interpreter]]" r+]
  4724     puts $f1 {puts hello_from_pipe}
  4725     flush $f1
  4726     gets $f1
  4727     fconfigure $f1 -blocking off -buffering full
  4728     puts $f1 {puts hello}
  4729     set x ""
  4730     lappend x [gets $f1]
  4731     lappend x [fblocked $f1]
  4732     flush $f1
  4733     after 200
  4734     lappend x [gets $f1]
  4735     lappend x [fblocked $f1]
  4736     lappend x [gets $f1]
  4737     lappend x [fblocked $f1]
  4738     close $f1
  4739     set x
  4740 } {{} 1 hello 0 {} 1}
  4741 test io-36.2 {Tcl_InputBlocked on blocking pipe} {stdio openpipe} {
  4742     set f1 [open "|[list [interpreter]]" r+]
  4743     fconfigure $f1 -buffering line
  4744     puts $f1 {puts hello_from_pipe}
  4745     set x ""
  4746     lappend x [gets $f1]
  4747     lappend x [fblocked $f1]
  4748     puts $f1 {exit}
  4749     lappend x [gets $f1]
  4750     lappend x [fblocked $f1]
  4751     lappend x [eof $f1]
  4752     close $f1
  4753     set x
  4754 } {hello_from_pipe 0 {} 0 1}
  4755 test io-36.3 {Tcl_InputBlocked vs files, short read} {
  4756     file delete $path(test1)
  4757     set f [open $path(test1) w]
  4758     puts $f abcdefghijklmnop
  4759     close $f
  4760     set f [open $path(test1) r]
  4761     set l ""
  4762     lappend l [fblocked $f]
  4763     lappend l [read $f 3]
  4764     lappend l [fblocked $f]
  4765     lappend l [read -nonewline $f]
  4766     lappend l [fblocked $f]
  4767     lappend l [eof $f]
  4768     close $f
  4769     set l
  4770 } {0 abc 0 defghijklmnop 0 1}
  4771 test io-36.4 {Tcl_InputBlocked vs files, event driven read} {fileevent} {
  4772     proc in {f} {
  4773         variable l
  4774         variable x
  4775 	lappend l [read $f 3]
  4776 	if {[eof $f]} {lappend l eof; close $f; set x done}
  4777     }
  4778     file delete $path(test1)
  4779     set f [open $path(test1) w]
  4780     puts $f abcdefghijklmnop
  4781     close $f
  4782     set f [open $path(test1) r]
  4783     set l ""
  4784     fileevent $f readable [namespace code [list in $f]]
  4785     variable x
  4786     vwait [namespace which -variable x]
  4787     set l
  4788 } {abc def ghi jkl mno {p
  4789 } eof}
  4790 test io-36.5 {Tcl_InputBlocked vs files, short read, nonblocking} {nonBlockFiles} {
  4791     file delete $path(test1)
  4792     set f [open $path(test1) w]
  4793     puts $f abcdefghijklmnop
  4794     close $f
  4795     set f [open $path(test1) r]
  4796     fconfigure $f -blocking off
  4797     set l ""
  4798     lappend l [fblocked $f]
  4799     lappend l [read $f 3]
  4800     lappend l [fblocked $f]
  4801     lappend l [read -nonewline $f]
  4802     lappend l [fblocked $f]
  4803     lappend l [eof $f]
  4804     close $f
  4805     set l
  4806 } {0 abc 0 defghijklmnop 0 1}
  4807 test io-36.6 {Tcl_InputBlocked vs files, event driven read} {nonBlockFiles fileevent} {
  4808     proc in {f} {
  4809         variable l
  4810         variable x
  4811 	lappend l [read $f 3]
  4812 	if {[eof $f]} {lappend l eof; close $f; set x done}
  4813     }
  4814     file delete $path(test1)
  4815     set f [open $path(test1) w]
  4816     puts $f abcdefghijklmnop
  4817     close $f
  4818     set f [open $path(test1) r]
  4819     fconfigure $f -blocking off
  4820     set l ""
  4821     fileevent $f readable [namespace code [list in $f]]
  4822     variable x
  4823     vwait [namespace which -variable x]
  4824     set l
  4825 } {abc def ghi jkl mno {p
  4826 } eof}
  4827 
  4828 # Test Tcl_InputBuffered
  4829 
  4830 test io-37.1 {Tcl_InputBuffered} {testchannel} {
  4831     set f [open $path(longfile) r]
  4832     fconfigure $f -buffersize 4096
  4833     read $f 3
  4834     set l ""
  4835     lappend l [testchannel inputbuffered $f]
  4836     lappend l [tell $f]
  4837     close $f
  4838     set l
  4839 } {4093 3}
  4840 test io-37.2 {Tcl_InputBuffered, test input flushing on seek} {testchannel} {
  4841     set f [open $path(longfile) r]
  4842     fconfigure $f -buffersize 4096
  4843     read $f 3
  4844     set l ""
  4845     lappend l [testchannel inputbuffered $f]
  4846     lappend l [tell $f]
  4847     seek $f 0 current
  4848     lappend l [testchannel inputbuffered $f]
  4849     lappend l [tell $f]
  4850     close $f
  4851     set l
  4852 } {4093 3 0 3}
  4853 
  4854 # Test Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize
  4855 
  4856 test io-38.1 {Tcl_GetChannelBufferSize, default buffer size} {
  4857     set f [open $path(longfile) r]
  4858     set s [fconfigure $f -buffersize]
  4859     close $f
  4860     set s
  4861 } 4096
  4862 test io-38.2 {Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize} {
  4863     set f [open $path(longfile) r]
  4864     set l ""
  4865     lappend l [fconfigure $f -buffersize]
  4866     fconfigure $f -buffersize 10000
  4867     lappend l [fconfigure $f -buffersize]
  4868     fconfigure $f -buffersize 1
  4869     lappend l [fconfigure $f -buffersize]
  4870     fconfigure $f -buffersize -1
  4871     lappend l [fconfigure $f -buffersize]
  4872     fconfigure $f -buffersize 0
  4873     lappend l [fconfigure $f -buffersize]
  4874     fconfigure $f -buffersize 100000
  4875     lappend l [fconfigure $f -buffersize]
  4876     fconfigure $f -buffersize 10000000
  4877     lappend l [fconfigure $f -buffersize]
  4878     close $f
  4879     set l
  4880 } {4096 10000 1 1 1 100000 100000}
  4881 
  4882 test io-38.3 {Tcl_SetChannelBufferSize, changing buffersize between reads} {
  4883     # This test crashes the interp if Bug #427196 is not fixed
  4884 
  4885     set chan [open [info script] r]
  4886     fconfigure $chan -buffersize 10
  4887     set var [read $chan 2]
  4888     fconfigure $chan -buffersize 32
  4889     append var [read $chan]
  4890     close $chan
  4891 } {}
  4892 
  4893 # Test Tcl_SetChannelOption, Tcl_GetChannelOption
  4894 
  4895 test io-39.1 {Tcl_GetChannelOption} {
  4896     file delete $path(test1)
  4897     set f1 [open $path(test1) w]
  4898     set x [fconfigure $f1 -blocking]
  4899     close $f1
  4900     set x
  4901 } 1
  4902 #
  4903 # Test 17.2 was removed.
  4904 #
  4905 test io-39.2 {Tcl_GetChannelOption} {
  4906     file delete $path(test1)
  4907     set f1 [open $path(test1) w]
  4908     set x [fconfigure $f1 -buffering]
  4909     close $f1
  4910     set x
  4911 } full
  4912 test io-39.3 {Tcl_GetChannelOption} {
  4913     file delete $path(test1)
  4914     set f1 [open $path(test1) w]
  4915     fconfigure $f1 -buffering line
  4916     set x [fconfigure $f1 -buffering]
  4917     close $f1
  4918     set x
  4919 } line
  4920 test io-39.4 {Tcl_GetChannelOption, Tcl_SetChannelOption} {
  4921     file delete $path(test1)
  4922     set f1 [open $path(test1) w]
  4923     set l ""
  4924     lappend l [fconfigure $f1 -buffering]
  4925     fconfigure $f1 -buffering line
  4926     lappend l [fconfigure $f1 -buffering]
  4927     fconfigure $f1 -buffering none
  4928     lappend l [fconfigure $f1 -buffering]
  4929     fconfigure $f1 -buffering line
  4930     lappend l [fconfigure $f1 -buffering]
  4931     fconfigure $f1 -buffering full
  4932     lappend l [fconfigure $f1 -buffering]
  4933     close $f1
  4934     set l
  4935 } {full line none line full}
  4936 test io-39.5 {Tcl_GetChannelOption, invariance} {
  4937     file delete $path(test1)
  4938     set f1 [open $path(test1) w]
  4939     set l ""
  4940     lappend l [fconfigure $f1 -buffering]
  4941     lappend l [list [catch {fconfigure $f1 -buffering green} msg] $msg]
  4942     lappend l [fconfigure $f1 -buffering]
  4943     close $f1
  4944     set l
  4945 } {full {1 {bad value for -buffering: must be one of full, line, or none}} full}
  4946 test io-39.6 {Tcl_SetChannelOption, multiple options} {
  4947     file delete $path(test1)
  4948     set f1 [open $path(test1) w]
  4949     fconfigure $f1 -translation lf -buffering line
  4950     puts $f1 hello
  4951     puts $f1 bye
  4952     set x [file size $path(test1)]
  4953     close $f1
  4954     set x
  4955 } 10
  4956 test io-39.7 {Tcl_SetChannelOption, buffering, translation} {
  4957     file delete $path(test1)
  4958     set f1 [open $path(test1) w]
  4959     fconfigure $f1 -translation lf
  4960     puts $f1 hello
  4961     puts $f1 bye
  4962     set x ""
  4963     fconfigure $f1 -buffering line
  4964     lappend x [file size $path(test1)]
  4965     puts $f1 really_bye
  4966     lappend x [file size $path(test1)]
  4967     close $f1
  4968     set x
  4969 } {0 21}
  4970 test io-39.8 {Tcl_SetChannelOption, different buffering options} {
  4971     file delete $path(test1)
  4972     set f1 [open $path(test1) w]
  4973     set l ""
  4974     fconfigure $f1 -translation lf -buffering none -eofchar {}
  4975     puts -nonewline $f1 hello
  4976     lappend l [file size $path(test1)]
  4977     puts -nonewline $f1 hello
  4978     lappend l [file size $path(test1)]
  4979     fconfigure $f1 -buffering full
  4980     puts -nonewline $f1 hello
  4981     lappend l [file size $path(test1)]
  4982     fconfigure $f1 -buffering none
  4983     lappend l [file size $path(test1)]
  4984     puts -nonewline $f1 hello
  4985     lappend l [file size $path(test1)]
  4986     close $f1
  4987     lappend l [file size $path(test1)]
  4988     set l
  4989 } {5 10 10 10 20 20}
  4990 test io-39.9 {Tcl_SetChannelOption, blocking mode} {nonBlockFiles} {
  4991     file delete $path(test1)
  4992     set f1 [open $path(test1) w]
  4993     close $f1
  4994     set f1 [open $path(test1) r]
  4995     set x ""
  4996     lappend x [fconfigure $f1 -blocking]
  4997     fconfigure $f1 -blocking off
  4998     lappend x [fconfigure $f1 -blocking]
  4999     lappend x [gets $f1]
  5000     lappend x [read $f1 1000]
  5001     lappend x [fblocked $f1]
  5002     lappend x [eof $f1]
  5003     close $f1
  5004     set x
  5005 } {1 0 {} {} 0 1}
  5006 test io-39.10 {Tcl_SetChannelOption, blocking mode} {stdio openpipe} {
  5007     file delete $path(pipe)
  5008     set f1 [open $path(pipe) w]
  5009     puts $f1 {
  5010 	gets stdin
  5011 	after 100
  5012 	puts hi
  5013 	gets stdin
  5014     }
  5015     close $f1
  5016     set x ""
  5017     set f1 [open "|[list [interpreter] $path(pipe)]" r+]
  5018     fconfigure $f1 -blocking off -buffering line
  5019     lappend x [fconfigure $f1 -blocking]
  5020     lappend x [gets $f1]
  5021     lappend x [fblocked $f1]
  5022     fconfigure $f1 -blocking on
  5023     puts $f1 hello
  5024     fconfigure $f1 -blocking off
  5025     lappend x [gets $f1]
  5026     lappend x [fblocked $f1]
  5027     fconfigure $f1 -blocking on
  5028     puts $f1 bye
  5029     fconfigure $f1 -blocking off
  5030     lappend x [gets $f1]
  5031     lappend x [fblocked $f1]
  5032     fconfigure $f1 -blocking on
  5033     lappend x [fconfigure $f1 -blocking]
  5034     lappend x [gets $f1]
  5035     lappend x [fblocked $f1]
  5036     lappend x [eof $f1]
  5037     lappend x [gets $f1]
  5038     lappend x [eof $f1]
  5039     close $f1
  5040     set x
  5041 } {0 {} 1 {} 1 {} 1 1 hi 0 0 {} 1}
  5042 test io-39.11 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size} {
  5043     file delete $path(test1)
  5044     set f [open $path(test1) w]
  5045     fconfigure $f -buffersize -10
  5046     set x [fconfigure $f -buffersize]
  5047     close $f
  5048     set x
  5049 } 4096
  5050 test io-39.12 {Tcl_SetChannelOption, Tcl_GetChannelOption buffer size} {
  5051     file delete $path(test1)
  5052     set f [open $path(test1) w]
  5053     fconfigure $f -buffersize 10000000
  5054     set x [fconfigure $f -buffersize]
  5055     close $f
  5056     set x
  5057 } 4096
  5058 test io-39.13 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size} {
  5059     file delete $path(test1)
  5060     set f [open $path(test1) w]
  5061     fconfigure $f -buffersize 40000
  5062     set x [fconfigure $f -buffersize]
  5063     close $f
  5064     set x
  5065 } 40000
  5066 test io-39.14 {Tcl_SetChannelOption: -encoding, binary & utf-8} {
  5067     file delete $path(test1)
  5068     set f [open $path(test1) w]
  5069     fconfigure $f -encoding {} 
  5070     puts -nonewline $f \xe7\x89\xa6
  5071     close $f
  5072     set f [open $path(test1) r]
  5073     fconfigure $f -encoding utf-8
  5074     set x [read $f]
  5075     close $f
  5076     set x
  5077 } \u7266
  5078 test io-39.15 {Tcl_SetChannelOption: -encoding, binary & utf-8} {
  5079     file delete $path(test1)
  5080     set f [open $path(test1) w]
  5081     fconfigure $f -encoding binary
  5082     puts -nonewline $f \xe7\x89\xa6
  5083     close $f
  5084     set f [open $path(test1) r]
  5085     fconfigure $f -encoding utf-8
  5086     set x [read $f]
  5087     close $f
  5088     set x
  5089 } \u7266
  5090 test io-39.16 {Tcl_SetChannelOption: -encoding, errors} {
  5091     file delete $path(test1)
  5092     set f [open $path(test1) w]
  5093     set result [list [catch {fconfigure $f -encoding foobar} msg] $msg]
  5094     close $f
  5095     set result
  5096 } {1 {unknown encoding "foobar"}}
  5097 test io-39.17 {Tcl_SetChannelOption: -encoding, clearing CHANNEL_NEED_MORE_DATA} {stdio openpipe fileevent} {
  5098     set f [open "|[list [interpreter] $path(cat)]" r+]
  5099     fconfigure $f -encoding binary
  5100     puts -nonewline $f "\xe7"
  5101     flush $f
  5102     fconfigure $f -encoding utf-8 -blocking 0
  5103     variable x {}
  5104     fileevent $f readable [namespace code { lappend x [read $f] }]
  5105     vwait [namespace which -variable x]
  5106     after 300 [namespace code { lappend x timeout }]
  5107     vwait [namespace which -variable x]
  5108     fconfigure $f -encoding utf-8
  5109     vwait [namespace which -variable x]
  5110     after 300 [namespace code { lappend x timeout }]
  5111     vwait [namespace which -variable x]
  5112     fconfigure $f -encoding binary
  5113     vwait [namespace which -variable x]
  5114     after 300 [namespace code { lappend x timeout }]
  5115     vwait [namespace which -variable x]
  5116     close $f
  5117     set x
  5118 } "{} timeout {} timeout \xe7 timeout"
  5119 
  5120 test io-39.18 {Tcl_SetChannelOption, setting read mode independently} \
  5121 	{socket} {
  5122     proc accept {s a p} {close $s}
  5123     set s1 [socket -server [namespace code accept] 0]
  5124     set port [lindex [fconfigure $s1 -sockname] 2]
  5125     set s2 [socket 127.0.0.1 $port]
  5126     update
  5127     fconfigure $s2 -translation {auto lf}
  5128     set modes [fconfigure $s2 -translation]
  5129     close $s1
  5130     close $s2
  5131     set modes
  5132 } {auto lf}
  5133 test io-39.19 {Tcl_SetChannelOption, setting read mode independently} \
  5134 	{socket} {
  5135     proc accept {s a p} {close $s}
  5136     set s1 [socket -server [namespace code accept] 0]
  5137     set port [lindex [fconfigure $s1 -sockname] 2]
  5138     set s2 [socket 127.0.0.1 $port]
  5139     update
  5140     fconfigure $s2 -translation {auto crlf}
  5141     set modes [fconfigure $s2 -translation]
  5142     close $s1
  5143     close $s2
  5144     set modes
  5145 } {auto crlf}
  5146 test io-39.20 {Tcl_SetChannelOption, setting read mode independently} \
  5147 	{socket} {
  5148     proc accept {s a p} {close $s}
  5149     set s1 [socket -server [namespace code accept] 0]
  5150     set port [lindex [fconfigure $s1 -sockname] 2]
  5151     set s2 [socket 127.0.0.1 $port]
  5152     update
  5153     fconfigure $s2 -translation {auto cr}
  5154     set modes [fconfigure $s2 -translation]
  5155     close $s1
  5156     close $s2
  5157     set modes
  5158 } {auto cr}
  5159 test io-39.21 {Tcl_SetChannelOption, setting read mode independently} \
  5160 	{socket} {
  5161     proc accept {s a p} {close $s}
  5162     set s1 [socket -server [namespace code accept] 0]
  5163     set port [lindex [fconfigure $s1 -sockname] 2]
  5164     set s2 [socket 127.0.0.1 $port]
  5165     update
  5166     fconfigure $s2 -translation {auto auto}
  5167     set modes [fconfigure $s2 -translation]
  5168     close $s1
  5169     close $s2
  5170     set modes
  5171 } {auto crlf}
  5172 
  5173 test io-39.22 {Tcl_SetChannelOption, invariance} {unixOnly} {
  5174     file delete $path(test1)
  5175     set f1 [open $path(test1) w+]
  5176     set l ""
  5177     lappend l [fconfigure $f1 -eofchar]
  5178     fconfigure $f1 -eofchar {ON GO}
  5179     lappend l [fconfigure $f1 -eofchar]
  5180     fconfigure $f1 -eofchar D
  5181     lappend l [fconfigure $f1 -eofchar]
  5182     close $f1
  5183     set l
  5184 } {{{} {}} {O G} {D D}}
  5185 
  5186 test io-39.22a {Tcl_SetChannelOption, invariance} {
  5187     file delete $path(test1)
  5188     set f1 [open $path(test1) w+]
  5189     set l [list]
  5190     fconfigure $f1 -eofchar {ON GO}
  5191     lappend l [fconfigure $f1 -eofchar]
  5192     fconfigure $f1 -eofchar D
  5193     lappend l [fconfigure $f1 -eofchar]
  5194     lappend l [list [catch {fconfigure $f1 -eofchar {1 2 3}} msg] $msg]
  5195     close $f1
  5196     set l
  5197 } {{O G} {D D} {1 {bad value for -eofchar: should be a list of zero, one, or two elements}}}
  5198 
  5199 
  5200 test io-39.23 {Tcl_GetChannelOption, server socket is not readable or
  5201         writeable, it should still have valid -eofchar and -translation options } {
  5202     set l [list]
  5203     set sock [socket -server [namespace code accept] 0]
  5204     lappend l [fconfigure $sock -eofchar] [fconfigure $sock -translation]
  5205     close $sock
  5206     set l
  5207 } {{{}} auto}
  5208 test io-39.24 {Tcl_SetChannelOption, server socket is not readable or
  5209         writable so we can't change -eofchar or -translation } {
  5210     set l [list]
  5211     set sock [socket -server [namespace code accept] 0]
  5212     fconfigure $sock -eofchar D -translation lf
  5213     lappend l [fconfigure $sock -eofchar] [fconfigure $sock -translation]
  5214     close $sock
  5215     set l
  5216 } {{{}} auto}
  5217 
  5218 test io-40.1 {POSIX open access modes: RDWR} {
  5219     file delete $path(test3)
  5220     set f [open $path(test3) w]
  5221     puts $f xyzzy
  5222     close $f
  5223     set f [open $path(test3) RDWR]
  5224     puts -nonewline $f "ab"
  5225     seek $f 0 current
  5226     set x [gets $f]
  5227     close $f
  5228     set f [open $path(test3) r]
  5229     lappend x [gets $f]
  5230     close $f
  5231     set x
  5232 } {zzy abzzy}
  5233 test io-40.2 {POSIX open access modes: CREAT} {unixOnly} {
  5234     file delete $path(test3)
  5235     set f [open $path(test3) {WRONLY CREAT} 0600]
  5236     file stat $path(test3) stats
  5237     set x [format "0%o" [expr $stats(mode)&0777]]
  5238     puts $f "line 1"
  5239     close $f
  5240     set f [open $path(test3) r]
  5241     lappend x [gets $f]
  5242     close $f
  5243     set x
  5244 } {0600 {line 1}}
  5245 
  5246 # some tests can only be run is umask is 2
  5247 # if "umask" cannot be run, the tests will be skipped.
  5248 catch {testConstraint umask2 [expr {[exec umask] == 2}]}
  5249 
  5250 test io-40.3 {POSIX open access modes: CREAT} {unixOnly umask2} {
  5251     # This test only works if your umask is 2, like ouster's.
  5252     file delete $path(test3)
  5253     set f [open $path(test3) {WRONLY CREAT}]
  5254     close $f
  5255     file stat test3 stats
  5256     format "0%o" [expr $stats(mode)&0777]
  5257 } 0664
  5258 test io-40.4 {POSIX open access modes: CREAT} {
  5259     file delete $path(test3)
  5260     set f [open $path(test3) w]
  5261     fconfigure $f -eofchar {}
  5262     puts $f xyzzy
  5263     close $f
  5264     set f [open $path(test3) {WRONLY CREAT}]
  5265     fconfigure $f -eofchar {}
  5266     puts -nonewline $f "ab"
  5267     close $f
  5268     set f [open $path(test3) r]
  5269     set x [gets $f]
  5270     close $f
  5271     set x
  5272 } abzzy
  5273 test io-40.5 {POSIX open access modes: APPEND} {
  5274     file delete $path(test3)
  5275     set f [open $path(test3) w]
  5276     fconfigure $f -translation lf -eofchar {}
  5277     puts $f xyzzy
  5278     close $f
  5279     set f [open $path(test3) {WRONLY APPEND}]
  5280     fconfigure $f -translation lf
  5281     puts $f "new line"
  5282     seek $f 0
  5283     puts $f "abc"
  5284     close $f
  5285     set f [open $path(test3) r]
  5286     fconfigure $f -translation lf
  5287     set x ""
  5288     seek $f 6 current
  5289     lappend x [gets $f]
  5290     lappend x [gets $f]
  5291     close $f
  5292     set x
  5293 } {{new line} abc}
  5294 test io-40.6 {POSIX open access modes: EXCL} -match regexp -body {
  5295     file delete $path(test3)
  5296     set f [open $path(test3) w]
  5297     puts $f xyzzy
  5298     close $f
  5299     open $path(test3) {WRONLY CREAT EXCL}
  5300 } -returnCodes error -result {(?i)couldn't open ".*test3": file (already )?exists}
  5301 test io-40.7 {POSIX open access modes: EXCL} {
  5302     file delete $path(test3)
  5303     set f [open $path(test3) {WRONLY CREAT EXCL}]
  5304     fconfigure $f -eofchar {}
  5305     puts $f "A test line"
  5306     close $f
  5307     viewFile test3
  5308 } {A test line}
  5309 test io-40.8 {POSIX open access modes: TRUNC} {
  5310     file delete $path(test3)
  5311     set f [open $path(test3) w]
  5312     puts $f xyzzy
  5313     close $f
  5314     set f [open $path(test3) {WRONLY TRUNC}]
  5315     puts $f abc
  5316     close $f
  5317     set f [open $path(test3) r]
  5318     set x [gets $f]
  5319     close $f
  5320     set x
  5321 } abc
  5322 test io-40.9 {POSIX open access modes: NONBLOCK} {nonPortable macOrUnix} {
  5323     file delete $path(test3)
  5324     set f [open $path(test3) {WRONLY NONBLOCK CREAT}]
  5325     puts $f "NONBLOCK test"
  5326     close $f
  5327     set f [open $path(test3) r]
  5328     set x [gets $f]
  5329     close $f
  5330     set x
  5331 } {NONBLOCK test}
  5332 test io-40.10 {POSIX open access modes: RDONLY} {
  5333     set f [open $path(test1) w]
  5334     puts $f "two lines: this one"
  5335     puts $f "and this"
  5336     close $f
  5337     set f [open $path(test1) RDONLY]
  5338     set x [list [gets $f] [catch {puts $f Test} msg] $msg]
  5339     close $f
  5340     string compare [string tolower $x] \
  5341 	[list {two lines: this one} 1 \
  5342 		[format "channel \"%s\" wasn't opened for writing" $f]]
  5343 } 0
  5344 test io-40.11 {POSIX open access modes: RDONLY} -match regexp -body {
  5345     file delete $path(test3)
  5346     open $path(test3) RDONLY
  5347 } -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
  5348 test io-40.12 {POSIX open access modes: WRONLY} -match regexp -body {
  5349     file delete $path(test3)
  5350     open $path(test3) WRONLY
  5351 } -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
  5352 test io-40.13 {POSIX open access modes: WRONLY} {
  5353     makeFile xyzzy test3
  5354     set f [open $path(test3) WRONLY]
  5355     fconfigure $f -eofchar {}
  5356     puts -nonewline $f "ab"
  5357     seek $f 0 current
  5358     set x [list [catch {gets $f} msg] $msg]
  5359     close $f
  5360     lappend x [viewFile test3]
  5361     string compare [string tolower $x] \
  5362 	[list 1 "channel \"$f\" wasn't opened for reading" abzzy]
  5363 } 0
  5364 test io-40.14 {POSIX open access modes: RDWR} -match regexp -body {
  5365     file delete $path(test3)
  5366     open $path(test3) RDWR
  5367 } -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
  5368 test io-40.15 {POSIX open access modes: RDWR} {
  5369     makeFile xyzzy test3
  5370     set f [open $path(test3) RDWR]
  5371     puts -nonewline $f "ab"
  5372     seek $f 0 current
  5373     set x [gets $f]
  5374     close $f
  5375     lappend x [viewFile test3]
  5376 } {zzy abzzy}
  5377 if {![file exists ~/_test_] && [file writable ~]} {
  5378     test io-40.16 {tilde substitution in open} -setup {
  5379 	makeFile {Some text} _test_ ~
  5380     } -body {
  5381 	file exists [file join $env(HOME) _test_]
  5382     } -cleanup {
  5383 	removeFile _test_ ~
  5384     } -result 1
  5385 }
  5386 test io-40.17 {tilde substitution in open} {
  5387     set home $env(HOME)
  5388     unset env(HOME)
  5389     set x [list [catch {open ~/foo} msg] $msg]
  5390     set env(HOME) $home
  5391     set x
  5392 } {1 {couldn't find HOME environment variable to expand path}}
  5393 
  5394 test io-41.1 {Tcl_FileeventCmd: errors} {fileevent} {
  5395     list [catch {fileevent foo} msg] $msg
  5396 } {1 {wrong # args: should be "fileevent channelId event ?script?"}}
  5397 test io-41.2 {Tcl_FileeventCmd: errors} {fileevent} {
  5398     list [catch {fileevent foo bar baz q} msg] $msg
  5399 } {1 {wrong # args: should be "fileevent channelId event ?script?"}}
  5400 test io-41.3 {Tcl_FileeventCmd: errors} {fileevent} {
  5401     list [catch {fileevent gorp readable} msg] $msg
  5402 } {1 {can not find channel named "gorp"}}
  5403 test io-41.4 {Tcl_FileeventCmd: errors} {fileevent} {
  5404     list [catch {fileevent gorp writable} msg] $msg
  5405 } {1 {can not find channel named "gorp"}}
  5406 test io-41.5 {Tcl_FileeventCmd: errors} {fileevent} {
  5407     list [catch {fileevent gorp who-knows} msg] $msg
  5408 } {1 {bad event name "who-knows": must be readable or writable}}
  5409 
  5410 #
  5411 # Test fileevent on a file
  5412 #
  5413 
  5414 set path(foo) [makeFile {} foo]
  5415 set f [open $path(foo) w+]
  5416 
  5417 test io-42.1 {Tcl_FileeventCmd: creating, deleting, querying} {fileevent} {
  5418     list [fileevent $f readable] [fileevent $f writable]
  5419 } {{} {}}
  5420 test io-42.2 {Tcl_FileeventCmd: replacing} {fileevent} {
  5421     set result {}
  5422     fileevent $f r "first script"
  5423     lappend result [fileevent $f readable]
  5424     fileevent $f r "new script"
  5425     lappend result [fileevent $f readable]
  5426     fileevent $f r "yet another"
  5427     lappend result [fileevent $f readable]
  5428     fileevent $f r ""
  5429     lappend result [fileevent $f readable]
  5430 } {{first script} {new script} {yet another} {}}
  5431 test io-42.3 {Tcl_FileeventCmd: replacing, with NULL chars in script} {fileevent} {
  5432     set result {}
  5433     fileevent $f r "first scr\0ipt"
  5434     lappend result [string length [fileevent $f readable]]
  5435     fileevent $f r "new scr\0ipt"
  5436     lappend result [string length [fileevent $f readable]]
  5437     fileevent $f r "yet ano\0ther"
  5438     lappend result [string length [fileevent $f readable]]
  5439     fileevent $f r ""
  5440     lappend result [fileevent $f readable]
  5441 } {13 11 12 {}}
  5442 
  5443 test io-43.1 {Tcl_FileeventCmd: creating, deleting, querying} {stdio unixExecs fileevent} {
  5444     set result {}
  5445     fileevent $f readable "script 1"
  5446     lappend result [fileevent $f readable] [fileevent $f writable]
  5447     fileevent $f writable "write script"
  5448     lappend result [fileevent $f readable] [fileevent $f writable]
  5449     fileevent $f readable {}
  5450     lappend result [fileevent $f readable] [fileevent $f writable]
  5451     fileevent $f writable {}
  5452     lappend result [fileevent $f readable] [fileevent $f writable]
  5453 } {{script 1} {} {script 1} {write script} {} {write script} {} {}}
  5454 test io-43.2 {Tcl_FileeventCmd: deleting when many present} -setup {
  5455     set f2 [open "|[list cat -u]" r+]
  5456     set f3 [open "|[list cat -u]" r+]
  5457 } -constraints {stdio unixExecs fileevent openpipe} -body {
  5458     set result {}
  5459     lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
  5460     fileevent $f r "read f"
  5461     fileevent $f2 r "read f2"
  5462     fileevent $f3 r "read f3"
  5463     lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
  5464     fileevent $f2 r {}
  5465     lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
  5466     fileevent $f3 r {}
  5467     lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
  5468     fileevent $f r {}
  5469     lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
  5470 } -cleanup {
  5471     catch {close $f2}
  5472     catch {close $f3}
  5473 } -result {{} {} {} {read f} {read f2} {read f3} {read f} {} {read f3} {read f} {} {} {} {} {}}
  5474 
  5475 test io-44.1 {FileEventProc procedure: normal read event} -setup {
  5476     set f2 [open "|[list cat -u]" r+]
  5477     set f3 [open "|[list cat -u]" r+]
  5478 } -constraints {stdio unixExecs fileevent openpipe} -body {
  5479     fileevent $f2 readable [namespace code {
  5480 	set x [gets $f2]; fileevent $f2 readable {}
  5481     }]
  5482     puts $f2 text; flush $f2
  5483     variable x initial
  5484     vwait [namespace which -variable x]
  5485     set x
  5486 } -cleanup {
  5487     catch {close $f2}
  5488     catch {close $f3}
  5489 } -result {text}
  5490 test io-44.2 {FileEventProc procedure: error in read event} -setup {
  5491     set f2 [open "|[list cat -u]" r+]
  5492     set f3 [open "|[list cat -u]" r+]
  5493 } -constraints {stdio unixExecs fileevent openpipe} -body {
  5494     proc ::bgerror args "set [namespace which -variable x] \$args"
  5495     fileevent $f2 readable {error bogus}
  5496     puts $f2 text; flush $f2
  5497     variable x initial
  5498     vwait [namespace which -variable x]
  5499     rename ::bgerror {}
  5500     list $x [fileevent $f2 readable]
  5501 } -cleanup {
  5502     catch {close $f2}
  5503     catch {close $f3}
  5504 } -result {bogus {}}
  5505 test io-44.3 {FileEventProc procedure: normal write event} -setup {
  5506     set f2 [open "|[list cat -u]" r+]
  5507     set f3 [open "|[list cat -u]" r+]
  5508 } -constraints {stdio unixExecs fileevent openpipe} -body {
  5509     fileevent $f2 writable [namespace code {
  5510 	lappend x "triggered"
  5511 	incr count -1
  5512 	if {$count <= 0} {
  5513 	    fileevent $f2 writable {}
  5514 	}
  5515     }]
  5516     variable x initial
  5517     set count 3
  5518     vwait [namespace which -variable x]
  5519     vwait [namespace which -variable x]
  5520     vwait [namespace which -variable x]
  5521     set x
  5522 } -cleanup {
  5523     catch {close $f2}
  5524     catch {close $f3}
  5525 } -result {initial triggered triggered triggered}
  5526 test io-44.4 {FileEventProc procedure: eror in write event} -setup {
  5527     set f2 [open "|[list cat -u]" r+]
  5528     set f3 [open "|[list cat -u]" r+]
  5529 } -constraints {stdio unixExecs fileevent openpipe} -body {
  5530     proc ::bgerror args "set [namespace which -variable x] \$args"
  5531     fileevent $f2 writable {error bad-write}
  5532     variable x initial
  5533     vwait [namespace which -variable x]
  5534     rename ::bgerror {}
  5535     list $x [fileevent $f2 writable]
  5536 } -cleanup {
  5537     catch {close $f2}
  5538     catch {close $f3}
  5539 } -result {bad-write {}}
  5540 test io-44.5 {FileEventProc procedure: end of file} {stdio unixExecs openpipe fileevent} {
  5541     set f4 [open "|[list [interpreter] $path(cat) << foo]" r]
  5542     fileevent $f4 readable [namespace code {
  5543 	if {[gets $f4 line] < 0} {
  5544 	    lappend x eof
  5545 	    fileevent $f4 readable {}
  5546 	} else {
  5547 	    lappend x $line
  5548 	}
  5549     }]
  5550     variable x initial
  5551     vwait [namespace which -variable x]
  5552     vwait [namespace which -variable x]
  5553     close $f4
  5554     set x
  5555 } {initial foo eof}
  5556 
  5557 
  5558 close $f
  5559 makeFile "foo bar" foo
  5560 test io-45.1 {DeleteFileEvent, cleanup on close} {fileevent} {
  5561     set f [open $path(foo) r]
  5562     fileevent $f readable [namespace code {
  5563 	lappend x "binding triggered: \"[gets $f]\""
  5564 	fileevent $f readable {}
  5565     }]
  5566     close $f
  5567     set x initial
  5568     after 100 [namespace code { set y done }]
  5569     variable y
  5570     vwait [namespace which -variable y]
  5571     set x
  5572 } {initial}
  5573 test io-45.2 {DeleteFileEvent, cleanup on close} {fileevent} {
  5574     set f  [open $path(foo) r]
  5575     set f2 [open $path(foo) r]
  5576     fileevent $f readable [namespace code {
  5577 	    lappend x "f triggered: \"[gets $f]\""
  5578 	    fileevent $f readable {}
  5579 	}]
  5580     fileevent $f2 readable [namespace code {
  5581 	lappend x "f2 triggered: \"[gets $f2]\""
  5582 	fileevent $f2 readable {}
  5583     }]
  5584     close $f
  5585     variable x initial
  5586     vwait [namespace which -variable x]
  5587     close $f2
  5588     set x
  5589 } {initial {f2 triggered: "foo bar"}}
  5590 test io-45.3 {DeleteFileEvent, cleanup on close} {fileevent} {
  5591     set f  [open $path(foo) r]
  5592     set f2 [open $path(foo) r]
  5593     set f3 [open $path(foo) r]
  5594     fileevent $f readable {f script}
  5595     fileevent $f2 readable {f2 script}
  5596     fileevent $f3 readable {f3 script}
  5597     set x {}
  5598     close $f2
  5599     lappend x [catch {fileevent $f readable} msg] $msg \
  5600 	    [catch {fileevent $f2 readable}] \
  5601 	    [catch {fileevent $f3 readable} msg] $msg
  5602     close $f3
  5603     lappend x [catch {fileevent $f readable} msg] $msg \
  5604 	    [catch {fileevent $f2 readable}] \
  5605 	    [catch {fileevent $f3 readable}]
  5606     close $f
  5607     lappend x [catch {fileevent $f readable}] \
  5608 	    [catch {fileevent $f2 readable}] \
  5609 	    [catch {fileevent $f3 readable}]
  5610 } {0 {f script} 1 0 {f3 script} 0 {f script} 1 1 1 1 1}
  5611 
  5612 # Execute these tests only if the "testfevent" command is present.
  5613 testConstraint testfevent [llength [info commands testfevent]]
  5614 
  5615 test io-46.1 {Tcl event loop vs multiple interpreters} {testfevent fileevent} {
  5616     testfevent create
  5617     set script "set f \[[list open $path(foo) r]]\n"
  5618     append script {
  5619 	set x "no event"
  5620 	fileevent $f readable [namespace code {
  5621 	    set x "f triggered: [gets $f]"
  5622 	    fileevent $f readable {}
  5623 	}]
  5624     }
  5625     testfevent cmd $script
  5626     after 1	;# We must delay because Windows takes a little time to notice
  5627     update
  5628     testfevent cmd {close $f}
  5629     list [testfevent cmd {set x}] [testfevent cmd {info commands after}]
  5630 } {{f triggered: foo bar} after}
  5631 test io-46.2 {Tcl event loop vs multiple interpreters} testfevent {
  5632     testfevent create
  5633     testfevent cmd {
  5634         variable x 0
  5635         after 100 {set x triggered}
  5636         vwait [namespace which -variable x]
  5637         set x
  5638     }
  5639 } {triggered}
  5640 test io-46.3 {Tcl event loop vs multiple interpreters} testfevent {
  5641     testfevent create
  5642     testfevent cmd {
  5643         set x 0
  5644         after 10 {lappend x timer}
  5645         after 30
  5646         set result $x
  5647         update idletasks
  5648         lappend result $x
  5649         update
  5650         lappend result $x
  5651     }
  5652 } {0 0 {0 timer}}
  5653 
  5654 test io-47.1 {fileevent vs multiple interpreters} {testfevent fileevent} {
  5655     set f  [open $path(foo) r]
  5656     set f2 [open $path(foo) r]
  5657     set f3 [open $path(foo) r]
  5658     fileevent $f readable {script 1}
  5659     testfevent create
  5660     testfevent share $f2
  5661     testfevent cmd "fileevent $f2 readable {script 2}"
  5662     fileevent $f3 readable {sript 3}
  5663     set x {}
  5664     lappend x [fileevent $f2 readable]
  5665     testfevent delete
  5666     lappend x [fileevent $f readable] [fileevent $f2 readable] \
  5667         [fileevent $f3 readable]
  5668     close $f
  5669     close $f2
  5670     close $f3
  5671     set x
  5672 } {{} {script 1} {} {sript 3}}
  5673 test io-47.2 {deleting fileevent on interpreter delete} {testfevent fileevent} {
  5674     set f  [open $path(foo) r]
  5675     set f2 [open $path(foo) r]
  5676     set f3 [open $path(foo) r]
  5677     set f4 [open $path(foo) r]
  5678     fileevent $f readable {script 1}
  5679     testfevent create
  5680     testfevent share $f2
  5681     testfevent share $f3
  5682     testfevent cmd "fileevent $f2 readable {script 2}
  5683         fileevent $f3 readable {script 3}"
  5684     fileevent $f4 readable {script 4}
  5685     testfevent delete
  5686     set x [list [fileevent $f readable] [fileevent $f2 readable] \
  5687                 [fileevent $f3 readable] [fileevent $f4 readable]]
  5688     close $f
  5689     close $f2
  5690     close $f3
  5691     close $f4
  5692     set x
  5693 } {{script 1} {} {} {script 4}}
  5694 test io-47.3 {deleting fileevent on interpreter delete} {testfevent fileevent} {
  5695     set f  [open $path(foo) r]
  5696     set f2 [open $path(foo) r]
  5697     set f3 [open $path(foo) r]
  5698     set f4 [open $path(foo) r]
  5699     testfevent create
  5700     testfevent share $f3
  5701     testfevent share $f4
  5702     fileevent $f readable {script 1}
  5703     fileevent $f2 readable {script 2}
  5704     testfevent cmd "fileevent $f3 readable {script 3}
  5705       fileevent $f4 readable {script 4}"
  5706     testfevent delete
  5707     set x [list [fileevent $f readable] [fileevent $f2 readable] \
  5708                 [fileevent $f3 readable] [fileevent $f4 readable]]
  5709     close $f
  5710     close $f2
  5711     close $f3
  5712     close $f4
  5713     set x
  5714 } {{script 1} {script 2} {} {}}
  5715 test io-47.4 {file events on shared files and multiple interpreters} {testfevent fileevent} {
  5716     set f  [open $path(foo) r]
  5717     set f2 [open $path(foo) r]
  5718     testfevent create
  5719     testfevent share $f
  5720     testfevent cmd "fileevent $f readable {script 1}"
  5721     fileevent $f readable {script 2}
  5722     fileevent $f2 readable {script 3}
  5723     set x [list [fileevent $f2 readable] \
  5724                 [testfevent cmd "fileevent $f readable"] \
  5725                 [fileevent $f readable]]
  5726     testfevent delete
  5727     close $f
  5728     close $f2
  5729     set x
  5730 } {{script 3} {script 1} {script 2}}
  5731 test io-47.5 {file events on shared files, deleting file events} {testfevent fileevent} {
  5732     set f [open $path(foo) r]
  5733     testfevent create
  5734     testfevent share $f
  5735     testfevent cmd "fileevent $f readable {script 1}"
  5736     fileevent $f readable {script 2}
  5737     testfevent cmd "fileevent $f readable {}"
  5738     set x [list [testfevent cmd "fileevent $f readable"] \
  5739                 [fileevent $f readable]]
  5740     testfevent delete
  5741     close $f
  5742     set x
  5743 } {{} {script 2}}
  5744 test io-47.6 {file events on shared files, deleting file events} {testfevent fileevent} {
  5745     set f [open $path(foo) r]
  5746     testfevent create
  5747     testfevent share $f
  5748     testfevent cmd "fileevent $f readable {script 1}"
  5749     fileevent $f readable {script 2}
  5750     fileevent $f readable {}
  5751     set x [list [testfevent cmd "fileevent $f readable"] \
  5752                 [fileevent $f readable]]
  5753     testfevent delete
  5754     close $f
  5755     set x
  5756 } {{script 1} {}}
  5757 
  5758 set path(bar) [makeFile {} bar]
  5759 
  5760 test io-48.1 {testing readability conditions} {fileevent} {
  5761     set f [open $path(bar) w]
  5762     puts $f abcdefg
  5763     puts $f abcdefg
  5764     puts $f abcdefg
  5765     puts $f abcdefg
  5766     puts $f abcdefg
  5767     close $f
  5768     set f [open $path(bar) r]
  5769     fileevent $f readable [namespace code [list consume $f]]
  5770     proc consume {f} {
  5771 	variable l
  5772 	variable x
  5773 	lappend l called
  5774 	if {[eof $f]} {
  5775 	    close $f
  5776 	    set x done
  5777 	} else {
  5778 	    gets $f
  5779 	}
  5780     }
  5781     set l ""
  5782     variable x not_done
  5783     vwait [namespace which -variable x]
  5784     list $x $l
  5785 } {done {called called called called called called called}}
  5786 test io-48.2 {testing readability conditions} {nonBlockFiles fileevent} {
  5787     set f [open $path(bar) w]
  5788     puts $f abcdefg
  5789     puts $f abcdefg
  5790     puts $f abcdefg
  5791     puts $f abcdefg
  5792     puts $f abcdefg
  5793     close $f
  5794     set f [open $path(bar) r]
  5795     fileevent $f readable [namespace code [list consume $f]]
  5796     fconfigure $f -blocking off
  5797     proc consume {f} {
  5798 	variable x
  5799 	variable l
  5800 	lappend l called
  5801 	if {[eof $f]} {
  5802 	    close $f
  5803 	    set x done
  5804 	} else {
  5805 	    gets $f
  5806 	}
  5807     }
  5808     set l ""
  5809     variable x not_done
  5810     vwait [namespace which -variable x]
  5811     list $x $l
  5812 } {done {called called called called called called called}}
  5813 
  5814 set path(my_script) [makeFile {} my_script]
  5815 
  5816 test io-48.3 {testing readability conditions} {stdio unixOnly nonBlockFiles openpipe fileevent} {
  5817     set f [open $path(bar) w]
  5818     puts $f abcdefg
  5819     puts $f abcdefg
  5820     puts $f abcdefg
  5821     puts $f abcdefg
  5822     puts $f abcdefg
  5823     close $f
  5824     set f [open $path(my_script) w]
  5825     puts $f {
  5826 	proc copy_slowly {f} {
  5827 	    while {![eof $f]} {
  5828 		puts [gets $f]
  5829 		after 200
  5830 	    }
  5831 	    close $f
  5832 	}
  5833     }
  5834     close $f
  5835     set f [open "|[list [interpreter]]" r+]
  5836     fileevent  $f readable [namespace code [list consume $f]]
  5837     fconfigure $f -buffering line
  5838     fconfigure $f -blocking off
  5839     proc consume {f} {
  5840 	variable l
  5841 	variable x
  5842 	if {[eof $f]} {
  5843 	    set x done
  5844 	} else {
  5845 	    gets $f
  5846 	    lappend l [fblocked $f]
  5847 	    gets $f
  5848 	    lappend l [fblocked $f]
  5849 	}
  5850     }
  5851     set l ""
  5852     variable x not_done
  5853     puts $f [list source $path(my_script)]
  5854     puts $f "set f \[[list open $path(bar) r]]"
  5855     puts $f {copy_slowly $f}
  5856     puts $f {exit}
  5857     vwait [namespace which -variable x]
  5858     close $f
  5859     list $x $l
  5860 } {done {0 1 0 1 0 1 0 1 0 1 0 1 0 0}}
  5861 test io-48.4 {lf write, testing readability, ^Z termination, auto read mode} {fileevent} {
  5862     file delete $path(test1)
  5863     set f [open $path(test1) w]
  5864     fconfigure $f -translation lf
  5865     variable c [format "abc\ndef\n%c" 26]
  5866     puts -nonewline $f $c
  5867     close $f
  5868     proc consume {f} {
  5869 	variable l
  5870 	variable c
  5871 	variable x
  5872 	if {[eof $f]} {
  5873 	   set x done
  5874 	   close $f
  5875 	} else {
  5876 	   lappend l [gets $f]
  5877 	   incr c
  5878 	}
  5879     }
  5880     set c 0
  5881     set l ""
  5882     set f [open $path(test1) r]
  5883     fconfigure $f -translation auto -eofchar \x1a
  5884     fileevent $f readable [namespace code [list consume $f]]
  5885     variable x
  5886     vwait [namespace which -variable x]
  5887     list $c $l
  5888 } {3 {abc def {}}}
  5889 test io-48.5 {lf write, testing readability, ^Z in middle, auto read mode} {fileevent} {
  5890     file delete $path(test1)
  5891     set f [open $path(test1) w]
  5892     fconfigure $f -translation lf
  5893     set c [format "abc\ndef\n%cfoo\nbar\n" 26]
  5894     puts -nonewline $f $c
  5895     close $f
  5896     proc consume {f} {
  5897 	variable l
  5898 	variable x
  5899 	variable c
  5900 	if {[eof $f]} {
  5901 	   set x done
  5902 	   close $f
  5903 	} else {
  5904 	   lappend l [gets $f]
  5905 	   incr c
  5906 	}
  5907     }
  5908     set c 0
  5909     set l ""
  5910     set f [open $path(test1) r]
  5911     fconfigure $f -eofchar \x1a -translation auto
  5912     fileevent $f readable [namespace code [list consume $f]]
  5913     variable x
  5914     vwait [namespace which -variable x]
  5915     list $c $l
  5916 } {3 {abc def {}}}
  5917 test io-48.6 {cr write, testing readability, ^Z termination, auto read mode} {fileevent} {
  5918     file delete $path(test1)
  5919     set f [open $path(test1) w]
  5920     fconfigure $f -translation cr
  5921     set c [format "abc\ndef\n%c" 26]
  5922     puts -nonewline $f $c
  5923     close $f
  5924     proc consume {f} {
  5925 	variable l
  5926 	variable x
  5927 	variable c
  5928 	if {[eof $f]} {
  5929 	   set x done
  5930 	   close $f
  5931 	} else {
  5932 	   lappend l [gets $f]
  5933 	   incr c
  5934 	}
  5935     }
  5936     set c 0
  5937     set l ""
  5938     set f [open $path(test1) r]
  5939     fconfigure $f -translation auto -eofchar \x1a
  5940     fileevent $f readable [namespace code [list consume $f]]
  5941     variable x
  5942     vwait [namespace which -variable x]
  5943     list $c $l
  5944 } {3 {abc def {}}}
  5945 test io-48.7 {cr write, testing readability, ^Z in middle, auto read mode} {fileevent} {
  5946     file delete $path(test1)
  5947     set f [open $path(test1) w]
  5948     fconfigure $f -translation cr
  5949     set c [format "abc\ndef\n%cfoo\nbar\n" 26]
  5950     puts -nonewline $f $c
  5951     close $f
  5952     proc consume {f} {
  5953 	variable l
  5954 	variable c
  5955 	variable x
  5956 	if {[eof $f]} {
  5957 	   set x done
  5958 	   close $f
  5959 	} else {
  5960 	   lappend l [gets $f]
  5961 	   incr c
  5962 	}
  5963     }
  5964     set c 0
  5965     set l ""
  5966     set f [open $path(test1) r]
  5967     fconfigure $f -eofchar \x1a -translation auto
  5968     fileevent $f readable [namespace code [list consume $f]]
  5969     variable x
  5970     vwait [namespace which -variable x]
  5971     list $c $l
  5972 } {3 {abc def {}}}
  5973 test io-48.8 {crlf write, testing readability, ^Z termination, auto read mode} {fileevent} {
  5974     file delete $path(test1)
  5975     set f [open $path(test1) w]
  5976     fconfigure $f -translation crlf
  5977     set c [format "abc\ndef\n%c" 26]
  5978     puts -nonewline $f $c
  5979     close $f
  5980     proc consume {f} {
  5981 	variable l
  5982 	variable x
  5983 	variable c
  5984 	if {[eof $f]} {
  5985 	   set x done
  5986 	   close $f
  5987 	} else {
  5988 	   lappend l [gets $f]
  5989 	   incr c
  5990 	}
  5991     }
  5992     set c 0
  5993     set l ""
  5994     set f [open $path(test1) r]
  5995     fconfigure $f -translation auto -eofchar \x1a
  5996     fileevent $f readable [namespace code [list consume $f]]
  5997     variable x
  5998     vwait [namespace which -variable x]
  5999     list $c $l
  6000 } {3 {abc def {}}}
  6001 test io-48.9 {crlf write, testing readability, ^Z in middle, auto read mode} {fileevent} {
  6002     file delete $path(test1)
  6003     set f [open $path(test1) w]
  6004     fconfigure $f -translation crlf
  6005     set c [format "abc\ndef\n%cfoo\nbar\n" 26]
  6006     puts -nonewline $f $c
  6007     close $f
  6008     proc consume {f} {
  6009 	variable l
  6010 	variable c
  6011 	variable x
  6012 	if {[eof $f]} {
  6013 	   set x done
  6014 	   close $f
  6015 	} else {
  6016 	   lappend l [gets $f]
  6017 	   incr c
  6018 	}
  6019     }
  6020     set c 0
  6021     set l ""
  6022     set f [open $path(test1) r]
  6023     fconfigure $f -eofchar \x1a -translation auto
  6024     fileevent $f readable [namespace code [list consume $f]]
  6025     variable x
  6026     vwait [namespace which -variable x]
  6027     list $c $l
  6028 } {3 {abc def {}}}
  6029 test io-48.10 {lf write, testing readability, ^Z in middle, lf read mode} {fileevent} {
  6030     file delete $path(test1)
  6031     set f [open $path(test1) w]
  6032     fconfigure $f -translation lf
  6033     set c [format "abc\ndef\n%cfoo\nbar\n" 26]
  6034     puts -nonewline $f $c
  6035     close $f
  6036     proc consume {f} {
  6037 	variable l
  6038 	variable c
  6039 	variable x
  6040 	if {[eof $f]} {
  6041 	   set x done
  6042 	   close $f
  6043 	} else {
  6044 	   lappend l [gets $f]
  6045 	   incr c
  6046 	}
  6047     }
  6048     set c 0
  6049     set l ""
  6050     set f [open $path(test1) r]
  6051     fconfigure $f -eofchar \x1a -translation lf
  6052     fileevent $f readable [namespace code [list consume $f]]
  6053     variable x
  6054     vwait [namespace which -variable x]
  6055     list $c $l
  6056 } {3 {abc def {}}}
  6057 test io-48.11 {lf write, testing readability, ^Z termination, lf read mode} {fileevent} {
  6058     file delete $path(test1)
  6059     set f [open $path(test1) w]
  6060     fconfigure $f -translation lf
  6061     set c [format "abc\ndef\n%c" 26]
  6062     puts -nonewline $f $c
  6063     close $f
  6064     proc consume {f} {
  6065 	variable l
  6066 	variable x
  6067 	variable c
  6068 	if {[eof $f]} {
  6069 	   set x done
  6070 	   close $f
  6071 	} else {
  6072 	   lappend l [gets $f]
  6073 	   incr c
  6074 	}
  6075     }
  6076     set c 0
  6077     set l ""
  6078     set f [open $path(test1) r]
  6079     fconfigure $f -translation lf -eofchar \x1a
  6080     fileevent $f readable [namespace code [list consume $f]]
  6081     variable x
  6082     vwait [namespace which -variable x]
  6083     list $c $l
  6084 } {3 {abc def {}}}
  6085 test io-48.12 {cr write, testing readability, ^Z in middle, cr read mode} {fileevent} {
  6086     file delete $path(test1)
  6087     set f [open $path(test1) w]
  6088     fconfigure $f -translation cr
  6089     set c [format "abc\ndef\n%cfoo\nbar\n" 26]
  6090     puts -nonewline $f $c
  6091     close $f
  6092     proc consume {f} {
  6093 	variable l
  6094 	variable x
  6095 	variable c
  6096 	if {[eof $f]} {
  6097 	   set x done
  6098 	   close $f
  6099 	} else {
  6100 	   lappend l [gets $f]
  6101 	   incr c
  6102 	}
  6103     }
  6104     set c 0
  6105     set l ""
  6106     set f [open $path(test1) r]
  6107     fconfigure $f -eofchar \x1a -translation cr
  6108     fileevent $f readable [namespace code [list consume $f]]
  6109     variable x
  6110     vwait [namespace which -variable x]
  6111     list $c $l
  6112 } {3 {abc def {}}}
  6113 test io-48.13 {cr write, testing readability, ^Z termination, cr read mode} {fileevent} {
  6114     file delete $path(test1)
  6115     set f [open $path(test1) w]
  6116     fconfigure $f -translation cr
  6117     set c [format "abc\ndef\n%c" 26]
  6118     puts -nonewline $f $c
  6119     close $f
  6120     proc consume {f} {
  6121 	variable c
  6122 	variable x
  6123 	variable l
  6124 	if {[eof $f]} {
  6125 	   set x done
  6126 	   close $f
  6127 	} else {
  6128 	   lappend l [gets $f]
  6129 	   incr c
  6130 	}
  6131     }
  6132     set c 0
  6133     set l ""
  6134     set f [open $path(test1) r]
  6135     fconfigure $f -translation cr -eofchar \x1a
  6136     fileevent $f readable [namespace code [list consume $f]]
  6137     variable x
  6138     vwait [namespace which -variable x]
  6139     list $c $l
  6140 } {3 {abc def {}}}
  6141 test io-48.14 {crlf write, testing readability, ^Z in middle, crlf read mode} {fileevent} {
  6142     file delete $path(test1)
  6143     set f [open $path(test1) w]
  6144     fconfigure $f -translation crlf
  6145     set c [format "abc\ndef\n%cfoo\nbar\n" 26]
  6146     puts -nonewline $f $c
  6147     close $f
  6148     proc consume {f} {
  6149 	variable c
  6150 	variable x
  6151 	variable l
  6152 	if {[eof $f]} {
  6153 	   set x done
  6154 	   close $f
  6155 	} else {
  6156 	   lappend l [gets $f]
  6157 	   incr c
  6158 	}
  6159     }
  6160     set c 0
  6161     set l ""
  6162     set f [open $path(test1) r]
  6163     fconfigure $f -eofchar \x1a -translation crlf
  6164     fileevent $f readable [namespace code [list consume $f]]
  6165     variable x
  6166     vwait [namespace which -variable x]
  6167     list $c $l
  6168 } {3 {abc def {}}}
  6169 test io-48.15 {crlf write, testing readability, ^Z termi, crlf read mode} {fileevent} {
  6170     file delete $path(test1)
  6171     set f [open $path(test1) w]
  6172     fconfigure $f -translation crlf
  6173     set c [format "abc\ndef\n%c" 26]
  6174     puts -nonewline $f $c
  6175     close $f
  6176     proc consume {f} {
  6177 	variable c
  6178 	variable x
  6179 	variable l
  6180 	if {[eof $f]} {
  6181 	   set x done
  6182 	   close $f
  6183 	} else {
  6184 	   lappend l [gets $f]
  6185 	   incr c
  6186 	}
  6187     }
  6188     set c 0
  6189     set l ""
  6190     set f [open $path(test1) r]
  6191     fconfigure $f -translation crlf -eofchar \x1a
  6192     fileevent $f readable [namespace code [list consume $f]]
  6193     variable x
  6194     vwait [namespace which -variable x]
  6195     list $c $l
  6196 } {3 {abc def {}}}
  6197 
  6198 test io-49.1 {testing crlf reading, leftover cr disgorgment} {
  6199     file delete $path(test1)
  6200     set f [open $path(test1) w]
  6201     fconfigure $f -translation lf
  6202     puts -nonewline $f "a\rb\rc\r\n"
  6203     close $f
  6204     set f [open $path(test1) r]
  6205     set l ""
  6206     lappend l [file size $path(test1)]
  6207     fconfigure $f -translation crlf
  6208     lappend l [read $f 1]
  6209     lappend l [tell $f]
  6210     lappend l [read $f 1]
  6211     lappend l [tell $f]
  6212     lappend l [read $f 1]
  6213     lappend l [tell $f]
  6214     lappend l [read $f 1]
  6215     lappend l [tell $f]
  6216     lappend l [read $f 1]
  6217     lappend l [tell $f]
  6218     lappend l [read $f 1]
  6219     lappend l [tell $f]
  6220     lappend l [eof $f]
  6221     lappend l [read $f 1]
  6222     lappend l [eof $f]
  6223     close $f
  6224     set l
  6225 } "7 a 1 [list \r] 2 b 3 [list \r] 4 c 5 {
  6226 } 7 0 {} 1"
  6227 test io-49.2 {testing crlf reading, leftover cr disgorgment} {
  6228     file delete $path(test1)
  6229     set f [open $path(test1) w]
  6230     fconfigure $f -translation lf
  6231     puts -nonewline $f "a\rb\rc\r\n"
  6232     close $f
  6233     set f [open $path(test1) r]
  6234     set l ""
  6235     lappend l [file size $path(test1)]
  6236     fconfigure $f -translation crlf
  6237     lappend l [read $f 2]
  6238     lappend l [tell $f]
  6239     lappend l [read $f 2]
  6240     lappend l [tell $f]
  6241     lappend l [read $f 2]
  6242     lappend l [tell $f]
  6243     lappend l [eof $f]
  6244     lappend l [read $f 2]
  6245     lappend l [tell $f]
  6246     lappend l [eof $f]
  6247     close $f
  6248     set l
  6249 } "7 [list a\r] 2 [list b\r] 4 [list c\n] 7 0 {} 7 1"
  6250 test io-49.3 {testing crlf reading, leftover cr disgorgment} {
  6251     file delete $path(test1)
  6252     set f [open $path(test1) w]
  6253     fconfigure $f -translation lf
  6254     puts -nonewline $f "a\rb\rc\r\n"
  6255     close $f
  6256     set f [open $path(test1) r]
  6257     set l ""
  6258     lappend l [file size $path(test1)]
  6259     fconfigure $f -translation crlf
  6260     lappend l [read $f 3]
  6261     lappend l [tell $f]
  6262     lappend l [read $f 3]
  6263     lappend l [tell $f]
  6264     lappend l [eof $f]
  6265     lappend l [read $f 3]
  6266     lappend l [tell $f]
  6267     lappend l [eof $f]
  6268     close $f
  6269     set l
  6270 } "7 [list a\rb] 3 [list \rc\n] 7 0 {} 7 1"
  6271 test io-49.4 {testing crlf reading, leftover cr disgorgment} {
  6272     file delete $path(test1)
  6273     set f [open $path(test1) w]
  6274     fconfigure $f -translation lf
  6275     puts -nonewline $f "a\rb\rc\r\n"
  6276     close $f
  6277     set f [open $path(test1) r]
  6278     set l ""
  6279     lappend l [file size $path(test1)]
  6280     fconfigure $f -translation crlf
  6281     lappend l [read $f 3]
  6282     lappend l [tell $f]
  6283     lappend l [gets $f]
  6284     lappend l [tell $f]
  6285     lappend l [eof $f]
  6286     lappend l [gets $f]
  6287     lappend l [tell $f]
  6288     lappend l [eof $f]
  6289     close $f
  6290     set l
  6291 } "7 [list a\rb] 3 [list \rc] 7 0 {} 7 1"
  6292 test io-49.5 {testing crlf reading, leftover cr disgorgment} {
  6293     file delete $path(test1)
  6294     set f [open $path(test1) w]
  6295     fconfigure $f -translation lf
  6296     puts -nonewline $f "a\rb\rc\r\n"
  6297     close $f
  6298     set f [open $path(test1) r]
  6299     set l ""
  6300     lappend l [file size $path(test1)]
  6301     fconfigure $f -translation crlf
  6302     lappend l [set x [gets $f]]
  6303     lappend l [tell $f]
  6304     lappend l [gets $f]
  6305     lappend l [tell $f]
  6306     lappend l [eof $f]
  6307     close $f
  6308     set l
  6309 } [list 7 a\rb\rc 7 {} 7 1]
  6310     
  6311 testConstraint testchannelevent [llength [info commands testchannelevent]]
  6312 test io-50.1 {testing handler deletion} {testchannelevent} {
  6313     file delete $path(test1)
  6314     set f [open $path(test1) w]
  6315     close $f
  6316     set f [open $path(test1) r]
  6317     testchannelevent $f add readable [namespace code [list delhandler $f]]
  6318     proc delhandler {f} {
  6319 	variable z
  6320 	set z called
  6321 	testchannelevent $f delete 0
  6322     }
  6323     set z not_called
  6324     update
  6325     close $f
  6326     set z
  6327 } called
  6328 test io-50.2 {testing handler deletion with multiple handlers} {testchannelevent} {
  6329     file delete $path(test1)
  6330     set f [open $path(test1) w]
  6331     close $f
  6332     set f [open $path(test1) r]
  6333     testchannelevent $f add readable [namespace code [list delhandler $f 1]]
  6334     testchannelevent $f add readable [namespace code [list delhandler $f 0]]
  6335     proc delhandler {f i} {
  6336 	variable z
  6337 	lappend z "called delhandler $f $i"
  6338 	testchannelevent $f delete 0
  6339     }
  6340     set z ""
  6341     update
  6342     close $f
  6343     string compare [string tolower $z] \
  6344 	[list [list called delhandler $f 0] [list called delhandler $f 1]]
  6345 } 0
  6346 test io-50.3 {testing handler deletion with multiple handlers} {testchannelevent} {
  6347     file delete $path(test1)
  6348     set f [open $path(test1) w]
  6349     close $f
  6350     set f [open $path(test1) r]
  6351     testchannelevent $f add readable [namespace code [list notcalled $f 1]]
  6352     testchannelevent $f add readable [namespace code [list delhandler $f 0]]
  6353     set z ""
  6354     proc notcalled {f i} {
  6355 	variable z
  6356 	lappend z "notcalled was called!! $f $i"
  6357     }
  6358     proc delhandler {f i} {
  6359 	variable z
  6360 	testchannelevent $f delete 1
  6361 	lappend z "delhandler $f $i called"
  6362 	testchannelevent $f delete 0
  6363 	lappend z "delhandler $f $i deleted myself"
  6364     }
  6365     set z ""
  6366     update
  6367     close $f
  6368     string compare [string tolower $z] \
  6369 	[list [list delhandler $f 0 called] \
  6370 	      [list delhandler $f 0 deleted myself]]
  6371 } 0
  6372 test io-50.4 {testing handler deletion vs reentrant calls} {testchannelevent} {
  6373     file delete $path(test1)
  6374     set f [open $path(test1) w]
  6375     close $f
  6376     set f [open $path(test1) r]
  6377     testchannelevent $f add readable [namespace code [list delrecursive $f]]
  6378     proc delrecursive {f} {
  6379 	variable z
  6380 	variable u
  6381 	if {"$u" == "recursive"} {
  6382 	    testchannelevent $f delete 0
  6383 	    lappend z "delrecursive deleting recursive"
  6384 	} else {
  6385 	    lappend z "delrecursive calling recursive"
  6386 	    set u recursive
  6387 	    update
  6388 	}
  6389     }
  6390     set u toplevel
  6391     set z ""
  6392     update
  6393     close $f
  6394     string compare [string tolower $z] \
  6395 	{{delrecursive calling recursive} {delrecursive deleting recursive}}
  6396 } 0
  6397 test io-50.5 {testing handler deletion vs reentrant calls} {testchannelevent} {
  6398     file delete $path(test1)
  6399     set f [open $path(test1) w]
  6400     close $f
  6401     set f [open $path(test1) r]
  6402     testchannelevent $f add readable [namespace code [list notcalled $f]]
  6403     testchannelevent $f add readable [namespace code [list del $f]]
  6404     proc notcalled {f} {
  6405 	variable z
  6406 	lappend z "notcalled was called!! $f"
  6407     }
  6408     proc del {f} {
  6409 	variable u
  6410 	variable z
  6411 	if {"$u" == "recursive"} {
  6412 	    testchannelevent $f delete 1
  6413 	    testchannelevent $f delete 0
  6414 	    lappend z "del deleted notcalled"
  6415 	    lappend z "del deleted myself"
  6416 	} else {
  6417 	    set u recursive
  6418 	    lappend z "del calling recursive"
  6419 	    update
  6420 	    lappend z "del after update"
  6421 	}
  6422     }
  6423     set z ""
  6424     set u toplevel
  6425     update
  6426     close $f
  6427     string compare [string tolower $z] \
  6428 	[list {del calling recursive} {del deleted notcalled} \
  6429 	      {del deleted myself} {del after update}]
  6430 } 0
  6431 test io-50.6 {testing handler deletion vs reentrant calls} {testchannelevent} {
  6432     file delete $path(test1)
  6433     set f [open $path(test1) w]
  6434     close $f
  6435     set f [open $path(test1) r]
  6436     testchannelevent $f add readable [namespace code [list second $f]]
  6437     testchannelevent $f add readable [namespace code [list first $f]]
  6438     proc first {f} {
  6439 	variable u
  6440 	variable z
  6441 	if {"$u" == "toplevel"} {
  6442 	    lappend z "first called"
  6443 	    set u first
  6444 	    update
  6445 	    lappend z "first after update"
  6446 	} else {
  6447 	    lappend z "first called not toplevel"
  6448 	}
  6449     }
  6450     proc second {f} {
  6451 	variable u
  6452 	variable z
  6453 	if {"$u" == "first"} {
  6454 	    lappend z "second called, first time"
  6455 	    set u second
  6456 	    testchannelevent $f delete 0
  6457 	} elseif {"$u" == "second"} {
  6458 	    lappend z "second called, second time"
  6459 	    testchannelevent $f delete 0
  6460 	} else {
  6461 	    lappend z "second called, cannot happen!"
  6462 	    testchannelevent $f removeall
  6463 	}
  6464     }
  6465     set z ""
  6466     set u toplevel
  6467     update
  6468     close $f
  6469     string compare [string tolower $z] \
  6470 	[list {first called} {first called not toplevel} \
  6471 	      {second called, first time} {second called, second time} \
  6472 	      {first after update}]
  6473 } 0
  6474 
  6475 test io-51.1 {Test old socket deletion on Macintosh} {socket} {
  6476     set x 0
  6477     set result ""
  6478     proc accept {s a p} {
  6479 	variable x
  6480 	variable wait
  6481 	fconfigure $s -blocking off
  6482 	puts $s "sock[incr x]"
  6483 	close $s
  6484 	set wait done
  6485     }
  6486     set ss [socket -server [namespace code accept] 0]
  6487     variable wait ""
  6488     set cs [socket [info hostname] [lindex [fconfigure $ss -sockname] 2]]
  6489     vwait [namespace which -variable wait]
  6490     lappend result [gets $cs]
  6491     close $cs
  6492 
  6493     set wait ""
  6494     set cs [socket [info hostname] [lindex [fconfigure $ss -sockname] 2]]
  6495     vwait [namespace which -variable wait]
  6496     lappend result [gets $cs]
  6497     close $cs
  6498 
  6499     set wait ""
  6500     set cs [socket [info hostname] [lindex [fconfigure $ss -sockname] 2]]
  6501     vwait [namespace which -variable wait]
  6502     lappend result [gets $cs]
  6503     close $cs
  6504 
  6505     set wait ""
  6506     set cs [socket [info hostname] [lindex [fconfigure $ss -sockname] 2]]
  6507     vwait [namespace which -variable wait]
  6508     lappend result [gets $cs]
  6509     close $cs
  6510     close $ss
  6511     set result
  6512 } {sock1 sock2 sock3 sock4}
  6513 
  6514 test io-52.1 {TclCopyChannel} {fcopy} {
  6515     file delete $path(test1)
  6516     set f1 [open $thisScript]
  6517     set f2 [open $path(test1) w]
  6518     fcopy $f1 $f2 -command { # }
  6519     catch { fcopy $f1 $f2 } msg
  6520     close $f1
  6521     close $f2
  6522     string compare $msg "channel \"$f1\" is busy"
  6523 } {0}
  6524 test io-52.2 {TclCopyChannel} {fcopy} {
  6525     file delete $path(test1)
  6526     set f1 [open $thisScript]
  6527     set f2 [open $path(test1) w]
  6528     set f3 [open $thisScript]
  6529     fcopy $f1 $f2 -command { # }
  6530     catch { fcopy $f3 $f2 } msg
  6531     close $f1
  6532     close $f2
  6533     close $f3
  6534     string compare $msg "channel \"$f2\" is busy"
  6535 } {0}
  6536 test io-52.3 {TclCopyChannel} {fcopy} {
  6537     file delete $path(test1)
  6538     set f1 [open $thisScript]
  6539     set f2 [open $path(test1) w]
  6540     fconfigure $f1 -translation lf -blocking 0
  6541     fconfigure $f2 -translation cr -blocking 0
  6542     set s0 [fcopy $f1 $f2]
  6543     set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
  6544     close $f1
  6545     close $f2
  6546     set s1 [file size $thisScript]
  6547     set s2 [file size $path(test1)]
  6548     if {("$s1" == "$s2") && ($s0 == $s1)} {
  6549         lappend result ok
  6550     }
  6551     set result
  6552 } {0 0 ok}
  6553 test io-52.4 {TclCopyChannel} {fcopy} {
  6554     file delete $path(test1)
  6555     set f1 [open $thisScript]
  6556     set f2 [open $path(test1) w]
  6557     fconfigure $f1 -translation lf -blocking 0
  6558     fconfigure $f2 -translation cr -blocking 0
  6559     fcopy $f1 $f2 -size 40
  6560     set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
  6561     close $f1
  6562     close $f2
  6563     lappend result [file size $path(test1)]
  6564 } {0 0 40}
  6565 test io-52.5 {TclCopyChannel} {fcopy} {
  6566     file delete $path(test1)
  6567     set f1 [open $thisScript]
  6568     set f2 [open $path(test1) w]
  6569     fconfigure $f1 -translation lf -blocking 0
  6570     fconfigure $f2 -translation lf -blocking 0
  6571     fcopy $f1 $f2 -size -1
  6572     set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
  6573     close $f1
  6574     close $f2
  6575     set s1 [file size $thisScript]
  6576     set s2 [file size $path(test1)]
  6577     if {"$s1" == "$s2"} {
  6578         lappend result ok
  6579     }
  6580     set result
  6581 } {0 0 ok}
  6582 test io-52.6 {TclCopyChannel} {fcopy} {
  6583     file delete $path(test1)
  6584     set f1 [open $thisScript]
  6585     set f2 [open $path(test1) w]
  6586     fconfigure $f1 -translation lf -blocking 0
  6587     fconfigure $f2 -translation lf -blocking 0
  6588     set s0 [fcopy $f1 $f2 -size [expr [file size $thisScript] + 5]]
  6589     set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
  6590     close $f1
  6591     close $f2
  6592     set s1 [file size $thisScript]
  6593     set s2 [file size $path(test1)]
  6594     if {("$s1" == "$s2") && ($s0 == $s1)} {
  6595         lappend result ok
  6596     }
  6597     set result
  6598 } {0 0 ok}
  6599 test io-52.7 {TclCopyChannel} {fcopy} {
  6600     file delete $path(test1)
  6601     set f1 [open $thisScript]
  6602     set f2 [open $path(test1) w]
  6603     fconfigure $f1 -translation lf -blocking 0
  6604     fconfigure $f2 -translation lf -blocking 0
  6605     fcopy $f1 $f2
  6606     set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
  6607     set s1 [file size $thisScript]
  6608     set s2 [file size $path(test1)]
  6609     close $f1
  6610     close $f2
  6611     if {"$s1" == "$s2"} {
  6612         lappend result ok
  6613     }
  6614     set result
  6615 } {0 0 ok}
  6616 test io-52.8 {TclCopyChannel} {stdio openpipe fcopy} {
  6617     file delete $path(test1)
  6618     file delete $path(pipe)
  6619     set f1 [open $path(pipe) w]
  6620     fconfigure $f1 -translation lf
  6621     puts $f1 "
  6622 	puts ready
  6623 	gets stdin
  6624 	set f1 \[open [list $thisScript] r\]
  6625 	fconfigure \$f1 -translation lf
  6626 	puts \[read \$f1 100\]
  6627 	close \$f1
  6628     "
  6629     close $f1
  6630     set f1 [open "|[list [interpreter] $path(pipe)]" r+]
  6631     fconfigure $f1 -translation lf
  6632     gets $f1
  6633     puts $f1 ready
  6634     flush $f1
  6635     set f2 [open $path(test1) w]
  6636     fconfigure $f2 -translation lf
  6637     set s0 [fcopy $f1 $f2 -size 40]
  6638     catch {close $f1}
  6639     close $f2
  6640     list $s0 [file size $path(test1)]
  6641 } {40 40}
  6642 
  6643 # Empty files, to register them with the test facility
  6644 set path(kyrillic.txt)   [makeFile {} kyrillic.txt]
  6645 set path(utf8-fcopy.txt) [makeFile {} utf8-fcopy.txt]
  6646 set path(utf8-rp.txt)    [makeFile {} utf8-rp.txt]
  6647 
  6648 # Create kyrillic file, use lf translation to avoid os eol issues
  6649 set out [open $path(kyrillic.txt) w]
  6650 fconfigure $out -encoding koi8-r -translation lf
  6651 puts       $out "\u0410\u0410"
  6652 close      $out
  6653 
  6654 test io-52.9 {TclCopyChannel & encodings} {fcopy} {
  6655     # Copy kyrillic to UTF-8, using fcopy.
  6656 
  6657     set in  [open $path(kyrillic.txt) r]
  6658     set out [open $path(utf8-fcopy.txt) w]
  6659 
  6660     fconfigure $in  -encoding koi8-r -translation lf
  6661     fconfigure $out -encoding utf-8 -translation lf
  6662 
  6663     fcopy $in $out
  6664     close $in
  6665     close $out
  6666 
  6667     # Do the same again, but differently (read/puts).
  6668 
  6669     set in  [open $path(kyrillic.txt) r]
  6670     set out [open $path(utf8-rp.txt) w]
  6671 
  6672     fconfigure $in  -encoding koi8-r -translation lf
  6673     fconfigure $out -encoding utf-8 -translation lf
  6674 
  6675     puts -nonewline $out [read $in]
  6676 
  6677     close $in
  6678     close $out
  6679 
  6680     list [file size $path(kyrillic.txt)] \
  6681 	    [file size $path(utf8-fcopy.txt)] \
  6682 	    [file size $path(utf8-rp.txt)]
  6683 } {3 5 5}
  6684 
  6685 test io-52.10 {TclCopyChannel & encodings} {fcopy} {
  6686     # encoding to binary (=> implies that the
  6687     # internal utf-8 is written)
  6688 
  6689     set in  [open $path(kyrillic.txt) r]
  6690     set out [open $path(utf8-fcopy.txt) w]
  6691 
  6692     fconfigure $in  -encoding koi8-r -translation lf
  6693     # -translation binary is also -encoding binary
  6694     fconfigure $out -translation binary
  6695 
  6696     fcopy $in $out
  6697     close $in
  6698     close $out
  6699 
  6700     file size $path(utf8-fcopy.txt)
  6701 } 5
  6702 
  6703 test io-52.11 {TclCopyChannel & encodings} {fcopy} {
  6704     # binary to encoding => the input has to be
  6705     # in utf-8 to make sense to the encoder
  6706 
  6707     set in  [open $path(utf8-fcopy.txt) r]
  6708     set out [open $path(kyrillic.txt) w]
  6709 
  6710     # -translation binary is also -encoding binary
  6711     fconfigure $in  -translation binary
  6712     fconfigure $out -encoding koi8-r -translation lf
  6713 
  6714     fcopy $in $out
  6715     close $in
  6716     close $out
  6717 
  6718     file size $path(kyrillic.txt)
  6719 } 3
  6720 
  6721 test io-53.1 {CopyData} {fcopy} {
  6722     file delete $path(test1)
  6723     set f1 [open $thisScript]
  6724     set f2 [open $path(test1) w]
  6725     fconfigure $f1 -translation lf -blocking 0
  6726     fconfigure $f2 -translation cr -blocking 0
  6727     fcopy $f1 $f2 -size 0
  6728     set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
  6729     close $f1
  6730     close $f2
  6731     lappend result [file size $path(test1)]
  6732 } {0 0 0}
  6733 test io-53.2 {CopyData} {fcopy} {
  6734     file delete $path(test1)
  6735     set f1 [open $thisScript]
  6736     set f2 [open $path(test1) w]
  6737     fconfigure $f1 -translation lf -blocking 0
  6738     fconfigure $f2 -translation cr -blocking 0
  6739     fcopy $f1 $f2 -command [namespace code {set s0}]
  6740     set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
  6741     variable s0
  6742     vwait [namespace which -variable s0]
  6743     close $f1
  6744     close $f2
  6745     set s1 [file size $thisScript]
  6746     set s2 [file size $path(test1)]
  6747     if {("$s1" == "$s2") && ($s0 == $s1)} {
  6748         lappend result ok
  6749     }
  6750     set result
  6751 } {0 0 ok}
  6752 test io-53.3 {CopyData: background read underflow} {stdio unixOnly openpipe fcopy} {
  6753     file delete $path(test1)
  6754     file delete $path(pipe)
  6755     set f1 [open $path(pipe) w]
  6756     puts -nonewline $f1 {
  6757 	puts ready
  6758 	flush stdout				;# Don't assume line buffered!
  6759 	fcopy stdin stdout -command { set x }
  6760 	vwait x
  6761 	set f [}
  6762     puts $f1 [list open $path(test1) w]]
  6763     puts $f1 {
  6764 	fconfigure $f -translation lf
  6765 	puts $f "done"
  6766 	close $f
  6767     }
  6768     close $f1
  6769     set f1 [open "|[list [interpreter] $path(pipe)]" r+]
  6770     set result [gets $f1]
  6771     puts $f1 line1
  6772     flush $f1
  6773     lappend result [gets $f1]
  6774     puts $f1 line2
  6775     flush $f1
  6776     lappend result [gets $f1]
  6777     close $f1
  6778     after 500
  6779     set f [open $path(test1)]
  6780     lappend result [read $f]
  6781     close $f
  6782     set result
  6783 } "ready line1 line2 {done\n}"
  6784 test io-53.4 {CopyData: background write overflow} {stdio unixOnly openpipe fileevent fcopy} {
  6785     set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n
  6786     variable x
  6787     for {set x 0} {$x < 12} {incr x} {
  6788 	append big $big
  6789     }
  6790     file delete $path(test1)
  6791     file delete $path(pipe)
  6792     set f1 [open $path(pipe) w]
  6793     puts $f1 {
  6794 	puts ready
  6795 	fcopy stdin stdout -command { set x }
  6796 	vwait x
  6797 	set f [open $path(test1) w]
  6798 	fconfigure $f -translation lf
  6799 	puts $f "done"
  6800 	close $f
  6801     }
  6802     close $f1
  6803     set f1 [open "|[list [interpreter] $path(pipe)]" r+]
  6804     set result [gets $f1]
  6805     fconfigure $f1 -blocking 0
  6806     puts $f1 $big
  6807     flush $f1
  6808     after 500
  6809     set result ""
  6810     fileevent $f1 read [namespace code {
  6811 	append result [read $f1 1024]
  6812 	if {[string length $result] >= [string length $big]} {
  6813 	    set x done
  6814 	}
  6815     }]
  6816     vwait [namespace which -variable x]
  6817     close $f1
  6818     set big {}
  6819     set x
  6820 } done
  6821 set result {}
  6822 
  6823 proc FcopyTestAccept {sock args} {
  6824     after 1000 "close $sock"
  6825 }
  6826 proc FcopyTestDone {bytes {error {}}} {
  6827     variable fcopyTestDone
  6828     if {[string length $error]} {
  6829 	set fcopyTestDone 1
  6830     } else {
  6831 	set fcopyTestDone 0
  6832     }
  6833 }
  6834 
  6835 test io-53.5 {CopyData: error during fcopy} {socket fcopy} {
  6836     variable fcopyTestDone
  6837     set listen [socket -server [namespace code FcopyTestAccept] 0]
  6838     set in [open $thisScript]	;# 126 K
  6839     set out [socket 127.0.0.1 [lindex [fconfigure $listen -sockname] 2]]
  6840     catch {unset fcopyTestDone}
  6841     close $listen	;# This means the socket open never really succeeds
  6842     fcopy $in $out -command [namespace code FcopyTestDone]
  6843     variable fcopyTestDone
  6844     if ![info exists fcopyTestDone] {
  6845 	vwait [namespace which -variable fcopyTestDone]		;# The error occurs here in the b.g.
  6846     }
  6847     close $in
  6848     close $out
  6849     set fcopyTestDone	;# 1 for error condition
  6850 } 1
  6851 test io-53.6 {CopyData: error during fcopy} {stdio openpipe fcopy} {
  6852     variable fcopyTestDone
  6853     file delete $path(pipe)
  6854     file delete $path(test1)
  6855     catch {unset fcopyTestDone}
  6856     set f1 [open $path(pipe) w]
  6857     puts $f1 "exit 1"
  6858     close $f1
  6859     set in [open "|[list [interpreter] $path(pipe)]" r+]
  6860     set out [open $path(test1) w]
  6861     fcopy $in $out -command [namespace code FcopyTestDone]
  6862     variable fcopyTestDone
  6863     if ![info exists fcopyTestDone] {
  6864 	vwait [namespace which -variable fcopyTestDone]
  6865     }
  6866     catch {close $in}
  6867     close $out
  6868     set fcopyTestDone	;# 0 for plain end of file
  6869 } {0}
  6870 
  6871 proc doFcopy {in out {bytes 0} {error {}}} {
  6872     variable fcopyTestDone
  6873     variable fcopyTestCount
  6874     incr fcopyTestCount $bytes
  6875     if {[string length $error]} {
  6876 	    set fcopyTestDone 1
  6877     } elseif {[eof $in]} {
  6878 	    set fcopyTestDone 0
  6879     } else {
  6880         # Delay next fcopy to wait for size>0 input bytes
  6881         after 100 [list 
  6882             fcopy $in $out -size 1000 \
  6883 		    -command [namespace code [list doFcopy $in $out]]
  6884         ]
  6885     }
  6886 }
  6887 
  6888 test io-53.7 {CopyData: Flooding fcopy from pipe} {stdio openpipe fcopy} {
  6889     variable fcopyTestDone
  6890     file delete $path(pipe)
  6891     catch {unset fcopyTestDone}
  6892     set fcopyTestCount 0
  6893     set f1 [open $path(pipe) w]
  6894     puts $f1 {
  6895 	# Write  10 bytes / 10 msec
  6896 	proc Write {count} {
  6897 	    puts -nonewline "1234567890"
  6898 	    if {[incr count -1]} {
  6899 	        after 10 [list Write $count]
  6900 	    } else {
  6901 	        set ::ready 1
  6902 	    }
  6903 	}
  6904 	fconfigure stdout -buffering none
  6905 	Write 345 ;# 3450 bytes ~3.45 sec
  6906 	vwait ready
  6907 	exit 0
  6908     }
  6909     close $f1
  6910     set in [open "|[list [interpreter] $path(pipe) &]" r+]
  6911     set out [open $path(test1) w]
  6912     doFcopy $in $out
  6913     variable fcopyTestDone
  6914     if ![info exists fcopyTestDone] {
  6915 	vwait [namespace which -variable fcopyTestDone]
  6916     }
  6917     catch {close $in}
  6918     close $out
  6919     # -1=error 0=script error N=number of bytes
  6920     expr ($fcopyTestDone == 0) ? $fcopyTestCount : -1
  6921 } {3450}
  6922 
  6923 test io-54.1 {Recursive channel events} {socket fileevent} {
  6924     # This test checks to see if file events are delivered during recursive
  6925     # event loops when there is buffered data on the channel.
  6926 
  6927     proc accept {s a p} {
  6928 	variable as
  6929 	fconfigure $s -translation lf
  6930 	puts $s "line 1\nline2\nline3"
  6931 	flush $s
  6932 	set as $s
  6933     }
  6934     proc readit {s next} {
  6935 	variable x
  6936 	variable result
  6937 	lappend result $next
  6938 	if {$next == 1} {
  6939 	    fileevent $s readable [namespace code [list readit $s 2]]
  6940 	    vwait [namespace which -variable x]
  6941 	}
  6942 	incr x
  6943     }
  6944     set ss [socket -server [namespace code accept] 0]
  6945 
  6946     # We need to delay on some systems until the creation of the
  6947     # server socket completes.
  6948 
  6949     set done 0
  6950     for {set i 0} {$i < 10} {incr i} {
  6951 	if {![catch {set cs [socket [info hostname] [lindex [fconfigure $ss -sockname] 2]]}]} {
  6952 	    set done 1
  6953 	    break
  6954 	}
  6955 	after 100
  6956     }
  6957     if {$done == 0} {
  6958 	close $ss
  6959 	error "failed to connect to server"
  6960     }
  6961     variable result {}
  6962     variable x 0
  6963     variable as
  6964     vwait [namespace which -variable as]
  6965     fconfigure $cs -translation lf
  6966     lappend result [gets $cs]
  6967     fconfigure $cs -blocking off
  6968     fileevent $cs readable [namespace code [list readit $cs 1]]
  6969     set a [after 2000 [namespace code { set x failure }]]
  6970     vwait [namespace which -variable x]
  6971     after cancel $a
  6972     close $as
  6973     close $ss
  6974     close $cs
  6975     list $result $x
  6976 } {{{line 1} 1 2} 2}
  6977 test io-54.2 {Testing for busy-wait in recursive channel events} {socket fileevent} {
  6978     set accept {}
  6979     set after {}
  6980     variable s [socket -server [namespace code accept] 0]
  6981     proc accept {s a p} {
  6982 	variable counter
  6983 	variable accept
  6984 
  6985 	set accept $s
  6986 	set counter 0
  6987 	fconfigure $s -blocking off -buffering line -translation lf
  6988 	fileevent $s readable [namespace code "doit $s"]
  6989     }
  6990     proc doit {s} {
  6991 	variable counter
  6992 	variable after
  6993 
  6994 	incr counter
  6995 	set l [gets $s]
  6996 	if {"$l" == ""} {
  6997 	    fileevent $s readable [namespace code "doit1 $s"]
  6998 	    set after [after 1000 [namespace code newline]]
  6999 	}
  7000     }
  7001     proc doit1 {s} {
  7002 	variable counter
  7003 	variable accept
  7004 
  7005 	incr counter
  7006 	set l [gets $s]
  7007 	close $s
  7008 	set accept {}
  7009     }
  7010     proc producer {} {
  7011 	variable s
  7012 	variable writer
  7013 
  7014 	set writer [socket 127.0.0.1 [lindex [fconfigure $s -sockname] 2]]
  7015 	fconfigure $writer -buffering line
  7016 	puts -nonewline $writer hello
  7017 	flush $writer
  7018     }
  7019     proc newline {} {
  7020 	variable done
  7021 	variable writer
  7022 
  7023 	puts $writer hello
  7024 	flush $writer
  7025 	set done 1
  7026     }
  7027     producer
  7028     variable done
  7029     vwait [namespace which -variable done]
  7030     close $writer
  7031     close $s
  7032     after cancel $after
  7033     if {$accept != {}} {close $accept}
  7034     set counter
  7035 } 1
  7036 
  7037 set path(fooBar) [makeFile {} fooBar]
  7038 
  7039 test io-55.1 {ChannelEventScriptInvoker: deletion} {fileevent} {
  7040     variable x
  7041     proc eventScript {fd} {
  7042 	variable x
  7043 	close $fd
  7044 	error "planned error"
  7045 	set x whoops
  7046     }
  7047     proc ::bgerror {args} "set [namespace which -variable x] got_error"
  7048     set f [open $path(fooBar) w]
  7049     fileevent $f writable [namespace code [list eventScript $f]]
  7050     variable x not_done
  7051     vwait [namespace which -variable x]
  7052     set x
  7053 } {got_error}
  7054 
  7055 test io-56.1 {ChannelTimerProc} {testchannelevent} {
  7056     set f [open $path(fooBar) w]
  7057     puts $f "this is a test"
  7058     close $f
  7059     set f [open $path(fooBar) r]
  7060     testchannelevent $f add readable [namespace code {
  7061 	read $f 1
  7062 	incr x
  7063     }]
  7064     variable x 0
  7065     vwait [namespace which -variable x]
  7066     vwait [namespace which -variable x]
  7067     set result $x
  7068     testchannelevent $f set 0 none
  7069     after idle [namespace code {set y done}]
  7070     variable y
  7071     vwait [namespace which -variable y]
  7072     close $f
  7073     lappend result $y
  7074 } {2 done}
  7075 
  7076 test io-57.1 {buffered data and file events, gets} {fileevent} {
  7077     proc accept {sock args} {
  7078 	variable s2
  7079 	set s2 $sock
  7080     }
  7081     set server [socket -server [namespace code accept] 0]
  7082     set s [socket 127.0.0.1 [lindex [fconfigure $server -sockname] 2]]
  7083     variable s2
  7084     vwait [namespace which -variable s2]
  7085     update
  7086     fileevent $s2 readable [namespace code {lappend result readable}]
  7087     puts $s "12\n34567890"
  7088     flush $s
  7089     variable result [gets $s2]
  7090     after 1000 [namespace code {lappend result timer}]
  7091     vwait [namespace which -variable result]
  7092     lappend result [gets $s2]
  7093     vwait [namespace which -variable result]
  7094     close $s
  7095     close $s2
  7096     close $server
  7097     set result
  7098 } {12 readable 34567890 timer}
  7099 test io-57.2 {buffered data and file events, read} {fileevent} {
  7100     proc accept {sock args} {
  7101 	variable s2
  7102 	set s2 $sock
  7103     }
  7104     set server [socket -server [namespace code accept] 0]
  7105     set s [socket 127.0.0.1 [lindex [fconfigure $server -sockname] 2]]
  7106     variable s2
  7107     vwait [namespace which -variable s2]
  7108     update
  7109     fileevent $s2 readable [namespace code {lappend result readable}]
  7110     puts -nonewline $s "1234567890"
  7111     flush $s
  7112     variable result [read $s2 1]
  7113     after 1000 [namespace code {lappend result timer}]
  7114     vwait [namespace which -variable result]
  7115     lappend result [read $s2 9]
  7116     vwait [namespace which -variable result]
  7117     close $s
  7118     close $s2
  7119     close $server
  7120     set result
  7121 } {1 readable 234567890 timer}
  7122         
  7123 test io-58.1 {Tcl_NotifyChannel and error when closing} {stdio unixOrPc openpipe fileevent} {
  7124     set out [open $path(script) w]
  7125     puts $out {
  7126 	puts "normal message from pipe"
  7127 	puts stderr "error message from pipe"
  7128 	exit 1
  7129     }
  7130     proc readit {pipe} {
  7131 	variable x
  7132 	variable result
  7133 	if {[eof $pipe]} {
  7134 	    set x [catch {close $pipe} line]
  7135 	    lappend result catch $line
  7136 	} else {
  7137 	    gets $pipe line
  7138 	    lappend result gets $line
  7139 	}
  7140     }
  7141     close $out
  7142     set pipe [open "|[list [interpreter] $path(script)]" r]
  7143     fileevent $pipe readable [namespace code [list readit $pipe]]
  7144     variable x ""
  7145     set result ""
  7146     vwait [namespace which -variable x]
  7147     list $x $result
  7148 } {1 {gets {normal message from pipe} gets {} catch {error message from pipe}}}
  7149 
  7150 
  7151 testConstraint testmainthread [llength [info commands testmainthread]]
  7152 test io-59.1 {Thread reference of channels} {testmainthread testchannel} {
  7153     # TIP #10
  7154     # More complicated tests (like that the reference changes as a
  7155     # channel is moved from thread to thread) can be done only in the
  7156     # extension which fully implements the moving of channels between
  7157     # threads, i.e. 'Threads'. Or we have to extend [testthread] as well.
  7158 
  7159     set f [open $path(longfile) r]
  7160     set result [testchannel mthread $f]
  7161     close $f
  7162     string equal $result [testmainthread]
  7163 } {1}
  7164 
  7165 
  7166 test io-60.1 {writing illegal utf sequences} {openpipe fileevent} {
  7167     # This test will hang in older revisions of the core.
  7168 
  7169     set out [open $path(script) w]
  7170     puts $out {
  7171 	puts [encoding convertfrom identity \xe2]
  7172 	exit 1
  7173     }
  7174     proc readit {pipe} {
  7175 	variable x
  7176 	variable result
  7177 	if {[eof $pipe]} {
  7178 	    set x [catch {close $pipe} line]
  7179 	    lappend result catch $line
  7180 	} else {
  7181 	    gets $pipe line
  7182 	    lappend result gets $line
  7183 	}
  7184     }
  7185     close $out
  7186     set pipe [open "|[list [interpreter] $path(script)]" r]
  7187     fileevent $pipe readable [namespace code [list readit $pipe]]
  7188     variable x ""
  7189     set result ""
  7190     vwait [namespace which -variable x]
  7191 
  7192     # cut of the remainder of the error stack, especially the filename
  7193     set result [lreplace $result 3 3 [lindex [split [lindex $result 3] \n] 0]]
  7194     list $x $result
  7195 } {1 {gets {} catch {error writing "stdout": invalid argument}}}
  7196 
  7197 test io-61.1 {Reset eof state after changing the eof char} -setup {
  7198     set datafile [makeFile {} eofchar]
  7199     set f [open $datafile w]
  7200     fconfigure $f -translation binary
  7201     puts -nonewline $f [string repeat "Ho hum\n" 11]
  7202     puts $f =
  7203     set line [string repeat "Ge gla " 4]
  7204     puts -nonewline $f [string repeat [string trimright $line]\n 834]
  7205     close $f
  7206 } -body {
  7207     set f [open $datafile r]
  7208     fconfigure $f -eofchar =
  7209     set res {}
  7210     lappend res [read $f; tell $f]
  7211     fconfigure $f -eofchar {}
  7212     lappend res [read $f 1]
  7213     lappend res [read $f; tell $f]
  7214     # Any seek zaps the internals into a good state.
  7215     #seek $f 0 start
  7216     #seek $f 0 current
  7217     #lappend res [read $f; tell $f]
  7218     close $f
  7219     set res
  7220 } -cleanup {
  7221     removeFile eofchar
  7222 } -result {77 = 23431}
  7223 
  7224 # cleanup
  7225 foreach file [list fooBar longfile script output test1 pipe my_script foo \
  7226 	bar test2 test3 cat stdout kyrillic.txt utf8-fcopy.txt utf8-rp.txt] {
  7227     removeFile $file
  7228 }
  7229 cleanupTests
  7230 }
  7231 namespace delete ::tcl::test::io
  7232 return