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