tclIO.h

Go to the documentation of this file.
00001 /*
00002  * tclIO.h --
00003  *
00004  *      This file provides the generic portions (those that are the same on
00005  *      all platforms and for all channel types) of Tcl's IO facilities.
00006  *
00007  * Copyright (c) 1998-2000 Ajuba Solutions
00008  * Copyright (c) 1995-1997 Sun Microsystems, Inc.
00009  *
00010  * See the file "license.terms" for information on usage and redistribution of
00011  * this file, and for a DISCLAIMER OF ALL WARRANTIES.
00012  *
00013  * RCS: @(#) $Id: tclIO.h,v 1.11 2007/12/13 15:23:18 dgp Exp $
00014  */
00015 
00016 /*
00017  * Make sure that both EAGAIN and EWOULDBLOCK are defined. This does not
00018  * compile on systems where neither is defined. We want both defined so that
00019  * we can test safely for both. In the code we still have to test for both
00020  * because there may be systems on which both are defined and have different
00021  * values.
00022  */
00023 
00024 #if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN)))
00025 #   define EWOULDBLOCK EAGAIN
00026 #endif
00027 #if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK)))
00028 #   define EAGAIN EWOULDBLOCK
00029 #endif
00030 #if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK)))
00031 #error one of EWOULDBLOCK or EAGAIN must be defined
00032 #endif
00033 
00034 /*
00035  * The following structure encapsulates the state for a background channel
00036  * copy. Note that the data buffer for the copy will be appended to this
00037  * structure.
00038  */
00039 
00040 typedef struct CopyState {
00041     struct Channel *readPtr;    /* Pointer to input channel. */
00042     struct Channel *writePtr;   /* Pointer to output channel. */
00043     int readFlags;              /* Original read channel flags. */
00044     int writeFlags;             /* Original write channel flags. */
00045     int toRead;                 /* Number of bytes to copy, or -1. */
00046     int total;                  /* Total bytes transferred (written). */
00047     Tcl_Interp *interp;         /* Interp that started the copy. */
00048     Tcl_Obj *cmdPtr;            /* Command to be invoked at completion. */
00049     int bufSize;                /* Size of appended buffer. */
00050     char buffer[1];             /* Copy buffer, this must be the last
00051                                  * field. */
00052 } CopyState;
00053 
00054 /*
00055  * struct ChannelBuffer:
00056  *
00057  * Buffers data being sent to or from a channel.
00058  */
00059 
00060 typedef struct ChannelBuffer {
00061     int nextAdded;              /* The next position into which a character
00062                                  * will be put in the buffer. */
00063     int nextRemoved;            /* Position of next byte to be removed from
00064                                  * the buffer. */
00065     int bufLength;              /* How big is the buffer? */
00066     struct ChannelBuffer *nextPtr;
00067                                 /* Next buffer in chain. */
00068     char buf[4];                /* Placeholder for real buffer. The real
00069                                  * buffer occuppies this space + bufSize-4
00070                                  * bytes. This must be the last field in the
00071                                  * structure. */
00072 } ChannelBuffer;
00073 
00074 #define CHANNELBUFFER_HEADER_SIZE       (sizeof(ChannelBuffer) - 4)
00075 
00076 /*
00077  * How much extra space to allocate in buffer to hold bytes from previous
00078  * buffer (when converting to UTF-8) or to hold bytes that will go to next
00079  * buffer (when converting from UTF-8).
00080  */
00081 
00082 #define BUFFER_PADDING          16
00083 
00084 /*
00085  * The following defines the *default* buffer size for channels.
00086  */
00087 
00088 #define CHANNELBUFFER_DEFAULT_SIZE      (1024 * 4)
00089 
00090 /*
00091  * Structure to record a close callback. One such record exists for each close
00092  * callback registered for a channel.
00093  */
00094 
00095 typedef struct CloseCallback {
00096     Tcl_CloseProc *proc;        /* The procedure to call. */
00097     ClientData clientData;      /* Arbitrary one-word data to pass to the
00098                                  * callback. */
00099     struct CloseCallback *nextPtr;
00100                                 /* For chaining close callbacks. */
00101 } CloseCallback;
00102 
00103 /*
00104  * The following structure describes the information saved from a call to
00105  * "fileevent". This is used later when the event being waited for to invoke
00106  * the saved script in the interpreter designed in this record.
00107  */
00108 
00109 typedef struct EventScriptRecord {
00110     struct Channel *chanPtr;    /* The channel for which this script is
00111                                  * registered. This is used only when an error
00112                                  * occurs during evaluation of the script, to
00113                                  * delete the handler. */
00114     Tcl_Obj *scriptPtr;         /* Script to invoke. */
00115     Tcl_Interp *interp;         /* In what interpreter to invoke script? */
00116     int mask;                   /* Events must overlap current mask for the
00117                                  * stored script to be invoked. */
00118     struct EventScriptRecord *nextPtr;
00119                                 /* Next in chain of records. */
00120 } EventScriptRecord;
00121 
00122 /*
00123  * struct Channel:
00124  *
00125  * One of these structures is allocated for each open channel. It contains
00126  * data specific to the channel but which belongs to the generic part of the
00127  * Tcl channel mechanism, and it points at an instance specific (and type
00128  * specific) instance data, and at a channel type structure.
00129  */
00130 
00131 typedef struct Channel {
00132     struct ChannelState *state; /* Split out state information */
00133     ClientData instanceData;    /* Instance-specific data provided by creator
00134                                  * of channel. */
00135     Tcl_ChannelType *typePtr;   /* Pointer to channel type structure. */
00136     struct Channel *downChanPtr;/* Refers to channel this one was stacked
00137                                  * upon. This reference is NULL for normal
00138                                  * channels. See Tcl_StackChannel. */
00139     struct Channel *upChanPtr;  /* Refers to the channel above stacked this
00140                                  * one. NULL for the top most channel. */
00141 
00142     /*
00143      * Intermediate buffers to hold pre-read data for consumption by a newly
00144      * stacked transformation. See 'Tcl_StackChannel'.
00145      */
00146 
00147     ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */
00148     ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */
00149 } Channel;
00150 
00151 /*
00152  * struct ChannelState:
00153  *
00154  * One of these structures is allocated for each open channel. It contains
00155  * data specific to the channel but which belongs to the generic part of the
00156  * Tcl channel mechanism, and it points at an instance specific (and type
00157  * specific) instance data, and at a channel type structure.
00158  */
00159 
00160 typedef struct ChannelState {
00161     CONST char *channelName;    /* The name of the channel instance in Tcl
00162                                  * commands. Storage is owned by the generic
00163                                  * IO code, is dynamically allocated. */
00164     int flags;                  /* ORed combination of the flags defined
00165                                  * below. */
00166     Tcl_Encoding encoding;      /* Encoding to apply when reading or writing
00167                                  * data on this channel. NULL means no
00168                                  * encoding is applied to data. */
00169     Tcl_EncodingState inputEncodingState;
00170                                 /* Current encoding state, used when
00171                                  * converting input data bytes to UTF-8. */
00172     int inputEncodingFlags;     /* Encoding flags to pass to conversion
00173                                  * routine when converting input data bytes to
00174                                  * UTF-8. May be TCL_ENCODING_START before
00175                                  * converting first byte and TCL_ENCODING_END
00176                                  * when EOF is seen. */
00177     Tcl_EncodingState outputEncodingState;
00178                                 /* Current encoding state, used when
00179                                  * converting UTF-8 to output data bytes. */
00180     int outputEncodingFlags;    /* Encoding flags to pass to conversion
00181                                  * routine when converting UTF-8 to output
00182                                  * data bytes. May be TCL_ENCODING_START
00183                                  * before converting first byte and
00184                                  * TCL_ENCODING_END when EOF is seen. */
00185     TclEolTranslation inputTranslation;
00186                                 /* What translation to apply for end of line
00187                                  * sequences on input? */
00188     TclEolTranslation outputTranslation;
00189                                 /* What translation to use for generating end
00190                                  * of line sequences in output? */
00191     int inEofChar;              /* If nonzero, use this as a signal of EOF on
00192                                  * input. */
00193     int outEofChar;             /* If nonzero, append this to the channel when
00194                                  * it is closed if it is open for writing. */
00195     int unreportedError;        /* Non-zero if an error report was deferred
00196                                  * because it happened in the background. The
00197                                  * value is the POSIX error code. */
00198     int refCount;               /* How many interpreters hold references to
00199                                  * this IO channel? */
00200     CloseCallback *closeCbPtr;  /* Callbacks registered to be called when the
00201                                  * channel is closed. */
00202     char *outputStage;          /* Temporary staging buffer used when
00203                                  * translating EOL before converting from
00204                                  * UTF-8 to external form. */
00205     ChannelBuffer *curOutPtr;   /* Current output buffer being filled. */
00206     ChannelBuffer *outQueueHead;/* Points at first buffer in output queue. */
00207     ChannelBuffer *outQueueTail;/* Points at last buffer in output queue. */
00208     ChannelBuffer *saveInBufPtr;/* Buffer saved for input queue - eliminates
00209                                  * need to allocate a new buffer for "gets"
00210                                  * that crosses buffer boundaries. */
00211     ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */
00212     ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */
00213     struct ChannelHandler *chPtr;/* List of channel handlers registered for
00214                                   * this channel. */
00215     int interestMask;           /* Mask of all events this channel has
00216                                  * handlers for. */
00217     EventScriptRecord *scriptRecordPtr;
00218                                 /* Chain of all scripts registered for event
00219                                  * handlers ("fileevent") on this channel. */
00220     int bufSize;                /* What size buffers to allocate? */
00221     Tcl_TimerToken timer;       /* Handle to wakeup timer for this channel. */
00222     CopyState *csPtr;           /* State of background copy, or NULL. */
00223     Channel *topChanPtr;        /* Refers to topmost channel in a stack. Never
00224                                  * NULL. */
00225     Channel *bottomChanPtr;     /* Refers to bottommost channel in a stack.
00226                                  * This channel can be relied on to live as
00227                                  * long as the channel state. Never NULL. */
00228     struct ChannelState *nextCSPtr;
00229                                 /* Next in list of channels currently open. */
00230     Tcl_ThreadId managingThread;/* TIP #10: Id of the thread managing this
00231                                  * stack of channels. */
00232 
00233     /*
00234      * TIP #219 ... Info for the I/O system ...
00235      * Error message set by channel drivers, for the propagation of arbitrary
00236      * Tcl errors. This information, if present (chanMsg not NULL), takes
00237      * precedence over a posix error code returned by a channel operation.
00238      */
00239 
00240     Tcl_Obj* chanMsg;
00241     Tcl_Obj* unreportedMsg;     /* Non-NULL if an error report was deferred
00242                                  * because it happened in the background. The
00243                                  * value is the chanMg, if any. #219's
00244                                  * companion to 'unreportedError'. */
00245 } ChannelState;
00246 
00247 /*
00248  * Values for the flags field in Channel. Any ORed combination of the
00249  * following flags can be stored in the field. These flags record various
00250  * options and state bits about the channel. In addition to the flags below,
00251  * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set.
00252  */
00253 
00254 #define CHANNEL_NONBLOCKING     (1<<3)  /* Channel is currently in nonblocking
00255                                          * mode. */
00256 #define CHANNEL_LINEBUFFERED    (1<<4)  /* Output to the channel must be
00257                                          * flushed after every newline. */
00258 #define CHANNEL_UNBUFFERED      (1<<5)  /* Output to the channel must always
00259                                          * be flushed immediately. */
00260 #define BUFFER_READY            (1<<6)  /* Current output buffer (the
00261                                          * curOutPtr field in the channel
00262                                          * structure) should be output as soon
00263                                          * as possible even though it may not
00264                                          * be full. */
00265 #define BG_FLUSH_SCHEDULED      (1<<7)  /* A background flush of the queued
00266                                          * output buffers has been
00267                                          * scheduled. */
00268 #define CHANNEL_CLOSED          (1<<8)  /* Channel has been closed. No further
00269                                          * Tcl-level IO on the channel is
00270                                          * allowed. */
00271 #define CHANNEL_EOF             (1<<9)  /* EOF occurred on this channel. This
00272                                          * bit is cleared before every input
00273                                          * operation. */
00274 #define CHANNEL_STICKY_EOF      (1<<10) /* EOF occurred on this channel
00275                                          * because we saw the input
00276                                          * eofChar. This bit prevents clearing
00277                                          * of the EOF bit before every input
00278                                          * operation. */
00279 #define CHANNEL_BLOCKED         (1<<11) /* EWOULDBLOCK or EAGAIN occurred on
00280                                          * this channel. This bit is cleared
00281                                          * before every input or output
00282                                          * operation. */
00283 #define INPUT_SAW_CR            (1<<12) /* Channel is in CRLF eol input
00284                                          * translation mode and the last byte
00285                                          * seen was a "\r". */
00286 #define INPUT_NEED_NL           (1<<15) /* Saw a '\r' at end of last buffer,
00287                                          * and there should be a '\n' at
00288                                          * beginning of next buffer. */
00289 #define CHANNEL_DEAD            (1<<13) /* The channel has been closed by the
00290                                          * exit handler (on exit) but not
00291                                          * deallocated. When any IO operation
00292                                          * sees this flag on a channel, it
00293                                          * does not call driver level
00294                                          * functions to avoid referring to
00295                                          * deallocated data. */
00296 #define CHANNEL_NEED_MORE_DATA  (1<<14) /* The last input operation failed
00297                                          * because there was not enough data
00298                                          * to complete the operation. This
00299                                          * flag is set when gets fails to get
00300                                          * a complete line or when read fails
00301                                          * to get a complete character. When
00302                                          * set, file events will not be
00303                                          * delivered for buffered data until
00304                                          * the state of the channel
00305                                          * changes. */
00306 #define CHANNEL_RAW_MODE        (1<<16) /* When set, notes that the Raw API is
00307                                          * being used. */
00308 #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
00309 #define CHANNEL_TIMER_FEV       (1<<17) /* When set the event we are notified
00310                                          * by is a fileevent generated by a
00311                                          * timer. We don't know if the driver
00312                                          * has more data and should not try to
00313                                          * read from it. If the system needs
00314                                          * more than is in the buffers out
00315                                          * read routines will simulate a short
00316                                          * read (0 characters read) */
00317 #define CHANNEL_HAS_MORE_DATA   (1<<18) /* Set by NotifyChannel for a channel
00318                                          * if and only if the channel is
00319                                          * configured non-blocking, the driver
00320                                          * for said channel has no
00321                                          * blockmodeproc, and data has arrived
00322                                          * for reading at the OS level). A
00323                                          * GetInput will pass reading from the
00324                                          * driver if the channel is
00325                                          * non-blocking, without blockmode
00326                                          * proc and the flag has not been set.
00327                                          * A read will be performed if the
00328                                          * flag is set. This will reset the
00329                                          * flag as well. */
00330 #endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
00331 
00332 #define CHANNEL_INCLOSE         (1<<19) /* Channel is currently being closed.
00333                                          * Its structures are still live and
00334                                          * usable, but it may not be closed
00335                                          * again from within the close
00336                                          * handler. */
00337 #define CHANNEL_TAINTED         (1<<20) /* Channel stack structure has changed.
00338                                          * Used by Channel Tcl_Obj type to
00339                                          * determine if we have to revalidate
00340                                          * the channel. */
00341 
00342 /*
00343  * For each channel handler registered in a call to Tcl_CreateChannelHandler,
00344  * there is one record of the following type. All of records for a specific
00345  * channel are chained together in a singly linked list which is stored in the
00346  * channel structure.
00347  */
00348 
00349 typedef struct ChannelHandler {
00350     Channel *chanPtr;           /* The channel structure for this channel. */
00351     int mask;                   /* Mask of desired events. */
00352     Tcl_ChannelProc *proc;      /* Procedure to call in the type of
00353                                  * Tcl_CreateChannelHandler. */
00354     ClientData clientData;      /* Argument to pass to procedure. */
00355     struct ChannelHandler *nextPtr;
00356                                 /* Next one in list of registered handlers. */
00357 } ChannelHandler;
00358 
00359 /*
00360  * This structure keeps track of the current ChannelHandler being invoked in
00361  * the current invocation of ChannelHandlerEventProc. There is a potential
00362  * problem if a ChannelHandler is deleted while it is the current one, since
00363  * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this
00364  * problem, structures of the type below indicate the next handler to be
00365  * processed for any (recursively nested) dispatches in progress. The
00366  * nextHandlerPtr field is updated if the handler being pointed to is deleted.
00367  * The nextPtr field is used to chain together all recursive invocations, so
00368  * that Tcl_DeleteChannelHandler can find all the recursively nested
00369  * invocations of ChannelHandlerEventProc and compare the handler being
00370  * deleted against the NEXT handler to be invoked in that invocation; when it
00371  * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr
00372  * field of the structure to the next handler.
00373  */
00374 
00375 typedef struct NextChannelHandler {
00376     ChannelHandler *nextHandlerPtr;
00377                                 /* The next handler to be invoked in this
00378                                  * invocation. */
00379     struct NextChannelHandler *nestedHandlerPtr;
00380                                 /* Next nested invocation of
00381                                  * ChannelHandlerEventProc. */
00382 } NextChannelHandler;
00383 
00384 /*
00385  * The following structure describes the event that is added to the Tcl event
00386  * queue by the channel handler check procedure.
00387  */
00388 
00389 typedef struct ChannelHandlerEvent {
00390     Tcl_Event header;           /* Standard header for all events. */
00391     Channel *chanPtr;           /* The channel that is ready. */
00392     int readyMask;              /* Events that have occurred. */
00393 } ChannelHandlerEvent;
00394 
00395 /*
00396  * The following structure is used by Tcl_GetsObj() to encapsulates the state
00397  * for a "gets" operation.
00398  */
00399 
00400 typedef struct GetsState {
00401     Tcl_Obj *objPtr;            /* The object to which UTF-8 characters will
00402                                  * be appended. */
00403     char **dstPtr;              /* Pointer into objPtr's string rep where next
00404                                  * character should be stored. */
00405     Tcl_Encoding encoding;      /* The encoding to use to convert raw bytes to
00406                                  * UTF-8. */
00407     ChannelBuffer *bufPtr;      /* The current buffer of raw bytes being
00408                                  * emptied. */
00409     Tcl_EncodingState state;    /* The encoding state just before the last
00410                                  * external to UTF-8 conversion in
00411                                  * FilterInputBytes(). */
00412     int rawRead;                /* The number of bytes removed from bufPtr in
00413                                  * the last call to FilterInputBytes(). */
00414     int bytesWrote;             /* The number of bytes of UTF-8 data appended
00415                                  * to objPtr during the last call to
00416                                  * FilterInputBytes(). */
00417     int charsWrote;             /* The corresponding number of UTF-8
00418                                  * characters appended to objPtr during the
00419                                  * last call to FilterInputBytes(). */
00420     int totalChars;             /* The total number of UTF-8 characters
00421                                  * appended to objPtr so far, just before the
00422                                  * last call to FilterInputBytes(). */
00423 } GetsState;
00424 
00425 /*
00426  * Local Variables:
00427  * mode: c
00428  * c-basic-offset: 4
00429  * fill-column: 78
00430  * End:
00431  */



Generated on Wed Mar 12 12:18:18 2008 by  doxygen 1.5.1