1/* 2 * tclIO.h -- 3 * 4 * This file provides the generic portions (those that are the same on 5 * all platforms and for all channel types) of Tcl's IO facilities. 6 * 7 * Copyright (c) 1998-2000 Ajuba Solutions 8 * Copyright (c) 1995-1997 Sun Microsystems, Inc. 9 * 10 * See the file "license.terms" for information on usage and redistribution 11 * of this file, and for a DISCLAIMER OF ALL WARRANTIES. 12 * 13 * RCS: @(#) $Id: tclIO.h,v 1.5.4.3 2008/04/07 22:17:37 andreas_kupries Exp $ 14 */ 15 16/* 17 * Make sure that both EAGAIN and EWOULDBLOCK are defined. This does not 18 * compile on systems where neither is defined. We want both defined so 19 * that we can test safely for both. In the code we still have to test for 20 * both because there may be systems on which both are defined and have 21 * different values. 22 */ 23 24#if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN))) 25# define EWOULDBLOCK EAGAIN 26#endif 27#if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK))) 28# define EAGAIN EWOULDBLOCK 29#endif 30#if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK))) 31error one of EWOULDBLOCK or EAGAIN must be defined 32#endif 33 34/* 35 * The following structure encapsulates the state for a background channel 36 * copy. Note that the data buffer for the copy will be appended to this 37 * structure. 38 */ 39 40typedef struct CopyState { 41 struct Channel *readPtr; /* Pointer to input channel. */ 42 struct Channel *writePtr; /* Pointer to output channel. */ 43 int readFlags; /* Original read channel flags. */ 44 int writeFlags; /* Original write channel flags. */ 45 int toRead; /* Number of bytes to copy, or -1. */ 46 int total; /* Total bytes transferred (written). */ 47 Tcl_Interp *interp; /* Interp that started the copy. */ 48 Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */ 49 int bufSize; /* Size of appended buffer. */ 50 char buffer[1]; /* Copy buffer, this must be the last 51 * field. */ 52} CopyState; 53 54/* 55 * struct ChannelBuffer: 56 * 57 * Buffers data being sent to or from a channel. 58 */ 59 60typedef struct ChannelBuffer { 61 int nextAdded; /* The next position into which a character 62 * will be put in the buffer. */ 63 int nextRemoved; /* Position of next byte to be removed 64 * from the buffer. */ 65 int bufLength; /* How big is the buffer? */ 66 struct ChannelBuffer *nextPtr; 67 /* Next buffer in chain. */ 68 char buf[4]; /* Placeholder for real buffer. The real 69 * buffer occuppies this space + bufSize-4 70 * bytes. This must be the last field in 71 * the structure. */ 72} ChannelBuffer; 73 74#define CHANNELBUFFER_HEADER_SIZE (sizeof(ChannelBuffer) - 4) 75 76/* 77 * How much extra space to allocate in buffer to hold bytes from previous 78 * buffer (when converting to UTF-8) or to hold bytes that will go to 79 * next buffer (when converting from UTF-8). 80 */ 81 82#define BUFFER_PADDING 16 83 84/* 85 * The following defines the *default* buffer size for channels. 86 */ 87 88#define CHANNELBUFFER_DEFAULT_SIZE (1024 * 4) 89 90/* 91 * Structure to record a close callback. One such record exists for 92 * each close callback registered for a channel. 93 */ 94 95typedef struct CloseCallback { 96 Tcl_CloseProc *proc; /* The procedure to call. */ 97 ClientData clientData; /* Arbitrary one-word data to pass 98 * to the callback. */ 99 struct CloseCallback *nextPtr; /* For chaining close callbacks. */ 100} CloseCallback; 101 102/* 103 * The following structure describes the information saved from a call to 104 * "fileevent". This is used later when the event being waited for to 105 * invoke the saved script in the interpreter designed in this record. 106 */ 107 108typedef struct EventScriptRecord { 109 struct Channel *chanPtr; /* The channel for which this script is 110 * registered. This is used only when an 111 * error occurs during evaluation of the 112 * script, to delete the handler. */ 113 Tcl_Obj *scriptPtr; /* Script to invoke. */ 114 Tcl_Interp *interp; /* In what interpreter to invoke script? */ 115 int mask; /* Events must overlap current mask for the 116 * stored script to be invoked. */ 117 struct EventScriptRecord *nextPtr; 118 /* Next in chain of records. */ 119} EventScriptRecord; 120 121/* 122 * struct Channel: 123 * 124 * One of these structures is allocated for each open channel. It contains data 125 * specific to the channel but which belongs to the generic part of the Tcl 126 * channel mechanism, and it points at an instance specific (and type 127 * specific) * instance data, and at a channel type structure. 128 */ 129 130typedef struct Channel { 131 struct ChannelState *state; /* Split out state information */ 132 133 ClientData instanceData; /* Instance-specific data provided by 134 * creator of channel. */ 135 Tcl_ChannelType *typePtr; /* Pointer to channel type structure. */ 136 137 struct Channel *downChanPtr;/* Refers to channel this one was stacked 138 * upon. This reference is NULL for normal 139 * channels. See Tcl_StackChannel. */ 140 struct Channel *upChanPtr; /* Refers to the channel above stacked this 141 * one. NULL for the top most channel. */ 142 143 /* 144 * Intermediate buffers to hold pre-read data for consumption by a 145 * newly stacked transformation. See 'Tcl_StackChannel'. 146 */ 147 ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */ 148 ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */ 149} Channel; 150 151/* 152 * struct ChannelState: 153 * 154 * One of these structures is allocated for each open channel. It contains data 155 * specific to the channel but which belongs to the generic part of the Tcl 156 * channel mechanism, and it points at an instance specific (and type 157 * specific) * instance data, and at a channel type structure. 158 */ 159 160typedef struct ChannelState { 161 CONST char *channelName; /* The name of the channel instance in Tcl 162 * commands. Storage is owned by the generic IO 163 * code, is dynamically allocated. */ 164 int flags; /* ORed combination of the flags defined 165 * below. */ 166 Tcl_Encoding encoding; /* Encoding to apply when reading or writing 167 * data on this channel. NULL means no 168 * encoding is applied to data. */ 169 Tcl_EncodingState inputEncodingState; 170 /* Current encoding state, used when converting 171 * input data bytes to UTF-8. */ 172 int inputEncodingFlags; /* Encoding flags to pass to conversion 173 * routine when converting input data bytes to 174 * UTF-8. May be TCL_ENCODING_START before 175 * converting first byte and TCL_ENCODING_END 176 * when EOF is seen. */ 177 Tcl_EncodingState outputEncodingState; 178 /* Current encoding state, used when converting 179 * UTF-8 to output data bytes. */ 180 int outputEncodingFlags; /* Encoding flags to pass to conversion 181 * routine when converting UTF-8 to output 182 * data bytes. May be TCL_ENCODING_START 183 * before converting first byte and 184 * TCL_ENCODING_END when EOF is seen. */ 185 TclEolTranslation inputTranslation; 186 /* What translation to apply for end of line 187 * sequences on input? */ 188 TclEolTranslation outputTranslation; 189 /* What translation to use for generating 190 * end of line sequences in output? */ 191 int inEofChar; /* If nonzero, use this as a signal of EOF 192 * on input. */ 193 int outEofChar; /* If nonzero, append this to the channel 194 * when it is closed if it is open for 195 * writing. */ 196 int unreportedError; /* Non-zero if an error report was deferred 197 * because it happened in the background. The 198 * value is the POSIX error code. */ 199 int refCount; /* How many interpreters hold references to 200 * this IO channel? */ 201 202 CloseCallback *closeCbPtr; /* Callbacks registered to be called when the 203 * channel is closed. */ 204 char *outputStage; /* Temporary staging buffer used when 205 * translating EOL before converting from 206 * UTF-8 to external form. */ 207 ChannelBuffer *curOutPtr; /* Current output buffer being filled. */ 208 ChannelBuffer *outQueueHead;/* Points at first buffer in output queue. */ 209 ChannelBuffer *outQueueTail;/* Points at last buffer in output queue. */ 210 211 ChannelBuffer *saveInBufPtr;/* Buffer saved for input queue - eliminates 212 * need to allocate a new buffer for "gets" 213 * that crosses buffer boundaries. */ 214 ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */ 215 ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */ 216 217 struct ChannelHandler *chPtr;/* List of channel handlers registered 218 * for this channel. */ 219 int interestMask; /* Mask of all events this channel has 220 * handlers for. */ 221 EventScriptRecord *scriptRecordPtr; 222 /* Chain of all scripts registered for 223 * event handlers ("fileevent") on this 224 * channel. */ 225 226 int bufSize; /* What size buffers to allocate? */ 227 Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ 228 CopyState *csPtrR; /* State of background copy for which channel is input, or NULL. */ 229 CopyState *csPtrW; /* State of background copy for which channel is output, or NULL. */ 230 Channel *topChanPtr; /* Refers to topmost channel in a stack. 231 * Never NULL. */ 232 Channel *bottomChanPtr; /* Refers to bottommost channel in a stack. 233 * This channel can be relied on to live as 234 * long as the channel state. Never NULL. */ 235 struct ChannelState *nextCSPtr; 236 /* Next in list of channels currently open. */ 237 Tcl_ThreadId managingThread; /* TIP #10: Id of the thread managing 238 * this stack of channels. */ 239} ChannelState; 240 241/* 242 * Values for the flags field in Channel. Any ORed combination of the 243 * following flags can be stored in the field. These flags record various 244 * options and state bits about the channel. In addition to the flags below, 245 * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set. 246 */ 247 248#define CHANNEL_NONBLOCKING (1<<3) /* Channel is currently in 249 * nonblocking mode. */ 250#define CHANNEL_LINEBUFFERED (1<<4) /* Output to the channel must be 251 * flushed after every newline. */ 252#define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always 253 * be flushed immediately. */ 254#define BUFFER_READY (1<<6) /* Current output buffer (the 255 * curOutPtr field in the 256 * channel structure) should be 257 * output as soon as possible even 258 * though it may not be full. */ 259#define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the 260 * queued output buffers has been 261 * scheduled. */ 262#define CHANNEL_CLOSED (1<<8) /* Channel has been closed. No 263 * further Tcl-level IO on the 264 * channel is allowed. */ 265#define CHANNEL_EOF (1<<9) /* EOF occurred on this channel. 266 * This bit is cleared before every 267 * input operation. */ 268#define CHANNEL_STICKY_EOF (1<<10) /* EOF occurred on this channel because 269 * we saw the input eofChar. This bit 270 * prevents clearing of the EOF bit 271 * before every input operation. */ 272#define CHANNEL_BLOCKED (1<<11) /* EWOULDBLOCK or EAGAIN occurred 273 * on this channel. This bit is 274 * cleared before every input or 275 * output operation. */ 276#define INPUT_SAW_CR (1<<12) /* Channel is in CRLF eol input 277 * translation mode and the last 278 * byte seen was a "\r". */ 279#define INPUT_NEED_NL (1<<15) /* Saw a '\r' at end of last buffer, 280 * and there should be a '\n' at 281 * beginning of next buffer. */ 282#define CHANNEL_DEAD (1<<13) /* The channel has been closed by 283 * the exit handler (on exit) but 284 * not deallocated. When any IO 285 * operation sees this flag on a 286 * channel, it does not call driver 287 * level functions to avoid referring 288 * to deallocated data. */ 289#define CHANNEL_NEED_MORE_DATA (1<<14) /* The last input operation failed 290 * because there was not enough data 291 * to complete the operation. This 292 * flag is set when gets fails to 293 * get a complete line or when read 294 * fails to get a complete character. 295 * When set, file events will not be 296 * delivered for buffered data until 297 * the state of the channel changes. */ 298#define CHANNEL_RAW_MODE (1<<16) /* When set, notes that the Raw API is 299 * being used. */ 300#ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING 301#define CHANNEL_TIMER_FEV (1<<17) /* When set the event we are 302 * notified by is a fileevent 303 * generated by a timer. We 304 * don't know if the driver 305 * has more data and should 306 * not try to read from it. If 307 * the system needs more than 308 * is in the buffers out read 309 * routines will simulate a 310 * short read (0 characters 311 * read) */ 312#define CHANNEL_HAS_MORE_DATA (1<<18) /* Set by NotifyChannel for a 313 * channel if and only if the 314 * channel is configured 315 * non-blocking, the driver 316 * for said channel has no 317 * blockmodeproc, and data has 318 * arrived for reading at the 319 * OS level). A GetInput will 320 * pass reading from the 321 * driver if the channel is 322 * non-blocking, without 323 * blockmode proc and the flag 324 * has not been set. A read 325 * will be performed if the 326 * flag is set. This will 327 * reset the flag as well. */ 328#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */ 329 330#define CHANNEL_INCLOSE (1<<19) /* Channel is currently being 331 * closed. Its structures are 332 * still live and usable, but 333 * it may not be closed again 334 * from within the close handler. 335 */ 336 337/* 338 * For each channel handler registered in a call to Tcl_CreateChannelHandler, 339 * there is one record of the following type. All of records for a specific 340 * channel are chained together in a singly linked list which is stored in 341 * the channel structure. 342 */ 343 344typedef struct ChannelHandler { 345 Channel *chanPtr; /* The channel structure for this channel. */ 346 int mask; /* Mask of desired events. */ 347 Tcl_ChannelProc *proc; /* Procedure to call in the type of 348 * Tcl_CreateChannelHandler. */ 349 ClientData clientData; /* Argument to pass to procedure. */ 350 struct ChannelHandler *nextPtr; 351 /* Next one in list of registered handlers. */ 352} ChannelHandler; 353 354/* 355 * This structure keeps track of the current ChannelHandler being invoked in 356 * the current invocation of ChannelHandlerEventProc. There is a potential 357 * problem if a ChannelHandler is deleted while it is the current one, since 358 * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this 359 * problem, structures of the type below indicate the next handler to be 360 * processed for any (recursively nested) dispatches in progress. The 361 * nextHandlerPtr field is updated if the handler being pointed to is deleted. 362 * The nextPtr field is used to chain together all recursive invocations, so 363 * that Tcl_DeleteChannelHandler can find all the recursively nested 364 * invocations of ChannelHandlerEventProc and compare the handler being 365 * deleted against the NEXT handler to be invoked in that invocation; when it 366 * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr 367 * field of the structure to the next handler. 368 */ 369 370typedef struct NextChannelHandler { 371 ChannelHandler *nextHandlerPtr; /* The next handler to be invoked in 372 * this invocation. */ 373 struct NextChannelHandler *nestedHandlerPtr; 374 /* Next nested invocation of 375 * ChannelHandlerEventProc. */ 376} NextChannelHandler; 377 378 379/* 380 * The following structure describes the event that is added to the Tcl 381 * event queue by the channel handler check procedure. 382 */ 383 384typedef struct ChannelHandlerEvent { 385 Tcl_Event header; /* Standard header for all events. */ 386 Channel *chanPtr; /* The channel that is ready. */ 387 int readyMask; /* Events that have occurred. */ 388} ChannelHandlerEvent; 389 390/* 391 * The following structure is used by Tcl_GetsObj() to encapsulates the 392 * state for a "gets" operation. 393 */ 394 395typedef struct GetsState { 396 Tcl_Obj *objPtr; /* The object to which UTF-8 characters 397 * will be appended. */ 398 char **dstPtr; /* Pointer into objPtr's string rep where 399 * next character should be stored. */ 400 Tcl_Encoding encoding; /* The encoding to use to convert raw bytes 401 * to UTF-8. */ 402 ChannelBuffer *bufPtr; /* The current buffer of raw bytes being 403 * emptied. */ 404 Tcl_EncodingState state; /* The encoding state just before the last 405 * external to UTF-8 conversion in 406 * FilterInputBytes(). */ 407 int rawRead; /* The number of bytes removed from bufPtr 408 * in the last call to FilterInputBytes(). */ 409 int bytesWrote; /* The number of bytes of UTF-8 data 410 * appended to objPtr during the last call to 411 * FilterInputBytes(). */ 412 int charsWrote; /* The corresponding number of UTF-8 413 * characters appended to objPtr during the 414 * last call to FilterInputBytes(). */ 415 int totalChars; /* The total number of UTF-8 characters 416 * appended to objPtr so far, just before the 417 * last call to FilterInputBytes(). */ 418} GetsState; 419