Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/tcl8.5.2/generic/tclIO.h @ 35

Last change on this file since 35 was 25, checked in by landauf, 17 years ago

added tcl to libs

File size: 17.0 KB
Line 
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 of
11 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 *
13 * RCS: @(#) $Id: tclIO.h,v 1.11 2007/12/13 15:23:18 dgp 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 that
19 * we can test safely for both. In the code we still have to test for both
20 * because there may be systems on which both are defined and have different
21 * 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)))
31#error 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 from
64                                 * 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 the
71                                 * 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 next
79 * 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 each close
92 * 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 to the
98                                 * callback. */
99    struct CloseCallback *nextPtr;
100                                /* For chaining close callbacks. */
101} CloseCallback;
102
103/*
104 * The following structure describes the information saved from a call to
105 * "fileevent". This is used later when the event being waited for to invoke
106 * the saved script in the interpreter designed in this record.
107 */
108
109typedef struct EventScriptRecord {
110    struct Channel *chanPtr;    /* The channel for which this script is
111                                 * registered. This is used only when an error
112                                 * occurs during evaluation of the script, to
113                                 * delete the handler. */
114    Tcl_Obj *scriptPtr;         /* Script to invoke. */
115    Tcl_Interp *interp;         /* In what interpreter to invoke script? */
116    int mask;                   /* Events must overlap current mask for the
117                                 * stored script to be invoked. */
118    struct EventScriptRecord *nextPtr;
119                                /* Next in chain of records. */
120} EventScriptRecord;
121
122/*
123 * struct Channel:
124 *
125 * One of these structures is allocated for each open channel. It contains
126 * data specific to the channel but which belongs to the generic part of the
127 * Tcl channel mechanism, and it points at an instance specific (and type
128 * specific) instance data, and at a channel type structure.
129 */
130
131typedef struct Channel {
132    struct ChannelState *state; /* Split out state information */
133    ClientData instanceData;    /* Instance-specific data provided by creator
134                                 * of channel. */
135    Tcl_ChannelType *typePtr;   /* Pointer to channel type structure. */
136    struct Channel *downChanPtr;/* Refers to channel this one was stacked
137                                 * upon. This reference is NULL for normal
138                                 * channels. See Tcl_StackChannel. */
139    struct Channel *upChanPtr;  /* Refers to the channel above stacked this
140                                 * one. NULL for the top most channel. */
141
142    /*
143     * Intermediate buffers to hold pre-read data for consumption by a newly
144     * stacked transformation. See 'Tcl_StackChannel'.
145     */
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
155 * data specific to the channel but which belongs to the generic part of the
156 * Tcl 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
163                                 * IO 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
171                                 * converting 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
179                                 * converting 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 end
190                                 * of line sequences in output? */
191    int inEofChar;              /* If nonzero, use this as a signal of EOF on
192                                 * input. */
193    int outEofChar;             /* If nonzero, append this to the channel when
194                                 * it is closed if it is open for writing. */
195    int unreportedError;        /* Non-zero if an error report was deferred
196                                 * because it happened in the background. The
197                                 * value is the POSIX error code. */
198    int refCount;               /* How many interpreters hold references to
199                                 * this IO channel? */
200    CloseCallback *closeCbPtr;  /* Callbacks registered to be called when the
201                                 * channel is closed. */
202    char *outputStage;          /* Temporary staging buffer used when
203                                 * translating EOL before converting from
204                                 * UTF-8 to external form. */
205    ChannelBuffer *curOutPtr;   /* Current output buffer being filled. */
206    ChannelBuffer *outQueueHead;/* Points at first buffer in output queue. */
207    ChannelBuffer *outQueueTail;/* Points at last buffer in output queue. */
208    ChannelBuffer *saveInBufPtr;/* Buffer saved for input queue - eliminates
209                                 * need to allocate a new buffer for "gets"
210                                 * that crosses buffer boundaries. */
211    ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */
212    ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */
213    struct ChannelHandler *chPtr;/* List of channel handlers registered for
214                                  * this channel. */
215    int interestMask;           /* Mask of all events this channel has
216                                 * handlers for. */
217    EventScriptRecord *scriptRecordPtr;
218                                /* Chain of all scripts registered for event
219                                 * handlers ("fileevent") on this channel. */
220    int bufSize;                /* What size buffers to allocate? */
221    Tcl_TimerToken timer;       /* Handle to wakeup timer for this channel. */
222    CopyState *csPtr;           /* State of background copy, or NULL. */
223    Channel *topChanPtr;        /* Refers to topmost channel in a stack. Never
224                                 * NULL. */
225    Channel *bottomChanPtr;     /* Refers to bottommost channel in a stack.
226                                 * This channel can be relied on to live as
227                                 * long as the channel state. Never NULL. */
228    struct ChannelState *nextCSPtr;
229                                /* Next in list of channels currently open. */
230    Tcl_ThreadId managingThread;/* TIP #10: Id of the thread managing this
231                                 * stack of channels. */
232
233    /*
234     * TIP #219 ... Info for the I/O system ...
235     * Error message set by channel drivers, for the propagation of arbitrary
236     * Tcl errors. This information, if present (chanMsg not NULL), takes
237     * precedence over a posix error code returned by a channel operation.
238     */
239
240    Tcl_Obj* chanMsg;
241    Tcl_Obj* unreportedMsg;     /* Non-NULL if an error report was deferred
242                                 * because it happened in the background. The
243                                 * value is the chanMg, if any. #219's
244                                 * companion to 'unreportedError'. */
245} ChannelState;
246
247/*
248 * Values for the flags field in Channel. Any ORed combination of the
249 * following flags can be stored in the field. These flags record various
250 * options and state bits about the channel. In addition to the flags below,
251 * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set.
252 */
253
254#define CHANNEL_NONBLOCKING     (1<<3)  /* Channel is currently in nonblocking
255                                         * mode. */
256#define CHANNEL_LINEBUFFERED    (1<<4)  /* Output to the channel must be
257                                         * flushed after every newline. */
258#define CHANNEL_UNBUFFERED      (1<<5)  /* Output to the channel must always
259                                         * be flushed immediately. */
260#define BUFFER_READY            (1<<6)  /* Current output buffer (the
261                                         * curOutPtr field in the channel
262                                         * structure) should be output as soon
263                                         * as possible even though it may not
264                                         * be full. */
265#define BG_FLUSH_SCHEDULED      (1<<7)  /* A background flush of the queued
266                                         * output buffers has been
267                                         * scheduled. */
268#define CHANNEL_CLOSED          (1<<8)  /* Channel has been closed. No further
269                                         * Tcl-level IO on the channel is
270                                         * allowed. */
271#define CHANNEL_EOF             (1<<9)  /* EOF occurred on this channel. This
272                                         * bit is cleared before every input
273                                         * operation. */
274#define CHANNEL_STICKY_EOF      (1<<10) /* EOF occurred on this channel
275                                         * because we saw the input
276                                         * eofChar. This bit prevents clearing
277                                         * of the EOF bit before every input
278                                         * operation. */
279#define CHANNEL_BLOCKED         (1<<11) /* EWOULDBLOCK or EAGAIN occurred on
280                                         * this channel. This bit is cleared
281                                         * before every input or output
282                                         * operation. */
283#define INPUT_SAW_CR            (1<<12) /* Channel is in CRLF eol input
284                                         * translation mode and the last byte
285                                         * seen was a "\r". */
286#define INPUT_NEED_NL           (1<<15) /* Saw a '\r' at end of last buffer,
287                                         * and there should be a '\n' at
288                                         * beginning of next buffer. */
289#define CHANNEL_DEAD            (1<<13) /* The channel has been closed by the
290                                         * exit handler (on exit) but not
291                                         * deallocated. When any IO operation
292                                         * sees this flag on a channel, it
293                                         * does not call driver level
294                                         * functions to avoid referring to
295                                         * deallocated data. */
296#define CHANNEL_NEED_MORE_DATA  (1<<14) /* The last input operation failed
297                                         * because there was not enough data
298                                         * to complete the operation. This
299                                         * flag is set when gets fails to get
300                                         * a complete line or when read fails
301                                         * to get a complete character. When
302                                         * set, file events will not be
303                                         * delivered for buffered data until
304                                         * the state of the channel
305                                         * changes. */
306#define CHANNEL_RAW_MODE        (1<<16) /* When set, notes that the Raw API is
307                                         * being used. */
308#ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
309#define CHANNEL_TIMER_FEV       (1<<17) /* When set the event we are notified
310                                         * by is a fileevent generated by a
311                                         * timer. We don't know if the driver
312                                         * has more data and should not try to
313                                         * read from it. If the system needs
314                                         * more than is in the buffers out
315                                         * read routines will simulate a short
316                                         * read (0 characters read) */
317#define CHANNEL_HAS_MORE_DATA   (1<<18) /* Set by NotifyChannel for a channel
318                                         * if and only if the channel is
319                                         * configured non-blocking, the driver
320                                         * for said channel has no
321                                         * blockmodeproc, and data has arrived
322                                         * for reading at the OS level). A
323                                         * GetInput will pass reading from the
324                                         * driver if the channel is
325                                         * non-blocking, without blockmode
326                                         * proc and the flag has not been set.
327                                         * A read will be performed if the
328                                         * flag is set. This will reset the
329                                         * flag as well. */
330#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
331
332#define CHANNEL_INCLOSE         (1<<19) /* Channel is currently being closed.
333                                         * Its structures are still live and
334                                         * usable, but it may not be closed
335                                         * again from within the close
336                                         * handler. */
337#define CHANNEL_TAINTED         (1<<20) /* Channel stack structure has changed.
338                                         * Used by Channel Tcl_Obj type to
339                                         * determine if we have to revalidate
340                                         * the channel. */
341
342/*
343 * For each channel handler registered in a call to Tcl_CreateChannelHandler,
344 * there is one record of the following type. All of records for a specific
345 * channel are chained together in a singly linked list which is stored in the
346 * channel structure.
347 */
348
349typedef struct ChannelHandler {
350    Channel *chanPtr;           /* The channel structure for this channel. */
351    int mask;                   /* Mask of desired events. */
352    Tcl_ChannelProc *proc;      /* Procedure to call in the type of
353                                 * Tcl_CreateChannelHandler. */
354    ClientData clientData;      /* Argument to pass to procedure. */
355    struct ChannelHandler *nextPtr;
356                                /* Next one in list of registered handlers. */
357} ChannelHandler;
358
359/*
360 * This structure keeps track of the current ChannelHandler being invoked in
361 * the current invocation of ChannelHandlerEventProc. There is a potential
362 * problem if a ChannelHandler is deleted while it is the current one, since
363 * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this
364 * problem, structures of the type below indicate the next handler to be
365 * processed for any (recursively nested) dispatches in progress. The
366 * nextHandlerPtr field is updated if the handler being pointed to is deleted.
367 * The nextPtr field is used to chain together all recursive invocations, so
368 * that Tcl_DeleteChannelHandler can find all the recursively nested
369 * invocations of ChannelHandlerEventProc and compare the handler being
370 * deleted against the NEXT handler to be invoked in that invocation; when it
371 * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr
372 * field of the structure to the next handler.
373 */
374
375typedef struct NextChannelHandler {
376    ChannelHandler *nextHandlerPtr;
377                                /* The next handler to be invoked in this
378                                 * invocation. */
379    struct NextChannelHandler *nestedHandlerPtr;
380                                /* Next nested invocation of
381                                 * ChannelHandlerEventProc. */
382} NextChannelHandler;
383
384/*
385 * The following structure describes the event that is added to the Tcl event
386 * queue by the channel handler check procedure.
387 */
388
389typedef struct ChannelHandlerEvent {
390    Tcl_Event header;           /* Standard header for all events. */
391    Channel *chanPtr;           /* The channel that is ready. */
392    int readyMask;              /* Events that have occurred. */
393} ChannelHandlerEvent;
394
395/*
396 * The following structure is used by Tcl_GetsObj() to encapsulates the state
397 * for a "gets" operation.
398 */
399
400typedef struct GetsState {
401    Tcl_Obj *objPtr;            /* The object to which UTF-8 characters will
402                                 * be appended. */
403    char **dstPtr;              /* Pointer into objPtr's string rep where next
404                                 * character should be stored. */
405    Tcl_Encoding encoding;      /* The encoding to use to convert raw bytes to
406                                 * UTF-8. */
407    ChannelBuffer *bufPtr;      /* The current buffer of raw bytes being
408                                 * emptied. */
409    Tcl_EncodingState state;    /* The encoding state just before the last
410                                 * external to UTF-8 conversion in
411                                 * FilterInputBytes(). */
412    int rawRead;                /* The number of bytes removed from bufPtr in
413                                 * the last call to FilterInputBytes(). */
414    int bytesWrote;             /* The number of bytes of UTF-8 data appended
415                                 * to objPtr during the last call to
416                                 * FilterInputBytes(). */
417    int charsWrote;             /* The corresponding number of UTF-8
418                                 * characters appended to objPtr during the
419                                 * last call to FilterInputBytes(). */
420    int totalChars;             /* The total number of UTF-8 characters
421                                 * appended to objPtr so far, just before the
422                                 * last call to FilterInputBytes(). */
423} GetsState;
424
425/*
426 * Local Variables:
427 * mode: c
428 * c-basic-offset: 4
429 * fill-column: 78
430 * End:
431 */
Note: See TracBrowser for help on using the repository browser.