From 2a0402cd1ade0a1641a24c5ba8d9f11c247ef0b8 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 4 Jun 2024 12:19:02 +0000 Subject: Let's review the chan.n changes in 8.7/trunk (which were never backported to 8.6) --- doc/chan.n | 1116 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 639 insertions(+), 477 deletions(-) diff --git a/doc/chan.n b/doc/chan.n index d78c445..3495924 100644 --- a/doc/chan.n +++ b/doc/chan.n @@ -1,6 +1,5 @@ '\" '\" Copyright (c) 2005-2006 Donal K. Fellows -'\" Copyright (c) 2021 Nathan Coulter '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -9,166 +8,191 @@ .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME -chan \- Reads, writes and manipulates channels. +chan \- Read, write and manipulate channels .SH SYNOPSIS -\fBchan \fIoperation\fR ?\fIarg arg ...\fR? +\fBchan \fIoption\fR ?\fIarg arg ...\fR? .BE .SH DESCRIPTION .PP -\fBchan\fR provides several operations for reading from, writing to, and -otherwise manipulating channels, e.g. those created by \fBopen\fR and -\fBsocket\fR, or the default channels \fBstdin\fR, \fBstdout\fR or \fBstderr\fR -which correspond respectively to the standard input, output, and error streams -of the process. Any unique abbreviation for \fIoperation\fR is acceptable. -Available operations are: -.TP -\fBchan blocked \fIchannelName\fR -. -Returns 1 when the channel is in non-blocking mode and the last input operation -on the channel failed because it would have otherwise caused the process to -block, and 0 otherwise. Each Tcl channel is in blocking mode unless configured -otherwise. -.TP -\fBchan close \fIchannelName\fR ?\fIdirection\fR? -. -Closes and destroys the named channel, deleting any existing event handlers -established for the channel, and returns the empty string. If \fIdirection\fR is -given, it is -.QW\fBread\fR -or -.QW\fBwrite\fR -or any unique abbreviation of those words, and only that side of the channel is -closed. I.e. a read-write channel may become read-only or write-only. -Closing a read-only channel for reading, or closing a write-only channel for -writing is the same as simply closing the channel. It is an error to close a -read-only channel for writing or to close a write-only channel for reading. +This command provides several operations for reading from, writing to +and otherwise manipulating open channels (such as have been created +with the \fBopen\fR and \fBsocket\fR commands, or the default named +channels \fBstdin\fR, \fBstdout\fR or \fBstderr\fR which correspond to +the process's standard input, output and error streams respectively). +\fIOption\fR indicates what to do with the channel; any unique +abbreviation for \fIoption\fR is acceptable. Valid options are: +.TP +\fBchan blocked \fIchannelId\fR +. +This tests whether the last input operation on the channel called +\fIchannelId\fR failed because it would have otherwise caused the +process to block, and returns 1 if that was the case. It returns 0 +otherwise. Note that this only ever returns 1 when the channel has +been configured to be non-blocking; all Tcl channels have blocking +turned on by default. +.TP +\fBchan close \fIchannelId\fR ?\fIdirection\fR? +. +Close and destroy the channel called \fIchannelId\fR. Note that this +deletes all existing file-events registered on the channel. +If the \fIdirection\fR argument (which must be \fBread\fR or \fBwrite\fR or +any unique abbreviation of them) is present, the channel will only be +half-closed, so that it can go from being read-write to write-only or +read-only respectively. If a read-only channel is closed for reading, it is +the same as if the channel is fully closed, and respectively similar for +write-only channels. Without the \fIdirection\fR argument, the channel is +closed for both reading and writing (but only if those directions are +currently open). It is an error to close a read-only channel for writing, or a +write-only channel for reading. .RS .PP -When a channel is closed for writing, any buffered output on the channel is -flushed. When a channel is closed for reading, any buffered input is discarded. -When a channel is destroyed the underlying resource is closed and the channel -is thereafter unavailable. -.PP -\fBchan close\fR fully flushes any output before closing the write side of a -channel unless it is non-blocking mode, where it returns immediately and the -channel is flushed in the background before finally being closed. -.PP -\fBchan close\fR may return an error if an error occurs while flushing -output. If a process in a command pipeline created by \fBopen\fR returns an -error (either by returning a non-zero exit code or writing to its standard -error file descriptor), \fBchan close\fR generates an error in the same -manner as \fBexec\fR. -.PP -Closing one side of a socket or command pipeline may lead to the shutdown() or -close() of the underlying system resource, leading to a reaction from whatever -is on the other side of the pipeline or socket. -.PP -If the channel for a command pipeline is in blocking mode, \fBchan close\fR -waits for the connected processes to complete. -.PP -\fBchan close\fR only affects the current interpreter. If the channel is open -in any other interpreter, its state is unchanged there. See \fBinterp\fR for a -description of channel sharing. -.PP -When the last interpreter sharing a channel is destroyed, the channel is -switched to blocking mode and fully flushed and then closed. -.PP -Channels are automatically closed when an interpreter is destroyed and -when the process exits. -From 8.6 on (TIP#398), nonblocking channels are no longer switched to -blocking mode when exiting; this guarantees a timely exit even when the -peer or a communication channel is stalled. To ensure proper flushing of -stalled nonblocking channels on exit, one must now either (a) actively -switch them back to blocking or (b) use the environment variable -\fBTCL_FLUSH_NONBLOCKING_ON_EXIT\fR, which when set and not equal to -.QW \fB0\fR -restores the previous behavior. +As part of closing the channel, all buffered output is flushed to the +channel's output device (only if the channel is ceasing to be writable), any +buffered input is discarded (only if the channel is ceasing to be readable), +the underlying operating system resource is closed and \fIchannelId\fR becomes +unavailable for future use (both only if the channel is being completely +closed). +.PP +If the channel is blocking and the channel is ceasing to be writable, the +command does not return until all output is flushed. If the channel is +non-blocking and there is unflushed output, the channel remains open and the +command returns immediately; output will be flushed in the background and the +channel will be closed when all the flushing is complete. +.PP +If \fIchannelId\fR is a blocking channel for a command pipeline then +\fBchan close\fR waits for the child processes to complete. +.PP +If the channel is shared between interpreters, then \fBchan close\fR +makes \fIchannelId\fR unavailable in the invoking interpreter but has +no other effect until all of the sharing interpreters have closed the +channel. When the last interpreter in which the channel is registered +invokes \fBchan close\fR (or \fBclose\fR), the cleanup actions +described above occur. With half-closing, the half-close of the channel only +applies to the current interpreter's view of the channel until all channels +have closed it in that direction (or completely). +See the \fBinterp\fR command for a description of channel sharing. +.PP +Channels are automatically fully closed when an interpreter is destroyed and +when the process exits. Channels are switched to blocking mode, to +ensure that all output is correctly flushed before the process exits. +.PP +The command returns an empty string, and may generate an error if +an error occurs while flushing output. If a command in a command +pipeline created with \fBopen\fR returns an error, \fBchan close\fR +generates an error (similar to the \fBexec\fR command.) +.PP +Note that half-closes of sockets and command pipelines can have important side +effects because they result in a shutdown() or close() of the underlying +system resource, which can change how other processes or systems respond to +the Tcl program. .RE .TP -\fBchan configure \fIchannelName\fR ?\fIoptionName\fR? ?\fIvalue\fR? ?\fIoptionName value\fR?... +\fBchan configure \fIchannelId\fR ?\fIoptionName\fR? ?\fIvalue\fR? ?\fIoptionName value\fR?... . -Configures or reports the configuration of \fIchannelName\fR. +Query or set the configuration options of the channel named +\fIchannelId\fR. .RS .PP -If no \fIoptionName\fR or \fIvalue\fR arguments are given, -\fBchan configure\fR returns a dictionary of option names and -values for the channel. If \fIoptionName\fR is supplied without a \fIvalue\fR, -\fBchan configure\fR returns the current value of the named option. If one or -more pairs of \fIoptionName\fR and \fIvalue\fR are supplied, -\fBchan configure\fR sets each of the named options to the corresponding -\fIvalue\fR and returns the empty string. -.PP -The options described below are supported for all channels. Each type of -channel may provide additional options. Those options are described in the -relevant documentation. For example, additional options are documented for -\fBsocket\fR, and also for serial devices at \fBopen\fR. +If no \fIoptionName\fR or \fIvalue\fR arguments are supplied, the +command returns a list containing alternating option names and values +for the channel. If \fIoptionName\fR is supplied but no \fIvalue\fR +then the command returns the current value of the given option. If +one or more pairs of \fIoptionName\fR and \fIvalue\fR are supplied, +the command sets each of the named options to the corresponding +\fIvalue\fR; in this case the return value is an empty string. +.PP +The options described below are supported for all channels. In +addition, each channel type may add options that only it supports. See +the manual entry for the command that creates each type of channel +for the options supported by that specific type of channel. For +example, see the manual entry for the \fBsocket\fR command for additional +options for sockets, and the \fBopen\fR command for additional options for +serial devices. .TP \fB\-blocking\fR \fIboolean\fR . -If \fB\-blocking\fR is set to \fBtrue\fR, which is the default, reading from or -writing to the channel may cause the process to block indefinitely. Otherwise, -operations such as \fBchan gets\fR, \fBchan read\fR, \fBchan puts\fR, \fBchan -flush\fR, and \fBchan close\fR take care not to block. Non-blocking mode in -generally requires that the event loop is entered, e.g. by calling -\fBTcl_DoOneEvent\fR or \fBvwait\fR or by using Tk, to give Tcl a chance to -process events on the channel. +The \fB\-blocking\fR option determines whether I/O operations on the +channel can cause the process to block indefinitely. The value of the +option must be a proper boolean value. Channels are normally in +blocking mode; if a channel is placed into non-blocking mode it will +affect the operation of the \fBchan gets\fR, \fBchan read\fR, \fBchan +puts\fR, \fBchan flush\fR, and \fBchan close\fR commands; see the +documentation for those commands for details. For non-blocking mode to +work correctly, the application must be using the Tcl event loop +(e.g. by calling \fBTcl_DoOneEvent\fR or invoking the \fBvwait\fR +command). .TP \fB\-buffering\fR \fInewValue\fR . -If \fInewValue\fR is \fBfull\fR, which is the default, output is buffered -until the internal buffer is full or until \fBchan flush\fR is called. If -\fInewValue\fR is \fBline\fR, output is flushed each time a end-of-line -character is written. If \fInewValue\fR is \fBnone\fR, output is flushed after -every output operation. For \fBstdin\fR, \fBstdout\fR, and channels that -connect to terminal-like devices, the default value is \fBline\fR. For -\fBstderr\fR the default value is \fBnone\fR. +If \fInewValue\fR is \fBfull\fR then the I/O system will buffer output +until its internal buffer is full or until the \fBchan flush\fR +command is invoked. If \fInewValue\fR is \fBline\fR, then the I/O +system will automatically flush output for the channel whenever a +newline character is output. If \fInewValue\fR is \fBnone\fR, the I/O +system will flush automatically after every output operation. The +default is for \fB\-buffering\fR to be set to \fBfull\fR except for +channels that connect to terminal-like devices; for these channels the +initial setting is \fBline\fR. Additionally, \fBstdin\fR and +\fBstdout\fR are initially set to \fBline\fR, and \fBstderr\fR is set +to \fBnone\fR. .TP \fB\-buffersize\fR \fInewSize\fR . -\fInewSize\fR, an integer no greater than one million, is the size in bytes of -any input or output buffers subsequently allocated for this channel. -.TP -\fB\-encoding\fR ?\fIname\fR? -. -Sets the encoding of the channel. \fIname\fR is either one of the names -returned by \fBencoding names\fR, or -.QW \fBbinary\fR -\&. Input is converted from the encoding into Unicode, and output is converted -from Unicode to the encoding. +\fINewvalue\fR must be an integer; its value is used to set the size +of buffers, in bytes, subsequently allocated for this channel to store +input or output. \fINewvalue\fR must be a number of no more than one +million, allowing buffers of up to one million bytes in size. +.TP +\fB\-encoding\fR \fIname\fR +. +This option is used to specify the encoding of the channel as one of +the named encodings returned by \fBencoding names\fR or the special +value \fBbinary\fR, so that the data can be converted to and from +Unicode for use in Tcl. For instance, in order for Tcl to read +characters from a Japanese file in \fBshiftjis\fR and properly process +and display the contents, the encoding would be set to \fBshiftjis\fR. +Thereafter, when reading from the channel, the bytes in the Japanese +file would be converted to Unicode as they are read. Writing is also +supported \- as Tcl strings are written to the channel they will +automatically be converted to the specified encoding on output. .RS .PP -\fBbinary\fR is an alias for \fBiso8859-1\fR: Each byte read from the -channel becomes the Unicode character having the same value as that byte, and -each character written to the channel becomes a single byte in the output, -allowing Tcl to work seamlessly with binary data as long as each "character" in -the data remains in the range of 0 to 255 so that there is no distinction between -binary data and text. For example, A JPEG image can be read from a -\fBbinary\fR channel, manipulated, and then written back to a \fBbinary\fR -channel. - -For working with binary data \fB\-translation binary\fR is usually used -instead, as it sets the encoding to \fBbinary\fR and also disables other -translations on the channel. -.PP -The encoding of a new channel is the value of \fBencoding system\fR, -which returns the platform- and locale-dependent system encoding used to -interface with the operating system, +If a file contains pure binary data (for instance, a JPEG image), the +encoding for the channel should be configured to be \fBbinary\fR. Tcl +will then assign no interpretation to the data in the file and simply +read or write raw bytes. The Tcl \fBbinary\fR command can be used to +manipulate this byte-oriented data. It is usually better to set the +\fB\-translation\fR option to \fBbinary\fR when you want to transfer +binary data, as this turns off the other automatic interpretations of +the bytes in the stream as well. +.PP +The default encoding for newly opened channels is the same platform- +and locale-dependent system encoding used for interfacing with the +operating system, as returned by \fBencoding system\fR. .RE .TP \fB\-eofchar\fR \fIchar\fR .TP \fB\-eofchar\fR \fB{\fIchar outChar\fB}\fR . -\fIchar\fR signals the end of the data when it is encountered in the input. -For output, \fIoutChar\fR is added when the channel is closed. If \fIchar\fR -is the empty string, there is no special character that marks the end of the -data. For read-write channels, one end-of-file character for input and another -for output may be given. When only one end-of-file character is given it is -applied to input only. - -The default value is the empty string, except that under Windows the default -value for reading is Control-z (\ex1A). The acceptable range is \ex01 - -\ex7F. A value outside this range results in an error. +This option supports DOS file systems that use Control-z (\ex1A) as an +end of file marker. If \fIchar\fR is not an empty string, then this +character signals end-of-file when it is encountered during input. +For output, the end-of-file character is output when the channel is +closed. If \fIchar\fR is the empty string, then there is no special +end of file character marker. For read-write channels, a two-element +list specifies the end of file marker for input and output, +respectively. As a convenience, when setting the end-of-file +character for a read-write channel you can specify a single value that +will apply to both reading and writing. When querying the end-of-file +character of a read-write channel, a two-element list will always be +returned. The default value for \fB\-eofchar\fR is the empty string +in all cases except for files under Windows. In that case the +\fB\-eofchar\fR is Control-z (\ex1A) for reading and the empty string +for writing. +The acceptable range for \fB\-eofchar\fR values is \ex01 - \ex7f; +attempting to set \fB\-eofchar\fR to a value outside of this range will +generate an error. .VS "TCL8.7 TIP656" .TP \fB\-profile\fR \fIprofile\fR @@ -180,437 +204,575 @@ rules of that profile. Any failures will result in a channel error. See profiles. .VE "TCL8.7 TIP656" .TP -\fB\-translation\fR \fItranslation\fR -.TP -\fB\-translation\fR \fB{\fIinTranslation outTranslation\fB}\fR -. -In Tcl a single line feed (\en) represents the end of a line. However, -at the destination the end of a line may be represented differently on -different platforms, or even for different devices on the same platform. For -example, under UNIX line feed is used in files and a -carriage-return-linefeed sequence is normally used in network connections. -Therefore, on input, e.g. with \fBchan gets\fR and \fBchan read\fR, each -external end-of-line character is translated into a line feed. On -output, e.g. with \fBchan puts\fR, each line feed is translated to the external -end-of-line character. The default translation, \fBauto\fR, handles all the common -cases, and \fB\-translation\fR provides explicit control over the end-of-line -character. +\fB\-translation\fR \fImode\fR +.TP +\fB\-translation\fR \fB{\fIinMode outMode\fB}\fR +. +In Tcl scripts the end of a line is always represented using a single +newline character (\en). However, in actual files and devices the end +of a line may be represented differently on different platforms, or +even for different devices on the same platform. For example, under +UNIX newlines are used in files, whereas carriage-return-linefeed +sequences are normally used in network connections. On input (i.e., +with \fBchan gets\fR and \fBchan read\fR) the Tcl I/O system +automatically translates the external end-of-line representation into +newline characters. Upon output (i.e., with \fBchan puts\fR), the I/O +system translates newlines to the external end-of-line representation. +The default translation mode, \fBauto\fR, handles all the common cases +automatically, but the \fB\-translation\fR option provides explicit +control over the end of line translations. .RS .PP -Returns the input translation for a read-only channel, the output translation -for a write-only channel, and both the input translation and the the output -translation for a read-write channel. When two translations are given, they -are the input and output translation, respectively. When only one translation -is given for a read-write channel, it is the translation for both input and -output. The following values are currently supported: +The value associated with \fB\-translation\fR is a single item for +read-only and write-only channels. The value is a two-element list for +read-write channels; the read translation mode is the first element of +the list, and the write translation mode is the second element. As a +convenience, when setting the translation mode for a read-write channel +you can specify a single value that will apply to both reading and +writing. When querying the translation mode of a read-write channel, a +two-element list will always be returned. The following values are +currently supported: .TP \fBauto\fR . -The default. For input each occurrence of a line feed (\fBlf\fR), carriage -return (\fBcr\fR), or carriage return followed by a line feed (\fBcrlf\fR) is -translated into a line feed. For output, each line feed is translated into a -platform-specific representation: For all Unix variants it is \fBlf\fR, and -for all Windows variants it is \fBcrlf\fR, except that for sockets on all -platforms it is \fBcrlf\fR for both input and output. +As the input translation mode, \fBauto\fR treats any of newline +(\fBlf\fR), carriage return (\fBcr\fR), or carriage return followed by +a newline (\fBcrlf\fR) as the end of line representation. The end of +line representation can even change from line-to-line, and all cases +are translated to a newline. As the output translation mode, +\fBauto\fR chooses a platform specific representation; for sockets on +all platforms Tcl chooses \fBcrlf\fR, for all Unix flavors, it chooses +\fBlf\fR, and for the various flavors of Windows it chooses +\fBcrlf\fR. The default setting for \fB\-translation\fR is \fBauto\fR +for both input and output. .TP \fBbinary\fR . -Like \fBlf\fR, no end-of-line translation is performed, but in addition, -\fB\-eofchar\fR is set to the empty string to disable it, and \fB\-encoding\fR -is set to \fBbinary\fR. With this one setting, a channel is fully configured -for binary input and output. +No end-of-line translations are performed. This is nearly identical +to \fBlf\fR mode, except that in addition \fBbinary\fR mode also sets +the end-of-file character to the empty string (which disables it) and +sets the encoding to \fBbinary\fR (which disables encoding filtering). +See the description of \fB\-eofchar\fR and \fB\-encoding\fR for more +information. .TP \fBcr\fR . -The end of a line is represented in the external data by a single carriage -return character. For input, each carriage return is translated to a line -feed, and for output each line feed character is translated to a carriage -return. +The end of a line in the underlying file or device is represented by a +single carriage return character. As the input translation mode, +\fBcr\fR mode converts carriage returns to newline characters. As the +output translation mode, \fBcr\fR mode translates newline characters +to carriage returns. .TP \fBcrlf\fR . -The end of a line is represented in the external data by a carriage return -character followed by a line feed. For input, each carriage-return-linefeed -sequence is translated to a line feed. For output, each line feed is -translated to a carriage-return-linefeed sequence. This translation is -typically used for network connections, and also on Windows systems. +The end of a line in the underlying file or device is represented by a +carriage return character followed by a linefeed character. As the +input translation mode, \fBcrlf\fR mode converts +carriage-return-linefeed sequences to newline characters. As the +output translation mode, \fBcrlf\fR mode translates newline characters +to carriage-return-linefeed sequences. This mode is typically used on +Windows platforms and for network connections. .TP \fBlf\fR . -The end of a line in the external data is represented by a line feed so no -translations occur during either input or output. This translation is -typically used on UNIX platforms, +The end of a line in the underlying file or device is represented by a +single newline (linefeed) character. In this mode no translations +occur during either input or output. This mode is typically used on +UNIX platforms. .RE .RE .TP \fBchan copy \fIinputChan outputChan\fR ?\fB\-size \fIsize\fR? ?\fB\-command \fIcallback\fR? . -Copies data from \fIinputChan\fR to \fIoutputChan\fR, leveraging internal -buffers to avoid extra copies and to avoid buffering too much data in main -memory when copying large files to slow destinations like network sockets. +Copy data from the channel \fIinputChan\fR, which must have been +opened for reading, to the channel \fIoutputChan\fR, which must have +been opened for writing. The \fBchan copy\fR command leverages the +buffering in the Tcl I/O system to avoid extra copies and to avoid +buffering too much data in main memory when copying large files to +slow destinations like network sockets. .RS .PP -If \fB\-size\fR is given, the size is in bytes if the two channels have the -same encoding and in characters otherwise, and only that amount is copied. -Otherwise, all data until the end of the file is copied. - -\fBchan copy\fR blocks until the copy is complete and returns the number of -bytes or characters written to \fIoutputChan\fR. -.PP -If \fB\-command\fR is given, \fBchan copy\fR returns immediately, the copy is -carried out in the background, and then \fIcallback\fR is called with the -number of bytes written to \fIoutputChan\fR as its first argument, and the -error message for any error that occurred as its second argument. -\fIinputChan\fR and \fIoutputChan\fR are automatically configured for -non-blocking mode if needed. Background copying only works correctly if the -event loop is active, e.g. via \fBvwait\fR or Tk. -.PP -During a background copy no other read or write operation may be performed on -\fIinputChan\fR or \fIoutputChan\fR. If either \fIinputChan\fR or -\fIoutputChan\fR is closed while the copy is in progress copying ceases and -\fBno\fR callback is made. If \fIinputChan\fR is closed all data already queued -is written to \fIoutputChan\fR. -.PP -The should be no event handler established for \fIinputChan\fR because it may -become readable during a background copy. An attempt to read or write -from within an event handler results result in the error, "channel busy". -.PP -Due to end-of-line translation the number of bytes read from \fIinputChan\fR -may be different than the number of bytes written to \fIoutputChan\fR. Only -the number of bytes written to \fIoutputChan\fR is reported. -.PP -\fBChan copy\fR reads the data according to the \fB\-encoding\fR, -\fB\-translation\fR, and \fB\-eofchar\fR of the source and writes to the -destination according to the configuration for that channel. If the encoding -and translation of both channels is \fBbinary\fR and the \fB\-eofchar\fR of -both channels is the empty string, an identical copy is made. If only the -encoding of the destination is \fBbinary\fR, Tcl's internal modified UTF-8 -representation of the characters read from the source is written to the -destination. If only the encoding of the source is \fBbinary\fR, each byte read -becomes one Unicode character in the range of 0 to 255, and that character is -subject to the encoding and translation of the destination as it is written. +The \fBchan copy\fR command transfers data from \fIinputChan\fR until +end of file or \fIsize\fR bytes or characters have been transferred; +\fIsize\fR is in bytes if the two channels are using the same encoding, +and is in characters otherwise. If no \fB\-size\fR argument is given, +then the copy goes until end of file. All the data read from +\fIinputChan\fR is copied to \fIoutputChan\fR. Without the +\fB\-command\fR option, \fBchan copy\fR blocks until the copy is +complete and returns the number of bytes or characters (using the same +rules as for the \fB\-size\fR option) written to \fIoutputChan\fR. +.PP +The \fB\-command\fR argument makes \fBchan copy\fR work in the +background. In this case it returns immediately and the +\fIcallback\fR is invoked later when the copy completes. The +\fIcallback\fR is called with one or two additional arguments that +indicates how many bytes were written to \fIoutputChan\fR. If an +error occurred during the background copy, the second argument is the +error string associated with the error. With a background copy, it is +not necessary to put \fIinputChan\fR or \fIoutputChan\fR into +non-blocking mode; the \fBchan copy\fR command takes care of that +automatically. However, it is necessary to enter the event loop by +using the \fBvwait\fR command or by using Tk. +.PP +You are not allowed to do other I/O operations with \fIinputChan\fR or +\fIoutputChan\fR during a background \fBchan copy\fR. If either +\fIinputChan\fR or \fIoutputChan\fR get closed while the copy is in +progress, the current copy is stopped and the command callback is +\fInot\fR made. If \fIinputChan\fR is closed, then all data already +queued for \fIoutputChan\fR is written out. +.PP +Note that \fIinputChan\fR can become readable during a background +copy. You should turn off any \fBchan event\fR or \fBfileevent\fR +handlers during a background copy so those handlers do not interfere +with the copy. Any I/O attempted by a \fBchan event\fR or +\fBfileevent\fR handler will get a +.QW "channel busy" +error. +.PP +\fBChan copy\fR translates end-of-line sequences in \fIinputChan\fR +and \fIoutputChan\fR according to the \fB\-translation\fR option for +these channels (see \fBchan configure\fR above). The translations +mean that the number of bytes read from \fIinputChan\fR can be +different than the number of bytes written to \fIoutputChan\fR. Only +the number of bytes written to \fIoutputChan\fR is reported, either as +the return value of a synchronous \fBchan copy\fR or as the argument +to the callback for an asynchronous \fBchan copy\fR. +.PP +\fBChan copy\fR obeys the encodings and character translations +configured for the channels. This means that the incoming characters +are converted internally first UTF-8 and then into the encoding of the +channel \fBchan copy\fR writes to (see \fBchan configure\fR above for +details on the \fB\-encoding\fR and \fB\-translation\fR options). No +conversion is done if both channels are set to encoding \fBbinary\fR +and have matching translations. If only the output channel is set to +encoding \fBbinary\fR the system will write the internal UTF-8 +representation of the incoming characters. If only the input channel +is set to encoding \fBbinary\fR the system will assume that the +incoming bytes are valid UTF-8 characters and convert them according +to the output encoding. The behaviour of the system for bytes which +are not valid UTF-8 characters is undefined in this case. .RE .TP \fBchan create \fImode cmdPrefix\fR . -Creates a new channel, called a \fBreflected\fR channel, with \fIcmdPrefix\fR -as its handler, and returns the name of the channel. \fBcmdPrefix\fR is the -first words of a command that provides the interface for a \fBrefchan\fR. +This subcommand creates a new script level channel using the command +prefix \fIcmdPrefix\fR as its handler. Any such channel is called a +\fBreflected\fR channel. The specified command prefix, \fBcmdPrefix\fR, +must be a non-empty list, and should provide the API described in the +\fBrefchan\fR manual page. The handle of the new channel is +returned as the result of the \fBchan create\fR command, and the +channel is open. Use either \fBclose\fR or \fBchan close\fR to remove +the channel. .RS .PP -\fBImode\fR is a list of one or more of the strings +The argument \fImode\fR specifies if the new channel is opened for +reading, writing, or both. It has to be a list containing any of the +strings .QW \fBread\fR or -.QW \fBwrite\fR , -indicating whether the channel is a read channel, a write channel, or both. -It is an error if the handler does not support the chosen mode. -.PP -The handler is called as needed from the global namespace at the top level, and -command resolution happens there at the time of the call. If the handler is -renamed or deleted any subsequent attempt to call it is an error, which may -not be able to describe the failure. -.PP -The handler is always called in the interpreter and thread it was created in, -even if the channel was shared with or moved into a different interpreter in a -different thread. This is achieved through event dispatch, so if the event -loop is not entered, e.g. by calling \fBTcl_DoOneEvent\fR or \fBvwait\fR or -using Tk, the thread performing the channel operation \fIblocks -indefinitely\fR, resulting in deadlock. -.PP -One side of a channel may be in one thread while the other side is in a -different thread, providing a stream-oriented bridge between the threads. This -provides a method for regular stream communication between threads as an -alternative to sending commands. -.PP -When the interpreter the handler is in is deleted each channel associated with -the handler is deleted as well, regardless of which interpreter or thread it -is currently in or shared with. -.PP -\fBchan create\fR is \fBsafe\fR and is accessible to safe interpreters. The -handler is always called in the safe interpreter it was created in. +.QW \fBwrite\fR . +The list must have at least one +element, as a channel you can neither write to nor read from makes no +sense. The handler command for the new channel must support the chosen +mode, or an error is thrown. +.PP +The command prefix is executed in the global namespace, at the top of +call stack, following the appending of arguments as described in the +\fBrefchan\fR manual page. Command resolution happens at the +time of the call. Renaming the command, or destroying it means that +the next call of a handler method may fail, causing the channel +command invoking the handler to fail as well. Depending on the +subcommand being invoked, the error message may not be able to explain +the reason for that failure. +.PP +Every channel created with this subcommand knows which interpreter it +was created in, and only ever executes its handler command in that +interpreter, even if the channel was shared with and/or was moved into +a different interpreter. Each reflected channel also knows the thread +it was created in, and executes its handler command only in that +thread, even if the channel was moved into a different thread. To this +end all invocations of the handler are forwarded to the original +thread by posting special events to it. This means that the original +thread (i.e. the thread that executed the \fBchan create\fR command) +must have an active event loop, i.e. it must be able to process such +events. Otherwise the thread sending them will \fIblock +indefinitely\fR. Deadlock may occur. +.PP +Note that this permits the creation of a channel whose two endpoints +live in two different threads, providing a stream-oriented bridge +between these threads. In other words, we can provide a way for +regular stream communication between threads instead of having to send +commands. +.PP +When a thread or interpreter is deleted, all channels created with +this subcommand and using this thread/interpreter as their computing +base are deleted as well, in all interpreters they have been shared +with or moved into, and in whatever thread they have been transferred +to. While this pulls the rug out under the other thread(s) and/or +interpreter(s), this cannot be avoided. Trying to use such a channel +will cause the generation of a regular error about unknown channel +handles. +.PP +This subcommand is \fBsafe\fR and made accessible to safe +interpreters. While it arranges for the execution of arbitrary Tcl +code the system also makes sure that the code is always executed +within the safe interpreter. .RE .TP -\fBchan eof \fIchannelName\fR -. -Returns 1 if the last read on the channel failed because the end of the data -was already reached, and 0 otherwise. -.TP -\fBchan event \fIchannelName event\fR ?\fIscript\fR? -. -Arranges for the given script, called a \fBchannel event handler\fR, to be -called whenever the given event, one of -.QW \fBreadable\fR -or -.QW \fBwritable\fR -occurs on the given channel, replacing any script that was previously set. If -\fIscript\fR is the empty string the current handler is deleted. It is also -deleted when the channel is closed. If \fIscript\fR is omitted, either the -existing script or the empty string is returned. The event loop must be -entered, e.g. via \fBvwait\fR or \fBupdate\fR, or by using Tk, for handlers to -be evaluated. - +\fBchan eof \fIchannelId\fR +. +Test whether the last input operation on the channel called +\fIchannelId\fR failed because the end of the data stream was reached, +returning 1 if end-of-file was reached, and 0 otherwise. +.TP +\fBchan event \fIchannelId event\fR ?\fIscript\fR? +. +Arrange for the Tcl script \fIscript\fR to be installed as a \fIfile +event handler\fR to be called whenever the channel called +\fIchannelId\fR enters the state described by \fIevent\fR (which must +be either \fBreadable\fR or \fBwritable\fR); only one such handler may +be installed per event per channel at a time. If \fIscript\fR is the +empty string, the current handler is deleted (this also happens if the +channel is closed or the interpreter deleted). If \fIscript\fR is +omitted, the currently installed script is returned (or an empty +string if no such handler is installed). The callback is only +performed if the event loop is being serviced (e.g. via \fBvwait\fR or +\fBupdate\fR). .RS .PP -\fIscript\fR is evaluated at the global level in the interpreter it was -established in. Any resulting error is handled in the background, i.e. via -\fBinterp bgerror\fR. In order to prevent an endless loop due to a buggy -handler, the handler is deleted if \fIscript\fR returns an error so that it is -not evaluated again. - -.PP -Without an event handler, \fBchan gets\fR or \fBchan read\fR on a channel in -blocking mode may block until data becomes available, become during which the -thread is unable to perform other work or respond to events on other channels. -This could cause the application to appear to -.QW "freeze up" -\&. -Channel event handlers allow events on the channel to direct channel handling -so that the reader or writer can continue to perform other processing while -waiting for a channel to become available and then handle channel operations -when the channel is ready for the operation. -.PP -A -.QW readable -event occurs when there is data that can be read from the channel and also when -there is an error on the channel. The handler must check for these conditions -and handle them appropriately. For example, a handler that does not check -whether the end of the data has been reached may be repeatedly evaluated in a -busy loop until the channel is closed. -.PP -A -.QW writable -event occurs when at least one byte of data can be written, or if there is an -error on the channel. A client socket opened in non-blocking mode becomes -writable when it becomes connected or if the connection fails. -.PP -Event-driven channel handling works best for channels in non-blocking mode. A -channel in blocking mode blocks when \fBchan puts\fR writes more data than the -channel can accept at the moment, and when \fBchan gets\fR or \fBchan read\fR -requests more data than is currently available. When a channel blocks, the -thread can not do any other processing or service any other events. A channel -in non-blocking mode allows a thread to carry on with other work and get back -to the channel at the right time. +A file event handler is a binding between a channel and a script, such +that the script is evaluated whenever the channel becomes readable or +writable. File event handlers are most commonly used to allow data to +be received from another process on an event-driven basis, so that the +receiver can continue to interact with the user or with other channels +while waiting for the data to arrive. If an application invokes +\fBchan gets\fR or \fBchan read\fR on a blocking channel when there is +no input data available, the process will block; until the input data +arrives, it will not be able to service other events, so it will +appear to the user to +.QW "freeze up" . +With \fBchan event\fR, the +process can tell when data is present and only invoke \fBchan gets\fR +or \fBchan read\fR when they will not block. +.PP +A channel is considered to be readable if there is unread data +available on the underlying device. A channel is also considered to +be readable if there is unread data in an input buffer, except in the +special case where the most recent attempt to read from the channel +was a \fBchan gets\fR call that could not find a complete line in the +input buffer. This feature allows a file to be read a line at a time +in non-blocking mode using events. A channel is also considered to be +readable if an end of file or error condition is present on the +underlying file or device. It is important for \fIscript\fR to check +for these conditions and handle them appropriately; for example, if +there is no special check for end of file, an infinite loop may occur +where \fIscript\fR reads no data, returns, and is immediately invoked +again. +.PP +A channel is considered to be writable if at least one byte of data +can be written to the underlying file or device without blocking, or +if an error condition is present on the underlying file or device. +Note that client sockets opened in asynchronous mode become writable +when they become connected or if the connection fails. +.PP +Event-driven I/O works best for channels that have been placed into +non-blocking mode with the \fBchan configure\fR command. In blocking +mode, a \fBchan puts\fR command may block if you give it more data +than the underlying file or device can accept, and a \fBchan gets\fR +or \fBchan read\fR command will block if you attempt to read more data +than is ready; no events will be processed while the commands block. +In non-blocking mode \fBchan puts\fR, \fBchan read\fR, and \fBchan +gets\fR never block. +.PP +The script for a file event is executed at global level (outside the +context of any Tcl procedure) in the interpreter in which the \fBchan +event\fR command was invoked. If an error occurs while executing the +script then the command registered with \fBinterp bgerror\fR is used +to report the error. In addition, the file event handler is deleted +if it ever returns an error; this is done in order to prevent infinite +loops due to buggy handlers. .RE .TP -\fBchan flush \fIchannelName\fR +\fBchan flush \fIchannelId\fR . -For a channel in blocking mode, flushes all buffered output to the destination, -and then returns. For a channel in non-blocking mode, returns immediately -while all buffered output is flushed in the background as soon as possible. +Ensures that all pending output for the channel called \fIchannelId\fR +is written. +.RS +.PP +If the channel is in blocking mode the command does not return until +all the buffered output has been flushed to the channel. If the +channel is in non-blocking mode, the command may return before all +buffered output has been flushed; the remainder will be flushed in the +background as fast as the underlying file or device is able to absorb +it. +.RE .TP -\fBchan gets \fIchannelName\fR ?\fIvarName\fR? -. -Returns the next line from the channel, removing the trailing line feed, or if -\fIvarName\fR is given, assigns the line to that variable and returns the -number of characters read. -the line that was read, removing the trailing line feed, or returns the -empty string if there is no data to return and the end of the file has been -reached, or in non-blocking mode, if no complete line is currently available. -If \fIvarName\fR is given, assigns the line that was read to variable named -\fIvarName\fR and returns the number of characters that were read, or -1 if -there no data available and the end of the channel was reached or the channel -is in non-blocking mode. +\fBchan gets \fIchannelId\fR ?\fIvarName\fR? +. +Reads the next line from the channel called \fIchannelId\fR. If +\fIvarName\fR is not specified, the result of the command will be the +line that has been read (without a trailing newline character) or an +empty string upon end-of-file or, in non-blocking mode, if the data +available is exhausted. If \fIvarName\fR is specified, the line that +has been read will be written to the variable called \fIvarName\fR and +result will be the number of characters that have been read or -1 if +end-of-file was reached or, in non-blocking mode, if the data +available is exhausted. .RS .PP -If the end of the channel is reached the data read so far is returned or -assigned to \fIvarName\fR. When \fIvarName\fR is not given, \fBchan eof\fR may -indicate that the empty string means that the end of the data has been reached, -and \fBchan blocked\fR may indicate that that the empty string means there -isn't currently enough data do return the next line. +If an end-of-file occurs while part way through reading a line, the +partial line will be returned (or written into \fIvarName\fR). When +\fIvarName\fR is not specified, the end-of-file case can be +distinguished from an empty line using the \fBchan eof\fR command, and +the partial-line-but-non-blocking case can be distinguished with the +\fBchan blocked\fR command. .RE .TP \fBchan names\fR ?\fIpattern\fR? . -Returns a list of all channel names, or if \fIpattern\fR is given, only those -names that match according to the rules of \fBstring match\fR. +Produces a list of all channel names. If \fIpattern\fR is specified, +only those channel names that match it (according to the rules of +\fBstring match\fR) will be returned. .TP -\fBchan pending \fImode channelName\fR +\fBchan pending \fImode channelId\fR . -Returns the number of bytes of input -when \fImode\fR is -.QW\fBinput\fR -, or output when \fImode\fR is -.QW\fBoutput\fR -, that are currently internally buffered for the channel. Useful in a readable -event callback to impose limits on input line length to avoid a potential -denial-of-service attack where an extremely long line exceeds the available -memory to buffer it. Returns -1 if the channel was not opened for the mode in -question. +Depending on whether \fImode\fR is \fBinput\fR or \fBoutput\fR, +returns the number of +bytes of input or output (respectively) currently buffered +internally for \fIchannelId\fR (especially useful in a readable event +callback to impose application-specific limits on input line lengths to avoid +a potential denial-of-service attack where a hostile user crafts +an extremely long line that exceeds the available memory to buffer it). +Returns -1 if the channel was not opened for the mode in question. .TP \fBchan pipe\fR -Creates a pipe, i.e. a readable channel and a writable channel, and returns the -names of the readable channel and the writable channel. Data written to the -writable channel can be read from the readable channel. Because the pipe is a -real system-level pipe, it can be connected to other processes using -redirection. For example, to redirect \fBstderr\fR from a subprocess into one -channel, and \fBstdout\fR into another, \fBexec\fR with "2>@" and ">@", each -onto the writable side of a pipe, closing the writable side immediately -thereafter so that EOF is signaled on the read side once the subprocess has -closed its output, typically on exit. +Creates a standalone pipe whose read- and write-side channels are +returned as a 2-element list, the first element being the read side and +the second the write side. Can be useful e.g. to redirect +separately \fBstderr\fR and \fBstdout\fR from a subprocess. To do +this, spawn with "2>@" or +">@" redirection operators onto the write side of a pipe, and then +immediately close it in the parent. This is necessary to get an EOF on +the read side once the child has exited or otherwise closed its output. .RS .PP -Due to buffering, data written to one side of a pipe might not immediately -become available on the other side. Tcl's own buffers can be configured via -\fBchan configure -buffering\fR, but overall behaviour still depends on -operating system buffers outside of Tcl's control. Once the write side of the -channel is closed, any data remaining in the buffers is flushed through to the -read side. It may be useful to arrange for the connected process to flush at -some point after writing to the channel or to have it use some system-provided -mechanism to configure buffering. When two pipes are connected to the same -process, one to send data to the process, and one to read data from the -process, a deadlock may occur if the channels are in blocking mode: If -reading, the channel may block waiting for data that can never come because -buffers are only flushed on subsequent writes, and if writing, the channel may -block while waiting for the buffers to become free, which can never happen -because the reader can not read while the writer is blocking. To avoid this -issue, either put the channels into non-blocking mode and use event handlers, -or place the read channel and the write channel in separate interpreters in -separate threads. +Note that the pipe buffering semantics can vary at the operating system level +substantially; it is not safe to assume that a write performed on the output +side of the pipe will appear instantly to the input side. This is a +fundamental difference and Tcl cannot conceal it. The overall stream semantics +\fIare\fR compatible, so blocking reads and writes will not see most of the +differences, but the details of what exactly gets written when are not. This +is most likely to show up when using pipelines for testing; care should be +taken to ensure that deadlocks do not occur and that potential short reads are +allowed for. .RE .TP -\fBchan pop \fIchannelName\fR -Removes the topmost transformation handler from the channel if there is one, -and closes the channel otherwise. The result is normally the empty string, but -may be an error in some situations, e.g. when closing the underlying resource -results in an error. -.TP -\fBchan postevent \fIchannelName eventSpec\fR -. -For use by handlers established with \fBchan create\fR. Notifies Tcl that -that one or more event(s) listed in \fIeventSpec\fR, each of which is either -.QW\fBread\fR -or -.QW\fBwrite\fR. -, have occurred. +\fBchan pop \fIchannelId\fR +Removes the topmost transformation from the channel \fIchannelId\fR, if there +is any. If there are no transformations added to \fIchannelId\fR, this is +equivalent to \fBchan close\fR of that channel. The result is normally the +empty string, but can be an error in some situations (i.e. where the +underlying system stream is closed and that results in an error). +.TP +\fBchan postevent \fIchannelId eventSpec\fR +. +This subcommand is used by command handlers specified with \fBchan +create\fR. It notifies the channel represented by the handle +\fIchannelId\fR that the event(s) listed in the \fIeventSpec\fR have +occurred. The argument has to be a list containing any of the strings +\fBread\fR and \fBwrite\fR. The list must contain at least one +element as it does not make sense to invoke the command if there are +no events to post. .RS .PP -For use only by handlers for a channel created by \fBchan create\fR. It is an -error to post an event for any other channel. -.PP -Since only the handler for a reflected channel channel should post events it is -an error to post an event from any interpreter other than the interpreter that -created the channel. -.PP -It is an error to post an event that the channel has no interest in. See -\fBwatch\fR in the \fBrefchan\fR documentation for more information -.PP -\fBchan postevent\fR is available in safe interpreters, as any handler for a -reflected channel would have been created, and will be evaluated in that -interpreter as well. +Note that this subcommand can only be used with channel handles that +were created/opened by \fBchan create\fR. All other channels will +cause this subcommand to report an error. +.PP +As only the Tcl level of a channel, i.e. its command handler, should +post events to it we also restrict the usage of this command to the +interpreter that created the channel. In other words, posting events +to a reflected channel from an interpreter that does not contain it's +implementation is not allowed. Attempting to post an event from any +other interpreter will cause this subcommand to report an error. +.PP +Another restriction is that it is not possible to post events that the +I/O core has not registered an interest in. Trying to do so will cause +the method to throw an error. See the command handler method +\fBwatch\fR described in \fBrefchan\fR, the document specifying +the API of command handlers for reflected channels. +.PP +This command is \fBsafe\fR and made accessible to safe interpreters. +It can trigger the execution of \fBchan event\fR handlers, whether in the +current interpreter or in other interpreters or other threads, even +where the event is posted from a safe interpreter and listened for by +a trusted interpreter. \fBChan event\fR handlers are \fIalways\fR +executed in the interpreter that set them up. .RE .TP -\fBchan push \fIchannelName cmdPrefix\fR -Adds a new transformation handler on top of the channel and returns a handle -for the transformation. \fIcmdPrefix\fR is the first words of a command that -provides the interface documented for \fBtranschan\fR, and transforms data on -the channel, It is an error if handler does not support the mode(s) the channel -is in. -.TP -\fBchan puts\fR ?\fB\-nonewline\fR? ?\fIchannelName\fR? \fIstring\fR -. -Writes \fIstring\fR and a line feed to the channel. If \fB\-nonewline\fR is -given, the trailing line feed is not written. The default channel is +\fBchan push \fIchannelId cmdPrefix\fR +Adds a new transformation on top of the channel \fIchannelId\fR. The +\fIcmdPrefix\fR argument describes a list of one or more words which represent +a handler that will be used to implement the transformation. The command +prefix must provide the API described in the \fBtranschan\fR manual page. +The result of this subcommand is a handle to the transformation. Note that it +is important to make sure that the transformation is capable of supporting the +channel mode that it is used with or this can make the channel neither +readable nor writable. +.TP +\fBchan puts\fR ?\fB\-nonewline\fR? ?\fIchannelId\fR? \fIstring\fR +. +Writes \fIstring\fR to the channel named \fIchannelId\fR followed by a +newline character. A trailing newline character is written unless the +optional flag \fB\-nonewline\fR is given. If \fIchannelId\fR is +omitted, the string is written to the standard output channel, \fBstdout\fR. .RS .PP -Each line feed in the output is translated according to the configuration of -\fB\-translation\fR. -.PP -Because Tcl internally buffers output, characters written to a channel may not -immediately be available at the destination. Tcl normally delays output until -the buffer is full or the channel is closed. \fBchan flush\fR forces output in -the direction of the destination. -.PP -When the output for a channel in blocking mode fills up, \fBchan puts\fR blocks -until space in the buffer is available again, but for a channel in non-blocking -mode, it returns immediately and the data is written in the background as fast -possible, constrained by the speed at which as the destination accepts it. -Output to a channel in non-blocking mode only works properly when the -application enters the event loop, giving Tcl a chance to find out that the -destination is ready to accept more data. When a channel is in non-blocking -mode, Tcl's internal buffers can hold an arbitrary amount of data, possibly -consuming a large amount of memory. To avoid wasting memory, channels in -non-blocking mode should normally be handled using \fBchan event\fR, where the -application only invokes \fBchan puts\fR after being recently notified through -a file event handler that the channel is ready for more output data. +Newline characters in the output are translated by \fBchan puts\fR to +platform-specific end-of-line sequences according to the currently +configured value of the \fB\-translation\fR option for the channel +(for example, on PCs newlines are normally replaced with +carriage-return-linefeed sequences; see \fBchan configure\fR above for +details). +.PP +Tcl buffers output internally, so characters written with \fBchan +puts\fR may not appear immediately on the output file or device; Tcl +will normally delay output until the buffer is full or the channel is +closed. You can force output to appear immediately with the \fBchan +flush\fR command. +.PP +When the output buffer fills up, the \fBchan puts\fR command will +normally block until all the buffered data has been accepted for +output by the operating system. If \fIchannelId\fR is in non-blocking +mode then the \fBchan puts\fR command will not block even if the +operating system cannot accept the data. Instead, Tcl continues to +buffer the data and writes it in the background as fast as the +underlying file or device can accept it. The application must use the +Tcl event loop for non-blocking output to work; otherwise Tcl never +finds out that the file or device is ready for more output data. It +is possible for an arbitrarily large amount of data to be buffered for +a channel in non-blocking mode, which could consume a large amount of +memory. To avoid wasting memory, non-blocking I/O should normally be +used in an event-driven fashion with the \fBchan event\fR command +(do not invoke \fBchan puts\fR unless you have recently been notified +via a file event that the channel is ready for more output data). .RE .TP -\fBchan read \fIchannelName\fR ?\fInumChars\fR? +\fBchan read \fIchannelId\fR ?\fInumChars\fR? .TP -\fBchan read \fR?\fB\-nonewline\fR? \fIchannelName\fR +\fBchan read \fR?\fB\-nonewline\fR? \fIchannelId\fR . -Reads and returns the next \fInumChars\fR characters from the channel. If -\fInumChars\fR is omitted, all available characters up to the end of the file -are read, or if the channel is in non-blocking mode, all currently-available -characters are read. If there is an error on the channel, reading ceases and -an error is returned. If \fInumChars\fR is not given, \fB\-nonewline\fR -may be given, causing any any trailing line feed to be trimmed. +In the first form, the result will be the next \fInumChars\fR +characters read from the channel named \fIchannelId\fR; if +\fInumChars\fR is omitted, all characters up to the point when the +channel would signal a failure (whether an end-of-file, blocked or +other error condition) are read. In the second form (i.e. when +\fInumChars\fR has been omitted) the flag \fB\-nonewline\fR may be +given to indicate that any trailing newline in the string that has +been read should be trimmed. .RS .PP -If the channel is in non-blocking mode, fewer characters than requested may be -returned. If the channel is configured to use a multi-byte encoding, bytes -that do not form a complete character are retained in the buffers until enough -bytes to complete the character accumulate, or the end of the data is reached. -\fB\-nonewline\fR is ignored if characters are returned before reaching the end -of the file. -.PP -Each end-of-line sequence according to the value of \fB\-translation\fR is -translated into a line feed. -.PP -When reading from a serial port, most applications should configure the serial -port channel to be in non-blocking mode, but not necessarily use an event -handler since most serial ports are comparatively slow. It is entirely -possible to get a \fBreadable\fR event for each individual character. In -blocking mode, \fBchan read\fR blocks forever when reading to the end of the -data if there is no \fBchan configure -eofchar\fR configured for the channel. +If \fIchannelId\fR is in non-blocking mode, \fBchan read\fR may not +read as many characters as requested: once all available input has +been read, the command will return the data that is available rather +than blocking for more input. If the channel is configured to use a +multi-byte encoding, then there may actually be some bytes remaining +in the internal buffers that do not form a complete character. These +bytes will not be returned until a complete character is available or +end-of-file is reached. The \fB\-nonewline\fR switch is ignored if +the command returns before reaching the end of the file. +.PP +\fBChan read\fR translates end-of-line sequences in the input into +newline characters according to the \fB\-translation\fR option for the +channel (see \fBchan configure\fR above for a discussion on the ways +in which \fBchan configure\fR will alter input). +.PP +When reading from a serial port, most applications should configure +the serial port channel to be non-blocking, like this: +.PP +.CS +\fBchan configure \fIchannelId \fB\-blocking \fI0\fR. +.CE +.PP +Then \fBchan read\fR behaves much like described above. Note that +most serial ports are comparatively slow; it is entirely possible to +get a \fBreadable\fR event for each character read from them. Care +must be taken when using \fBchan read\fR on blocking serial ports: +.TP +\fBchan read \fIchannelId numChars\fR +. +In this form \fBchan read\fR blocks until \fInumChars\fR have been +received from the serial port. +.TP +\fBchan read \fIchannelId\fR +. +In this form \fBchan read\fR blocks until the reception of the +end-of-file character, see \fBchan configure -eofchar\fR. If there no +end-of-file character has been configured for the channel, then +\fBchan read\fR will block forever. .RE .TP -\fBchan seek \fIchannelName offset\fR ?\fIorigin\fR? +\fBchan seek \fIchannelId offset\fR ?\fIorigin\fR? . -Sets the current position for the data in the channel to integer \fIoffset\fR -bytes relative to \fIorigin\fR. A negative offset moves the current position -backwards from the origin. \fIorigin\fR is one of the -following: +Sets the current access position within the underlying data stream for +the channel named \fIchannelId\fR to be \fIoffset\fR bytes relative to +\fIorigin\fR. \fIOffset\fR must be an integer (which may be negative) +and \fIorigin\fR must be one of the following: .RS -.PP .TP 10 \fBstart\fR . -The origin is the start of the data. This is the default. +The new access position will be \fIoffset\fR bytes from the start +of the underlying file or device. .TP 10 \fBcurrent\fR . -The origin is the current position. +The new access position will be \fIoffset\fR bytes from the current +access position; a negative \fIoffset\fR moves the access position +backwards in the underlying file or device. .TP 10 \fBend\fR . -The origin is the end of the data. +The new access position will be \fIoffset\fR bytes from the end of the +file or device. A negative \fIoffset\fR places the access position +before the end of file, and a positive \fIoffset\fR places the access +position after the end of file. +.PP +The \fIorigin\fR argument defaults to \fBstart\fR. .PP -\fBChan seek\fR flushes all buffered output even if the channel is in -non-blocking mode, discards any buffered and unread input, and returns the -empty string or an error if the channel does not support seeking. +\fBChan seek\fR flushes all buffered output for the channel before the +command returns, even if the channel is in non-blocking mode. It also +discards any buffered and unread input. This command returns an empty +string. An error occurs if this command is applied to channels whose +underlying file or device does not support seeking. .PP -\fIoffset\fR values are byte offsets, not character offsets. Unlike \fBchan -read\fR, both \fBchan seek\fR and \fBchan tell\fR operate in terms of bytes, -not characters, +Note that \fIoffset\fR values are byte offsets, not character offsets. +Both \fBchan seek\fR and \fBchan tell\fR operate in terms of bytes, +not characters, unlike \fBchan read\fR. .RE .TP -\fBchan tell \fIchannelName\fR +\fBchan tell \fIchannelId\fR . -Returns the offset in bytes of the current position in the underlying data, or --1 if the channel does not suport seeking. The value can be passed to \fBchan -seek\fR to set current position to that offset. +Returns a number giving the current access position within the +underlying data stream for the channel named \fIchannelId\fR. This +value returned is a byte offset that can be passed to \fBchan seek\fR +in order to set the channel to a particular position. Note that this +value is in terms of bytes, not characters like \fBchan read\fR. The +value returned is -1 for channels that do not support seeking. .TP -\fBchan truncate \fIchannelName\fR ?\fIlength\fR? +\fBchan truncate \fIchannelId\fR ?\fIlength\fR? . -Flushes the channel and truncates the data in the channel to \fIlength\fR -bytes, or to the current position in bytes if \fIlength\fR is omitted. +Sets the byte length of the underlying data stream for the channel +named \fIchannelId\fR to be \fIlength\fR (or to the current byte +offset within the underlying data stream if \fIlength\fR is +omitted). The channel is flushed before truncation. . .SH EXAMPLES .PP -In the following example a file is opened using the encoding CP1252, which is -common on Windows, searches for a string, rewrites that part, and truncates the -file two lines later. +This opens a file using a known encoding (CP1252, a very common encoding +on Windows), searches for a string, rewrites that part, and truncates the +file after a further two lines. .PP .CS set f [open somefile.txt r+] @@ -641,12 +803,12 @@ while {[\fBchan gets\fR $f line] >= 0} { \fBchan close\fR $f .CE .PP -A network server that echoes its input line-by-line without -preventing servicing of other connections at the same time: +A network server that does echoing of its input line-by-line without +preventing servicing of other connections at the same time. .PP .CS # This is a very simple logger... -proc log message { +proc log {message} { \fBchan puts\fR stdout $message } -- cgit v0.12