Version 13 of close

Updated 2011-04-05 17:36:08 by Lordmundi
close channelId ?r(ead)|w(rite)?'

DESCRIPTION

This Tcl command closes the channel given by channelId.

ChannelId must be an identifier for an open channel such as a Tcl standard channel (stdin, stdout, or stderr), the return value from an invocation of open or socket, or the result of a channel creation command provided by a Tcl extension.

If r (or read) is present and channelId was opened bidirectionally, then the channel will be “half-closed” so that it becomes only possible to write to it. Conversely with w (or write) which closes the reader side of a bidirectional channel. This is particularly useful with a pipe or socket.

MAN PAGE

http://www.tcl.tk/man/tcl8.5/TclCmd/close.htm

SEE ALSO

file, open, socket, eof, channel, exec, stderr

EXAMPLES

 set fh [open output.txt r]
 set data [read $fh]
 close $fh

LV What are the ramifications if you don't close a file in Tcl? Any? I assume a memory leak in long running daemon type apps...


glennj: When working with pipes (i.e. [set pipe [open "| some command"]]]), and the pipe is blocking (i.e. [fconfigure $pipe -blocking yes] which is the default), then [close $pipe] throws an error if the command exited with non-zero status or if the command sent any output to stderr.

example:

 set command {sh -c {echo "to stdout"; echo >&2 "to stderr"; exit 42}}
 set pipe [open "| $command"]
 set standard_output [read -nonewline $pipe]
 set exit_status 0
 if {[catch {close $pipe} standard_error] != 0} {
     global errorCode
     if {"CHILDSTATUS" == [lindex $errorCode 0]} {
         set exit_status [lindex $errorCode 2]
     }
 }
 puts "exit status is $exit_status"
 puts "captured standard output: {$standard_output}"
 puts "captured standard error: {$standard_error}"

Output is:

 exit status is 42
 captured standard output: {to stdout}
 captured standard error: {to stderr}

AMG: TIP #332 "Half-Close for Bidirectional Channels" [L1 ] adds an optional argument to specify which direction of the channel to close, like the shutdown(2) system call [L2 ].

close channel ?read|write?


Lordmundi (2011-04-05): My google searches haven't been very fruitful, but is there any way to detect that a peer closed the connection before issuing the close on the socket?

For example, I have a tcl web server which works will with most browsers, but when using wget, apparently it (wget) will close the socket as soon as it sees 404 in the header. So after i'm done writing all this output information to the socket, when i run close $sock i get an error saying "connection reset by peer".

I'd like to be able to detect this if I could, but eof $sock doesn't return true and neither does fblocked $sock. Should I just wrap the close in a catch and forget about it? Or is there some cleanup i should be doing if the client closes the socket ahead of me?