if 0 {[Richard Suchenwirth] 2004-01-25 - It is very standard I/O to read a line from standard input with [gets] - but older [wish]es on Windows, or the Keuchel port on [Windows/CE] don't allow this: either stdin reports EOF, or the channel name is not even known. Here is a workaround that creates a toplevel window with an entry, which is returned to the caller (and the window destroyed) once is hit. It solved the [gets] inability both on my W95 box and my [PocketPC]. First we have to save the original [gets], as it may still be needed for file I/O, by renaming it into the tcl namespace:} if {[info command tcl::gets] eq ""} {rename gets tcl::gets} # This is the substitute (workaround) which discriminates use cases: proc gets {chan {varN ""}} { if {$varN ne ""} {upvar 1 $varN var} if {$chan ne "stdin"} { if {$varN ne ""} { tcl::gets $chan $var ;# return character count } else { tcl::gets $chan ;# return the string } } else { set var [gets_window] ;# always return string } } # And now for the minimal dialog window: proc gets_window {{echo 1}} { set w [toplevel .[clock clicks]] wm title $w gets: pack [entry $w.e -textvar gets_w -width 42] set ::gets_w "" raise $w focus $w.e bind $w {set getsw_done 1} vwait ::getsw_done destroy $w if $echo {puts $::gets_w} set ::gets_w } Here is a simpler rewrite, all in one proc (and this returns string length if called with a variable name): proc gets {channel {var {}}} { if {$var ne ""} {upvar 1 $var v} if {$channel eq "stdin"} { toplevel .gets pack [entry .gets.e -width 45] bind .gets.e {set gets 1} set f [focus] focus .gets.e vwait ::gets set res [.gets.e get] destroy .gets focus $f if {$var ne ""} { set v $res; string length $v } else {set res} } else { uplevel 1 tcl::[info level 0] } } ---- [RS] 2005-02-09: Here's a variant that uses the Windows/Mac [console]: if {[info command tcl::gets] eq ""} {rename gets tcl::gets} proc gets {chan {varN ""}} { if {$varN ne ""} {upvar 1 $varN var} if {$chan ne "stdin"} { if {$varN ne ""} { tcl::gets $chan $var ;# return character count } else { tcl::gets $chan ;# return the string } } else { gets_window set var [console eval {set ::consolegets}] ;# always return string } } proc gets_window {} { console show console eval { .console insert end "\n% " .console see end .console mark set insert end-1c .console mark set begin end-2c focus .console bind .console { set consolegets [.console get begin+1c end-1c];break } vwait ::consolegets consoleinterp eval {raise .} } }