tclIO.h
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:17k
- /*
- * tclIO.h --
- *
- * This file provides the generic portions (those that are the same on
- * all platforms and for all channel types) of Tcl's IO facilities.
- *
- * 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.5.4.2 2004/07/15 20:46:19 andreas_kupries Exp $
- */
- /*
- * 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.
- */
- #if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN)))
- # define EWOULDBLOCK EAGAIN
- #endif
- #if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK)))
- # define EAGAIN EWOULDBLOCK
- #endif
- #if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK)))
- 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 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. */
- 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. */
- } ChannelBuffer;
- #define CHANNELBUFFER_HEADER_SIZE (sizeof(ChannelBuffer) - 4)
- /*
- * 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.
- */
- #define CHANNELBUFFER_DEFAULT_SIZE (1024 * 4)
- /*
- * Structure to record a close callback. One such record exists for
- * each close callback registered for a channel.
- */
- 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;
- /*
- * 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.
- */
- 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. */
- Tcl_Obj *scriptPtr; /* Script to invoke. */
- Tcl_Interp *interp; /* In what interpreter to invoke script? */
- int mask; /* Events must overlap current mask for the
- * stored script to be invoked. */
- struct EventScriptRecord *nextPtr;
- /* Next in chain of records. */
- } 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.
- */
- 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. */
- struct Channel *downChanPtr;/* Refers to channel this one was stacked
- * 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'.
- */
- ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */
- ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */
- } 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.
- */
- 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. */
- 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
- * encoding is applied to data. */
- Tcl_EncodingState inputEncodingState;
- /* 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
- * 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. */
- int outputEncodingFlags; /* Encoding flags to pass to conversion
- * routine when converting UTF-8 to output
- * 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? */
- 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. */
- 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
- * channel is closed. */
- char *outputStage; /* Temporary staging buffer used when
- * translating EOL before converting from
- * UTF-8 to external form. */
- 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. */
- 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. */
- 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. */
- 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. */
- } 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
- * options and state bits about the channel. In addition to the flags below,
- * 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_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. */
- #define INPUT_SAW_CR (1<<12) /* Channel is in CRLF eol input
- * 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_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
- * delivered for buffered data until
- * 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
- * for said channel has no
- * 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. */
- #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;
- /*
- * The following structure describes the event that is added to the Tcl
- * event queue by the channel handler check procedure.
- */
- 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;
- /*
- * The following structure is used by Tcl_GetsObj() to encapsulates the
- * state for a "gets" operation.
- */
-
- 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;