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