diff options
Diffstat (limited to 'generic/tclIO.h')
-rw-r--r-- | generic/tclIO.h | 431 |
1 files changed, 164 insertions, 267 deletions
diff --git a/generic/tclIO.h b/generic/tclIO.h index 9ec4abc..1e02749 100644 --- a/generic/tclIO.h +++ b/generic/tclIO.h @@ -1,4 +1,4 @@ -/* +/* * tclIO.h -- * * This file provides the generic portions (those that are the same on @@ -7,18 +7,16 @@ * Copyright (c) 1998-2000 Ajuba Solutions * Copyright (c) 1995-1997 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclIO.h,v 1.8 2005/08/24 17:56:23 andreas_kupries Exp $ + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ /* * Make sure that both EAGAIN and EWOULDBLOCK are defined. This does not - * compile on systems where neither is defined. We want both defined so - * that we can test safely for both. In the code we still have to test for - * both because there may be systems on which both are defined and have - * different values. + * compile on systems where neither is defined. We want both defined so that + * we can test safely for both. In the code we still have to test for both + * because there may be systems on which both are defined and have different + * values. */ #if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN))) @@ -28,88 +26,57 @@ # define EAGAIN EWOULDBLOCK #endif #if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK))) -error one of EWOULDBLOCK or EAGAIN must be defined +#error one of EWOULDBLOCK or EAGAIN must be defined #endif /* - * The following structure encapsulates the state for a background channel - * copy. Note that the data buffer for the copy will be appended to this - * structure. - */ - -typedef struct CopyState { - struct Channel *readPtr; /* Pointer to input channel. */ - struct Channel *writePtr; /* Pointer to output channel. */ - int readFlags; /* Original read channel flags. */ - int writeFlags; /* Original write channel flags. */ - int toRead; /* Number of bytes to copy, or -1. */ - int total; /* Total bytes transferred (written). */ - Tcl_Interp *interp; /* Interp that started the copy. */ - Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */ - int bufSize; /* Size of appended buffer. */ - char buffer[1]; /* Copy buffer, this must be the last - * field. */ -} CopyState; - -/* * struct ChannelBuffer: * * Buffers data being sent to or from a channel. */ typedef struct ChannelBuffer { + int refCount; /* Current uses count */ int nextAdded; /* The next position into which a character - * will be put in the buffer. */ - int nextRemoved; /* Position of next byte to be removed - * from the buffer. */ + * will be put in the buffer. */ + int nextRemoved; /* Position of next byte to be removed from + * the buffer. */ int bufLength; /* How big is the buffer? */ struct ChannelBuffer *nextPtr; /* Next buffer in chain. */ - char buf[4]; /* Placeholder for real buffer. The real - * buffer occuppies this space + bufSize-4 - * bytes. This must be the last field in - * the structure. */ + char buf[1]; /* Placeholder for real buffer. The real + * buffer occuppies this space + bufSize-1 + * bytes. This must be the last field in the + * structure. */ } ChannelBuffer; -#define CHANNELBUFFER_HEADER_SIZE (sizeof(ChannelBuffer) - 4) +#define CHANNELBUFFER_HEADER_SIZE TclOffset(ChannelBuffer, buf) /* * How much extra space to allocate in buffer to hold bytes from previous - * buffer (when converting to UTF-8) or to hold bytes that will go to - * next buffer (when converting from UTF-8). - */ - -#define BUFFER_PADDING 16 - -/* - * The following defines the *default* buffer size for channels. + * buffer (when converting to UTF-8) or to hold bytes that will go to next + * buffer (when converting from UTF-8). */ -#define CHANNELBUFFER_DEFAULT_SIZE (1024 * 4) +#define BUFFER_PADDING 16 /* - * Structure to record a close callback. One such record exists for - * each close callback registered for a channel. + * The following defines the *default* buffer size for channels. */ -typedef struct CloseCallback { - Tcl_CloseProc *proc; /* The procedure to call. */ - ClientData clientData; /* Arbitrary one-word data to pass - * to the callback. */ - struct CloseCallback *nextPtr; /* For chaining close callbacks. */ -} CloseCallback; +#define CHANNELBUFFER_DEFAULT_SIZE (1024 * 4) /* * The following structure describes the information saved from a call to - * "fileevent". This is used later when the event being waited for to - * invoke the saved script in the interpreter designed in this record. + * "fileevent". This is used later when the event being waited for to invoke + * the saved script in the interpreter designed in this record. */ typedef struct EventScriptRecord { struct Channel *chanPtr; /* The channel for which this script is - * registered. This is used only when an - * error occurs during evaluation of the - * script, to delete the handler. */ + * registered. This is used only when an error + * occurs during evaluation of the script, to + * delete the handler. */ Tcl_Obj *scriptPtr; /* Script to invoke. */ Tcl_Interp *interp; /* In what interpreter to invoke script? */ int mask; /* Events must overlap current mask for the @@ -121,29 +88,28 @@ typedef struct EventScriptRecord { /* * struct Channel: * - * One of these structures is allocated for each open channel. It contains data - * specific to the channel but which belongs to the generic part of the Tcl - * channel mechanism, and it points at an instance specific (and type - * specific) * instance data, and at a channel type structure. + * One of these structures is allocated for each open channel. It contains + * data specific to the channel but which belongs to the generic part of the + * Tcl channel mechanism, and it points at an instance specific (and type + * specific) instance data, and at a channel type structure. */ typedef struct Channel { struct ChannelState *state; /* Split out state information */ - - ClientData instanceData; /* Instance-specific data provided by - * creator of channel. */ - Tcl_ChannelType *typePtr; /* Pointer to channel type structure. */ - + ClientData instanceData; /* Instance-specific data provided by creator + * of channel. */ + const Tcl_ChannelType *typePtr; /* Pointer to channel type structure. */ struct Channel *downChanPtr;/* Refers to channel this one was stacked - * upon. This reference is NULL for normal - * channels. See Tcl_StackChannel. */ + * upon. This reference is NULL for normal + * channels. See Tcl_StackChannel. */ struct Channel *upChanPtr; /* Refers to the channel above stacked this * one. NULL for the top most channel. */ /* - * Intermediate buffers to hold pre-read data for consumption by a - * newly stacked transformation. See 'Tcl_StackChannel'. + * Intermediate buffers to hold pre-read data for consumption by a newly + * stacked transformation. See 'Tcl_StackChannel'. */ + ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */ ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */ } Channel; @@ -151,55 +117,54 @@ typedef struct Channel { /* * struct ChannelState: * - * One of these structures is allocated for each open channel. It contains data - * specific to the channel but which belongs to the generic part of the Tcl - * channel mechanism, and it points at an instance specific (and type - * specific) * instance data, and at a channel type structure. + * One of these structures is allocated for each open channel. It contains + * data specific to the channel but which belongs to the generic part of the + * Tcl channel mechanism, and it points at an instance specific (and type + * specific) instance data, and at a channel type structure. */ typedef struct ChannelState { - CONST char *channelName; /* The name of the channel instance in Tcl - * commands. Storage is owned by the generic IO - * code, is dynamically allocated. */ + const char *channelName; /* The name of the channel instance in Tcl + * commands. Storage is owned by the generic + * IO code, is dynamically allocated. */ int flags; /* ORed combination of the flags defined * below. */ Tcl_Encoding encoding; /* Encoding to apply when reading or writing - * data on this channel. NULL means no + * data on this channel. NULL means no * encoding is applied to data. */ Tcl_EncodingState inputEncodingState; - /* Current encoding state, used when converting - * input data bytes to UTF-8. */ + /* Current encoding state, used when + * converting input data bytes to UTF-8. */ int inputEncodingFlags; /* Encoding flags to pass to conversion * routine when converting input data bytes to - * UTF-8. May be TCL_ENCODING_START before + * UTF-8. May be TCL_ENCODING_START before * converting first byte and TCL_ENCODING_END * when EOF is seen. */ Tcl_EncodingState outputEncodingState; - /* Current encoding state, used when converting - * UTF-8 to output data bytes. */ + /* Current encoding state, used when + * converting UTF-8 to output data bytes. */ int outputEncodingFlags; /* Encoding flags to pass to conversion * routine when converting UTF-8 to output - * data bytes. May be TCL_ENCODING_START + * data bytes. May be TCL_ENCODING_START * before converting first byte and * TCL_ENCODING_END when EOF is seen. */ TclEolTranslation inputTranslation; /* What translation to apply for end of line - * sequences on input? */ + * sequences on input? */ TclEolTranslation outputTranslation; - /* What translation to use for generating - * end of line sequences in output? */ - int inEofChar; /* If nonzero, use this as a signal of EOF - * on input. */ - int outEofChar; /* If nonzero, append this to the channel - * when it is closed if it is open for - * writing. */ + /* What translation to use for generating end + * of line sequences in output? */ + int inEofChar; /* If nonzero, use this as a signal of EOF on + * input. */ + int outEofChar; /* If nonzero, append this to the channel when + * it is closed if it is open for writing. */ int unreportedError; /* Non-zero if an error report was deferred * because it happened in the background. The * value is the POSIX error code. */ int refCount; /* How many interpreters hold references to * this IO channel? */ - - CloseCallback *closeCbPtr; /* Callbacks registered to be called when the + struct CloseCallback *closeCbPtr; + /* Callbacks registered to be called when the * channel is closed. */ char *outputStage; /* Temporary staging buffer used when * translating EOL before converting from @@ -207,50 +172,48 @@ typedef struct ChannelState { ChannelBuffer *curOutPtr; /* Current output buffer being filled. */ ChannelBuffer *outQueueHead;/* Points at first buffer in output queue. */ ChannelBuffer *outQueueTail;/* Points at last buffer in output queue. */ - ChannelBuffer *saveInBufPtr;/* Buffer saved for input queue - eliminates * need to allocate a new buffer for "gets" * that crosses buffer boundaries. */ ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */ ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */ - - struct ChannelHandler *chPtr;/* List of channel handlers registered - * for this channel. */ + struct ChannelHandler *chPtr;/* List of channel handlers registered for + * this channel. */ int interestMask; /* Mask of all events this channel has * handlers for. */ EventScriptRecord *scriptRecordPtr; - /* Chain of all scripts registered for - * event handlers ("fileevent") on this - * channel. */ - + /* Chain of all scripts registered for event + * handlers ("fileevent") on this channel. */ int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ - CopyState *csPtr; /* State of background copy, or NULL. */ - Channel *topChanPtr; /* Refers to topmost channel in a stack. - * Never NULL. */ + struct CopyState *csPtrR; /* State of background copy for which channel + * is input, or NULL. */ + struct CopyState *csPtrW; /* State of background copy for which channel + * is output, or NULL. */ + Channel *topChanPtr; /* Refers to topmost channel in a stack. Never + * NULL. */ Channel *bottomChanPtr; /* Refers to bottommost channel in a stack. * This channel can be relied on to live as * long as the channel state. Never NULL. */ struct ChannelState *nextCSPtr; /* Next in list of channels currently open. */ - Tcl_ThreadId managingThread; /* TIP #10: Id of the thread managing - * this stack of channels. */ + Tcl_ThreadId managingThread;/* TIP #10: Id of the thread managing this + * stack of channels. */ - /* TIP #219 ... Info for the I/O system ... - * Error message set by channel drivers, for the propagation of - * arbitrary Tcl errors. This information, if present (chanMsg not - * NULL), takes precedence over a posix error code returned by a - * channel operation. + /* + * TIP #219 ... Info for the I/O system ... + * Error message set by channel drivers, for the propagation of arbitrary + * Tcl errors. This information, if present (chanMsg not NULL), takes + * precedence over a posix error code returned by a channel operation. */ Tcl_Obj* chanMsg; - Tcl_Obj* unreportedMsg; /* Non-NULL if an error report was - * deferred because it happened in the - * background. The value is the - * chanMg, if any. #219's companion to - * 'unreportedError'. */ + Tcl_Obj* unreportedMsg; /* Non-NULL if an error report was deferred + * because it happened in the background. The + * value is the chanMg, if any. #219's + * companion to 'unreportedError'. */ } ChannelState; - + /* * Values for the flags field in Channel. Any ORed combination of the * following flags can be stored in the field. These flags record various @@ -258,174 +221,108 @@ typedef struct ChannelState { * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set. */ -#define CHANNEL_NONBLOCKING (1<<3) /* Channel is currently in - * nonblocking mode. */ +#define CHANNEL_NONBLOCKING (1<<3) /* Channel is currently in nonblocking + * mode. */ #define CHANNEL_LINEBUFFERED (1<<4) /* Output to the channel must be * flushed after every newline. */ #define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always * be flushed immediately. */ #define BUFFER_READY (1<<6) /* Current output buffer (the - * curOutPtr field in the - * channel structure) should be - * output as soon as possible even - * though it may not be full. */ -#define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the - * queued output buffers has been - * scheduled. */ -#define CHANNEL_CLOSED (1<<8) /* Channel has been closed. No - * further Tcl-level IO on the - * channel is allowed. */ -#define CHANNEL_EOF (1<<9) /* EOF occurred on this channel. - * This bit is cleared before every - * input operation. */ -#define CHANNEL_STICKY_EOF (1<<10) /* EOF occurred on this channel because - * we saw the input eofChar. This bit - * prevents clearing of the EOF bit - * before every input operation. */ -#define CHANNEL_BLOCKED (1<<11) /* EWOULDBLOCK or EAGAIN occurred - * on this channel. This bit is - * cleared before every input or - * output operation. */ + * curOutPtr field in the channel + * structure) should be output as soon + * as possible even though it may not + * be full. */ +#define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the queued + * output buffers has been + * scheduled. */ +#define CHANNEL_CLOSED (1<<8) /* Channel has been closed. No further + * Tcl-level IO on the channel is + * allowed. */ +#define CHANNEL_EOF (1<<9) /* EOF occurred on this channel. This + * bit is cleared before every input + * operation. */ +#define CHANNEL_STICKY_EOF (1<<10) /* EOF occurred on this channel + * because we saw the input + * eofChar. This bit prevents clearing + * of the EOF bit before every input + * operation. */ +#define CHANNEL_BLOCKED (1<<11) /* EWOULDBLOCK or EAGAIN occurred on + * this channel. This bit is cleared + * before every input or output + * operation. */ #define INPUT_SAW_CR (1<<12) /* Channel is in CRLF eol input - * translation mode and the last - * byte seen was a "\r". */ + * translation mode and the last byte + * seen was a "\r". */ #define INPUT_NEED_NL (1<<15) /* Saw a '\r' at end of last buffer, * and there should be a '\n' at * beginning of next buffer. */ -#define CHANNEL_DEAD (1<<13) /* The channel has been closed by - * the exit handler (on exit) but - * not deallocated. When any IO - * operation sees this flag on a - * channel, it does not call driver - * level functions to avoid referring - * to deallocated data. */ +#define CHANNEL_DEAD (1<<13) /* The channel has been closed by the + * exit handler (on exit) but not + * deallocated. When any IO operation + * sees this flag on a channel, it + * does not call driver level + * functions to avoid referring to + * deallocated data. */ #define CHANNEL_NEED_MORE_DATA (1<<14) /* The last input operation failed * because there was not enough data - * to complete the operation. This - * flag is set when gets fails to - * get a complete line or when read - * fails to get a complete character. - * When set, file events will not be + * to complete the operation. This + * flag is set when gets fails to get + * a complete line or when read fails + * to get a complete character. When + * set, file events will not be * delivered for buffered data until - * the state of the channel changes. */ + * the state of the channel + * changes. */ #define CHANNEL_RAW_MODE (1<<16) /* When set, notes that the Raw API is * being used. */ #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING -#define CHANNEL_TIMER_FEV (1<<17) /* When set the event we are - * notified by is a fileevent - * generated by a timer. We - * don't know if the driver - * has more data and should - * not try to read from it. If - * the system needs more than - * is in the buffers out read - * routines will simulate a - * short read (0 characters - * read) */ -#define CHANNEL_HAS_MORE_DATA (1<<18) /* Set by NotifyChannel for a - * channel if and only if the - * channel is configured - * non-blocking, the driver +#define CHANNEL_TIMER_FEV (1<<17) /* When set the event we are notified + * by is a fileevent generated by a + * timer. We don't know if the driver + * has more data and should not try to + * read from it. If the system needs + * more than is in the buffers out + * read routines will simulate a short + * read (0 characters read) */ +#define CHANNEL_HAS_MORE_DATA (1<<18) /* Set by NotifyChannel for a channel + * if and only if the channel is + * configured non-blocking, the driver * for said channel has no - * blockmodeproc, and data has - * arrived for reading at the - * OS level). A GetInput will - * pass reading from the + * blockmodeproc, and data has arrived + * for reading at the OS level). A + * GetInput will pass reading from the * driver if the channel is - * non-blocking, without - * blockmode proc and the flag - * has not been set. A read - * will be performed if the - * flag is set. This will - * reset the flag as well. */ + * non-blocking, without blockmode + * proc and the flag has not been set. + * A read will be performed if the + * flag is set. This will reset the + * flag as well. */ #endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */ -#define CHANNEL_INCLOSE (1<<19) /* Channel is currently being - * closed. Its structures are - * still live and usable, but - * it may not be closed again - * from within the close handler. - */ - -/* - * For each channel handler registered in a call to Tcl_CreateChannelHandler, - * there is one record of the following type. All of records for a specific - * channel are chained together in a singly linked list which is stored in - * the channel structure. - */ - -typedef struct ChannelHandler { - Channel *chanPtr; /* The channel structure for this channel. */ - int mask; /* Mask of desired events. */ - Tcl_ChannelProc *proc; /* Procedure to call in the type of - * Tcl_CreateChannelHandler. */ - ClientData clientData; /* Argument to pass to procedure. */ - struct ChannelHandler *nextPtr; - /* Next one in list of registered handlers. */ -} ChannelHandler; - -/* - * This structure keeps track of the current ChannelHandler being invoked in - * the current invocation of ChannelHandlerEventProc. There is a potential - * problem if a ChannelHandler is deleted while it is the current one, since - * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this - * problem, structures of the type below indicate the next handler to be - * processed for any (recursively nested) dispatches in progress. The - * nextHandlerPtr field is updated if the handler being pointed to is deleted. - * The nextPtr field is used to chain together all recursive invocations, so - * that Tcl_DeleteChannelHandler can find all the recursively nested - * invocations of ChannelHandlerEventProc and compare the handler being - * deleted against the NEXT handler to be invoked in that invocation; when it - * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr - * field of the structure to the next handler. - */ - -typedef struct NextChannelHandler { - ChannelHandler *nextHandlerPtr; /* The next handler to be invoked in - * this invocation. */ - struct NextChannelHandler *nestedHandlerPtr; - /* Next nested invocation of - * ChannelHandlerEventProc. */ -} NextChannelHandler; - +#define CHANNEL_INCLOSE (1<<19) /* Channel is currently being closed. + * Its structures are still live and + * usable, but it may not be closed + * again from within the close + * handler. */ +#define CHANNEL_TAINTED (1<<20) /* Channel stack structure has changed. + * Used by Channel Tcl_Obj type to + * determine if we have to revalidate + * the channel. */ +#define CHANNEL_CLOSEDWRITE (1<<21) /* Channel write side has been closed. + * No further Tcl-level write IO on + * the channel is allowed. */ /* - * The following structure describes the event that is added to the Tcl - * event queue by the channel handler check procedure. + * The length of time to wait between synthetic timer events. Must be zero or + * bad things tend to happen. */ -typedef struct ChannelHandlerEvent { - Tcl_Event header; /* Standard header for all events. */ - Channel *chanPtr; /* The channel that is ready. */ - int readyMask; /* Events that have occurred. */ -} ChannelHandlerEvent; - +#define SYNTHETIC_EVENT_TIME 0 + /* - * The following structure is used by Tcl_GetsObj() to encapsulates the - * state for a "gets" operation. + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: */ - -typedef struct GetsState { - Tcl_Obj *objPtr; /* The object to which UTF-8 characters - * will be appended. */ - char **dstPtr; /* Pointer into objPtr's string rep where - * next character should be stored. */ - Tcl_Encoding encoding; /* The encoding to use to convert raw bytes - * to UTF-8. */ - ChannelBuffer *bufPtr; /* The current buffer of raw bytes being - * emptied. */ - Tcl_EncodingState state; /* The encoding state just before the last - * external to UTF-8 conversion in - * FilterInputBytes(). */ - int rawRead; /* The number of bytes removed from bufPtr - * in the last call to FilterInputBytes(). */ - int bytesWrote; /* The number of bytes of UTF-8 data - * appended to objPtr during the last call to - * FilterInputBytes(). */ - int charsWrote; /* The corresponding number of UTF-8 - * characters appended to objPtr during the - * last call to FilterInputBytes(). */ - int totalChars; /* The total number of UTF-8 characters - * appended to objPtr so far, just before the - * last call to FilterInputBytes(). */ -} GetsState; |