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