os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclIO.c
First public contribution.
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.
7 * Copyright (c) 1998-2000 Ajuba Solutions
8 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
9 * Portions Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiaries. All rights reserved.
11 * See the file "license.terms" for information on usage and redistribution
12 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14 * RCS: @(#) $Id: tclIO.c,v 1.61.2.23 2007/05/24 19:31:55 dgp Exp $
21 #if defined(__SYMBIAN32__) && defined(__WINSCW__)
22 #include "tclSymbianGlobals.h"
23 #define dataKey getdataKey(3)
26 #ifndef TCL_INHERIT_STD_CHANNELS
27 #define TCL_INHERIT_STD_CHANNELS 1
32 * All static variables used in this file are collected into a single
33 * instance of the following structure. For multi-threaded implementations,
34 * there is one instance of this structure for each thread.
36 * Notice that different structures with the same name appear in other
37 * files. The structure defined below is used in this file only.
40 typedef struct ThreadSpecificData {
43 * This variable holds the list of nested ChannelHandlerEventProc
46 NextChannelHandler *nestedHandlerPtr;
49 * List of all channels currently open, indexed by ChannelState,
50 * as only one ChannelState exists per set of stacked channels.
52 ChannelState *firstCSPtr;
55 * Has a channel exit handler been created yet?
57 int channelExitHandlerCreated;
60 * Has the channel event source been created and registered with the
63 int channelEventSourceCreated;
66 * Static variables to hold channels for stdin, stdout and stderr.
68 Tcl_Channel stdinChannel;
70 Tcl_Channel stdoutChannel;
71 int stdoutInitialized;
72 Tcl_Channel stderrChannel;
73 int stderrInitialized;
77 #if !defined(__SYMBIAN32__) || !defined(__WINSCW__)
78 static Tcl_ThreadDataKey dataKey;
82 * Static functions in this file:
85 static ChannelBuffer * AllocChannelBuffer _ANSI_ARGS_((int length));
86 static void ChannelTimerProc _ANSI_ARGS_((
87 ClientData clientData));
88 static int CheckChannelErrors _ANSI_ARGS_((ChannelState *statePtr,
90 static int CheckFlush _ANSI_ARGS_((Channel *chanPtr,
91 ChannelBuffer *bufPtr, int newlineFlag));
92 static int CheckForDeadChannel _ANSI_ARGS_((Tcl_Interp *interp,
93 ChannelState *statePtr));
94 static void CheckForStdChannelsBeingClosed _ANSI_ARGS_((
96 static void CleanupChannelHandlers _ANSI_ARGS_((
97 Tcl_Interp *interp, Channel *chanPtr));
98 static int CloseChannel _ANSI_ARGS_((Tcl_Interp *interp,
99 Channel *chanPtr, int errorCode));
100 static void CommonGetsCleanup _ANSI_ARGS_((Channel *chanPtr,
101 Tcl_Encoding encoding));
102 static int CopyAndTranslateBuffer _ANSI_ARGS_((
103 ChannelState *statePtr, char *result,
105 static int CopyBuffer _ANSI_ARGS_((
106 Channel *chanPtr, char *result, int space));
107 static int CopyData _ANSI_ARGS_((CopyState *csPtr, int mask));
108 static void CopyEventProc _ANSI_ARGS_((ClientData clientData,
110 static void CreateScriptRecord _ANSI_ARGS_((
111 Tcl_Interp *interp, Channel *chanPtr,
112 int mask, Tcl_Obj *scriptPtr));
113 static void DeleteChannelTable _ANSI_ARGS_((
114 ClientData clientData, Tcl_Interp *interp));
115 static void DeleteScriptRecord _ANSI_ARGS_((Tcl_Interp *interp,
116 Channel *chanPtr, int mask));
117 static int DetachChannel _ANSI_ARGS_((Tcl_Interp *interp,
119 static void DiscardInputQueued _ANSI_ARGS_((ChannelState *statePtr,
120 int discardSavedBuffers));
121 static void DiscardOutputQueued _ANSI_ARGS_((
122 ChannelState *chanPtr));
123 static int DoRead _ANSI_ARGS_((Channel *chanPtr, char *srcPtr,
125 static int DoWrite _ANSI_ARGS_((Channel *chanPtr, CONST char *src,
127 static int DoReadChars _ANSI_ARGS_ ((Channel* chan,
128 Tcl_Obj* objPtr, int toRead, int appendFlag));
129 static int DoWriteChars _ANSI_ARGS_ ((Channel* chan,
130 CONST char* src, int len));
131 static int FilterInputBytes _ANSI_ARGS_((Channel *chanPtr,
132 GetsState *statePtr));
133 static int FlushChannel _ANSI_ARGS_((Tcl_Interp *interp,
134 Channel *chanPtr, int calledFromAsyncFlush));
135 static Tcl_HashTable * GetChannelTable _ANSI_ARGS_((Tcl_Interp *interp));
136 static int GetInput _ANSI_ARGS_((Channel *chanPtr));
137 static int HaveVersion _ANSI_ARGS_((Tcl_ChannelType *typePtr,
138 Tcl_ChannelTypeVersion minimumVersion));
139 static void PeekAhead _ANSI_ARGS_((Channel *chanPtr,
140 char **dstEndPtr, GetsState *gsPtr));
141 static int ReadBytes _ANSI_ARGS_((ChannelState *statePtr,
142 Tcl_Obj *objPtr, int charsLeft,
144 static int ReadChars _ANSI_ARGS_((ChannelState *statePtr,
145 Tcl_Obj *objPtr, int charsLeft,
146 int *offsetPtr, int *factorPtr));
147 static void RecycleBuffer _ANSI_ARGS_((ChannelState *statePtr,
148 ChannelBuffer *bufPtr, int mustDiscard));
149 static int StackSetBlockMode _ANSI_ARGS_((Channel *chanPtr,
151 static int SetBlockMode _ANSI_ARGS_((Tcl_Interp *interp,
152 Channel *chanPtr, int mode));
153 static void StopCopy _ANSI_ARGS_((CopyState *csPtr));
154 static int TranslateInputEOL _ANSI_ARGS_((ChannelState *statePtr,
155 char *dst, CONST char *src,
156 int *dstLenPtr, int *srcLenPtr));
157 static int TranslateOutputEOL _ANSI_ARGS_((ChannelState *statePtr,
158 char *dst, CONST char *src,
159 int *dstLenPtr, int *srcLenPtr));
160 static void UpdateInterest _ANSI_ARGS_((Channel *chanPtr));
161 static int WriteBytes _ANSI_ARGS_((Channel *chanPtr,
162 CONST char *src, int srcLen));
163 static int WriteChars _ANSI_ARGS_((Channel *chanPtr,
164 CONST char *src, int srcLen));
168 *---------------------------------------------------------------------------
170 * TclInitIOSubsystem --
172 * Initialize all resources used by this subsystem on a per-process
179 * Depends on the memory subsystems.
181 *---------------------------------------------------------------------------
188 * By fetching thread local storage we take care of
189 * allocating it for each thread.
191 (void) TCL_TSD_INIT(&dataKey);
195 *-------------------------------------------------------------------------
197 * TclFinalizeIOSubsystem --
199 * Releases all resources used by this subsystem on a per-thread
200 * basis. Closes all extant channels that have not already been
201 * closed because they were not owned by any interp.
207 * Depends on encoding and memory subsystems.
209 *-------------------------------------------------------------------------
214 TclFinalizeIOSubsystem(void)
216 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
217 Channel *chanPtr = NULL; /* Iterates over open channels. */
218 ChannelState *statePtr; /* State of channel stack */
219 int active = 1; /* Flag == 1 while there's still work to do */
222 * Walk all channel state structures known to this thread and
223 * close corresponding channels.
229 * Iterate through the open channel list, and find the first
230 * channel that isn't dead. We start from the head of the list
231 * each time, because the close action on one channel can close
236 for (statePtr = tsdPtr->firstCSPtr;
238 statePtr = statePtr->nextCSPtr) {
239 chanPtr = statePtr->topChanPtr;
240 if (!(statePtr->flags & CHANNEL_DEAD)) {
247 * We've found a live channel. Close it.
253 * Set the channel back into blocking mode to ensure that we
254 * wait for all data to flush out.
257 (void) Tcl_SetChannelOption(NULL, (Tcl_Channel) chanPtr,
260 if ((chanPtr == (Channel *) tsdPtr->stdinChannel) ||
261 (chanPtr == (Channel *) tsdPtr->stdoutChannel) ||
262 (chanPtr == (Channel *) tsdPtr->stderrChannel)) {
264 * Decrement the refcount which was earlier artificially
265 * bumped up to keep the channel from being closed.
268 statePtr->refCount--;
271 if (statePtr->refCount <= 0) {
273 * Close it only if the refcount indicates that the channel
274 * is not referenced from any interpreter. If it is, that
275 * interpreter will close the channel when it gets destroyed.
278 (void) Tcl_Close(NULL, (Tcl_Channel) chanPtr);
281 * The refcount is greater than zero, so flush the channel.
284 Tcl_Flush((Tcl_Channel) chanPtr);
287 * Call the device driver to actually close the underlying
288 * device for this channel.
291 if (chanPtr->typePtr->closeProc != TCL_CLOSE2PROC) {
292 (chanPtr->typePtr->closeProc)(chanPtr->instanceData, NULL);
294 (chanPtr->typePtr->close2Proc)(chanPtr->instanceData,
299 * Finally, we clean up the fields in the channel data
300 * structure since all of them have been deleted already.
301 * We mark the channel with CHANNEL_DEAD to prevent any
302 * further IO operations
306 chanPtr->instanceData = NULL;
307 statePtr->flags |= CHANNEL_DEAD;
312 TclpFinalizeSockets();
318 *----------------------------------------------------------------------
320 * Tcl_SetStdChannel --
322 * This function is used to change the channels that are used
323 * for stdin/stdout/stderr in new interpreters.
331 *----------------------------------------------------------------------
335 Tcl_SetStdChannel(channel, type)
337 int type; /* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */
339 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
342 tsdPtr->stdinInitialized = 1;
343 tsdPtr->stdinChannel = channel;
346 tsdPtr->stdoutInitialized = 1;
347 tsdPtr->stdoutChannel = channel;
350 tsdPtr->stderrInitialized = 1;
351 tsdPtr->stderrChannel = channel;
357 *----------------------------------------------------------------------
359 * Tcl_GetStdChannel --
361 * Returns the specified standard channel.
364 * Returns the specified standard channel, or NULL.
367 * May cause the creation of a standard channel and the underlying
370 *----------------------------------------------------------------------
373 Tcl_GetStdChannel(type)
374 int type; /* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */
376 Tcl_Channel channel = NULL;
377 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
380 * If the channels were not created yet, create them now and
381 * store them in the static variables.
386 if (!tsdPtr->stdinInitialized) {
387 tsdPtr->stdinChannel = TclpGetDefaultStdChannel(TCL_STDIN);
388 tsdPtr->stdinInitialized = 1;
391 * Artificially bump the refcount to ensure that the channel
392 * is only closed on exit.
394 * NOTE: Must only do this if stdinChannel is not NULL. It
395 * can be NULL in situations where Tcl is unable to connect
396 * to the standard input.
399 if (tsdPtr->stdinChannel != (Tcl_Channel) NULL) {
400 (void) Tcl_RegisterChannel((Tcl_Interp *) NULL,
401 tsdPtr->stdinChannel);
404 channel = tsdPtr->stdinChannel;
407 if (!tsdPtr->stdoutInitialized) {
408 tsdPtr->stdoutChannel = TclpGetDefaultStdChannel(TCL_STDOUT);
409 tsdPtr->stdoutInitialized = 1;
410 if (tsdPtr->stdoutChannel != (Tcl_Channel) NULL) {
411 (void) Tcl_RegisterChannel((Tcl_Interp *) NULL,
412 tsdPtr->stdoutChannel);
415 channel = tsdPtr->stdoutChannel;
418 if (!tsdPtr->stderrInitialized) {
419 tsdPtr->stderrChannel = TclpGetDefaultStdChannel(TCL_STDERR);
420 tsdPtr->stderrInitialized = 1;
421 if (tsdPtr->stderrChannel != (Tcl_Channel) NULL) {
422 (void) Tcl_RegisterChannel((Tcl_Interp *) NULL,
423 tsdPtr->stderrChannel);
426 channel = tsdPtr->stderrChannel;
434 *----------------------------------------------------------------------
436 * Tcl_CreateCloseHandler
438 * Creates a close callback which will be called when the channel is
445 * Causes the callback to be called in the future when the channel
448 *----------------------------------------------------------------------
452 Tcl_CreateCloseHandler(chan, proc, clientData)
453 Tcl_Channel chan; /* The channel for which to create the
455 Tcl_CloseProc *proc; /* The callback routine to call when the
456 * channel will be closed. */
457 ClientData clientData; /* Arbitrary data to pass to the
460 ChannelState *statePtr;
461 CloseCallback *cbPtr;
463 statePtr = ((Channel *) chan)->state;
465 cbPtr = (CloseCallback *) ckalloc((unsigned) sizeof(CloseCallback));
467 cbPtr->clientData = clientData;
469 cbPtr->nextPtr = statePtr->closeCbPtr;
470 statePtr->closeCbPtr = cbPtr;
474 *----------------------------------------------------------------------
476 * Tcl_DeleteCloseHandler --
478 * Removes a callback that would have been called on closing
479 * the channel. If there is no matching callback then this
480 * function has no effect.
486 * The callback will not be called in the future when the channel
487 * is eventually closed.
489 *----------------------------------------------------------------------
493 Tcl_DeleteCloseHandler(chan, proc, clientData)
494 Tcl_Channel chan; /* The channel for which to cancel the
496 Tcl_CloseProc *proc; /* The procedure for the callback to
498 ClientData clientData; /* The callback data for the callback
501 ChannelState *statePtr;
502 CloseCallback *cbPtr, *cbPrevPtr;
504 statePtr = ((Channel *) chan)->state;
505 for (cbPtr = statePtr->closeCbPtr, cbPrevPtr = (CloseCallback *) NULL;
506 cbPtr != (CloseCallback *) NULL;
507 cbPtr = cbPtr->nextPtr) {
508 if ((cbPtr->proc == proc) && (cbPtr->clientData == clientData)) {
509 if (cbPrevPtr == (CloseCallback *) NULL) {
510 statePtr->closeCbPtr = cbPtr->nextPtr;
512 ckfree((char *) cbPtr);
521 *----------------------------------------------------------------------
525 * Gets and potentially initializes the channel table for an
526 * interpreter. If it is initializing the table it also inserts
527 * channels for stdin, stdout and stderr if the interpreter is
531 * A pointer to the hash table created, for use by the caller.
534 * Initializes the channel table for an interpreter. May create
535 * channels for stdin, stdout and stderr.
537 *----------------------------------------------------------------------
540 static Tcl_HashTable *
541 GetChannelTable(interp)
544 Tcl_HashTable *hTblPtr; /* Hash table of channels. */
545 Tcl_Channel stdinChan, stdoutChan, stderrChan;
547 hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);
548 if (hTblPtr == (Tcl_HashTable *) NULL) {
549 hTblPtr = (Tcl_HashTable *) ckalloc((unsigned) sizeof(Tcl_HashTable));
550 Tcl_InitHashTable(hTblPtr, TCL_STRING_KEYS);
552 (void) Tcl_SetAssocData(interp, "tclIO",
553 (Tcl_InterpDeleteProc *) DeleteChannelTable,
554 (ClientData) hTblPtr);
557 * If the interpreter is trusted (not "safe"), insert channels
558 * for stdin, stdout and stderr (possibly creating them in the
562 if (Tcl_IsSafe(interp) == 0) {
563 stdinChan = Tcl_GetStdChannel(TCL_STDIN);
564 if (stdinChan != NULL) {
565 Tcl_RegisterChannel(interp, stdinChan);
567 stdoutChan = Tcl_GetStdChannel(TCL_STDOUT);
568 if (stdoutChan != NULL) {
569 Tcl_RegisterChannel(interp, stdoutChan);
571 stderrChan = Tcl_GetStdChannel(TCL_STDERR);
572 if (stderrChan != NULL) {
573 Tcl_RegisterChannel(interp, stderrChan);
582 *----------------------------------------------------------------------
584 * DeleteChannelTable --
586 * Deletes the channel table for an interpreter, closing any open
587 * channels whose refcount reaches zero. This procedure is invoked
588 * when an interpreter is deleted, via the AssocData cleanup
595 * Deletes the hash table of channels. May close channels. May flush
596 * output on closed channels. Removes any channeEvent handlers that were
597 * registered in this interpreter.
599 *----------------------------------------------------------------------
603 DeleteChannelTable(clientData, interp)
604 ClientData clientData; /* The per-interpreter data structure. */
605 Tcl_Interp *interp; /* The interpreter being deleted. */
607 Tcl_HashTable *hTblPtr; /* The hash table. */
608 Tcl_HashSearch hSearch; /* Search variable. */
609 Tcl_HashEntry *hPtr; /* Search variable. */
610 Channel *chanPtr; /* Channel being deleted. */
611 ChannelState *statePtr; /* State of Channel being deleted. */
612 EventScriptRecord *sPtr, *prevPtr, *nextPtr;
613 /* Variables to loop over all channel events
614 * registered, to delete the ones that refer
615 * to the interpreter being deleted. */
618 * Delete all the registered channels - this will close channels whose
619 * refcount reaches zero.
622 hTblPtr = (Tcl_HashTable *) clientData;
623 for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
624 hPtr != (Tcl_HashEntry *) NULL;
625 hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch)) {
627 chanPtr = (Channel *) Tcl_GetHashValue(hPtr);
628 statePtr = chanPtr->state;
631 * Remove any fileevents registered in this interpreter.
634 for (sPtr = statePtr->scriptRecordPtr,
635 prevPtr = (EventScriptRecord *) NULL;
636 sPtr != (EventScriptRecord *) NULL;
638 nextPtr = sPtr->nextPtr;
639 if (sPtr->interp == interp) {
640 if (prevPtr == (EventScriptRecord *) NULL) {
641 statePtr->scriptRecordPtr = nextPtr;
643 prevPtr->nextPtr = nextPtr;
646 Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
647 TclChannelEventScriptInvoker, (ClientData) sPtr);
649 Tcl_DecrRefCount(sPtr->scriptPtr);
650 ckfree((char *) sPtr);
657 * Cannot call Tcl_UnregisterChannel because that procedure calls
658 * Tcl_GetAssocData to get the channel table, which might already
659 * be inaccessible from the interpreter structure. Instead, we
660 * emulate the behavior of Tcl_UnregisterChannel directly here.
663 Tcl_DeleteHashEntry(hPtr);
664 statePtr->refCount--;
665 if (statePtr->refCount <= 0) {
666 if (!(statePtr->flags & BG_FLUSH_SCHEDULED)) {
667 (void) Tcl_Close(interp, (Tcl_Channel) chanPtr);
671 Tcl_DeleteHashTable(hTblPtr);
672 ckfree((char *) hTblPtr);
676 *----------------------------------------------------------------------
678 * CheckForStdChannelsBeingClosed --
680 * Perform special handling for standard channels being closed. When
681 * given a standard channel, if the refcount is now 1, it means that
682 * the last reference to the standard channel is being explicitly
683 * closed. Now bump the refcount artificially down to 0, to ensure the
684 * normal handling of channels being closed will occur. Also reset the
685 * static pointer to the channel to NULL, to avoid dangling references.
691 * Manipulates the refcount on standard channels. May smash the global
692 * static pointer to a standard channel.
694 *----------------------------------------------------------------------
698 CheckForStdChannelsBeingClosed(chan)
701 ChannelState *statePtr = ((Channel *) chan)->state;
702 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
704 if ((chan == tsdPtr->stdinChannel) && (tsdPtr->stdinInitialized)) {
705 if (statePtr->refCount < 2) {
706 statePtr->refCount = 0;
707 tsdPtr->stdinChannel = NULL;
710 } else if ((chan == tsdPtr->stdoutChannel)
711 && (tsdPtr->stdoutInitialized)) {
712 if (statePtr->refCount < 2) {
713 statePtr->refCount = 0;
714 tsdPtr->stdoutChannel = NULL;
717 } else if ((chan == tsdPtr->stderrChannel)
718 && (tsdPtr->stderrInitialized)) {
719 if (statePtr->refCount < 2) {
720 statePtr->refCount = 0;
721 tsdPtr->stderrChannel = NULL;
728 *----------------------------------------------------------------------
730 * Tcl_IsStandardChannel --
732 * Test if the given channel is a standard channel. No attempt
733 * is made to check if the channel or the standard channels
734 * are initialized or otherwise valid.
737 * Returns 1 if true, 0 if false.
742 *----------------------------------------------------------------------
745 Tcl_IsStandardChannel(chan)
746 Tcl_Channel chan; /* Channel to check. */
748 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
750 if ((chan == tsdPtr->stdinChannel)
751 || (chan == tsdPtr->stdoutChannel)
752 || (chan == tsdPtr->stderrChannel)) {
760 *----------------------------------------------------------------------
762 * Tcl_RegisterChannel --
764 * Adds an already-open channel to the channel table of an interpreter.
765 * If the interpreter passed as argument is NULL, it only increments
766 * the channel refCount.
772 * May increment the reference count of a channel.
774 *----------------------------------------------------------------------
778 Tcl_RegisterChannel(interp, chan)
779 Tcl_Interp *interp; /* Interpreter in which to add the channel. */
780 Tcl_Channel chan; /* The channel to add to this interpreter
783 Tcl_HashTable *hTblPtr; /* Hash table of channels. */
784 Tcl_HashEntry *hPtr; /* Search variable. */
785 int new; /* Is the hash entry new or does it exist? */
786 Channel *chanPtr; /* The actual channel. */
787 ChannelState *statePtr; /* State of the actual channel. */
790 * Always (un)register bottom-most channel in the stack. This makes
791 * management of the channel list easier because no manipulation is
792 * necessary during (un)stack operation.
794 chanPtr = ((Channel *) chan)->state->bottomChanPtr;
795 statePtr = chanPtr->state;
797 if (statePtr->channelName == (CONST char *) NULL) {
798 panic("Tcl_RegisterChannel: channel without name");
800 if (interp != (Tcl_Interp *) NULL) {
801 hTblPtr = GetChannelTable(interp);
802 hPtr = Tcl_CreateHashEntry(hTblPtr, statePtr->channelName, &new);
804 if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) {
808 panic("Tcl_RegisterChannel: duplicate channel names");
810 Tcl_SetHashValue(hPtr, (ClientData) chanPtr);
813 statePtr->refCount++;
817 *----------------------------------------------------------------------
819 * Tcl_UnregisterChannel --
821 * Deletes the hash entry for a channel associated with an interpreter.
822 * If the interpreter given as argument is NULL, it only decrements the
823 * reference count. (This all happens in the Tcl_DetachChannel helper
826 * Finally, if the reference count of the channel drops to zero,
830 * A standard Tcl result.
833 * Calls Tcl_DetachChannel which deletes the hash entry for a channel
834 * associated with an interpreter.
836 * May delete the channel, which can have a variety of consequences,
837 * especially if we are forced to close the channel.
839 *----------------------------------------------------------------------
843 Tcl_UnregisterChannel(interp, chan)
844 Tcl_Interp *interp; /* Interpreter in which channel is defined. */
845 Tcl_Channel chan; /* Channel to delete. */
847 ChannelState *statePtr; /* State of the real channel. */
849 statePtr = ((Channel *) chan)->state->bottomChanPtr->state;
851 if (statePtr->flags & CHANNEL_INCLOSE) {
852 if (interp != (Tcl_Interp*) NULL) {
853 Tcl_AppendResult(interp,
854 "Illegal recursive call to close through close-handler of channel",
860 if (DetachChannel(interp, chan) != TCL_OK) {
864 statePtr = ((Channel *) chan)->state->bottomChanPtr->state;
867 * Perform special handling for standard channels being closed. If the
868 * refCount is now 1 it means that the last reference to the standard
869 * channel is being explicitly closed, so bump the refCount down
870 * artificially to 0. This will ensure that the channel is actually
871 * closed, below. Also set the static pointer to NULL for the channel.
874 CheckForStdChannelsBeingClosed(chan);
877 * If the refCount reached zero, close the actual channel.
880 if (statePtr->refCount <= 0) {
883 * Ensure that if there is another buffer, it gets flushed
884 * whether or not we are doing a background flush.
887 if ((statePtr->curOutPtr != NULL) &&
888 (statePtr->curOutPtr->nextAdded >
889 statePtr->curOutPtr->nextRemoved)) {
890 statePtr->flags |= BUFFER_READY;
892 Tcl_Preserve((ClientData)statePtr);
893 if (!(statePtr->flags & BG_FLUSH_SCHEDULED)) {
894 /* We don't want to re-enter Tcl_Close */
895 if (!(statePtr->flags & CHANNEL_CLOSED)) {
896 if (Tcl_Close(interp, chan) != TCL_OK) {
897 statePtr->flags |= CHANNEL_CLOSED;
898 Tcl_Release((ClientData)statePtr);
903 statePtr->flags |= CHANNEL_CLOSED;
904 Tcl_Release((ClientData)statePtr);
910 *----------------------------------------------------------------------
912 * Tcl_DetachChannel --
914 * Deletes the hash entry for a channel associated with an interpreter.
915 * If the interpreter given as argument is NULL, it only decrements the
916 * reference count. Even if the ref count drops to zero, the
917 * channel is NOT closed or cleaned up. This allows a channel to
918 * be detached from an interpreter and left in the same state it
919 * was in when it was originally returned by 'Tcl_OpenFileChannel',
922 * This function cannot be used on the standard channels, and
923 * will return TCL_ERROR if that is attempted.
925 * This function should only be necessary for special purposes
926 * in which you need to generate a pristine channel from one
927 * that has already been used. All ordinary purposes will almost
928 * always want to use Tcl_UnregisterChannel instead.
930 * Provided the channel is not attached to any other interpreter,
931 * it can then be closed with Tcl_Close, rather than with
932 * Tcl_UnregisterChannel.
935 * A standard Tcl result. If the channel is not currently registered
936 * with the given interpreter, TCL_ERROR is returned, otherwise
937 * TCL_OK. However no error messages are left in the interp's result.
940 * Deletes the hash entry for a channel associated with an
943 *----------------------------------------------------------------------
947 Tcl_DetachChannel(interp, chan)
948 Tcl_Interp *interp; /* Interpreter in which channel is defined. */
949 Tcl_Channel chan; /* Channel to delete. */
951 if (Tcl_IsStandardChannel(chan)) {
955 return DetachChannel(interp, chan);
959 *----------------------------------------------------------------------
963 * Deletes the hash entry for a channel associated with an interpreter.
964 * If the interpreter given as argument is NULL, it only decrements the
965 * reference count. Even if the ref count drops to zero, the
966 * channel is NOT closed or cleaned up. This allows a channel to
967 * be detached from an interpreter and left in the same state it
968 * was in when it was originally returned by 'Tcl_OpenFileChannel',
972 * A standard Tcl result. If the channel is not currently registered
973 * with the given interpreter, TCL_ERROR is returned, otherwise
974 * TCL_OK. However no error messages are left in the interp's result.
977 * Deletes the hash entry for a channel associated with an
980 *----------------------------------------------------------------------
984 DetachChannel(interp, chan)
985 Tcl_Interp *interp; /* Interpreter in which channel is defined. */
986 Tcl_Channel chan; /* Channel to delete. */
988 Tcl_HashTable *hTblPtr; /* Hash table of channels. */
989 Tcl_HashEntry *hPtr; /* Search variable. */
990 Channel *chanPtr; /* The real IO channel. */
991 ChannelState *statePtr; /* State of the real channel. */
994 * Always (un)register bottom-most channel in the stack. This makes
995 * management of the channel list easier because no manipulation is
996 * necessary during (un)stack operation.
998 chanPtr = ((Channel *) chan)->state->bottomChanPtr;
999 statePtr = chanPtr->state;
1001 if (interp != (Tcl_Interp *) NULL) {
1002 hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);
1003 if (hTblPtr == (Tcl_HashTable *) NULL) {
1006 hPtr = Tcl_FindHashEntry(hTblPtr, statePtr->channelName);
1007 if (hPtr == (Tcl_HashEntry *) NULL) {
1010 if ((Channel *) Tcl_GetHashValue(hPtr) != chanPtr) {
1013 Tcl_DeleteHashEntry(hPtr);
1016 * Remove channel handlers that refer to this interpreter, so that they
1017 * will not be present if the actual close is delayed and more events
1018 * happen on the channel. This may occur if the channel is shared
1019 * between several interpreters, or if the channel has async
1023 CleanupChannelHandlers(interp, chanPtr);
1026 statePtr->refCount--;
1033 *---------------------------------------------------------------------------
1037 * Finds an existing Tcl_Channel structure by name in a given
1038 * interpreter. This function is public because it is used by
1039 * channel-type-specific functions.
1042 * A Tcl_Channel or NULL on failure. If failed, interp's result
1043 * object contains an error message. *modePtr is filled with the
1044 * modes in which the channel was opened.
1049 *---------------------------------------------------------------------------
1052 EXPORT_C Tcl_Channel
1053 Tcl_GetChannel(interp, chanName, modePtr)
1054 Tcl_Interp *interp; /* Interpreter in which to find or create
1056 CONST char *chanName; /* The name of the channel. */
1057 int *modePtr; /* Where to store the mode in which the
1058 * channel was opened? Will contain an ORed
1059 * combination of TCL_READABLE and
1060 * TCL_WRITABLE, if non-NULL. */
1062 Channel *chanPtr; /* The actual channel. */
1063 Tcl_HashTable *hTblPtr; /* Hash table of channels. */
1064 Tcl_HashEntry *hPtr; /* Search variable. */
1065 CONST char *name; /* Translated name. */
1068 * Substitute "stdin", etc. Note that even though we immediately
1069 * find the channel using Tcl_GetStdChannel, we still need to look
1070 * it up in the specified interpreter to ensure that it is present
1071 * in the channel table. Otherwise, safe interpreters would always
1072 * have access to the standard channels.
1076 if ((chanName[0] == 's') && (chanName[1] == 't')) {
1078 if (strcmp(chanName, "stdin") == 0) {
1079 chanPtr = (Channel *) Tcl_GetStdChannel(TCL_STDIN);
1080 } else if (strcmp(chanName, "stdout") == 0) {
1081 chanPtr = (Channel *) Tcl_GetStdChannel(TCL_STDOUT);
1082 } else if (strcmp(chanName, "stderr") == 0) {
1083 chanPtr = (Channel *) Tcl_GetStdChannel(TCL_STDERR);
1085 if (chanPtr != NULL) {
1086 name = chanPtr->state->channelName;
1090 hTblPtr = GetChannelTable(interp);
1091 hPtr = Tcl_FindHashEntry(hTblPtr, name);
1092 if (hPtr == (Tcl_HashEntry *) NULL) {
1093 Tcl_AppendResult(interp, "can not find channel named \"",
1094 chanName, "\"", (char *) NULL);
1099 * Always return bottom-most channel in the stack. This one lives
1100 * the longest - other channels may go away unnoticed.
1101 * The other APIs compensate where necessary to retrieve the
1102 * topmost channel again.
1104 chanPtr = (Channel *) Tcl_GetHashValue(hPtr);
1105 chanPtr = chanPtr->state->bottomChanPtr;
1106 if (modePtr != NULL) {
1107 *modePtr = (chanPtr->state->flags & (TCL_READABLE|TCL_WRITABLE));
1110 return (Tcl_Channel) chanPtr;
1114 *----------------------------------------------------------------------
1116 * Tcl_CreateChannel --
1118 * Creates a new entry in the hash table for a Tcl_Channel
1122 * Returns the new Tcl_Channel.
1125 * Creates a new Tcl_Channel instance and inserts it into the
1128 *----------------------------------------------------------------------
1131 EXPORT_C Tcl_Channel
1132 Tcl_CreateChannel(typePtr, chanName, instanceData, mask)
1133 Tcl_ChannelType *typePtr; /* The channel type record. */
1134 CONST char *chanName; /* Name of channel to record. */
1135 ClientData instanceData; /* Instance specific data. */
1136 int mask; /* TCL_READABLE & TCL_WRITABLE to indicate
1137 * if the channel is readable, writable. */
1139 Channel *chanPtr; /* The channel structure newly created. */
1140 ChannelState *statePtr; /* The stack-level independent state info
1141 * for the channel. */
1143 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
1146 * With the change of the Tcl_ChannelType structure to use a version in
1147 * 8.3.2+, we have to make sure that our assumption that the structure
1148 * remains a binary compatible size is true.
1150 * If this assertion fails on some system, then it can be removed
1151 * only if the user recompiles code with older channel drivers in
1152 * the new system as well.
1155 assert(sizeof(Tcl_ChannelTypeVersion) == sizeof(Tcl_DriverBlockModeProc*));
1158 * JH: We could subsequently memset these to 0 to avoid the
1159 * numerous assignments to 0/NULL below.
1161 chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel));
1162 statePtr = (ChannelState *) ckalloc((unsigned) sizeof(ChannelState));
1163 chanPtr->state = statePtr;
1165 chanPtr->instanceData = instanceData;
1166 chanPtr->typePtr = typePtr;
1169 * Set all the bits that are part of the stack-independent state
1170 * information for the channel.
1173 if (chanName != (char *) NULL) {
1174 char *tmp = ckalloc((unsigned) (strlen(chanName) + 1));
1175 statePtr->channelName = tmp;
1176 strcpy(tmp, chanName);
1178 panic("Tcl_CreateChannel: NULL channel name");
1181 statePtr->flags = mask;
1184 * Set the channel to system default encoding.
1187 statePtr->encoding = NULL;
1188 name = Tcl_GetEncodingName(NULL);
1189 if (strcmp(name, "binary") != 0) {
1190 statePtr->encoding = Tcl_GetEncoding(NULL, name);
1192 statePtr->inputEncodingState = NULL;
1193 statePtr->inputEncodingFlags = TCL_ENCODING_START;
1194 statePtr->outputEncodingState = NULL;
1195 statePtr->outputEncodingFlags = TCL_ENCODING_START;
1198 * Set the channel up initially in AUTO input translation mode to
1199 * accept "\n", "\r" and "\r\n". Output translation mode is set to
1200 * a platform specific default value. The eofChar is set to 0 for both
1201 * input and output, so that Tcl does not look for an in-file EOF
1202 * indicator (e.g. ^Z) and does not append an EOF indicator to files.
1205 statePtr->inputTranslation = TCL_TRANSLATE_AUTO;
1206 statePtr->outputTranslation = TCL_PLATFORM_TRANSLATION;
1207 statePtr->inEofChar = 0;
1208 statePtr->outEofChar = 0;
1210 statePtr->unreportedError = 0;
1211 statePtr->refCount = 0;
1212 statePtr->closeCbPtr = (CloseCallback *) NULL;
1213 statePtr->curOutPtr = (ChannelBuffer *) NULL;
1214 statePtr->outQueueHead = (ChannelBuffer *) NULL;
1215 statePtr->outQueueTail = (ChannelBuffer *) NULL;
1216 statePtr->saveInBufPtr = (ChannelBuffer *) NULL;
1217 statePtr->inQueueHead = (ChannelBuffer *) NULL;
1218 statePtr->inQueueTail = (ChannelBuffer *) NULL;
1219 statePtr->chPtr = (ChannelHandler *) NULL;
1220 statePtr->interestMask = 0;
1221 statePtr->scriptRecordPtr = (EventScriptRecord *) NULL;
1222 statePtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE;
1223 statePtr->timer = NULL;
1224 statePtr->csPtr = NULL;
1226 statePtr->outputStage = NULL;
1227 if ((statePtr->encoding != NULL) && (statePtr->flags & TCL_WRITABLE)) {
1228 statePtr->outputStage = (char *)
1229 ckalloc((unsigned) (statePtr->bufSize + 2));
1233 * As we are creating the channel, it is obviously the top for now
1235 statePtr->topChanPtr = chanPtr;
1236 statePtr->bottomChanPtr = chanPtr;
1237 chanPtr->downChanPtr = (Channel *) NULL;
1238 chanPtr->upChanPtr = (Channel *) NULL;
1239 chanPtr->inQueueHead = (ChannelBuffer*) NULL;
1240 chanPtr->inQueueTail = (ChannelBuffer*) NULL;
1243 * Link the channel into the list of all channels; create an on-exit
1244 * handler if there is not one already, to close off all the channels
1245 * in the list on exit.
1247 * JH: Could call Tcl_SpliceChannel, but need to avoid NULL check.
1250 * AK: Just initialize the field to NULL before invoking Tcl_SpliceChannel
1251 * We need Tcl_SpliceChannel, for the threadAction calls.
1252 * There is no real reason to duplicate all of this.
1253 * NOTE: All drivers using thread actions now have to perform their TSD
1254 * manipulation only in their thread action proc. Doing it when
1255 * creating their instance structures will collide with the thread
1256 * action activity and lead to damaged lists.
1259 statePtr->nextCSPtr = (ChannelState *) NULL;
1260 Tcl_SpliceChannel ((Tcl_Channel) chanPtr);
1263 * Install this channel in the first empty standard channel slot, if
1264 * the channel was previously closed explicitly.
1266 #if TCL_INHERIT_STD_CHANNELS
1267 if ((tsdPtr->stdinChannel == NULL) &&
1268 (tsdPtr->stdinInitialized == 1)) {
1269 Tcl_SetStdChannel((Tcl_Channel) chanPtr, TCL_STDIN);
1270 Tcl_RegisterChannel((Tcl_Interp *) NULL, (Tcl_Channel) chanPtr);
1271 } else if ((tsdPtr->stdoutChannel == NULL) &&
1272 (tsdPtr->stdoutInitialized == 1)) {
1273 Tcl_SetStdChannel((Tcl_Channel) chanPtr, TCL_STDOUT);
1274 Tcl_RegisterChannel((Tcl_Interp *) NULL, (Tcl_Channel) chanPtr);
1275 } else if ((tsdPtr->stderrChannel == NULL) &&
1276 (tsdPtr->stderrInitialized == 1)) {
1277 Tcl_SetStdChannel((Tcl_Channel) chanPtr, TCL_STDERR);
1278 Tcl_RegisterChannel((Tcl_Interp *) NULL, (Tcl_Channel) chanPtr);
1281 return (Tcl_Channel) chanPtr;
1285 *----------------------------------------------------------------------
1287 * Tcl_StackChannel --
1289 * Replaces an entry in the hash table for a Tcl_Channel
1290 * record. The replacement is a new channel with same name,
1291 * it supercedes the replaced channel. Input and output of
1292 * the superceded channel is now going through the newly
1293 * created channel and allows the arbitrary filtering/manipulation
1296 * Andreas Kupries <a.kupries@westend.com>, 12/13/1998
1297 * "Trf-Patch for filtering channels"
1300 * Returns the new Tcl_Channel, which actually contains the
1301 * saved information about prevChan.
1304 * A new channel structure is allocated and linked below
1305 * the existing channel. The channel operations and client
1306 * data of the existing channel are copied down to the newly
1307 * created channel, and the current channel has its operations
1308 * replaced by the new typePtr.
1310 *----------------------------------------------------------------------
1313 EXPORT_C Tcl_Channel
1314 Tcl_StackChannel(interp, typePtr, instanceData, mask, prevChan)
1315 Tcl_Interp *interp; /* The interpreter we are working in */
1316 Tcl_ChannelType *typePtr; /* The channel type record for the new
1318 ClientData instanceData; /* Instance specific data for the new
1320 int mask; /* TCL_READABLE & TCL_WRITABLE to indicate
1321 * if the channel is readable, writable. */
1322 Tcl_Channel prevChan; /* The channel structure to replace */
1324 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
1325 Channel *chanPtr, *prevChanPtr;
1326 ChannelState *statePtr;
1329 * Find the given channel in the list of all channels.
1330 * If we don't find it, then it was never registered correctly.
1332 * This operation should occur at the top of a channel stack.
1335 statePtr = (ChannelState *) tsdPtr->firstCSPtr;
1336 prevChanPtr = ((Channel *) prevChan)->state->topChanPtr;
1338 while ((statePtr != NULL) && (statePtr->topChanPtr != prevChanPtr)) {
1339 statePtr = statePtr->nextCSPtr;
1342 if (statePtr == NULL) {
1344 Tcl_AppendResult(interp, "couldn't find state for channel \"",
1345 Tcl_GetChannelName(prevChan), "\"", (char *) NULL);
1347 return (Tcl_Channel) NULL;
1351 * Here we check if the given "mask" matches the "flags"
1352 * of the already existing channel.
1354 * | - | R | W | RW |
1355 * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask)
1357 * R | | + | | + | The superceding channel is allowed to
1358 * W | | | + | + | restrict the capabilities of the
1359 * RW| | + | + | + | superceded one !
1360 * --+---+---+---+----+
1363 if ((mask & (statePtr->flags & (TCL_READABLE | TCL_WRITABLE))) == 0) {
1365 Tcl_AppendResult(interp,
1366 "reading and writing both disallowed for channel \"",
1367 Tcl_GetChannelName(prevChan), "\"", (char *) NULL);
1369 return (Tcl_Channel) NULL;
1373 * Flush the buffers. This ensures that any data still in them
1374 * at this time is not handled by the new transformation. Restrict
1375 * this to writable channels. Take care to hide a possible bg-copy
1376 * in progress from Tcl_Flush and the CheckForChannelErrors inside.
1379 if ((mask & TCL_WRITABLE) != 0) {
1382 csPtr = statePtr->csPtr;
1383 statePtr->csPtr = (CopyState*) NULL;
1385 if (Tcl_Flush((Tcl_Channel) prevChanPtr) != TCL_OK) {
1386 statePtr->csPtr = csPtr;
1388 Tcl_AppendResult(interp, "could not flush channel \"",
1389 Tcl_GetChannelName(prevChan), "\"", (char *) NULL);
1391 return (Tcl_Channel) NULL;
1394 statePtr->csPtr = csPtr;
1397 * Discard any input in the buffers. They are not yet read by the
1398 * user of the channel, so they have to go through the new
1399 * transformation before reading. As the buffers contain the
1400 * untransformed form their contents are not only useless but actually
1401 * distorts our view of the system.
1403 * To preserve the information without having to read them again and
1404 * to avoid problems with the location in the channel (seeking might
1405 * be impossible) we move the buffers from the common state structure
1406 * into the channel itself. We use the buffers in the channel below
1407 * the new transformation to hold the data. In the future this allows
1408 * us to write transformations which pre-read data and push the unused
1409 * part back when they are going away.
1412 if (((mask & TCL_READABLE) != 0) &&
1413 (statePtr->inQueueHead != (ChannelBuffer*) NULL)) {
1415 * Remark: It is possible that the channel buffers contain data from
1416 * some earlier push-backs.
1419 statePtr->inQueueTail->nextPtr = prevChanPtr->inQueueHead;
1420 prevChanPtr->inQueueHead = statePtr->inQueueHead;
1422 if (prevChanPtr->inQueueTail == (ChannelBuffer*) NULL) {
1423 prevChanPtr->inQueueTail = statePtr->inQueueTail;
1426 statePtr->inQueueHead = (ChannelBuffer*) NULL;
1427 statePtr->inQueueTail = (ChannelBuffer*) NULL;
1430 chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel));
1433 * Save some of the current state into the new structure,
1434 * reinitialize the parts which will stay with the transformation.
1439 chanPtr->state = statePtr;
1440 chanPtr->instanceData = instanceData;
1441 chanPtr->typePtr = typePtr;
1442 chanPtr->downChanPtr = prevChanPtr;
1443 chanPtr->upChanPtr = (Channel *) NULL;
1444 chanPtr->inQueueHead = (ChannelBuffer*) NULL;
1445 chanPtr->inQueueTail = (ChannelBuffer*) NULL;
1448 * Place new block at the head of a possibly existing list of previously
1452 prevChanPtr->upChanPtr = chanPtr;
1453 statePtr->topChanPtr = chanPtr;
1455 return (Tcl_Channel) chanPtr;
1459 *----------------------------------------------------------------------
1461 * Tcl_UnstackChannel --
1463 * Unstacks an entry in the hash table for a Tcl_Channel
1464 * record. This is the reverse to 'Tcl_StackChannel'.
1467 * A standard Tcl result.
1470 * If TCL_ERROR is returned, the posix error code will be set
1471 * with Tcl_SetErrno.
1473 *----------------------------------------------------------------------
1477 Tcl_UnstackChannel (interp, chan)
1478 Tcl_Interp *interp; /* The interpreter we are working in */
1479 Tcl_Channel chan; /* The channel to unstack */
1481 Channel *chanPtr = (Channel *) chan;
1482 ChannelState *statePtr = chanPtr->state;
1486 * This operation should occur at the top of a channel stack.
1489 chanPtr = statePtr->topChanPtr;
1491 if (chanPtr->downChanPtr != (Channel *) NULL) {
1493 * Instead of manipulating the per-thread / per-interp list/hashtable
1494 * of registered channels we wind down the state of the transformation,
1495 * and then restore the state of underlying channel into the old
1498 Channel *downChanPtr = chanPtr->downChanPtr;
1501 * Flush the buffers. This ensures that any data still in them
1502 * at this time _is_ handled by the transformation we are unstacking
1503 * right now. Restrict this to writable channels. Take care to hide
1504 * a possible bg-copy in progress from Tcl_Flush and the
1505 * CheckForChannelErrors inside.
1508 if (statePtr->flags & TCL_WRITABLE) {
1511 csPtr = statePtr->csPtr;
1512 statePtr->csPtr = (CopyState*) NULL;
1514 if (Tcl_Flush((Tcl_Channel) chanPtr) != TCL_OK) {
1515 statePtr->csPtr = csPtr;
1517 Tcl_AppendResult(interp, "could not flush channel \"",
1518 Tcl_GetChannelName((Tcl_Channel) chanPtr), "\"",
1524 statePtr->csPtr = csPtr;
1528 * Anything in the input queue and the push-back buffers of
1529 * the transformation going away is transformed data, but not
1530 * yet read. As unstacking means that the caller does not want
1531 * to see transformed data any more we have to discard these
1532 * bytes. To avoid writing an analogue to 'DiscardInputQueued'
1533 * we move the information in the push back buffers to the
1534 * input queue and then call 'DiscardInputQueued' on that.
1537 if (((statePtr->flags & TCL_READABLE) != 0) &&
1538 ((statePtr->inQueueHead != (ChannelBuffer*) NULL) ||
1539 (chanPtr->inQueueHead != (ChannelBuffer*) NULL))) {
1541 if ((statePtr->inQueueHead != (ChannelBuffer*) NULL) &&
1542 (chanPtr->inQueueHead != (ChannelBuffer*) NULL)) {
1543 statePtr->inQueueTail->nextPtr = chanPtr->inQueueHead;
1544 statePtr->inQueueTail = chanPtr->inQueueTail;
1545 statePtr->inQueueHead = statePtr->inQueueTail;
1547 } else if (chanPtr->inQueueHead != (ChannelBuffer*) NULL) {
1548 statePtr->inQueueHead = chanPtr->inQueueHead;
1549 statePtr->inQueueTail = chanPtr->inQueueTail;
1552 chanPtr->inQueueHead = (ChannelBuffer*) NULL;
1553 chanPtr->inQueueTail = (ChannelBuffer*) NULL;
1555 DiscardInputQueued (statePtr, 0);
1558 statePtr->topChanPtr = downChanPtr;
1559 downChanPtr->upChanPtr = (Channel *) NULL;
1562 * Leave this link intact for closeproc
1563 * chanPtr->downChanPtr = (Channel *) NULL;
1567 * Close and free the channel driver state.
1570 if (chanPtr->typePtr->closeProc != TCL_CLOSE2PROC) {
1571 result = (chanPtr->typePtr->closeProc)(chanPtr->instanceData,
1574 result = (chanPtr->typePtr->close2Proc)(chanPtr->instanceData,
1578 chanPtr->typePtr = NULL;
1580 * AK: Tcl_NotifyChannel may hold a reference to this block of memory
1582 Tcl_EventuallyFree((ClientData) chanPtr, TCL_DYNAMIC);
1583 UpdateInterest(downChanPtr);
1586 Tcl_SetErrno(result);
1591 * This channel does not cover another one.
1592 * Simply do a close, if necessary.
1595 if (statePtr->refCount <= 0) {
1596 if (Tcl_Close(interp, chan) != TCL_OK) {
1606 *----------------------------------------------------------------------
1608 * Tcl_GetStackedChannel --
1610 * Determines whether the specified channel is stacked upon another.
1613 * NULL if the channel is not stacked upon another one, or a reference
1614 * to the channel it is stacked upon. This reference can be used in
1615 * queries, but modification is not allowed.
1620 *----------------------------------------------------------------------
1623 EXPORT_C Tcl_Channel
1624 Tcl_GetStackedChannel(chan)
1627 Channel *chanPtr = (Channel *) chan; /* The actual channel. */
1629 return (Tcl_Channel) chanPtr->downChanPtr;
1633 *----------------------------------------------------------------------
1635 * Tcl_GetTopChannel --
1637 * Returns the top channel of a channel stack.
1640 * NULL if the channel is not stacked upon another one, or a reference
1641 * to the channel it is stacked upon. This reference can be used in
1642 * queries, but modification is not allowed.
1647 *----------------------------------------------------------------------
1650 EXPORT_C Tcl_Channel
1651 Tcl_GetTopChannel(chan)
1654 Channel *chanPtr = (Channel *) chan; /* The actual channel. */
1656 return (Tcl_Channel) chanPtr->state->topChanPtr;
1660 *----------------------------------------------------------------------
1662 * Tcl_GetChannelInstanceData --
1664 * Returns the client data associated with a channel.
1672 *----------------------------------------------------------------------
1676 Tcl_GetChannelInstanceData(chan)
1677 Tcl_Channel chan; /* Channel for which to return client data. */
1679 Channel *chanPtr = (Channel *) chan; /* The actual channel. */
1681 return chanPtr->instanceData;
1685 *----------------------------------------------------------------------
1687 * Tcl_GetChannelThread --
1689 * Given a channel structure, returns the thread managing it.
1693 * Returns the id of the thread managing the channel.
1698 *----------------------------------------------------------------------
1701 EXPORT_C Tcl_ThreadId
1702 Tcl_GetChannelThread(chan)
1703 Tcl_Channel chan; /* The channel to return managing thread for. */
1705 Channel *chanPtr = (Channel *) chan; /* The actual channel. */
1707 return chanPtr->state->managingThread;
1711 *----------------------------------------------------------------------
1713 * Tcl_GetChannelType --
1715 * Given a channel structure, returns the channel type structure.
1718 * Returns a pointer to the channel type structure.
1723 *----------------------------------------------------------------------
1726 EXPORT_C Tcl_ChannelType *
1727 Tcl_GetChannelType(chan)
1728 Tcl_Channel chan; /* The channel to return type for. */
1730 Channel *chanPtr = (Channel *) chan; /* The actual channel. */
1732 return chanPtr->typePtr;
1736 *----------------------------------------------------------------------
1738 * Tcl_GetChannelMode --
1740 * Computes a mask indicating whether the channel is open for
1741 * reading and writing.
1744 * An OR-ed combination of TCL_READABLE and TCL_WRITABLE.
1749 *----------------------------------------------------------------------
1753 Tcl_GetChannelMode(chan)
1754 Tcl_Channel chan; /* The channel for which the mode is
1755 * being computed. */
1757 ChannelState *statePtr = ((Channel *) chan)->state;
1758 /* State of actual channel. */
1760 return (statePtr->flags & (TCL_READABLE | TCL_WRITABLE));
1764 *----------------------------------------------------------------------
1766 * Tcl_GetChannelName --
1768 * Returns the string identifying the channel name.
1771 * The string containing the channel name. This memory is
1772 * owned by the generic layer and should not be modified by
1778 *----------------------------------------------------------------------
1781 EXPORT_C CONST char *
1782 Tcl_GetChannelName(chan)
1783 Tcl_Channel chan; /* The channel for which to return the name. */
1785 ChannelState *statePtr; /* State of actual channel. */
1787 statePtr = ((Channel *) chan)->state;
1788 return statePtr->channelName;
1792 *----------------------------------------------------------------------
1794 * Tcl_GetChannelHandle --
1796 * Returns an OS handle associated with a channel.
1799 * Returns TCL_OK and places the handle in handlePtr, or returns
1800 * TCL_ERROR on failure.
1805 *----------------------------------------------------------------------
1809 Tcl_GetChannelHandle(chan, direction, handlePtr)
1810 Tcl_Channel chan; /* The channel to get file from. */
1811 int direction; /* TCL_WRITABLE or TCL_READABLE. */
1812 ClientData *handlePtr; /* Where to store handle */
1814 Channel *chanPtr; /* The actual channel. */
1818 chanPtr = ((Channel *) chan)->state->bottomChanPtr;
1819 result = (chanPtr->typePtr->getHandleProc)(chanPtr->instanceData,
1820 direction, &handle);
1822 *handlePtr = handle;
1828 *---------------------------------------------------------------------------
1830 * AllocChannelBuffer --
1832 * A channel buffer has BUFFER_PADDING bytes extra at beginning to
1833 * hold any bytes of a native-encoding character that got split by
1834 * the end of the previous buffer and need to be moved to the
1835 * beginning of the next buffer to make a contiguous string so it
1836 * can be converted to UTF-8.
1838 * A channel buffer has BUFFER_PADDING bytes extra at the end to
1839 * hold any bytes of a native-encoding character (generated from a
1840 * UTF-8 character) that overflow past the end of the buffer and
1841 * need to be moved to the next buffer.
1844 * A newly allocated channel buffer.
1849 *---------------------------------------------------------------------------
1852 static ChannelBuffer *
1853 AllocChannelBuffer(length)
1854 int length; /* Desired length of channel buffer. */
1856 ChannelBuffer *bufPtr;
1859 n = length + CHANNELBUFFER_HEADER_SIZE + BUFFER_PADDING + BUFFER_PADDING;
1860 bufPtr = (ChannelBuffer *) ckalloc((unsigned) n);
1861 bufPtr->nextAdded = BUFFER_PADDING;
1862 bufPtr->nextRemoved = BUFFER_PADDING;
1863 bufPtr->bufLength = length + BUFFER_PADDING;
1864 bufPtr->nextPtr = (ChannelBuffer *) NULL;
1869 *----------------------------------------------------------------------
1873 * Helper function to recycle input and output buffers. Ensures
1874 * that two input buffers are saved (one in the input queue and
1875 * another in the saveInBufPtr field) and that curOutPtr is set
1876 * to a buffer. Only if these conditions are met is the buffer
1883 * May free a buffer to the OS.
1885 *----------------------------------------------------------------------
1889 RecycleBuffer(statePtr, bufPtr, mustDiscard)
1890 ChannelState *statePtr; /* ChannelState in which to recycle buffers. */
1891 ChannelBuffer *bufPtr; /* The buffer to recycle. */
1892 int mustDiscard; /* If nonzero, free the buffer to the
1896 * Do we have to free the buffer to the OS?
1900 ckfree((char *) bufPtr);
1905 * Only save buffers which are at least as big as the requested
1906 * buffersize for the channel. This is to honor dynamic changes
1907 * of the buffersize made by the user.
1910 if ((bufPtr->bufLength - BUFFER_PADDING) < statePtr->bufSize) {
1911 ckfree((char *) bufPtr);
1916 * Only save buffers for the input queue if the channel is readable.
1919 if (statePtr->flags & TCL_READABLE) {
1920 if (statePtr->inQueueHead == (ChannelBuffer *) NULL) {
1921 statePtr->inQueueHead = bufPtr;
1922 statePtr->inQueueTail = bufPtr;
1925 if (statePtr->saveInBufPtr == (ChannelBuffer *) NULL) {
1926 statePtr->saveInBufPtr = bufPtr;
1932 * Only save buffers for the output queue if the channel is writable.
1935 if (statePtr->flags & TCL_WRITABLE) {
1936 if (statePtr->curOutPtr == (ChannelBuffer *) NULL) {
1937 statePtr->curOutPtr = bufPtr;
1943 * If we reached this code we return the buffer to the OS.
1946 ckfree((char *) bufPtr);
1950 bufPtr->nextRemoved = BUFFER_PADDING;
1951 bufPtr->nextAdded = BUFFER_PADDING;
1952 bufPtr->nextPtr = (ChannelBuffer *) NULL;
1956 *----------------------------------------------------------------------
1958 * DiscardOutputQueued --
1960 * Discards all output queued in the output queue of a channel.
1968 *----------------------------------------------------------------------
1972 DiscardOutputQueued(statePtr)
1973 ChannelState *statePtr; /* ChannelState for which to discard output. */
1975 ChannelBuffer *bufPtr;
1977 while (statePtr->outQueueHead != (ChannelBuffer *) NULL) {
1978 bufPtr = statePtr->outQueueHead;
1979 statePtr->outQueueHead = bufPtr->nextPtr;
1980 RecycleBuffer(statePtr, bufPtr, 0);
1982 statePtr->outQueueHead = (ChannelBuffer *) NULL;
1983 statePtr->outQueueTail = (ChannelBuffer *) NULL;
1987 *----------------------------------------------------------------------
1989 * CheckForDeadChannel --
1991 * This function checks is a given channel is Dead.
1992 * (A channel that has been closed but not yet deallocated.)
1995 * True (1) if channel is Dead, False (0) if channel is Ok
2000 *----------------------------------------------------------------------
2004 CheckForDeadChannel(interp, statePtr)
2005 Tcl_Interp *interp; /* For error reporting (can be NULL) */
2006 ChannelState *statePtr; /* The channel state to check. */
2008 if (statePtr->flags & CHANNEL_DEAD) {
2009 Tcl_SetErrno(EINVAL);
2011 Tcl_AppendResult(interp,
2012 "unable to access channel: invalid channel",
2021 *----------------------------------------------------------------------
2025 * This function flushes as much of the queued output as is possible
2026 * now. If calledFromAsyncFlush is nonzero, it is being called in an
2027 * event handler to flush channel output asynchronously.
2030 * 0 if successful, else the error code that was returned by the
2031 * channel type operation.
2034 * May produce output on a channel. May block indefinitely if the
2035 * channel is synchronous. May schedule an async flush on the channel.
2036 * May recycle memory for buffers in the output queue.
2038 *----------------------------------------------------------------------
2042 FlushChannel(interp, chanPtr, calledFromAsyncFlush)
2043 Tcl_Interp *interp; /* For error reporting during close. */
2044 Channel *chanPtr; /* The channel to flush on. */
2045 int calledFromAsyncFlush; /* If nonzero then we are being
2046 * called from an asynchronous
2047 * flush callback. */
2049 ChannelState *statePtr = chanPtr->state;
2050 /* State of the channel stack. */
2051 ChannelBuffer *bufPtr; /* Iterates over buffered output
2053 int toWrite; /* Amount of output data in current
2054 * buffer available to be written. */
2055 int written; /* Amount of output data actually
2056 * written in current round. */
2057 int errorCode = 0; /* Stores POSIX error codes from
2058 * channel driver operations. */
2059 int wroteSome = 0; /* Set to one if any data was
2060 * written to the driver. */
2063 * Prevent writing on a dead channel -- a channel that has been closed
2064 * but not yet deallocated. This can occur if the exit handler for the
2065 * channel deallocation runs before all channels are deregistered in
2069 if (CheckForDeadChannel(interp, statePtr)) return -1;
2072 * Loop over the queued buffers and attempt to flush as
2073 * much as possible of the queued output to the channel.
2079 * If the queue is empty and there is a ready current buffer, OR if
2080 * the current buffer is full, then move the current buffer to the
2084 if (((statePtr->curOutPtr != (ChannelBuffer *) NULL) &&
2085 (statePtr->curOutPtr->nextAdded == statePtr->curOutPtr->bufLength))
2086 || ((statePtr->flags & BUFFER_READY) &&
2087 (statePtr->outQueueHead == (ChannelBuffer *) NULL))) {
2088 statePtr->flags &= (~(BUFFER_READY));
2089 statePtr->curOutPtr->nextPtr = (ChannelBuffer *) NULL;
2090 if (statePtr->outQueueHead == (ChannelBuffer *) NULL) {
2091 statePtr->outQueueHead = statePtr->curOutPtr;
2093 statePtr->outQueueTail->nextPtr = statePtr->curOutPtr;
2095 statePtr->outQueueTail = statePtr->curOutPtr;
2096 statePtr->curOutPtr = (ChannelBuffer *) NULL;
2098 bufPtr = statePtr->outQueueHead;
2101 * If we are not being called from an async flush and an async
2102 * flush is active, we just return without producing any output.
2105 if ((!calledFromAsyncFlush) &&
2106 (statePtr->flags & BG_FLUSH_SCHEDULED)) {
2111 * If the output queue is still empty, break out of the while loop.
2114 if (bufPtr == (ChannelBuffer *) NULL) {
2115 break; /* Out of the "while (1)". */
2119 * Produce the output on the channel.
2122 toWrite = bufPtr->nextAdded - bufPtr->nextRemoved;
2123 written = (chanPtr->typePtr->outputProc) (chanPtr->instanceData,
2124 bufPtr->buf + bufPtr->nextRemoved, toWrite,
2128 * If the write failed completely attempt to start the asynchronous
2129 * flush mechanism and break out of this loop - do not attempt to
2130 * write any more output at this time.
2136 * If the last attempt to write was interrupted, simply retry.
2139 if (errorCode == EINTR) {
2145 * If the channel is non-blocking and we would have blocked,
2146 * start a background flushing handler and break out of the loop.
2149 if ((errorCode == EWOULDBLOCK) || (errorCode == EAGAIN)) {
2151 * This used to check for CHANNEL_NONBLOCKING, and panic
2152 * if the channel was blocking. However, it appears
2153 * that setting stdin to -blocking 0 has some effect on
2154 * the stdout when it's a tty channel (dup'ed underneath)
2156 if (!(statePtr->flags & BG_FLUSH_SCHEDULED)) {
2157 statePtr->flags |= BG_FLUSH_SCHEDULED;
2158 UpdateInterest(chanPtr);
2165 * Decide whether to report the error upwards or defer it.
2168 if (calledFromAsyncFlush) {
2169 if (statePtr->unreportedError == 0) {
2170 statePtr->unreportedError = errorCode;
2173 Tcl_SetErrno(errorCode);
2174 if (interp != NULL) {
2177 * Casting away CONST here is safe because the
2178 * TCL_VOLATILE flag guarantees CONST treatment
2179 * of the Posix error string.
2182 Tcl_SetResult(interp,
2183 (char *) Tcl_PosixError(interp), TCL_VOLATILE);
2188 * When we get an error we throw away all the output
2192 DiscardOutputQueued(statePtr);
2198 bufPtr->nextRemoved += written;
2201 * If this buffer is now empty, recycle it.
2204 if (bufPtr->nextRemoved == bufPtr->nextAdded) {
2205 statePtr->outQueueHead = bufPtr->nextPtr;
2206 if (statePtr->outQueueHead == (ChannelBuffer *) NULL) {
2207 statePtr->outQueueTail = (ChannelBuffer *) NULL;
2209 RecycleBuffer(statePtr, bufPtr, 0);
2211 } /* Closes "while (1)". */
2214 * If we wrote some data while flushing in the background, we are done.
2215 * We can't finish the background flush until we run out of data and
2216 * the channel becomes writable again. This ensures that all of the
2217 * pending data has been flushed at the system level.
2220 if (statePtr->flags & BG_FLUSH_SCHEDULED) {
2223 } else if (statePtr->outQueueHead == (ChannelBuffer *) NULL) {
2224 statePtr->flags &= (~(BG_FLUSH_SCHEDULED));
2225 (chanPtr->typePtr->watchProc)(chanPtr->instanceData,
2226 statePtr->interestMask);
2231 * If the channel is flagged as closed, delete it when the refCount
2232 * drops to zero, the output queue is empty and there is no output
2233 * in the current output buffer.
2236 if ((statePtr->flags & CHANNEL_CLOSED) && (statePtr->refCount <= 0) &&
2237 (statePtr->outQueueHead == (ChannelBuffer *) NULL) &&
2238 ((statePtr->curOutPtr == (ChannelBuffer *) NULL) ||
2239 (statePtr->curOutPtr->nextAdded ==
2240 statePtr->curOutPtr->nextRemoved))) {
2241 return CloseChannel(interp, chanPtr, errorCode);
2247 *----------------------------------------------------------------------
2251 * Utility procedure to close a channel and free associated resources.
2253 * If the channel was stacked, then the it will copy the necessary
2254 * elements of the NEXT channel into the TOP channel, in essence
2255 * unstacking the channel. The NEXT channel will then be freed.
2257 * If the channel was not stacked, then we will free all the bits
2258 * for the TOP channel, including the data structure itself.
2261 * 1 if the channel was stacked, 0 otherwise.
2264 * May close the actual channel; may free memory.
2265 * May change the value of errno.
2267 *----------------------------------------------------------------------
2271 CloseChannel(interp, chanPtr, errorCode)
2272 Tcl_Interp *interp; /* For error reporting. */
2273 Channel *chanPtr; /* The channel to close. */
2274 int errorCode; /* Status of operation so far. */
2276 int result = 0; /* Of calling driver close
2278 ChannelState *statePtr; /* state of the channel stack. */
2279 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
2281 if (chanPtr == NULL) {
2284 statePtr = chanPtr->state;
2287 * No more input can be consumed so discard any leftover input.
2290 DiscardInputQueued(statePtr, 1);
2293 * Discard a leftover buffer in the current output buffer field.
2296 if (statePtr->curOutPtr != (ChannelBuffer *) NULL) {
2297 ckfree((char *) statePtr->curOutPtr);
2298 statePtr->curOutPtr = (ChannelBuffer *) NULL;
2302 * The caller guarantees that there are no more buffers
2303 * queued for output.
2306 if (statePtr->outQueueHead != (ChannelBuffer *) NULL) {
2307 panic("TclFlush, closed channel: queued output left");
2311 * If the EOF character is set in the channel, append that to the
2315 if ((statePtr->outEofChar != 0) && (statePtr->flags & TCL_WRITABLE)) {
2319 c = (char) statePtr->outEofChar;
2320 (chanPtr->typePtr->outputProc) (chanPtr->instanceData, &c, 1, &dummy);
2324 * Remove this channel from of the list of all channels.
2326 Tcl_CutChannel((Tcl_Channel) chanPtr);
2329 * Close and free the channel driver state.
2332 if (chanPtr->typePtr->closeProc != TCL_CLOSE2PROC) {
2333 result = (chanPtr->typePtr->closeProc)(chanPtr->instanceData, interp);
2335 result = (chanPtr->typePtr->close2Proc)(chanPtr->instanceData, interp,
2340 * Some resources can be cleared only if the bottom channel
2341 * in a stack is closed. All the other channels in the stack
2342 * are not allowed to remove.
2345 if (chanPtr == statePtr->bottomChanPtr) {
2346 if (statePtr->channelName != (char *) NULL) {
2347 ckfree((char *) statePtr->channelName);
2348 statePtr->channelName = NULL;
2351 Tcl_FreeEncoding(statePtr->encoding);
2352 if (statePtr->outputStage != NULL) {
2353 ckfree((char *) statePtr->outputStage);
2354 statePtr->outputStage = (char *) NULL;
2359 * If we are being called synchronously, report either
2360 * any latent error on the channel or the current error.
2363 if (statePtr->unreportedError != 0) {
2364 errorCode = statePtr->unreportedError;
2366 if (errorCode == 0) {
2368 if (errorCode != 0) {
2369 Tcl_SetErrno(errorCode);
2374 * Cancel any outstanding timer.
2377 Tcl_DeleteTimerHandler(statePtr->timer);
2380 * Mark the channel as deleted by clearing the type structure.
2383 if (chanPtr->downChanPtr != (Channel *) NULL) {
2384 Channel *downChanPtr = chanPtr->downChanPtr;
2386 statePtr->nextCSPtr = tsdPtr->firstCSPtr;
2387 tsdPtr->firstCSPtr = statePtr;
2389 statePtr->topChanPtr = downChanPtr;
2390 downChanPtr->upChanPtr = (Channel *) NULL;
2391 chanPtr->typePtr = NULL;
2393 Tcl_EventuallyFree((ClientData) chanPtr, TCL_DYNAMIC);
2394 return Tcl_Close(interp, (Tcl_Channel) downChanPtr);
2398 * There is only the TOP Channel, so we free the remaining
2399 * pointers we have and then ourselves. Since this is the
2400 * last of the channels in the stack, make sure to free the
2401 * ChannelState structure associated with it. We use
2402 * Tcl_EventuallyFree to allow for any last
2404 chanPtr->typePtr = NULL;
2406 Tcl_EventuallyFree((ClientData) statePtr, TCL_DYNAMIC);
2407 Tcl_EventuallyFree((ClientData) chanPtr, TCL_DYNAMIC);
2413 *----------------------------------------------------------------------
2417 * Removes a channel from the (thread-)global list of all channels
2418 * (in that thread). This is actually the statePtr for the stack
2425 * Resets the field 'nextCSPtr' of the specified channel state to NULL.
2428 * The channel to cut out of the list must not be referenced
2429 * in any interpreter. This is something this procedure cannot
2430 * check (despite the refcount) because the caller usually wants
2431 * fiddle with the channel (like transfering it to a different
2432 * thread) and thus keeps the refcount artifically high to prevent
2435 *----------------------------------------------------------------------
2439 Tcl_CutChannel(chan)
2440 Tcl_Channel chan; /* The channel being removed. Must
2441 * not be referenced in any
2444 ThreadSpecificData* tsdPtr = TCL_TSD_INIT(&dataKey);
2445 ChannelState *prevCSPtr; /* Preceding channel state in list of
2446 * all states - used to splice a
2447 * channel out of the list on close. */
2448 ChannelState *statePtr = ((Channel *) chan)->state;
2449 /* state of the channel stack. */
2450 Tcl_DriverThreadActionProc *threadActionProc;
2453 * Remove this channel from of the list of all channels
2454 * (in the current thread).
2457 if (tsdPtr->firstCSPtr && (statePtr == tsdPtr->firstCSPtr)) {
2458 tsdPtr->firstCSPtr = statePtr->nextCSPtr;
2460 for (prevCSPtr = tsdPtr->firstCSPtr;
2461 prevCSPtr && (prevCSPtr->nextCSPtr != statePtr);
2462 prevCSPtr = prevCSPtr->nextCSPtr) {
2463 /* Empty loop body. */
2465 if (prevCSPtr == (ChannelState *) NULL) {
2466 panic("FlushChannel: damaged channel list");
2468 prevCSPtr->nextCSPtr = statePtr->nextCSPtr;
2471 statePtr->nextCSPtr = (ChannelState *) NULL;
2473 /* TIP #218, Channel Thread Actions */
2474 threadActionProc = Tcl_ChannelThreadActionProc (Tcl_GetChannelType (chan));
2475 if (threadActionProc != NULL) {
2476 (*threadActionProc) (Tcl_GetChannelInstanceData(chan),
2477 TCL_CHANNEL_THREAD_REMOVE);
2482 *----------------------------------------------------------------------
2484 * Tcl_SpliceChannel --
2486 * Adds a channel to the (thread-)global list of all channels
2487 * (in that thread). Expects that the field 'nextChanPtr' in
2488 * the channel is set to NULL.
2497 * The channel to splice into the list must not be referenced in any
2498 * interpreter. This is something this procedure cannot check
2499 * (despite the refcount) because the caller usually wants figgle
2500 * with the channel (like transfering it to a different thread)
2501 * and thus keeps the refcount artifically high to prevent its
2504 *----------------------------------------------------------------------
2508 Tcl_SpliceChannel(chan)
2509 Tcl_Channel chan; /* The channel being added. Must
2510 * not be referenced in any
2513 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
2514 ChannelState *statePtr = ((Channel *) chan)->state;
2515 Tcl_DriverThreadActionProc *threadActionProc;
2517 if (statePtr->nextCSPtr != (ChannelState *) NULL) {
2518 panic("Tcl_SpliceChannel: trying to add channel used in different list");
2521 statePtr->nextCSPtr = tsdPtr->firstCSPtr;
2522 tsdPtr->firstCSPtr = statePtr;
2525 * TIP #10. Mark the current thread as the new one managing this
2526 * channel. Note: 'Tcl_GetCurrentThread' returns sensible
2527 * values even for a non-threaded core.
2530 statePtr->managingThread = Tcl_GetCurrentThread ();
2532 /* TIP #218, Channel Thread Actions */
2533 threadActionProc = Tcl_ChannelThreadActionProc (Tcl_GetChannelType (chan));
2534 if (threadActionProc != NULL) {
2535 (*threadActionProc) (Tcl_GetChannelInstanceData(chan),
2536 TCL_CHANNEL_THREAD_INSERT);
2541 *----------------------------------------------------------------------
2548 * A standard Tcl result.
2551 * Closes the channel if this is the last reference.
2554 * Tcl_Close removes the channel as far as the user is concerned.
2555 * However, it may continue to exist for a while longer if it has
2556 * a background flush scheduled. The device itself is eventually
2557 * closed and the channel record removed, in CloseChannel, above.
2559 *----------------------------------------------------------------------
2564 Tcl_Close(interp, chan)
2565 Tcl_Interp *interp; /* Interpreter for errors. */
2566 Tcl_Channel chan; /* The channel being closed. Must
2567 * not be referenced in any
2570 CloseCallback *cbPtr; /* Iterate over close callbacks
2571 * for this channel. */
2572 Channel *chanPtr; /* The real IO channel. */
2573 ChannelState *statePtr; /* State of real IO channel. */
2574 int result; /* Of calling FlushChannel. */
2576 if (chan == (Tcl_Channel) NULL) {
2581 * Perform special handling for standard channels being closed. If the
2582 * refCount is now 1 it means that the last reference to the standard
2583 * channel is being explicitly closed, so bump the refCount down
2584 * artificially to 0. This will ensure that the channel is actually
2585 * closed, below. Also set the static pointer to NULL for the channel.
2588 CheckForStdChannelsBeingClosed(chan);
2591 * This operation should occur at the top of a channel stack.
2594 chanPtr = (Channel *) chan;
2595 statePtr = chanPtr->state;
2596 chanPtr = statePtr->topChanPtr;
2598 if (statePtr->refCount > 0) {
2599 panic("called Tcl_Close on channel with refCount > 0");
2602 if (statePtr->flags & CHANNEL_INCLOSE) {
2604 Tcl_AppendResult(interp,
2605 "Illegal recursive call to close through close-handler of channel",
2610 statePtr->flags |= CHANNEL_INCLOSE;
2613 * When the channel has an escape sequence driven encoding such as
2614 * iso2022, the terminated escape sequence must write to the buffer.
2616 if ((statePtr->encoding != NULL) && (statePtr->curOutPtr != NULL)
2617 && (CheckChannelErrors(statePtr, TCL_WRITABLE) == 0)) {
2618 statePtr->outputEncodingFlags |= TCL_ENCODING_END;
2619 WriteChars(chanPtr, "", 0);
2622 Tcl_ClearChannelHandlers(chan);
2625 * Invoke the registered close callbacks and delete their records.
2628 while (statePtr->closeCbPtr != (CloseCallback *) NULL) {
2629 cbPtr = statePtr->closeCbPtr;
2630 statePtr->closeCbPtr = cbPtr->nextPtr;
2631 (cbPtr->proc) (cbPtr->clientData);
2632 ckfree((char *) cbPtr);
2635 statePtr->flags &= ~CHANNEL_INCLOSE;
2638 * Ensure that the last output buffer will be flushed.
2641 if ((statePtr->curOutPtr != (ChannelBuffer *) NULL) &&
2642 (statePtr->curOutPtr->nextAdded > statePtr->curOutPtr->nextRemoved)) {
2643 statePtr->flags |= BUFFER_READY;
2647 * If this channel supports it, close the read side, since we don't need it
2648 * anymore and this will help avoid deadlocks on some channel types.
2651 if (chanPtr->typePtr->closeProc == TCL_CLOSE2PROC) {
2652 result = (chanPtr->typePtr->close2Proc)(chanPtr->instanceData, interp,
2659 * The call to FlushChannel will flush any queued output and invoke
2660 * the close function of the channel driver, or it will set up the
2661 * channel to be flushed and closed asynchronously.
2664 statePtr->flags |= CHANNEL_CLOSED;
2665 if ((FlushChannel(interp, chanPtr, 0) != 0) || (result != 0)) {
2672 *----------------------------------------------------------------------
2674 * Tcl_ClearChannelHandlers --
2676 * Removes all channel handlers and event scripts from the channel,
2677 * cancels all background copies involving the channel and any interest
2684 * See above. Deallocates memory.
2686 *----------------------------------------------------------------------
2690 Tcl_ClearChannelHandlers (channel)
2691 Tcl_Channel channel;
2693 ChannelHandler *chPtr, *chNext; /* Iterate over channel handlers. */
2694 EventScriptRecord *ePtr, *eNextPtr; /* Iterate over eventscript records. */
2695 Channel *chanPtr; /* The real IO channel. */
2696 ChannelState *statePtr; /* State of real IO channel. */
2697 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
2698 NextChannelHandler *nhPtr;
2701 * This operation should occur at the top of a channel stack.
2704 chanPtr = (Channel *) channel;
2705 statePtr = chanPtr->state;
2706 chanPtr = statePtr->topChanPtr;
2709 * Cancel any outstanding timer.
2712 Tcl_DeleteTimerHandler(statePtr->timer);
2715 * Remove any references to channel handlers for this channel that
2716 * may be about to be invoked.
2719 for (nhPtr = tsdPtr->nestedHandlerPtr;
2720 nhPtr != (NextChannelHandler *) NULL;
2721 nhPtr = nhPtr->nestedHandlerPtr) {
2722 if (nhPtr->nextHandlerPtr &&
2723 (nhPtr->nextHandlerPtr->chanPtr == chanPtr)) {
2724 nhPtr->nextHandlerPtr = NULL;
2729 * Remove all the channel handler records attached to the channel
2733 for (chPtr = statePtr->chPtr;
2734 chPtr != (ChannelHandler *) NULL;
2736 chNext = chPtr->nextPtr;
2737 ckfree((char *) chPtr);
2739 statePtr->chPtr = (ChannelHandler *) NULL;
2742 * Cancel any pending copy operation.
2745 StopCopy(statePtr->csPtr);
2748 * Must set the interest mask now to 0, otherwise infinite loops
2749 * will occur if Tcl_DoOneEvent is called before the channel is
2750 * finally deleted in FlushChannel. This can happen if the channel
2751 * has a background flush active.
2754 statePtr->interestMask = 0;
2757 * Remove any EventScript records for this channel.
2760 for (ePtr = statePtr->scriptRecordPtr;
2761 ePtr != (EventScriptRecord *) NULL;
2763 eNextPtr = ePtr->nextPtr;
2764 Tcl_DecrRefCount(ePtr->scriptPtr);
2765 ckfree((char *) ePtr);
2767 statePtr->scriptRecordPtr = (EventScriptRecord *) NULL;
2771 *----------------------------------------------------------------------
2775 * Puts a sequence of bytes into an output buffer, may queue the
2776 * buffer for output if it gets full, and also remembers whether the
2777 * current buffer is ready e.g. if it contains a newline and we are in
2778 * line buffering mode. Compensates stacking, i.e. will redirect the
2779 * data from the specified channel to the topmost channel in a stack.
2781 * No encoding conversions are applied to the bytes being read.
2784 * The number of bytes written or -1 in case of error. If -1,
2785 * Tcl_GetErrno will return the error code.
2788 * May buffer up output and may cause output to be produced on the
2791 *----------------------------------------------------------------------
2795 Tcl_Write(chan, src, srcLen)
2796 Tcl_Channel chan; /* The channel to buffer output for. */
2797 CONST char *src; /* Data to queue in output buffer. */
2798 int srcLen; /* Length of data in bytes, or < 0 for
2802 * Always use the topmost channel of the stack
2805 ChannelState *statePtr; /* state info for channel */
2807 statePtr = ((Channel *) chan)->state;
2808 chanPtr = statePtr->topChanPtr;
2810 if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) {
2815 srcLen = strlen(src);
2817 return DoWrite(chanPtr, src, srcLen);
2821 *----------------------------------------------------------------------
2825 * Puts a sequence of bytes into an output buffer, may queue the
2826 * buffer for output if it gets full, and also remembers whether the
2827 * current buffer is ready e.g. if it contains a newline and we are in
2828 * line buffering mode. Writes directly to the driver of the channel,
2829 * does not compensate for stacking.
2831 * No encoding conversions are applied to the bytes being read.
2834 * The number of bytes written or -1 in case of error. If -1,
2835 * Tcl_GetErrno will return the error code.
2838 * May buffer up output and may cause output to be produced on the
2841 *----------------------------------------------------------------------
2845 Tcl_WriteRaw(chan, src, srcLen)
2846 Tcl_Channel chan; /* The channel to buffer output for. */
2847 CONST char *src; /* Data to queue in output buffer. */
2848 int srcLen; /* Length of data in bytes, or < 0 for
2851 Channel *chanPtr = ((Channel *) chan);
2852 ChannelState *statePtr = chanPtr->state; /* state info for channel */
2853 int errorCode, written;
2855 if (CheckChannelErrors(statePtr, TCL_WRITABLE | CHANNEL_RAW_MODE) != 0) {
2860 srcLen = strlen(src);
2864 * Go immediately to the driver, do all the error handling by ourselves.
2865 * The code was stolen from 'FlushChannel'.
2868 written = (chanPtr->typePtr->outputProc) (chanPtr->instanceData,
2869 src, srcLen, &errorCode);
2872 Tcl_SetErrno(errorCode);
2879 *---------------------------------------------------------------------------
2883 * Takes a sequence of UTF-8 characters and converts them for output
2884 * using the channel's current encoding, may queue the buffer for
2885 * output if it gets full, and also remembers whether the current
2886 * buffer is ready e.g. if it contains a newline and we are in
2887 * line buffering mode. Compensates stacking, i.e. will redirect the
2888 * data from the specified channel to the topmost channel in a stack.
2891 * The number of bytes written or -1 in case of error. If -1,
2892 * Tcl_GetErrno will return the error code.
2895 * May buffer up output and may cause output to be produced on the
2898 *----------------------------------------------------------------------
2902 Tcl_WriteChars(chan, src, len)
2903 Tcl_Channel chan; /* The channel to buffer output for. */
2904 CONST char *src; /* UTF-8 characters to queue in output buffer. */
2905 int len; /* Length of string in bytes, or < 0 for
2908 ChannelState *statePtr; /* state info for channel */
2910 statePtr = ((Channel *) chan)->state;
2912 if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) {
2916 return DoWriteChars ((Channel*) chan, src, len);
2920 *---------------------------------------------------------------------------
2924 * Takes a sequence of UTF-8 characters and converts them for output
2925 * using the channel's current encoding, may queue the buffer for
2926 * output if it gets full, and also remembers whether the current
2927 * buffer is ready e.g. if it contains a newline and we are in
2928 * line buffering mode. Compensates stacking, i.e. will redirect the
2929 * data from the specified channel to the topmost channel in a stack.
2932 * The number of bytes written or -1 in case of error. If -1,
2933 * Tcl_GetErrno will return the error code.
2936 * May buffer up output and may cause output to be produced on the
2939 *----------------------------------------------------------------------
2943 DoWriteChars(chanPtr, src, len)
2944 Channel* chanPtr; /* The channel to buffer output for. */
2945 CONST char *src; /* UTF-8 characters to queue in output buffer. */
2946 int len; /* Length of string in bytes, or < 0 for
2950 * Always use the topmost channel of the stack
2952 ChannelState *statePtr; /* state info for channel */
2954 statePtr = chanPtr->state;
2955 chanPtr = statePtr->topChanPtr;
2960 if (statePtr->encoding == NULL) {
2962 * Inefficient way to convert UTF-8 to byte-array, but the
2963 * code parallels the way it is done for objects.
2969 objPtr = Tcl_NewStringObj(src, len);
2970 src = (char *) Tcl_GetByteArrayFromObj(objPtr, &len);
2971 result = WriteBytes(chanPtr, src, len);
2972 Tcl_DecrRefCount(objPtr);
2975 return WriteChars(chanPtr, src, len);
2979 *---------------------------------------------------------------------------
2983 * Takes the Tcl object and queues its contents for output. If the
2984 * encoding of the channel is NULL, takes the byte-array representation
2985 * of the object and queues those bytes for output. Otherwise, takes
2986 * the characters in the UTF-8 (string) representation of the object
2987 * and converts them for output using the channel's current encoding.
2988 * May flush internal buffers to output if one becomes full or is ready
2989 * for some other reason, e.g. if it contains a newline and the channel
2990 * is in line buffering mode.
2993 * The number of bytes written or -1 in case of error. If -1,
2994 * Tcl_GetErrno() will return the error code.
2997 * May buffer up output and may cause output to be produced on the
3000 *----------------------------------------------------------------------
3004 Tcl_WriteObj(chan, objPtr)
3005 Tcl_Channel chan; /* The channel to buffer output for. */
3006 Tcl_Obj *objPtr; /* The object to write. */
3009 * Always use the topmost channel of the stack
3012 ChannelState *statePtr; /* state info for channel */
3016 statePtr = ((Channel *) chan)->state;
3017 chanPtr = statePtr->topChanPtr;
3019 if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) {
3022 if (statePtr->encoding == NULL) {
3023 src = (char *) Tcl_GetByteArrayFromObj(objPtr, &srcLen);
3024 return WriteBytes(chanPtr, src, srcLen);
3026 src = Tcl_GetStringFromObj(objPtr, &srcLen);
3027 return WriteChars(chanPtr, src, srcLen);
3032 *----------------------------------------------------------------------
3036 * Write a sequence of bytes into an output buffer, may queue the
3037 * buffer for output if it gets full, and also remembers whether the
3038 * current buffer is ready e.g. if it contains a newline and we are in
3039 * line buffering mode.
3042 * The number of bytes written or -1 in case of error. If -1,
3043 * Tcl_GetErrno will return the error code.
3046 * May buffer up output and may cause output to be produced on the
3049 *----------------------------------------------------------------------
3053 WriteBytes(chanPtr, src, srcLen)
3054 Channel *chanPtr; /* The channel to buffer output for. */
3055 CONST char *src; /* Bytes to write. */
3056 int srcLen; /* Number of bytes to write. */
3058 ChannelState *statePtr = chanPtr->state; /* state info for channel */
3059 ChannelBuffer *bufPtr;
3061 int dstMax, sawLF, savedLF, total, dstLen, toWrite;
3068 * Loop over all bytes in src, storing them in output buffer with
3069 * proper EOL translation.
3072 while (srcLen + savedLF > 0) {
3073 bufPtr = statePtr->curOutPtr;
3074 if (bufPtr == NULL) {
3075 bufPtr = AllocChannelBuffer(statePtr->bufSize);
3076 statePtr->curOutPtr = bufPtr;
3078 dst = bufPtr->buf + bufPtr->nextAdded;
3079 dstMax = bufPtr->bufLength - bufPtr->nextAdded;
3083 if (toWrite > srcLen) {
3089 * A '\n' was left over from last call to TranslateOutputEOL()
3090 * and we need to store it in this buffer. If the channel is
3091 * line-based, we will need to flush it.
3098 sawLF += TranslateOutputEOL(statePtr, dst, src, &dstLen, &toWrite);
3102 if (dstLen > dstMax) {
3106 bufPtr->nextAdded += dstLen;
3107 if (CheckFlush(chanPtr, bufPtr, sawLF) != 0) {
3119 *----------------------------------------------------------------------
3123 * Convert UTF-8 bytes to the channel's external encoding and
3124 * write the produced bytes into an output buffer, may queue the
3125 * buffer for output if it gets full, and also remembers whether the
3126 * current buffer is ready e.g. if it contains a newline and we are in
3127 * line buffering mode.
3130 * The number of bytes written or -1 in case of error. If -1,
3131 * Tcl_GetErrno will return the error code.
3134 * May buffer up output and may cause output to be produced on the
3137 *----------------------------------------------------------------------
3141 WriteChars(chanPtr, src, srcLen)
3142 Channel *chanPtr; /* The channel to buffer output for. */
3143 CONST char *src; /* UTF-8 string to write. */
3144 int srcLen; /* Length of UTF-8 string in bytes. */
3146 ChannelState *statePtr = chanPtr->state; /* state info for channel */
3147 ChannelBuffer *bufPtr;
3149 int saved, savedLF, sawLF, total, dstLen, stageMax, dstWrote;
3150 int stageLen, toWrite, stageRead, endEncoding, result;
3151 int consumedSomething;
3152 Tcl_Encoding encoding;
3153 char safe[BUFFER_PADDING];
3159 encoding = statePtr->encoding;
3162 * Write the terminated escape sequence even if srcLen is 0.
3165 endEncoding = ((statePtr->outputEncodingFlags & TCL_ENCODING_END) != 0);
3168 * Loop over all UTF-8 characters in src, storing them in staging buffer
3169 * with proper EOL translation.
3172 consumedSomething = 1;
3173 while (consumedSomething && (srcLen + savedLF + endEncoding > 0)) {
3174 consumedSomething = 0;
3175 stage = statePtr->outputStage;
3176 stageMax = statePtr->bufSize;
3177 stageLen = stageMax;
3180 if (toWrite > srcLen) {
3186 * A '\n' was left over from last call to TranslateOutputEOL()
3187 * and we need to store it in the staging buffer. If the
3188 * channel is line-based, we will need to flush the output
3189 * buffer (after translating the staging buffer).
3196 sawLF += TranslateOutputEOL(statePtr, stage, src, &stageLen, &toWrite);
3199 stageLen += savedLF;
3202 if (stageLen > stageMax) {
3204 stageLen = stageMax;
3210 * Loop over all UTF-8 characters in staging buffer, converting them
3211 * to external encoding, storing them in output buffer.
3214 while (stageLen + saved + endEncoding > 0) {
3215 bufPtr = statePtr->curOutPtr;
3216 if (bufPtr == NULL) {
3217 bufPtr = AllocChannelBuffer(statePtr->bufSize);
3218 statePtr->curOutPtr = bufPtr;
3220 dst = bufPtr->buf + bufPtr->nextAdded;
3221 dstLen = bufPtr->bufLength - bufPtr->nextAdded;
3225 * Here's some translated bytes left over from the last
3226 * buffer that we need to stick at the beginning of this
3230 memcpy((VOID *) dst, (VOID *) safe, (size_t) saved);
3231 bufPtr->nextAdded += saved;
3237 result = Tcl_UtfToExternal(NULL, encoding, stage, stageLen,
3238 statePtr->outputEncodingFlags,
3239 &statePtr->outputEncodingState, dst,
3240 dstLen + BUFFER_PADDING, &stageRead, &dstWrote, NULL);
3242 /* Fix for SF #506297, reported by Martin Forssen
3243 * <ruric@users.sourceforge.net>.
3245 * The encoding chosen in the script exposing the bug writes out
3246 * three intro characters when TCL_ENCODING_START is set, but does
3247 * not consume any input as TCL_ENCODING_END is cleared. As some
3248 * output was generated the enclosing loop calls UtfToExternal
3249 * again, again with START set. Three more characters in the out
3250 * and still no use of input ... To break this infinite loop we
3251 * remove TCL_ENCODING_START from the set of flags after the first
3252 * call (no condition is required, the later calls remove an unset
3253 * flag, which is a no-op). This causes the subsequent calls to
3254 * UtfToExternal to consume and convert the actual input.
3257 statePtr->outputEncodingFlags &= ~TCL_ENCODING_START;
3259 * The following code must be executed only when result is not 0.
3261 if (result && ((stageRead + dstWrote) == 0)) {
3263 * We have an incomplete UTF-8 character at the end of the
3264 * staging buffer. It will get moved to the beginning of the
3265 * staging buffer followed by more bytes from src.
3274 bufPtr->nextAdded += dstWrote;
3275 if (bufPtr->nextAdded > bufPtr->bufLength) {
3277 * When translating from UTF-8 to external encoding, we
3278 * allowed the translation to produce a character that
3279 * crossed the end of the output buffer, so that we would
3280 * get a completely full buffer before flushing it. The
3281 * extra bytes will be moved to the beginning of the next
3285 saved = bufPtr->nextAdded - bufPtr->bufLength;
3286 memcpy((VOID *) safe, (VOID *) (dst + dstLen), (size_t) saved);
3287 bufPtr->nextAdded = bufPtr->bufLength;
3289 if (CheckFlush(chanPtr, bufPtr, sawLF) != 0) {
3295 stageLen -= stageRead;
3298 consumedSomething = 1;
3301 * If all translated characters are written to the buffer,
3302 * endEncoding is set to 0 because the escape sequence may be
3306 if ((stageLen + saved == 0) && (result == 0)) {
3312 /* If nothing was written and it happened because there was no progress
3313 * in the UTF conversion, we throw an error.
3316 if (!consumedSomething && (total == 0)) {
3317 Tcl_SetErrno (EINVAL);
3324 *---------------------------------------------------------------------------
3326 * TranslateOutputEOL --
3328 * Helper function for WriteBytes() and WriteChars(). Converts the
3329 * '\n' characters in the source buffer into the appropriate EOL
3330 * form specified by the output translation mode.
3332 * EOL translation stops either when the source buffer is empty
3333 * or the output buffer is full.
3335 * When converting to CRLF mode and there is only 1 byte left in
3336 * the output buffer, this routine stores the '\r' in the last
3337 * byte and then stores the '\n' in the byte just past the end of the
3338 * buffer. The caller is responsible for passing in a buffer that
3339 * is large enough to hold the extra byte.
3342 * The return value is 1 if a '\n' was translated from the source
3343 * buffer, or 0 otherwise -- this can be used by the caller to
3344 * decide to flush a line-based channel even though the channel
3345 * buffer is not full.
3347 * *dstLenPtr is filled with how many bytes of the output buffer
3348 * were used. As mentioned above, this can be one more that
3349 * the output buffer's specified length if a CRLF was stored.
3351 * *srcLenPtr is filled with how many bytes of the source buffer
3355 * It may be obvious, but bears mentioning that when converting
3356 * in CRLF mode (which requires two bytes of storage in the output
3357 * buffer), the number of bytes consumed from the source buffer
3358 * will be less than the number of bytes stored in the output buffer.
3360 *---------------------------------------------------------------------------
3364 TranslateOutputEOL(statePtr, dst, src, dstLenPtr, srcLenPtr)
3365 ChannelState *statePtr; /* Channel being read, for translation and
3366 * buffering modes. */
3367 char *dst; /* Output buffer filled with UTF-8 chars by
3368 * applying appropriate EOL translation to
3369 * source characters. */
3370 CONST char *src; /* Source UTF-8 characters. */
3371 int *dstLenPtr; /* On entry, the maximum length of output
3372 * buffer in bytes. On exit, the number of
3373 * bytes actually used in output buffer. */
3374 int *srcLenPtr; /* On entry, the length of source buffer.
3375 * On exit, the number of bytes read from
3376 * the source buffer. */
3379 int srcLen, newlineFound;
3382 srcLen = *srcLenPtr;
3384 switch (statePtr->outputTranslation) {
3385 case TCL_TRANSLATE_LF: {
3386 for (dstEnd = dst + srcLen; dst < dstEnd; ) {
3392 *dstLenPtr = srcLen;
3395 case TCL_TRANSLATE_CR: {
3396 for (dstEnd = dst + srcLen; dst < dstEnd;) {
3405 *dstLenPtr = srcLen;
3408 case TCL_TRANSLATE_CRLF: {
3410 * Since this causes the number of bytes to grow, we
3411 * start off trying to put 'srcLen' bytes into the
3412 * output buffer, but allow it to store more bytes, as
3413 * long as there's still source bytes and room in the
3417 char *dstStart, *dstMax;
3418 CONST char *srcStart;
3421 dstMax = dst + *dstLenPtr;
3425 if (srcLen < *dstLenPtr) {
3426 dstEnd = dst + srcLen;
3428 dstEnd = dst + *dstLenPtr;
3430 while (dst < dstEnd) {
3432 if (dstEnd < dstMax) {
3440 *srcLenPtr = src - srcStart;
3441 *dstLenPtr = dst - dstStart;
3448 return newlineFound;
3452 *---------------------------------------------------------------------------
3456 * Helper function for WriteBytes() and WriteChars(). If the
3457 * channel buffer is ready to be flushed, flush it.
3460 * The return value is -1 if there was a problem flushing the
3461 * channel buffer, or 0 otherwise.
3464 * The buffer will be recycled if it is flushed.
3466 *---------------------------------------------------------------------------
3470 CheckFlush(chanPtr, bufPtr, newlineFlag)
3471 Channel *chanPtr; /* Channel being read, for buffering mode. */
3472 ChannelBuffer *bufPtr; /* Channel buffer to possibly flush. */
3473 int newlineFlag; /* Non-zero if a the channel buffer
3474 * contains a newline. */
3476 ChannelState *statePtr = chanPtr->state; /* state info for channel */
3478 * The current buffer is ready for output:
3480 * 2. if it contains a newline and this channel is line-buffered.
3481 * 3. if it contains any output and this channel is unbuffered.
3484 if ((statePtr->flags & BUFFER_READY) == 0) {
3485 if (bufPtr->nextAdded == bufPtr->bufLength) {
3486 statePtr->flags |= BUFFER_READY;
3487 } else if (statePtr->flags & CHANNEL_LINEBUFFERED) {
3488 if (newlineFlag != 0) {
3489 statePtr->flags |= BUFFER_READY;
3491 } else if (statePtr->flags & CHANNEL_UNBUFFERED) {
3492 statePtr->flags |= BUFFER_READY;
3495 if (statePtr->flags & BUFFER_READY) {
3496 if (FlushChannel(NULL, chanPtr, 0) != 0) {
3504 *---------------------------------------------------------------------------
3508 * Reads a complete line of input from the channel into a Tcl_DString.
3511 * Length of line read (in characters) or -1 if error, EOF, or blocked.
3512 * If -1, use Tcl_GetErrno() to retrieve the POSIX error code for the
3513 * error or condition that occurred.
3516 * May flush output on the channel. May cause input to be consumed
3519 *---------------------------------------------------------------------------
3523 Tcl_Gets(chan, lineRead)
3524 Tcl_Channel chan; /* Channel from which to read. */
3525 Tcl_DString *lineRead; /* The line read will be appended to this
3526 * DString as UTF-8 characters. The caller
3527 * must have initialized it and is responsible
3528 * for managing the storage. */
3531 int charsStored, length;
3534 objPtr = Tcl_NewObj();
3535 charsStored = Tcl_GetsObj(chan, objPtr);
3536 if (charsStored > 0) {
3537 string = Tcl_GetStringFromObj(objPtr, &length);
3538 Tcl_DStringAppend(lineRead, string, length);
3540 Tcl_DecrRefCount(objPtr);
3545 *---------------------------------------------------------------------------
3549 * Accumulate input from the input channel until end-of-line or
3550 * end-of-file has been seen. Bytes read from the input channel
3551 * are converted to UTF-8 using the encoding specified by the
3555 * Number of characters accumulated in the object or -1 if error,
3556 * blocked, or EOF. If -1, use Tcl_GetErrno() to retrieve the
3557 * POSIX error code for the error or condition that occurred.
3560 * Consumes input from the channel.
3562 * On reading EOF, leave channel pointing at EOF char.
3563 * On reading EOL, leave channel pointing after EOL, but don't
3564 * return EOL in dst buffer.
3566 *---------------------------------------------------------------------------
3570 Tcl_GetsObj(chan, objPtr)
3571 Tcl_Channel chan; /* Channel from which to read. */
3572 Tcl_Obj *objPtr; /* The line read will be appended to this
3573 * object as UTF-8 characters. */
3576 Channel *chanPtr = (Channel *) chan;
3577 ChannelState *statePtr = chanPtr->state; /* state info for channel */
3578 ChannelBuffer *bufPtr;
3579 int inEofChar, skip, copiedTotal, oldLength, oldFlags, oldRemoved;
3580 Tcl_Encoding encoding;
3581 char *dst, *dstEnd, *eol, *eof;
3582 Tcl_EncodingState oldState;
3585 * This operation should occur at the top of a channel stack.
3588 chanPtr = statePtr->topChanPtr;
3590 if (CheckChannelErrors(statePtr, TCL_READABLE) != 0) {
3595 bufPtr = statePtr->inQueueHead;
3596 encoding = statePtr->encoding;
3599 * Preserved so we can restore the channel's state in case we don't
3600 * find a newline in the available input.
3603 Tcl_GetStringFromObj(objPtr, &oldLength);
3604 oldFlags = statePtr->inputEncodingFlags;
3605 oldState = statePtr->inputEncodingState;
3606 oldRemoved = BUFFER_PADDING;
3607 if (bufPtr != NULL) {
3608 oldRemoved = bufPtr->nextRemoved;
3612 * If there is no encoding, use "iso8859-1" -- Tcl_GetsObj() doesn't
3613 * produce ByteArray objects. To avoid circularity problems,
3614 * "iso8859-1" is builtin to Tcl.
3617 if (encoding == NULL) {
3618 encoding = Tcl_GetEncoding(NULL, "iso8859-1");
3622 * Object used by FilterInputBytes to keep track of how much data has
3623 * been consumed from the channel buffers.
3628 gs.encoding = encoding;
3630 gs.state = oldState;
3636 dst = objPtr->bytes + oldLength;
3641 inEofChar = statePtr->inEofChar;
3644 if (dst >= dstEnd) {
3645 if (FilterInputBytes(chanPtr, &gs) != 0) {
3648 dstEnd = dst + gs.bytesWrote;
3652 * Remember if EOF char is seen, then look for EOL anyhow, because
3653 * the EOL might be before the EOF char.
3656 if (inEofChar != '\0') {
3657 for (eol = dst; eol < dstEnd; eol++) {
3658 if (*eol == inEofChar) {
3667 * On EOL, leave current file position pointing after the EOL, but
3668 * don't store the EOL in the output string.
3671 switch (statePtr->inputTranslation) {
3672 case TCL_TRANSLATE_LF: {
3673 for (eol = dst; eol < dstEnd; eol++) {
3681 case TCL_TRANSLATE_CR: {
3682 for (eol = dst; eol < dstEnd; eol++) {
3690 case TCL_TRANSLATE_CRLF: {
3691 for (eol = dst; eol < dstEnd; eol++) {
3694 if (eol >= dstEnd) {
3697 offset = eol - objPtr->bytes;
3699 if (FilterInputBytes(chanPtr, &gs) != 0) {
3702 dstEnd = dst + gs.bytesWrote;
3703 eol = objPtr->bytes + offset;
3704 if (eol >= dstEnd) {
3718 case TCL_TRANSLATE_AUTO: {
3721 if (statePtr->flags & INPUT_SAW_CR) {
3722 statePtr->flags &= ~INPUT_SAW_CR;
3725 * Skip the raw bytes that make up the '\n'.
3728 char tmp[1 + TCL_UTF_MAX];
3732 Tcl_ExternalToUtf(NULL, gs.encoding,
3733 bufPtr->buf + bufPtr->nextRemoved,
3734 gs.rawRead, statePtr->inputEncodingFlags,
3735 &gs.state, tmp, 1 + TCL_UTF_MAX, &rawRead,
3737 bufPtr->nextRemoved += rawRead;
3738 gs.rawRead -= rawRead;
3741 memmove(dst, dst + 1, (size_t) (dstEnd - dst));
3745 for (eol = dst; eol < dstEnd; eol++) {
3748 if (eol == dstEnd) {
3750 * If buffer ended on \r, peek ahead to see if a
3756 offset = eol - objPtr->bytes;
3758 PeekAhead(chanPtr, &dstEnd, &gs);
3759 eol = objPtr->bytes + offset;
3760 if (eol >= dstEnd) {
3762 statePtr->flags |= INPUT_SAW_CR;
3771 } else if (*eol == '\n') {
3779 * EOF character was seen. On EOF, leave current file position
3780 * pointing at the EOF character, but don't store the EOF
3781 * character in the output string.
3785 statePtr->flags |= (CHANNEL_EOF | CHANNEL_STICKY_EOF);
3786 statePtr->inputEncodingFlags |= TCL_ENCODING_END;
3788 if (statePtr->flags & CHANNEL_EOF) {
3791 if (eol == objPtr->bytes + oldLength) {
3793 * If we didn't append any bytes before encountering EOF,
3794 * caller needs to see -1.
3797 Tcl_SetObjLength(objPtr, oldLength);
3798 CommonGetsCleanup(chanPtr, encoding);
3808 * Found EOL or EOF, but the output buffer may now contain too many
3809 * UTF-8 characters. We need to know how many raw bytes correspond to
3810 * the number of UTF-8 characters we want, plus how many raw bytes
3811 * correspond to the character(s) making up EOL (if any), so we can
3812 * remove the correct number of bytes from the channel buffer.
3817 statePtr->inputEncodingState = gs.state;
3818 Tcl_ExternalToUtf(NULL, gs.encoding, bufPtr->buf + bufPtr->nextRemoved,
3819 gs.rawRead, statePtr->inputEncodingFlags,
3820 &statePtr->inputEncodingState, dst,
3821 eol - dst + skip + TCL_UTF_MAX, &gs.rawRead, NULL,
3823 bufPtr->nextRemoved += gs.rawRead;
3826 * Recycle all the emptied buffers.
3829 Tcl_SetObjLength(objPtr, eol - objPtr->bytes);
3830 CommonGetsCleanup(chanPtr, encoding);
3831 statePtr->flags &= ~CHANNEL_BLOCKED;
3832 copiedTotal = gs.totalChars + gs.charsWrote - skip;
3836 * Couldn't get a complete line. This only happens if we get a error
3837 * reading from the channel or we are non-blocking and there wasn't
3838 * an EOL or EOF in the data available.
3842 bufPtr = statePtr->inQueueHead;
3843 bufPtr->nextRemoved = oldRemoved;
3845 for (bufPtr = bufPtr->nextPtr; bufPtr != NULL; bufPtr = bufPtr->nextPtr) {
3846 bufPtr->nextRemoved = BUFFER_PADDING;
3848 CommonGetsCleanup(chanPtr, encoding);
3850 statePtr->inputEncodingState = oldState;
3851 statePtr->inputEncodingFlags = oldFlags;
3852 Tcl_SetObjLength(objPtr, oldLength);
3855 * We didn't get a complete line so we need to indicate to UpdateInterest
3856 * that the gets blocked. It will wait for more data instead of firing
3857 * a timer, avoiding a busy wait. This is where we are assuming that the
3858 * next operation is a gets. No more file events will be delivered on
3859 * this channel until new data arrives or some operation is performed
3860 * on the channel (e.g. gets, read, fconfigure) that changes the blocking
3861 * state. Note that this means a file event will not be delivered even
3862 * though a read would be able to consume the buffered data.
3865 statePtr->flags |= CHANNEL_NEED_MORE_DATA;
3870 * Update the notifier state so we don't block while there is still
3871 * data in the buffers.
3874 UpdateInterest(chanPtr);
3879 *---------------------------------------------------------------------------
3881 * FilterInputBytes --
3883 * Helper function for Tcl_GetsObj. Produces UTF-8 characters from
3884 * raw bytes read from the channel.
3886 * Consumes available bytes from channel buffers. When channel
3887 * buffers are exhausted, reads more bytes from channel device into
3888 * a new channel buffer. It is the caller's responsibility to
3889 * free the channel buffers that have been exhausted.
3892 * The return value is -1 if there was an error reading from the
3893 * channel, 0 otherwise.
3896 * Status object keeps track of how much data from channel buffers
3897 * has been consumed and where UTF-8 bytes should be stored.
3899 *---------------------------------------------------------------------------
3903 FilterInputBytes(chanPtr, gsPtr)
3904 Channel *chanPtr; /* Channel to read. */
3905 GetsState *gsPtr; /* Current state of gets operation. */
3907 ChannelState *statePtr = chanPtr->state; /* state info for channel */
3908 ChannelBuffer *bufPtr;
3909 char *raw, *rawStart, *rawEnd;
3911 int offset, toRead, dstNeeded, spaceLeft, result, rawLen, length;
3913 #define ENCODING_LINESIZE 20 /* Lower bound on how many bytes to convert
3914 * at a time. Since we don't know a priori
3915 * how many bytes of storage this many source
3916 * bytes will use, we actually need at least
3917 * ENCODING_LINESIZE * TCL_MAX_UTF bytes of
3920 objPtr = gsPtr->objPtr;
3923 * Subtract the number of bytes that were removed from channel buffer
3927 bufPtr = gsPtr->bufPtr;
3928 if (bufPtr != NULL) {
3929 bufPtr->nextRemoved += gsPtr->rawRead;
3930 if (bufPtr->nextRemoved >= bufPtr->nextAdded) {
3931 bufPtr = bufPtr->nextPtr;
3934 gsPtr->totalChars += gsPtr->charsWrote;
3936 if ((bufPtr == NULL) || (bufPtr->nextAdded == BUFFER_PADDING)) {
3938 * All channel buffers were exhausted and the caller still hasn't
3939 * seen EOL. Need to read more bytes from the channel device.
3940 * Side effect is to allocate another channel buffer.
3944 if (statePtr->flags & CHANNEL_BLOCKED) {
3945 if (statePtr->flags & CHANNEL_NONBLOCKING) {
3946 gsPtr->charsWrote = 0;
3950 statePtr->flags &= ~CHANNEL_BLOCKED;
3952 if (GetInput(chanPtr) != 0) {
3953 gsPtr->charsWrote = 0;
3957 bufPtr = statePtr->inQueueTail;
3958 gsPtr->bufPtr = bufPtr;
3962 * Convert some of the bytes from the channel buffer to UTF-8. Space in
3963 * objPtr's string rep is used to hold the UTF-8 characters. Grow the
3964 * string rep if we need more space.
3967 rawStart = bufPtr->buf + bufPtr->nextRemoved;
3969 rawEnd = bufPtr->buf + bufPtr->nextAdded;
3970 rawLen = rawEnd - rawStart;
3972 dst = *gsPtr->dstPtr;
3973 offset = dst - objPtr->bytes;
3974 toRead = ENCODING_LINESIZE;
3975 if (toRead > rawLen) {
3978 dstNeeded = toRead * TCL_UTF_MAX + 1;
3979 spaceLeft = objPtr->length - offset - TCL_UTF_MAX - 1;
3980 if (dstNeeded > spaceLeft) {
3981 length = offset * 2;
3982 if (offset < dstNeeded) {
3983 length = offset + dstNeeded;
3985 length += TCL_UTF_MAX + 1;
3986 Tcl_SetObjLength(objPtr, length);
3987 spaceLeft = length - offset;
3988 dst = objPtr->bytes + offset;
3989 *gsPtr->dstPtr = dst;
3991 gsPtr->state = statePtr->inputEncodingState;
3992 result = Tcl_ExternalToUtf(NULL, gsPtr->encoding, raw, rawLen,
3993 statePtr->inputEncodingFlags, &statePtr->inputEncodingState,
3994 dst, spaceLeft, &gsPtr->rawRead, &gsPtr->bytesWrote,
3995 &gsPtr->charsWrote);
3998 * Make sure that if we go through 'gets', that we reset the
3999 * TCL_ENCODING_START flag still. [Bug #523988]
4001 statePtr->inputEncodingFlags &= ~TCL_ENCODING_START;
4003 if (result == TCL_CONVERT_MULTIBYTE) {
4005 * The last few bytes in this channel buffer were the start of a
4006 * multibyte sequence. If this buffer was full, then move them to
4007 * the next buffer so the bytes will be contiguous.
4010 ChannelBuffer *nextPtr;
4013 nextPtr = bufPtr->nextPtr;
4014 if (bufPtr->nextAdded < bufPtr->bufLength) {
4015 if (gsPtr->rawRead > 0) {
4017 * Some raw bytes were converted to UTF-8. Fall through,
4018 * returning those UTF-8 characters because a EOL might be
4021 } else if (statePtr->flags & CHANNEL_EOF) {
4023 * There was a partial character followed by EOF on the
4024 * device. Fall through, returning that nothing was found.
4027 bufPtr->nextRemoved = bufPtr->nextAdded;
4030 * There are no more cached raw bytes left. See if we can
4037 if (nextPtr == NULL) {
4038 nextPtr = AllocChannelBuffer(statePtr->bufSize);
4039 bufPtr->nextPtr = nextPtr;
4040 statePtr->inQueueTail = nextPtr;
4042 extra = rawLen - gsPtr->rawRead;
4043 memcpy((VOID *) (nextPtr->buf + BUFFER_PADDING - extra),
4044 (VOID *) (raw + gsPtr->rawRead), (size_t) extra);
4045 nextPtr->nextRemoved -= extra;
4046 bufPtr->nextAdded -= extra;
4050 gsPtr->bufPtr = bufPtr;
4055 *---------------------------------------------------------------------------
4059 * Helper function used by Tcl_GetsObj(). Called when we've seen a
4060 * \r at the end of the UTF-8 string and want to look ahead one
4061 * character to see if it is a \n.
4064 * *gsPtr->dstPtr is filled with a pointer to the start of the range of
4065 * UTF-8 characters that were found by peeking and *dstEndPtr is filled
4066 * with a pointer to the bytes just after the end of the range.
4069 * If no more raw bytes were available in one of the channel buffers,
4070 * tries to perform a non-blocking read to get more bytes from the
4073 *---------------------------------------------------------------------------
4077 PeekAhead(chanPtr, dstEndPtr, gsPtr)
4078 Channel *chanPtr; /* The channel to read. */
4079 char **dstEndPtr; /* Filled with pointer to end of new range
4080 * of UTF-8 characters. */
4081 GetsState *gsPtr; /* Current state of gets operation. */
4083 ChannelState *statePtr = chanPtr->state; /* state info for channel */
4084 ChannelBuffer *bufPtr;
4085 Tcl_DriverBlockModeProc *blockModeProc;
4088 bufPtr = gsPtr->bufPtr;
4091 * If there's any more raw input that's still buffered, we'll peek into
4092 * that. Otherwise, only get more data from the channel driver if it
4093 * looks like there might actually be more data. The assumption is that
4094 * if the channel buffer is filled right up to the end, then there
4095 * might be more data to read.
4098 blockModeProc = NULL;
4099 if (bufPtr->nextPtr == NULL) {
4100 bytesLeft = bufPtr->nextAdded - (bufPtr->nextRemoved + gsPtr->rawRead);
4101 if (bytesLeft == 0) {
4102 if (bufPtr->nextAdded < bufPtr->bufLength) {
4104 * Don't peek ahead if last read was short read.
4109 if ((statePtr->flags & CHANNEL_NONBLOCKING) == 0) {
4110 blockModeProc = Tcl_ChannelBlockModeProc(chanPtr->typePtr);
4111 if (blockModeProc == NULL) {
4113 * Don't peek ahead if cannot set non-blocking mode.
4118 StackSetBlockMode(chanPtr, TCL_MODE_NONBLOCKING);
4122 if (FilterInputBytes(chanPtr, gsPtr) == 0) {
4123 *dstEndPtr = *gsPtr->dstPtr + gsPtr->bytesWrote;
4125 if (blockModeProc != NULL) {
4126 StackSetBlockMode(chanPtr, TCL_MODE_BLOCKING);
4131 bufPtr->nextRemoved += gsPtr->rawRead;
4133 gsPtr->totalChars += gsPtr->charsWrote;
4134 gsPtr->bytesWrote = 0;
4135 gsPtr->charsWrote = 0;
4139 *---------------------------------------------------------------------------
4141 * CommonGetsCleanup --
4143 * Helper function for Tcl_GetsObj() to restore the channel after
4144 * a "gets" operation.
4150 * Encoding may be freed.
4152 *---------------------------------------------------------------------------
4156 CommonGetsCleanup(chanPtr, encoding)
4158 Tcl_Encoding encoding;
4160 ChannelState *statePtr = chanPtr->state; /* state info for channel */
4161 ChannelBuffer *bufPtr, *nextPtr;
4163 bufPtr = statePtr->inQueueHead;
4164 for ( ; bufPtr != NULL; bufPtr = nextPtr) {
4165 nextPtr = bufPtr->nextPtr;
4166 if (bufPtr->nextRemoved < bufPtr->nextAdded) {
4169 RecycleBuffer(statePtr, bufPtr, 0);
4171 statePtr->inQueueHead = bufPtr;
4172 if (bufPtr == NULL) {
4173 statePtr->inQueueTail = NULL;
4176 * If any multi-byte characters were split across channel buffer
4177 * boundaries, the split-up bytes were moved to the next channel
4178 * buffer by FilterInputBytes(). Move the bytes back to their
4179 * original buffer because the caller could change the channel's
4180 * encoding which could change the interpretation of whether those
4181 * bytes really made up multi-byte characters after all.
4184 nextPtr = bufPtr->nextPtr;
4185 for ( ; nextPtr != NULL; nextPtr = bufPtr->nextPtr) {
4188 extra = bufPtr->bufLength - bufPtr->nextAdded;
4190 memcpy((VOID *) (bufPtr->buf + bufPtr->nextAdded),
4191 (VOID *) (nextPtr->buf + BUFFER_PADDING - extra),
4193 bufPtr->nextAdded += extra;
4194 nextPtr->nextRemoved = BUFFER_PADDING;
4199 if (statePtr->encoding == NULL) {
4200 Tcl_FreeEncoding(encoding);
4205 *----------------------------------------------------------------------
4209 * Reads a given number of bytes from a channel. EOL and EOF
4210 * translation is done on the bytes being read, so the the number
4211 * of bytes consumed from the channel may not be equal to the
4212 * number of bytes stored in the destination buffer.
4214 * No encoding conversions are applied to the bytes being read.
4217 * The number of bytes read, or -1 on error. Use Tcl_GetErrno()
4218 * to retrieve the error code for the error that occurred.
4221 * May cause input to be buffered.
4223 *----------------------------------------------------------------------
4227 Tcl_Read(chan, dst, bytesToRead)
4228 Tcl_Channel chan; /* The channel from which to read. */
4229 char *dst; /* Where to store input read. */
4230 int bytesToRead; /* Maximum number of bytes to read. */
4232 Channel *chanPtr = (Channel *) chan;
4233 ChannelState *statePtr = chanPtr->state; /* state info for channel */
4236 * This operation should occur at the top of a channel stack.
4239 chanPtr = statePtr->topChanPtr;
4241 if (CheckChannelErrors(statePtr, TCL_READABLE) != 0) {
4245 return DoRead(chanPtr, dst, bytesToRead);
4249 *----------------------------------------------------------------------
4253 * Reads a given number of bytes from a channel. EOL and EOF
4254 * translation is done on the bytes being read, so the the number
4255 * of bytes consumed from the channel may not be equal to the
4256 * number of bytes stored in the destination buffer.
4258 * No encoding conversions are applied to the bytes being read.
4261 * The number of bytes read, or -1 on error. Use Tcl_GetErrno()
4262 * to retrieve the error code for the error that occurred.
4265 * May cause input to be buffered.
4267 *----------------------------------------------------------------------
4271 Tcl_ReadRaw(chan, bufPtr, bytesToRead)
4272 Tcl_Channel chan; /* The channel from which to read. */
4273 char *bufPtr; /* Where to store input read. */
4274 int bytesToRead; /* Maximum number of bytes to read. */
4276 Channel *chanPtr = (Channel *) chan;
4277 ChannelState *statePtr = chanPtr->state; /* state info for channel */
4279 int copied, copiedNow;
4282 * The check below does too much because it will reject a call to this
4283 * function with a channel which is part of an 'fcopy'. But we have to
4284 * allow this here or else the chaining in the transformation drivers
4285 * will fail with 'file busy' error instead of retrieving and
4286 * transforming the data to copy.
4288 * We let the check procedure now believe that there is no fcopy in
4289 * progress. A better solution than this might be an additional flag
4290 * argument to switch off specific checks.
4293 if (CheckChannelErrors(statePtr, TCL_READABLE | CHANNEL_RAW_MODE) != 0) {
4298 * Check for information in the push-back buffers. If there is
4299 * some, use it. Go to the driver only if there is none (anymore)
4300 * and the caller requests more bytes.
4303 for (copied = 0; copied < bytesToRead; copied += copiedNow) {
4304 copiedNow = CopyBuffer(chanPtr, bufPtr + copied,
4305 bytesToRead - copied);
4306 if (copiedNow == 0) {
4307 if (statePtr->flags & CHANNEL_EOF) {
4310 if (statePtr->flags & CHANNEL_BLOCKED) {
4311 if (statePtr->flags & CHANNEL_NONBLOCKING) {
4314 statePtr->flags &= (~(CHANNEL_BLOCKED));
4317 #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
4318 /* [SF Tcl Bug 943274]. Better emulation of non-blocking
4319 * channels for channels without BlockModeProc, by keeping
4320 * track of true fileevents generated by the OS == Data
4321 * waiting and reading if and only if we are sure to have
4325 if ((statePtr->flags & CHANNEL_NONBLOCKING) &&
4326 (Tcl_ChannelBlockModeProc(chanPtr->typePtr) == NULL) &&
4327 !(statePtr->flags & CHANNEL_HAS_MORE_DATA)) {
4329 /* We bypass the driver, it would block, as no data is available */
4331 result = EWOULDBLOCK;
4333 #endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
4335 * Now go to the driver to get as much as is possible to
4336 * fill the remaining request. Do all the error handling
4337 * by ourselves. The code was stolen from 'GetInput' and
4338 * slightly adapted (different return value here).
4340 * The case of 'bytesToRead == 0' at this point cannot happen.
4343 nread = (chanPtr->typePtr->inputProc)(chanPtr->instanceData,
4344 bufPtr + copied, bytesToRead - copied, &result);
4345 #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
4347 #endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
4350 * If we get a short read, signal up that we may be
4351 * BLOCKED. We should avoid calling the driver because
4352 * on some platforms we will block in the low level
4353 * reading code even though the channel is set into
4357 if (nread < (bytesToRead - copied)) {
4358 statePtr->flags |= CHANNEL_BLOCKED;
4361 #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
4362 if (nread <= (bytesToRead - copied)) {
4363 /* [SF Tcl Bug 943274] We have read the available
4364 * data, clear flag */
4365 statePtr->flags &= ~CHANNEL_HAS_MORE_DATA;
4367 #endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
4368 } else if (nread == 0) {
4369 statePtr->flags |= CHANNEL_EOF;
4370 statePtr->inputEncodingFlags |= TCL_ENCODING_END;
4371 } else if (nread < 0) {
4372 if ((result == EWOULDBLOCK) || (result == EAGAIN)) {
4375 * Information that was copied earlier has precedence
4376 * over EAGAIN/WOULDBLOCK handling.
4381 statePtr->flags |= CHANNEL_BLOCKED;
4385 Tcl_SetErrno(result);
4389 return copied + nread;
4398 *---------------------------------------------------------------------------
4402 * Reads from the channel until the requested number of characters
4403 * have been seen, EOF is seen, or the channel would block. EOL
4404 * and EOF translation is done. If reading binary data, the raw
4405 * bytes are wrapped in a Tcl byte array object. Otherwise, the raw
4406 * bytes are converted to UTF-8 using the channel's current encoding
4407 * and stored in a Tcl string object.
4410 * The number of characters read, or -1 on error. Use Tcl_GetErrno()
4411 * to retrieve the error code for the error that occurred.
4414 * May cause input to be buffered.
4416 *---------------------------------------------------------------------------
4420 Tcl_ReadChars(chan, objPtr, toRead, appendFlag)
4421 Tcl_Channel chan; /* The channel to read. */
4422 Tcl_Obj *objPtr; /* Input data is stored in this object. */
4423 int toRead; /* Maximum number of characters to store,
4424 * or -1 to read all available data (up to EOF
4425 * or when channel blocks). */
4426 int appendFlag; /* If non-zero, data read from the channel
4427 * will be appended to the object. Otherwise,
4428 * the data will replace the existing contents
4432 Channel* chanPtr = (Channel *) chan;
4433 ChannelState* statePtr = chanPtr->state; /* state info for channel */
4436 * This operation should occur at the top of a channel stack.
4439 chanPtr = statePtr->topChanPtr;
4441 if (CheckChannelErrors(statePtr, TCL_READABLE) != 0) {
4443 * Update the notifier state so we don't block while there is still
4444 * data in the buffers.
4446 UpdateInterest(chanPtr);
4450 return DoReadChars (chanPtr, objPtr, toRead, appendFlag);
4453 *---------------------------------------------------------------------------
4457 * Reads from the channel until the requested number of characters
4458 * have been seen, EOF is seen, or the channel would block. EOL
4459 * and EOF translation is done. If reading binary data, the raw
4460 * bytes are wrapped in a Tcl byte array object. Otherwise, the raw
4461 * bytes are converted to UTF-8 using the channel's current encoding
4462 * and stored in a Tcl string object.
4465 * The number of characters read, or -1 on error. Use Tcl_GetErrno()
4466 * to retrieve the error code for the error that occurred.
4469 * May cause input to be buffered.
4471 *---------------------------------------------------------------------------
4475 DoReadChars(chanPtr, objPtr, toRead, appendFlag)
4476 Channel* chanPtr; /* The channel to read. */
4477 Tcl_Obj *objPtr; /* Input data is stored in this object. */
4478 int toRead; /* Maximum number of characters to store,
4479 * or -1 to read all available data (up to EOF
4480 * or when channel blocks). */
4481 int appendFlag; /* If non-zero, data read from the channel
4482 * will be appended to the object. Otherwise,
4483 * the data will replace the existing contents
4487 ChannelState *statePtr = chanPtr->state; /* state info for channel */
4488 ChannelBuffer *bufPtr;
4489 int offset, factor, copied, copiedNow, result;
4490 Tcl_Encoding encoding;
4491 #define UTF_EXPANSION_FACTOR 1024
4494 * This operation should occur at the top of a channel stack.
4497 chanPtr = statePtr->topChanPtr;
4498 encoding = statePtr->encoding;
4499 factor = UTF_EXPANSION_FACTOR;
4501 if (appendFlag == 0) {
4502 if (encoding == NULL) {
4503 Tcl_SetByteArrayLength(objPtr, 0);
4505 Tcl_SetObjLength(objPtr, 0);
4507 * We're going to access objPtr->bytes directly, so
4508 * we must ensure that this is actually a string
4509 * object (otherwise it might have been pure Unicode).
4511 Tcl_GetString(objPtr);
4515 if (encoding == NULL) {
4516 Tcl_GetByteArrayFromObj(objPtr, &offset);
4518 Tcl_GetStringFromObj(objPtr, &offset);
4522 for (copied = 0; (unsigned) toRead > 0; ) {
4524 if (statePtr->inQueueHead != NULL) {
4525 if (encoding == NULL) {
4526 copiedNow = ReadBytes(statePtr, objPtr, toRead, &offset);
4528 copiedNow = ReadChars(statePtr, objPtr, toRead, &offset,
4533 * If the current buffer is empty recycle it.
4536 bufPtr = statePtr->inQueueHead;
4537 if (bufPtr->nextRemoved == bufPtr->nextAdded) {
4538 ChannelBuffer *nextPtr;
4540 nextPtr = bufPtr->nextPtr;
4541 RecycleBuffer(statePtr, bufPtr, 0);
4542 statePtr->inQueueHead = nextPtr;
4543 if (nextPtr == NULL) {
4544 statePtr->inQueueTail = NULL;
4548 if (copiedNow < 0) {
4549 if (statePtr->flags & CHANNEL_EOF) {
4552 if (statePtr->flags & CHANNEL_BLOCKED) {
4553 if (statePtr->flags & CHANNEL_NONBLOCKING) {
4556 statePtr->flags &= ~CHANNEL_BLOCKED;
4558 result = GetInput(chanPtr);
4560 if (result == EAGAIN) {
4567 copied += copiedNow;
4568 toRead -= copiedNow;
4571 statePtr->flags &= ~CHANNEL_BLOCKED;
4572 if (encoding == NULL) {
4573 Tcl_SetByteArrayLength(objPtr, offset);
4575 Tcl_SetObjLength(objPtr, offset);
4580 * Update the notifier state so we don't block while there is still
4581 * data in the buffers.
4584 UpdateInterest(chanPtr);
4588 *---------------------------------------------------------------------------
4592 * Reads from the channel until the requested number of bytes have
4593 * been seen, EOF is seen, or the channel would block. Bytes from
4594 * the channel are stored in objPtr as a ByteArray object. EOL
4595 * and EOF translation are done.
4597 * 'bytesToRead' can safely be a very large number because
4598 * space is only allocated to hold data read from the channel
4602 * The return value is the number of bytes appended to the object
4603 * and *offsetPtr is filled with the total number of bytes in the
4604 * object (greater than the return value if there were already bytes
4610 *---------------------------------------------------------------------------
4614 ReadBytes(statePtr, objPtr, bytesToRead, offsetPtr)
4615 ChannelState *statePtr; /* State of the channel to read. */
4616 Tcl_Obj *objPtr; /* Input data is appended to this ByteArray
4617 * object. Its length is how much space
4618 * has been allocated to hold data, not how
4619 * many bytes of data have been stored in the
4621 int bytesToRead; /* Maximum number of bytes to store,
4622 * or < 0 to get all available bytes.
4623 * Bytes are obtained from the first
4624 * buffer in the queue -- even if this number
4625 * is larger than the number of bytes
4626 * available in the first buffer, only the
4627 * bytes from the first buffer are
4629 int *offsetPtr; /* On input, contains how many bytes of
4630 * objPtr have been used to hold data. On
4631 * output, filled with how many bytes are now
4634 int toRead, srcLen, offset, length, srcRead, dstWrote;
4635 ChannelBuffer *bufPtr;
4638 offset = *offsetPtr;
4640 bufPtr = statePtr->inQueueHead;
4641 src = bufPtr->buf + bufPtr->nextRemoved;
4642 srcLen = bufPtr->nextAdded - bufPtr->nextRemoved;
4644 toRead = bytesToRead;
4645 if ((unsigned) toRead > (unsigned) srcLen) {
4649 dst = (char *) Tcl_GetByteArrayFromObj(objPtr, &length);
4650 if (toRead > length - offset - 1) {
4652 * Double the existing size of the object or make enough room to
4653 * hold all the characters we may get from the source buffer,
4654 * whichever is larger.
4657 length = offset * 2;
4658 if (offset < toRead) {
4659 length = offset + toRead + 1;
4661 dst = (char *) Tcl_SetByteArrayLength(objPtr, length);
4665 if (statePtr->flags & INPUT_NEED_NL) {
4666 statePtr->flags &= ~INPUT_NEED_NL;
4667 if ((srcLen == 0) || (*src != '\n')) {
4680 if (TranslateInputEOL(statePtr, dst, src, &dstWrote, &srcRead) != 0) {
4681 if (dstWrote == 0) {
4685 bufPtr->nextRemoved += srcRead;
4686 *offsetPtr += dstWrote;
4691 *---------------------------------------------------------------------------
4695 * Reads from the channel until the requested number of UTF-8
4696 * characters have been seen, EOF is seen, or the channel would
4697 * block. Raw bytes from the channel are converted to UTF-8
4698 * and stored in objPtr. EOL and EOF translation is done.
4700 * 'charsToRead' can safely be a very large number because
4701 * space is only allocated to hold data read from the channel
4705 * The return value is the number of characters appended to
4706 * the object, *offsetPtr is filled with the number of bytes that
4707 * were appended, and *factorPtr is filled with the expansion
4708 * factor used to guess how many bytes of UTF-8 to allocate to
4709 * hold N source bytes.
4714 *---------------------------------------------------------------------------
4718 ReadChars(statePtr, objPtr, charsToRead, offsetPtr, factorPtr)
4719 ChannelState *statePtr; /* State of channel to read. */
4720 Tcl_Obj *objPtr; /* Input data is appended to this object.
4721 * objPtr->length is how much space has been
4722 * allocated to hold data, not how many bytes
4723 * of data have been stored in the object. */
4724 int charsToRead; /* Maximum number of characters to store,
4725 * or -1 to get all available characters.
4726 * Characters are obtained from the first
4727 * buffer in the queue -- even if this number
4728 * is larger than the number of characters
4729 * available in the first buffer, only the
4730 * characters from the first buffer are
4732 int *offsetPtr; /* On input, contains how many bytes of
4733 * objPtr have been used to hold data. On
4734 * output, filled with how many bytes are now
4736 int *factorPtr; /* On input, contains a guess of how many
4737 * bytes need to be allocated to hold the
4738 * result of converting N source bytes to
4739 * UTF-8. On output, contains another guess
4740 * based on the data seen so far. */
4742 int toRead, factor, offset, spaceLeft, length, srcLen, dstNeeded;
4743 int srcRead, dstWrote, numChars, dstRead;
4744 ChannelBuffer *bufPtr;
4746 Tcl_EncodingState oldState;
4747 int encEndFlagSuppressed = 0;
4749 factor = *factorPtr;
4750 offset = *offsetPtr;
4752 bufPtr = statePtr->inQueueHead;
4753 src = bufPtr->buf + bufPtr->nextRemoved;
4754 srcLen = bufPtr->nextAdded - bufPtr->nextRemoved;
4756 toRead = charsToRead;
4757 if ((unsigned)toRead > (unsigned)srcLen) {
4762 * 'factor' is how much we guess that the bytes in the source buffer
4763 * will expand when converted to UTF-8 chars. This guess comes from
4764 * analyzing how many characters were produced by the previous
4768 dstNeeded = toRead * factor / UTF_EXPANSION_FACTOR;
4769 spaceLeft = objPtr->length - offset - TCL_UTF_MAX - 1;
4771 if (dstNeeded > spaceLeft) {
4773 * Double the existing size of the object or make enough room to
4774 * hold all the characters we want from the source buffer,
4775 * whichever is larger.
4778 length = offset * 2;
4779 if (offset < dstNeeded) {
4780 length = offset + dstNeeded;
4782 spaceLeft = length - offset;
4783 length += TCL_UTF_MAX + 1;
4784 Tcl_SetObjLength(objPtr, length);
4786 if (toRead == srcLen) {
4788 * Want to convert the whole buffer in one pass. If we have
4789 * enough space, convert it using all available space in object
4790 * rather than using the factor.
4793 dstNeeded = spaceLeft;
4795 dst = objPtr->bytes + offset;
4798 * SF Tcl Bug 1462248
4799 * The cause of the crash reported in the referenced bug is this:
4801 * - ReadChars, called with a single buffer, with a incomplete
4802 * multi-byte character at the end (only the first byte of it).
4803 * - Encoding translation fails, asks for more data
4804 * - Data is read, and eof is reached, TCL_ENCODING_END (TEE) is set.
4805 * - ReadChar is called again, converts the first buffer, but due
4806 * to TEE it does not check for incomplete multi-byte data, and the
4807 * character just after the end of the first buffer is a valid
4808 * completion of the multi-byte header in the actual buffer. The
4809 * conversion reads more characters from the buffer then present.
4810 * This causes nextRemoved to overshoot nextAdded and the next
4811 * reads compute a negative srcLen, cause further translations to
4812 * fail, causing copying of data into the next buffer using bad
4813 * arguments, causing the mecpy for to eventually fail.
4815 * In the end it is a memory access bug spiraling out of control
4816 * if the conditions are _just so_. And ultimate cause is that TEE
4817 * is given to a conversion where it should not. TEE signals that
4818 * this is the last buffer. Except in our case it is not.
4820 * My solution is to suppress TEE if the first buffer is not the
4821 * last. We will eventually need it given that EOF has been
4822 * reached, but not right now. This is what the new flag
4823 * "endEncSuppressFlag" is for.
4825 * The bug in 'Tcl_Utf2UtfProc' where it read from memory behind
4826 * the actual buffer has been fixed as well, and fixes the problem
4827 * with the crash too, but this would still allow the generic
4828 * layer to accidentially break a multi-byte sequence if the
4829 * conditions are just right, because again the ExternalToUtf
4830 * would be successful where it should not.
4833 if ((statePtr->inputEncodingFlags & TCL_ENCODING_END) &&
4834 (bufPtr->nextPtr != NULL)) {
4836 /* TEE is set for a buffer which is not the last. Squash it
4837 * for now, and restore it later, before yielding control to
4841 statePtr->inputEncodingFlags &= ~TCL_ENCODING_END;
4842 encEndFlagSuppressed = 1;
4845 oldState = statePtr->inputEncodingState;
4846 if (statePtr->flags & INPUT_NEED_NL) {
4848 * We want a '\n' because the last character we saw was '\r'.
4851 statePtr->flags &= ~INPUT_NEED_NL;
4852 Tcl_ExternalToUtf(NULL, statePtr->encoding, src, srcLen,
4853 statePtr->inputEncodingFlags, &statePtr->inputEncodingState,
4854 dst, TCL_UTF_MAX + 1, &srcRead, &dstWrote, &numChars);
4855 if ((dstWrote > 0) && (*dst == '\n')) {
4857 * The next char was a '\n'. Consume it and produce a '\n'.
4860 bufPtr->nextRemoved += srcRead;
4863 * The next char was not a '\n'. Produce a '\r'.
4868 statePtr->inputEncodingFlags &= ~TCL_ENCODING_START;
4871 if (encEndFlagSuppressed) {
4872 statePtr->inputEncodingFlags |= TCL_ENCODING_END;
4877 Tcl_ExternalToUtf(NULL, statePtr->encoding, src, srcLen,
4878 statePtr->inputEncodingFlags, &statePtr->inputEncodingState, dst,
4879 dstNeeded + TCL_UTF_MAX, &srcRead, &dstWrote, &numChars);
4881 if (encEndFlagSuppressed) {
4882 statePtr->inputEncodingFlags |= TCL_ENCODING_END;
4887 * Not enough bytes in src buffer to make a complete char. Copy
4888 * the bytes to the next buffer to make a new contiguous string,
4889 * then tell the caller to fill the buffer with more bytes.
4892 ChannelBuffer *nextPtr;
4894 nextPtr = bufPtr->nextPtr;
4895 if (nextPtr == NULL) {
4898 * There isn't enough data in the buffers to complete the next
4899 * character, so we need to wait for more data before the next
4900 * file event can be delivered.
4904 * The exception to this is if the input buffer was
4905 * completely empty before we tried to convert its
4906 * contents. Nothing in, nothing out, and no incomplete
4907 * character data. The conversion before the current one
4911 statePtr->flags |= CHANNEL_NEED_MORE_DATA;
4916 /* Space is made at the beginning of the buffer to copy the
4917 * previous unused bytes there. Check first if the buffer we
4918 * are using actually has enough space at its beginning for
4919 * the data we are copying. Because if not we will write over the
4920 * buffer management information, especially the 'nextPtr'.
4922 * Note that the BUFFER_PADDING (See AllocChannelBuffer) is
4923 * used to prevent exactly this situation. I.e. it should
4924 * never happen. Therefore it is ok to panic should it happen
4925 * despite the precautions.
4928 if (nextPtr->nextRemoved - srcLen < 0) {
4929 Tcl_Panic ("Buffer Underflow, BUFFER_PADDING not enough");
4932 nextPtr->nextRemoved -= srcLen;
4933 memcpy((VOID *) (nextPtr->buf + nextPtr->nextRemoved), (VOID *) src,
4935 RecycleBuffer(statePtr, bufPtr, 0);
4936 statePtr->inQueueHead = nextPtr;
4937 return ReadChars(statePtr, objPtr, charsToRead, offsetPtr, factorPtr);
4941 if (TranslateInputEOL(statePtr, dst, dst, &dstWrote, &dstRead) != 0) {
4943 * Hit EOF char. How many bytes of src correspond to where the
4944 * EOF was located in dst? Run the conversion again with an
4945 * output buffer just big enough to hold the data so we can
4946 * get the correct value for srcRead.
4949 if (dstWrote == 0) {
4952 statePtr->inputEncodingState = oldState;
4953 Tcl_ExternalToUtf(NULL, statePtr->encoding, src, srcLen,
4954 statePtr->inputEncodingFlags, &statePtr->inputEncodingState,
4955 dst, dstRead + TCL_UTF_MAX, &srcRead, &dstWrote, &numChars);
4956 TranslateInputEOL(statePtr, dst, dst, &dstWrote, &dstRead);
4960 * The number of characters that we got may be less than the number
4961 * that we started with because "\r\n" sequences may have been
4962 * turned into just '\n' in dst.
4965 numChars -= (dstRead - dstWrote);
4967 if ((unsigned) numChars > (unsigned) toRead) {
4969 * Got too many chars.
4974 eof = Tcl_UtfAtIndex(dst, toRead);
4975 statePtr->inputEncodingState = oldState;
4976 Tcl_ExternalToUtf(NULL, statePtr->encoding, src, srcLen,
4977 statePtr->inputEncodingFlags, &statePtr->inputEncodingState,
4978 dst, eof - dst + TCL_UTF_MAX, &srcRead, &dstWrote, &numChars);
4980 TranslateInputEOL(statePtr, dst, dst, &dstWrote, &dstRead);
4981 numChars -= (dstRead - dstWrote);
4983 statePtr->inputEncodingFlags &= ~TCL_ENCODING_START;
4985 bufPtr->nextRemoved += srcRead;
4986 if (dstWrote > srcRead + 1) {
4987 *factorPtr = dstWrote * UTF_EXPANSION_FACTOR / srcRead;
4989 *offsetPtr += dstWrote;
4994 *---------------------------------------------------------------------------
4996 * TranslateInputEOL --
4998 * Perform input EOL and EOF translation on the source buffer,
4999 * leaving the translated result in the destination buffer.
5002 * The return value is 1 if the EOF character was found when copying
5003 * bytes to the destination buffer, 0 otherwise.
5008 *---------------------------------------------------------------------------
5012 TranslateInputEOL(statePtr, dstStart, srcStart, dstLenPtr, srcLenPtr)
5013 ChannelState *statePtr; /* Channel being read, for EOL translation
5014 * and EOF character. */
5015 char *dstStart; /* Output buffer filled with chars by
5016 * applying appropriate EOL translation to
5017 * source characters. */
5018 CONST char *srcStart; /* Source characters. */
5019 int *dstLenPtr; /* On entry, the maximum length of output
5020 * buffer in bytes; must be <= *srcLenPtr. On
5021 * exit, the number of bytes actually used in
5023 int *srcLenPtr; /* On entry, the length of source buffer.
5024 * On exit, the number of bytes read from
5025 * the source buffer. */
5027 int dstLen, srcLen, inEofChar;
5030 dstLen = *dstLenPtr;
5033 inEofChar = statePtr->inEofChar;
5034 if (inEofChar != '\0') {
5036 * Find EOF in translated buffer then compress out the EOL. The
5037 * source buffer may be much longer than the destination buffer --
5038 * we only want to return EOF if the EOF has been copied to the
5039 * destination buffer.
5042 CONST char *src, *srcMax;
5044 srcMax = srcStart + *srcLenPtr;
5045 for (src = srcStart; src < srcMax; src++) {
5046 if (*src == inEofChar) {
5048 srcLen = src - srcStart;
5049 if (srcLen < dstLen) {
5052 *srcLenPtr = srcLen;
5057 switch (statePtr->inputTranslation) {
5058 case TCL_TRANSLATE_LF: {
5059 if (dstStart != srcStart) {
5060 memcpy((VOID *) dstStart, (VOID *) srcStart, (size_t) dstLen);
5065 case TCL_TRANSLATE_CR: {
5068 if (dstStart != srcStart) {
5069 memcpy((VOID *) dstStart, (VOID *) srcStart, (size_t) dstLen);
5071 dstEnd = dstStart + dstLen;
5072 for (dst = dstStart; dst < dstEnd; dst++) {
5080 case TCL_TRANSLATE_CRLF: {
5082 CONST char *src, *srcEnd, *srcMax;
5086 srcEnd = srcStart + dstLen;
5087 srcMax = srcStart + *srcLenPtr;
5089 for ( ; src < srcEnd; ) {
5092 if (src >= srcMax) {
5093 statePtr->flags |= INPUT_NEED_NL;
5094 } else if (*src == '\n') {
5103 srcLen = src - srcStart;
5104 dstLen = dst - dstStart;
5107 case TCL_TRANSLATE_AUTO: {
5109 CONST char *src, *srcEnd, *srcMax;
5113 srcEnd = srcStart + dstLen;
5114 srcMax = srcStart + *srcLenPtr;
5116 if ((statePtr->flags & INPUT_SAW_CR) && (src < srcMax)) {
5120 statePtr->flags &= ~INPUT_SAW_CR;
5122 for ( ; src < srcEnd; ) {
5125 if (src >= srcMax) {
5126 statePtr->flags |= INPUT_SAW_CR;
5127 } else if (*src == '\n') {
5128 if (srcEnd < srcMax) {
5138 srcLen = src - srcStart;
5139 dstLen = dst - dstStart;
5142 default: { /* lint. */
5146 *dstLenPtr = dstLen;
5148 if ((eof != NULL) && (srcStart + srcLen >= eof)) {
5150 * EOF character was seen in EOL translated range. Leave current
5151 * file position pointing at the EOF character, but don't store the
5152 * EOF character in the output string.
5155 statePtr->flags |= (CHANNEL_EOF | CHANNEL_STICKY_EOF);
5156 statePtr->inputEncodingFlags |= TCL_ENCODING_END;
5157 statePtr->flags &= ~(INPUT_SAW_CR | INPUT_NEED_NL);
5161 *srcLenPtr = srcLen;
5166 *----------------------------------------------------------------------
5170 * Causes the supplied string to be added to the input queue of
5171 * the channel, at either the head or tail of the queue.
5174 * The number of bytes stored in the channel, or -1 on error.
5177 * Adds input to the input queue of a channel.
5179 *----------------------------------------------------------------------
5183 Tcl_Ungets(chan, str, len, atEnd)
5184 Tcl_Channel chan; /* The channel for which to add the input. */
5185 CONST char *str; /* The input itself. */
5186 int len; /* The length of the input. */
5187 int atEnd; /* If non-zero, add at end of queue; otherwise
5188 * add at head of queue. */
5190 Channel *chanPtr; /* The real IO channel. */
5191 ChannelState *statePtr; /* State of actual channel. */
5192 ChannelBuffer *bufPtr; /* Buffer to contain the data. */
5195 chanPtr = (Channel *) chan;
5196 statePtr = chanPtr->state;
5199 * This operation should occur at the top of a channel stack.
5202 chanPtr = statePtr->topChanPtr;
5205 * CheckChannelErrors clears too many flag bits in this one case.
5208 flags = statePtr->flags;
5209 if (CheckChannelErrors(statePtr, TCL_READABLE) != 0) {
5213 statePtr->flags = flags;
5216 * If we have encountered a sticky EOF, just punt without storing.
5217 * (sticky EOF is set if we have seen the input eofChar, to prevent
5218 * reading beyond the eofChar). Otherwise, clear the EOF flags, and
5219 * clear the BLOCKED bit. We want to discover these conditions anew
5220 * in each operation.
5223 if (statePtr->flags & CHANNEL_STICKY_EOF) {
5226 statePtr->flags &= (~(CHANNEL_BLOCKED | CHANNEL_EOF));
5228 bufPtr = AllocChannelBuffer(len);
5229 for (i = 0; i < len; i++) {
5230 bufPtr->buf[bufPtr->nextAdded++] = str[i];
5233 if (statePtr->inQueueHead == (ChannelBuffer *) NULL) {
5234 bufPtr->nextPtr = (ChannelBuffer *) NULL;
5235 statePtr->inQueueHead = bufPtr;
5236 statePtr->inQueueTail = bufPtr;
5238 bufPtr->nextPtr = (ChannelBuffer *) NULL;
5239 statePtr->inQueueTail->nextPtr = bufPtr;
5240 statePtr->inQueueTail = bufPtr;
5242 bufPtr->nextPtr = statePtr->inQueueHead;
5243 statePtr->inQueueHead = bufPtr;
5248 * Update the notifier state so we don't block while there is still
5249 * data in the buffers.
5252 UpdateInterest(chanPtr);
5257 *----------------------------------------------------------------------
5261 * Flushes output data on a channel.
5264 * A standard Tcl result.
5267 * May flush output queued on this channel.
5269 *----------------------------------------------------------------------
5274 Tcl_Channel chan; /* The Channel to flush. */
5276 int result; /* Of calling FlushChannel. */
5277 Channel *chanPtr = (Channel *) chan; /* The actual channel. */
5278 ChannelState *statePtr = chanPtr->state; /* State of actual channel. */
5281 * This operation should occur at the top of a channel stack.
5284 chanPtr = statePtr->topChanPtr;
5286 if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) {
5291 * Force current output buffer to be output also.
5294 if ((statePtr->curOutPtr != NULL)
5295 && (statePtr->curOutPtr->nextAdded > 0)) {
5296 statePtr->flags |= BUFFER_READY;
5299 result = FlushChannel(NULL, chanPtr, 0);
5308 *----------------------------------------------------------------------
5310 * DiscardInputQueued --
5312 * Discards any input read from the channel but not yet consumed
5313 * by Tcl reading commands.
5319 * May discard input from the channel. If discardLastBuffer is zero,
5320 * leaves one buffer in place for back-filling.
5322 *----------------------------------------------------------------------
5326 DiscardInputQueued(statePtr, discardSavedBuffers)
5327 ChannelState *statePtr; /* Channel on which to discard
5328 * the queued input. */
5329 int discardSavedBuffers; /* If non-zero, discard all buffers including
5332 ChannelBuffer *bufPtr, *nxtPtr; /* Loop variables. */
5334 bufPtr = statePtr->inQueueHead;
5335 statePtr->inQueueHead = (ChannelBuffer *) NULL;
5336 statePtr->inQueueTail = (ChannelBuffer *) NULL;
5337 for (; bufPtr != (ChannelBuffer *) NULL; bufPtr = nxtPtr) {
5338 nxtPtr = bufPtr->nextPtr;
5339 RecycleBuffer(statePtr, bufPtr, discardSavedBuffers);
5343 * If discardSavedBuffers is nonzero, must also discard any previously
5344 * saved buffer in the saveInBufPtr field.
5347 if (discardSavedBuffers) {
5348 if (statePtr->saveInBufPtr != (ChannelBuffer *) NULL) {
5349 ckfree((char *) statePtr->saveInBufPtr);
5350 statePtr->saveInBufPtr = (ChannelBuffer *) NULL;
5356 *---------------------------------------------------------------------------
5360 * Reads input data from a device into a channel buffer.
5363 * The return value is the Posix error code if an error occurred while
5364 * reading from the file, or 0 otherwise.
5367 * Reads from the underlying device.
5369 *---------------------------------------------------------------------------
5374 Channel *chanPtr; /* Channel to read input from. */
5376 int toRead; /* How much to read? */
5377 int result; /* Of calling driver. */
5378 int nread; /* How much was read from channel? */
5379 ChannelBuffer *bufPtr; /* New buffer to add to input queue. */
5380 ChannelState *statePtr = chanPtr->state; /* state info for channel */
5383 * Prevent reading from a dead channel -- a channel that has been closed
5384 * but not yet deallocated, which can happen if the exit handler for
5385 * channel cleanup has run but the channel is still registered in some
5389 if (CheckForDeadChannel(NULL, statePtr)) {
5394 * First check for more buffers in the pushback area of the
5395 * topmost channel in the stack and use them. They can be the
5396 * result of a transformation which went away without reading all
5397 * the information placed in the area when it was stacked.
5399 * Two possibilities for the state: No buffers in it, or a single
5400 * empty buffer. In the latter case we can recycle it now.
5403 if (chanPtr->inQueueHead != (ChannelBuffer*) NULL) {
5404 if (statePtr->inQueueHead != (ChannelBuffer*) NULL) {
5405 RecycleBuffer(statePtr, statePtr->inQueueHead, 0);
5406 statePtr->inQueueHead = (ChannelBuffer*) NULL;
5409 statePtr->inQueueHead = chanPtr->inQueueHead;
5410 statePtr->inQueueTail = chanPtr->inQueueTail;
5411 chanPtr->inQueueHead = (ChannelBuffer*) NULL;
5412 chanPtr->inQueueTail = (ChannelBuffer*) NULL;
5417 * Nothing in the pushback area, fall back to the usual handling
5422 * See if we can fill an existing buffer. If we can, read only
5423 * as much as will fit in it. Otherwise allocate a new buffer,
5424 * add it to the input queue and attempt to fill it to the max.
5427 bufPtr = statePtr->inQueueTail;
5428 if ((bufPtr != NULL) && (bufPtr->nextAdded < bufPtr->bufLength)) {
5429 toRead = bufPtr->bufLength - bufPtr->nextAdded;
5431 bufPtr = statePtr->saveInBufPtr;
5432 statePtr->saveInBufPtr = NULL;
5435 * Check the actual buffersize against the requested
5436 * buffersize. Buffers which are smaller than requested are
5437 * squashed. This is done to honor dynamic changes of the
5438 * buffersize made by the user.
5441 if ((bufPtr != NULL) && ((bufPtr->bufLength - BUFFER_PADDING) < statePtr->bufSize)) {
5442 ckfree((char *) bufPtr);
5446 if (bufPtr == NULL) {
5447 bufPtr = AllocChannelBuffer(statePtr->bufSize);
5449 bufPtr->nextPtr = (ChannelBuffer *) NULL;
5451 /* SF #427196: Use the actual size of the buffer to determine
5452 * the number of bytes to read from the channel and not the
5453 * size for new buffers. They can be different if the
5454 * buffersize was changed between reads.
5456 * Note: This affects performance negatively if the buffersize
5457 * was extended but this small buffer is reused for all
5458 * subsequent reads. The system never uses buffers with the
5459 * requested bigger size in that case. An adjunct patch could
5460 * try and delete all unused buffers it encounters and which
5461 * are smaller than the formally requested buffersize.
5464 toRead = bufPtr->bufLength - bufPtr->nextAdded;
5466 if (statePtr->inQueueTail == NULL) {
5467 statePtr->inQueueHead = bufPtr;
5469 statePtr->inQueueTail->nextPtr = bufPtr;
5471 statePtr->inQueueTail = bufPtr;
5475 * If EOF is set, we should avoid calling the driver because on some
5476 * platforms it is impossible to read from a device after EOF.
5479 if (statePtr->flags & CHANNEL_EOF) {
5483 #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
5484 /* [SF Tcl Bug 943274]. Better emulation of non-blocking channels
5485 * for channels without BlockModeProc, by keeping track of true
5486 * fileevents generated by the OS == Data waiting and reading if
5487 * and only if we are sure to have data.
5490 if ((statePtr->flags & CHANNEL_NONBLOCKING) &&
5491 (Tcl_ChannelBlockModeProc(chanPtr->typePtr) == NULL) &&
5492 !(statePtr->flags & CHANNEL_HAS_MORE_DATA)) {
5494 /* Bypass the driver, it would block, as no data is available */
5496 result = EWOULDBLOCK;
5498 #endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
5500 nread = (chanPtr->typePtr->inputProc)(chanPtr->instanceData,
5501 bufPtr->buf + bufPtr->nextAdded, toRead, &result);
5503 #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
5505 #endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
5508 bufPtr->nextAdded += nread;
5511 * If we get a short read, signal up that we may be BLOCKED. We
5512 * should avoid calling the driver because on some platforms we
5513 * will block in the low level reading code even though the
5514 * channel is set into nonblocking mode.
5517 if (nread < toRead) {
5518 statePtr->flags |= CHANNEL_BLOCKED;
5521 #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
5522 if (nread <= toRead) {
5523 /* [SF Tcl Bug 943274] We have read the available data,
5525 statePtr->flags &= ~CHANNEL_HAS_MORE_DATA;
5527 #endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
5529 } else if (nread == 0) {
5530 statePtr->flags |= CHANNEL_EOF;
5531 statePtr->inputEncodingFlags |= TCL_ENCODING_END;
5532 } else if (nread < 0) {
5533 if ((result == EWOULDBLOCK) || (result == EAGAIN)) {
5534 statePtr->flags |= CHANNEL_BLOCKED;
5537 Tcl_SetErrno(result);
5544 *----------------------------------------------------------------------
5548 * Implements seeking on Tcl Channels. This is a public function
5549 * so that other C facilities may be implemented on top of it.
5552 * The new access point or -1 on error. If error, use Tcl_GetErrno()
5553 * to retrieve the POSIX error code for the error that occurred.
5556 * May flush output on the channel. May discard queued input.
5558 *----------------------------------------------------------------------
5561 EXPORT_C Tcl_WideInt
5562 Tcl_Seek(chan, offset, mode)
5563 Tcl_Channel chan; /* The channel on which to seek. */
5564 Tcl_WideInt offset; /* Offset to seek to. */
5565 int mode; /* Relative to which location to seek? */
5567 Channel *chanPtr = (Channel *) chan; /* The real IO channel. */
5568 ChannelState *statePtr = chanPtr->state; /* state info for channel */
5569 int inputBuffered, outputBuffered;
5570 /* # bytes held in buffers. */
5571 int result; /* Of device driver operations. */
5572 Tcl_WideInt curPos; /* Position on the device. */
5573 int wasAsync; /* Was the channel nonblocking before the
5574 * seek operation? If so, must restore to
5575 * nonblocking mode after the seek. */
5577 if (CheckChannelErrors(statePtr, TCL_WRITABLE | TCL_READABLE) != 0) {
5578 return Tcl_LongAsWide(-1);
5582 * Disallow seek on dead channels -- channels that have been closed but
5583 * not yet been deallocated. Such channels can be found if the exit
5584 * handler for channel cleanup has run but the channel is still
5585 * registered in an interpreter.
5588 if (CheckForDeadChannel(NULL, statePtr)) {
5589 return Tcl_LongAsWide(-1);
5593 * This operation should occur at the top of a channel stack.
5596 chanPtr = statePtr->topChanPtr;
5599 * Disallow seek on channels whose type does not have a seek procedure
5600 * defined. This means that the channel does not support seeking.
5603 if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) {
5604 Tcl_SetErrno(EINVAL);
5605 return Tcl_LongAsWide(-1);
5609 * Compute how much input and output is buffered. If both input and
5610 * output is buffered, cannot compute the current position.
5613 inputBuffered = Tcl_InputBuffered(chan);
5614 outputBuffered = Tcl_OutputBuffered(chan);
5616 if ((inputBuffered != 0) && (outputBuffered != 0)) {
5617 Tcl_SetErrno(EFAULT);
5618 return Tcl_LongAsWide(-1);
5622 * If we are seeking relative to the current position, compute the
5623 * corrected offset taking into account the amount of unread input.
5626 if (mode == SEEK_CUR) {
5627 offset -= inputBuffered;
5631 * Discard any queued input - this input should not be read after
5635 DiscardInputQueued(statePtr, 0);
5638 * Reset EOF and BLOCKED flags. We invalidate them by moving the
5639 * access point. Also clear CR related flags.
5643 (~(CHANNEL_EOF | CHANNEL_STICKY_EOF | CHANNEL_BLOCKED | INPUT_SAW_CR));
5646 * If the channel is in asynchronous output mode, switch it back
5647 * to synchronous mode and cancel any async flush that may be
5648 * scheduled. After the flush, the channel will be put back into
5649 * asynchronous output mode.
5653 if (statePtr->flags & CHANNEL_NONBLOCKING) {
5655 result = StackSetBlockMode(chanPtr, TCL_MODE_BLOCKING);
5657 return Tcl_LongAsWide(-1);
5659 statePtr->flags &= (~(CHANNEL_NONBLOCKING));
5660 if (statePtr->flags & BG_FLUSH_SCHEDULED) {
5661 statePtr->flags &= (~(BG_FLUSH_SCHEDULED));
5666 * If the flush fails we cannot recover the original position. In
5667 * that case the seek is not attempted because we do not know where
5668 * the access position is - instead we return the error. FlushChannel
5669 * has already called Tcl_SetErrno() to report the error upwards.
5670 * If the flush succeeds we do the seek also.
5673 if (FlushChannel(NULL, chanPtr, 0) != 0) {
5678 * Now seek to the new position in the channel as requested by the
5679 * caller. Note that we prefer the wideSeekProc if that is
5680 * available and non-NULL...
5683 if (HaveVersion(chanPtr->typePtr, TCL_CHANNEL_VERSION_3) &&
5684 chanPtr->typePtr->wideSeekProc != NULL) {
5685 curPos = (chanPtr->typePtr->wideSeekProc) (chanPtr->instanceData,
5686 offset, mode, &result);
5687 } else if (offset < Tcl_LongAsWide(LONG_MIN) ||
5688 offset > Tcl_LongAsWide(LONG_MAX)) {
5690 curPos = Tcl_LongAsWide(-1);
5692 curPos = Tcl_LongAsWide((chanPtr->typePtr->seekProc) (
5693 chanPtr->instanceData, Tcl_WideAsLong(offset), mode,
5696 if (curPos == Tcl_LongAsWide(-1)) {
5697 Tcl_SetErrno(result);
5702 * Restore to nonblocking mode if that was the previous behavior.
5704 * NOTE: Even if there was an async flush active we do not restore
5705 * it now because we already flushed all the queued output, above.
5709 statePtr->flags |= CHANNEL_NONBLOCKING;
5710 result = StackSetBlockMode(chanPtr, TCL_MODE_NONBLOCKING);
5712 return Tcl_LongAsWide(-1);
5720 *----------------------------------------------------------------------
5724 * Returns the position of the next character to be read/written on
5728 * A nonnegative integer on success, -1 on failure. If failed,
5729 * use Tcl_GetErrno() to retrieve the POSIX error code for the
5730 * error that occurred.
5735 *----------------------------------------------------------------------
5738 EXPORT_C Tcl_WideInt
5740 Tcl_Channel chan; /* The channel to return pos for. */
5742 Channel *chanPtr = (Channel *) chan; /* The real IO channel. */
5743 ChannelState *statePtr = chanPtr->state; /* state info for channel */
5744 int inputBuffered, outputBuffered; /* # bytes held in buffers. */
5745 int result; /* Of calling device driver. */
5746 Tcl_WideInt curPos; /* Position on device. */
5748 if (CheckChannelErrors(statePtr, TCL_WRITABLE | TCL_READABLE) != 0) {
5749 return Tcl_LongAsWide(-1);
5753 * Disallow tell on dead channels -- channels that have been closed but
5754 * not yet been deallocated. Such channels can be found if the exit
5755 * handler for channel cleanup has run but the channel is still
5756 * registered in an interpreter.
5759 if (CheckForDeadChannel(NULL, statePtr)) {
5760 return Tcl_LongAsWide(-1);
5764 * This operation should occur at the top of a channel stack.
5767 chanPtr = statePtr->topChanPtr;
5770 * Disallow tell on channels whose type does not have a seek procedure
5771 * defined. This means that the channel does not support seeking.
5774 if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) {
5775 Tcl_SetErrno(EINVAL);
5776 return Tcl_LongAsWide(-1);
5780 * Compute how much input and output is buffered. If both input and
5781 * output is buffered, cannot compute the current position.
5784 inputBuffered = Tcl_InputBuffered(chan);
5785 outputBuffered = Tcl_OutputBuffered(chan);
5787 if ((inputBuffered != 0) && (outputBuffered != 0)) {
5788 Tcl_SetErrno(EFAULT);
5789 return Tcl_LongAsWide(-1);
5793 * Get the current position in the device and compute the position
5794 * where the next character will be read or written. Note that we
5795 * prefer the wideSeekProc if that is available and non-NULL...
5798 if (HaveVersion(chanPtr->typePtr, TCL_CHANNEL_VERSION_3) &&
5799 chanPtr->typePtr->wideSeekProc != NULL) {
5800 curPos = (chanPtr->typePtr->wideSeekProc) (chanPtr->instanceData,
5801 Tcl_LongAsWide(0), SEEK_CUR, &result);
5803 curPos = Tcl_LongAsWide((chanPtr->typePtr->seekProc) (
5804 chanPtr->instanceData, 0, SEEK_CUR, &result));
5806 if (curPos == Tcl_LongAsWide(-1)) {
5807 Tcl_SetErrno(result);
5808 return Tcl_LongAsWide(-1);
5810 if (inputBuffered != 0) {
5811 return curPos - inputBuffered;
5813 return curPos + outputBuffered;
5817 *---------------------------------------------------------------------------
5819 * Tcl_SeekOld, Tcl_TellOld --
5821 * Backward-compatability versions of the seek/tell interface that
5822 * do not support 64-bit offsets. This interface is not documented
5823 * or expected to be supported indefinitely.
5826 * As for Tcl_Seek and Tcl_Tell respectively, except truncated to
5827 * whatever value will fit in an 'int'.
5830 * As for Tcl_Seek and Tcl_Tell respectively.
5832 *---------------------------------------------------------------------------
5836 Tcl_SeekOld(chan, offset, mode)
5837 Tcl_Channel chan; /* The channel on which to seek. */
5838 int offset; /* Offset to seek to. */
5839 int mode; /* Relative to which location to seek? */
5841 Tcl_WideInt wOffset, wResult;
5843 wOffset = Tcl_LongAsWide((long)offset);
5844 wResult = Tcl_Seek(chan, wOffset, mode);
5845 return (int)Tcl_WideAsLong(wResult);
5850 Tcl_Channel chan; /* The channel to return pos for. */
5852 Tcl_WideInt wResult;
5854 wResult = Tcl_Tell(chan);
5855 return (int)Tcl_WideAsLong(wResult);
5859 *---------------------------------------------------------------------------
5861 * CheckChannelErrors --
5863 * See if the channel is in an ready state and can perform the
5864 * desired operation.
5867 * The return value is 0 if the channel is OK, otherwise the
5868 * return value is -1 and errno is set to indicate the error.
5871 * May clear the EOF and/or BLOCKED bits if reading from channel.
5873 *---------------------------------------------------------------------------
5877 CheckChannelErrors(statePtr, flags)
5878 ChannelState *statePtr; /* Channel to check. */
5879 int flags; /* Test if channel supports desired operation:
5880 * TCL_READABLE, TCL_WRITABLE. Also indicates
5881 * Raw read or write for special close
5884 int direction = flags & (TCL_READABLE|TCL_WRITABLE);
5887 * Check for unreported error.
5890 if (statePtr->unreportedError != 0) {
5891 Tcl_SetErrno(statePtr->unreportedError);
5892 statePtr->unreportedError = 0;
5897 * Only the raw read and write operations are allowed during close
5898 * in order to drain data from stacked channels.
5901 if ((statePtr->flags & CHANNEL_CLOSED) &&
5902 ((flags & CHANNEL_RAW_MODE) == 0)) {
5903 Tcl_SetErrno(EACCES);
5908 * Fail if the channel is not opened for desired operation.
5911 if ((statePtr->flags & direction) == 0) {
5912 Tcl_SetErrno(EACCES);
5917 * Fail if the channel is in the middle of a background copy.
5919 * Don't do this tests for raw channels here or else the chaining in the
5920 * transformation drivers will fail with 'file busy' error instead of
5921 * retrieving and transforming the data to copy.
5924 if ((statePtr->csPtr != NULL) && ((flags & CHANNEL_RAW_MODE) == 0)) {
5925 Tcl_SetErrno(EBUSY);
5929 if (direction == TCL_READABLE) {
5931 * If we have not encountered a sticky EOF, clear the EOF bit
5932 * (sticky EOF is set if we have seen the input eofChar, to prevent
5933 * reading beyond the eofChar). Also, always clear the BLOCKED bit.
5934 * We want to discover these conditions anew in each operation.
5937 if ((statePtr->flags & CHANNEL_STICKY_EOF) == 0) {
5938 statePtr->flags &= ~CHANNEL_EOF;
5940 statePtr->flags &= ~(CHANNEL_BLOCKED | CHANNEL_NEED_MORE_DATA);
5947 *----------------------------------------------------------------------
5951 * Returns 1 if the channel is at EOF, 0 otherwise.
5959 *----------------------------------------------------------------------
5964 Tcl_Channel chan; /* Does this channel have EOF? */
5966 ChannelState *statePtr = ((Channel *) chan)->state;
5967 /* State of real channel structure. */
5969 return ((statePtr->flags & CHANNEL_STICKY_EOF) ||
5970 ((statePtr->flags & CHANNEL_EOF) &&
5971 (Tcl_InputBuffered(chan) == 0))) ? 1 : 0;
5975 *----------------------------------------------------------------------
5977 * Tcl_InputBlocked --
5979 * Returns 1 if input is blocked on this channel, 0 otherwise.
5987 *----------------------------------------------------------------------
5991 Tcl_InputBlocked(chan)
5992 Tcl_Channel chan; /* Is this channel blocked? */
5994 ChannelState *statePtr = ((Channel *) chan)->state;
5995 /* State of real channel structure. */
5997 return (statePtr->flags & CHANNEL_BLOCKED) ? 1 : 0;
6001 *----------------------------------------------------------------------
6003 * Tcl_InputBuffered --
6005 * Returns the number of bytes of input currently buffered in the
6006 * common internal buffer of a channel.
6009 * The number of input bytes buffered, or zero if the channel is not
6015 *----------------------------------------------------------------------
6019 Tcl_InputBuffered(chan)
6020 Tcl_Channel chan; /* The channel to query. */
6022 ChannelState *statePtr = ((Channel *) chan)->state;
6023 /* State of real channel structure. */
6024 ChannelBuffer *bufPtr;
6027 for (bytesBuffered = 0, bufPtr = statePtr->inQueueHead;
6028 bufPtr != (ChannelBuffer *) NULL;
6029 bufPtr = bufPtr->nextPtr) {
6030 bytesBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved);
6034 * Don't forget the bytes in the topmost pushback area.
6037 for (bufPtr = statePtr->topChanPtr->inQueueHead;
6038 bufPtr != (ChannelBuffer *) NULL;
6039 bufPtr = bufPtr->nextPtr) {
6040 bytesBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved);
6043 return bytesBuffered;
6047 *----------------------------------------------------------------------
6049 * Tcl_OutputBuffered --
6051 * Returns the number of bytes of output currently buffered in the
6052 * common internal buffer of a channel.
6055 * The number of output bytes buffered, or zero if the channel is not
6061 *----------------------------------------------------------------------
6065 Tcl_OutputBuffered(chan)
6066 Tcl_Channel chan; /* The channel to query. */
6068 ChannelState *statePtr = ((Channel *) chan)->state;
6069 /* State of real channel structure. */
6070 ChannelBuffer *bufPtr;
6073 for (bytesBuffered = 0, bufPtr = statePtr->outQueueHead;
6074 bufPtr != (ChannelBuffer *) NULL;
6075 bufPtr = bufPtr->nextPtr) {
6076 bytesBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved);
6078 if ((statePtr->curOutPtr != (ChannelBuffer *) NULL) &&
6079 (statePtr->curOutPtr->nextAdded > statePtr->curOutPtr->nextRemoved)) {
6080 statePtr->flags |= BUFFER_READY;
6082 (statePtr->curOutPtr->nextAdded - statePtr->curOutPtr->nextRemoved);
6085 return bytesBuffered;
6089 *----------------------------------------------------------------------
6091 * Tcl_ChannelBuffered --
6093 * Returns the number of bytes of input currently buffered in the
6094 * internal buffer (push back area) of a channel.
6097 * The number of input bytes buffered, or zero if the channel is not
6103 *----------------------------------------------------------------------
6107 Tcl_ChannelBuffered(chan)
6108 Tcl_Channel chan; /* The channel to query. */
6110 Channel *chanPtr = (Channel *) chan;
6111 /* real channel structure. */
6112 ChannelBuffer *bufPtr;
6115 for (bytesBuffered = 0, bufPtr = chanPtr->inQueueHead;
6116 bufPtr != (ChannelBuffer *) NULL;
6117 bufPtr = bufPtr->nextPtr) {
6118 bytesBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved);
6121 return bytesBuffered;
6125 *----------------------------------------------------------------------
6127 * Tcl_SetChannelBufferSize --
6129 * Sets the size of buffers to allocate to store input or output
6130 * in the channel. The size must be between 1 byte and 1 MByte.
6136 * Sets the size of buffers subsequently allocated for this channel.
6138 *----------------------------------------------------------------------
6142 Tcl_SetChannelBufferSize(chan, sz)
6143 Tcl_Channel chan; /* The channel whose buffer size
6145 int sz; /* The size to set. */
6147 ChannelState *statePtr; /* State of real channel structure. */
6150 * If the buffer size is smaller than 1 byte or larger than one MByte,
6151 * do not accept the requested size and leave the current buffer size.
6157 if (sz > (1024 * 1024)) {
6161 statePtr = ((Channel *) chan)->state;
6162 statePtr->bufSize = sz;
6164 if (statePtr->outputStage != NULL) {
6165 ckfree((char *) statePtr->outputStage);
6166 statePtr->outputStage = NULL;
6168 if ((statePtr->encoding != NULL) && (statePtr->flags & TCL_WRITABLE)) {
6169 statePtr->outputStage = (char *)
6170 ckalloc((unsigned) (statePtr->bufSize + 2));
6175 *----------------------------------------------------------------------
6177 * Tcl_GetChannelBufferSize --
6179 * Retrieves the size of buffers to allocate for this channel.
6187 *----------------------------------------------------------------------
6191 Tcl_GetChannelBufferSize(chan)
6192 Tcl_Channel chan; /* The channel for which to find the
6195 ChannelState *statePtr = ((Channel *) chan)->state;
6196 /* State of real channel structure. */
6198 return statePtr->bufSize;
6202 *----------------------------------------------------------------------
6204 * Tcl_BadChannelOption --
6206 * This procedure generates a "bad option" error message in an
6207 * (optional) interpreter. It is used by channel drivers when
6208 * a invalid Set/Get option is requested. Its purpose is to concatenate
6209 * the generic options list to the specific ones and factorize
6210 * the generic options error message string.
6216 * An error message is generated in interp's result object to
6217 * indicate that a command was invoked with the a bad option
6218 * The message has the form
6219 * bad option "blah": should be one of
6220 * <...generic options...>+<...specific options...>
6221 * "blah" is the optionName argument and "<specific options>"
6222 * is a space separated list of specific option words.
6223 * The function takes good care of inserting minus signs before
6224 * each option, commas after, and an "or" before the last option.
6226 *----------------------------------------------------------------------
6230 Tcl_BadChannelOption(interp, optionName, optionList)
6231 Tcl_Interp *interp; /* Current interpreter. (can be NULL)*/
6232 CONST char *optionName; /* 'bad option' name */
6233 CONST char *optionList; /* Specific options list to append
6234 * to the standard generic options.
6235 * can be NULL for generic options
6240 CONST char *genericopt =
6241 "blocking buffering buffersize encoding eofchar translation";
6246 Tcl_DStringInit(&ds);
6247 Tcl_DStringAppend(&ds, genericopt, -1);
6248 if (optionList && (*optionList)) {
6249 Tcl_DStringAppend(&ds, " ", 1);
6250 Tcl_DStringAppend(&ds, optionList, -1);
6252 if (Tcl_SplitList(interp, Tcl_DStringValue(&ds),
6253 &argc, &argv) != TCL_OK) {
6254 panic("malformed option list in channel driver");
6256 Tcl_ResetResult(interp);
6257 Tcl_AppendResult(interp, "bad option \"", optionName,
6258 "\": should be one of ", (char *) NULL);
6260 for (i = 0; i < argc; i++) {
6261 Tcl_AppendResult(interp, "-", argv[i], ", ", (char *) NULL);
6263 Tcl_AppendResult(interp, "or -", argv[i], (char *) NULL);
6264 Tcl_DStringFree(&ds);
6265 ckfree((char *) argv);
6267 Tcl_SetErrno(EINVAL);
6272 *----------------------------------------------------------------------
6274 * Tcl_GetChannelOption --
6276 * Gets a mode associated with an IO channel. If the optionName arg
6277 * is non NULL, retrieves the value of that option. If the optionName
6278 * arg is NULL, retrieves a list of alternating option names and
6279 * values for the given channel.
6282 * A standard Tcl result. Also sets the supplied DString to the
6283 * string value of the option(s) returned.
6288 *----------------------------------------------------------------------
6292 Tcl_GetChannelOption(interp, chan, optionName, dsPtr)
6293 Tcl_Interp *interp; /* For error reporting - can be NULL. */
6294 Tcl_Channel chan; /* Channel on which to get option. */
6295 CONST char *optionName; /* Option to get. */
6296 Tcl_DString *dsPtr; /* Where to store value(s). */
6298 size_t len; /* Length of optionName string. */
6299 char optionVal[128]; /* Buffer for sprintf. */
6300 Channel *chanPtr = (Channel *) chan;
6301 ChannelState *statePtr = chanPtr->state; /* state info for channel */
6305 * Disallow options on dead channels -- channels that have been closed but
6306 * not yet been deallocated. Such channels can be found if the exit
6307 * handler for channel cleanup has run but the channel is still
6308 * registered in an interpreter.
6311 if (CheckForDeadChannel(interp, statePtr)) {
6316 * This operation should occur at the top of a channel stack.
6319 chanPtr = statePtr->topChanPtr;
6322 * If we are in the middle of a background copy, use the saved flags.
6325 if (statePtr->csPtr) {
6326 if (chanPtr == statePtr->csPtr->readPtr) {
6327 flags = statePtr->csPtr->readFlags;
6329 flags = statePtr->csPtr->writeFlags;
6332 flags = statePtr->flags;
6336 * If the optionName is NULL it means that we want a list of all
6337 * options and values.
6340 if (optionName == (char *) NULL) {
6343 len = strlen(optionName);
6346 if ((len == 0) || ((len > 2) && (optionName[1] == 'b') &&
6347 (strncmp(optionName, "-blocking", len) == 0))) {
6349 Tcl_DStringAppendElement(dsPtr, "-blocking");
6351 Tcl_DStringAppendElement(dsPtr,
6352 (flags & CHANNEL_NONBLOCKING) ? "0" : "1");
6357 if ((len == 0) || ((len > 7) && (optionName[1] == 'b') &&
6358 (strncmp(optionName, "-buffering", len) == 0))) {
6360 Tcl_DStringAppendElement(dsPtr, "-buffering");
6362 if (flags & CHANNEL_LINEBUFFERED) {
6363 Tcl_DStringAppendElement(dsPtr, "line");
6364 } else if (flags & CHANNEL_UNBUFFERED) {
6365 Tcl_DStringAppendElement(dsPtr, "none");
6367 Tcl_DStringAppendElement(dsPtr, "full");
6373 if ((len == 0) || ((len > 7) && (optionName[1] == 'b') &&
6374 (strncmp(optionName, "-buffersize", len) == 0))) {
6376 Tcl_DStringAppendElement(dsPtr, "-buffersize");
6378 TclFormatInt(optionVal, statePtr->bufSize);
6379 Tcl_DStringAppendElement(dsPtr, optionVal);
6385 ((len > 2) && (optionName[1] == 'e') &&
6386 (strncmp(optionName, "-encoding", len) == 0))) {
6388 Tcl_DStringAppendElement(dsPtr, "-encoding");
6390 if (statePtr->encoding == NULL) {
6391 Tcl_DStringAppendElement(dsPtr, "binary");
6393 Tcl_DStringAppendElement(dsPtr,
6394 Tcl_GetEncodingName(statePtr->encoding));
6401 ((len > 2) && (optionName[1] == 'e') &&
6402 (strncmp(optionName, "-eofchar", len) == 0))) {
6404 Tcl_DStringAppendElement(dsPtr, "-eofchar");
6406 if (((flags & (TCL_READABLE|TCL_WRITABLE)) ==
6407 (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) {
6408 Tcl_DStringStartSublist(dsPtr);
6410 if (flags & TCL_READABLE) {
6411 if (statePtr->inEofChar == 0) {
6412 Tcl_DStringAppendElement(dsPtr, "");
6416 sprintf(buf, "%c", statePtr->inEofChar);
6417 Tcl_DStringAppendElement(dsPtr, buf);
6420 if (flags & TCL_WRITABLE) {
6421 if (statePtr->outEofChar == 0) {
6422 Tcl_DStringAppendElement(dsPtr, "");
6426 sprintf(buf, "%c", statePtr->outEofChar);
6427 Tcl_DStringAppendElement(dsPtr, buf);
6430 if ( !(flags & (TCL_READABLE|TCL_WRITABLE))) {
6431 /* Not readable or writable (server socket) */
6432 Tcl_DStringAppendElement(dsPtr, "");
6434 if (((flags & (TCL_READABLE|TCL_WRITABLE)) ==
6435 (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) {
6436 Tcl_DStringEndSublist(dsPtr);
6443 ((len > 1) && (optionName[1] == 't') &&
6444 (strncmp(optionName, "-translation", len) == 0))) {
6446 Tcl_DStringAppendElement(dsPtr, "-translation");
6448 if (((flags & (TCL_READABLE|TCL_WRITABLE)) ==
6449 (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) {
6450 Tcl_DStringStartSublist(dsPtr);
6452 if (flags & TCL_READABLE) {
6453 if (statePtr->inputTranslation == TCL_TRANSLATE_AUTO) {
6454 Tcl_DStringAppendElement(dsPtr, "auto");
6455 } else if (statePtr->inputTranslation == TCL_TRANSLATE_CR) {
6456 Tcl_DStringAppendElement(dsPtr, "cr");
6457 } else if (statePtr->inputTranslation == TCL_TRANSLATE_CRLF) {
6458 Tcl_DStringAppendElement(dsPtr, "crlf");
6460 Tcl_DStringAppendElement(dsPtr, "lf");
6463 if (flags & TCL_WRITABLE) {
6464 if (statePtr->outputTranslation == TCL_TRANSLATE_AUTO) {
6465 Tcl_DStringAppendElement(dsPtr, "auto");
6466 } else if (statePtr->outputTranslation == TCL_TRANSLATE_CR) {
6467 Tcl_DStringAppendElement(dsPtr, "cr");
6468 } else if (statePtr->outputTranslation == TCL_TRANSLATE_CRLF) {
6469 Tcl_DStringAppendElement(dsPtr, "crlf");
6471 Tcl_DStringAppendElement(dsPtr, "lf");
6474 if ( !(flags & (TCL_READABLE|TCL_WRITABLE))) {
6475 /* Not readable or writable (server socket) */
6476 Tcl_DStringAppendElement(dsPtr, "auto");
6478 if (((flags & (TCL_READABLE|TCL_WRITABLE)) ==
6479 (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) {
6480 Tcl_DStringEndSublist(dsPtr);
6486 if (chanPtr->typePtr->getOptionProc != (Tcl_DriverGetOptionProc *) NULL) {
6488 * let the driver specific handle additional options
6489 * and result code and message.
6492 return (chanPtr->typePtr->getOptionProc) (chanPtr->instanceData,
6493 interp, optionName, dsPtr);
6496 * no driver specific options case.
6502 return Tcl_BadChannelOption(interp, optionName, NULL);
6507 *---------------------------------------------------------------------------
6509 * Tcl_SetChannelOption --
6511 * Sets an option on a channel.
6514 * A standard Tcl result. On error, sets interp's result object
6515 * if interp is not NULL.
6518 * May modify an option on a device.
6520 *---------------------------------------------------------------------------
6524 Tcl_SetChannelOption(interp, chan, optionName, newValue)
6525 Tcl_Interp *interp; /* For error reporting - can be NULL. */
6526 Tcl_Channel chan; /* Channel on which to set mode. */
6527 CONST char *optionName; /* Which option to set? */
6528 CONST char *newValue; /* New value for option. */
6530 Channel *chanPtr = (Channel *) chan; /* The real IO channel. */
6531 ChannelState *statePtr = chanPtr->state; /* state info for channel */
6532 size_t len; /* Length of optionName string. */
6537 * If the channel is in the middle of a background copy, fail.
6540 if (statePtr->csPtr) {
6542 Tcl_AppendResult(interp,
6543 "unable to set channel options: background copy in progress",
6550 * Disallow options on dead channels -- channels that have been closed but
6551 * not yet been deallocated. Such channels can be found if the exit
6552 * handler for channel cleanup has run but the channel is still
6553 * registered in an interpreter.
6556 if (CheckForDeadChannel(NULL, statePtr)) {
6561 * This operation should occur at the top of a channel stack.
6564 chanPtr = statePtr->topChanPtr;
6566 len = strlen(optionName);
6568 if ((len > 2) && (optionName[1] == 'b') &&
6569 (strncmp(optionName, "-blocking", len) == 0)) {
6571 if (Tcl_GetBoolean(interp, newValue, &newMode) == TCL_ERROR) {
6575 newMode = TCL_MODE_BLOCKING;
6577 newMode = TCL_MODE_NONBLOCKING;
6579 return SetBlockMode(interp, chanPtr, newMode);
6580 } else if ((len > 7) && (optionName[1] == 'b') &&
6581 (strncmp(optionName, "-buffering", len) == 0)) {
6582 len = strlen(newValue);
6583 if ((newValue[0] == 'f') && (strncmp(newValue, "full", len) == 0)) {
6585 (~(CHANNEL_UNBUFFERED|CHANNEL_LINEBUFFERED));
6586 } else if ((newValue[0] == 'l') &&
6587 (strncmp(newValue, "line", len) == 0)) {
6588 statePtr->flags &= (~(CHANNEL_UNBUFFERED));
6589 statePtr->flags |= CHANNEL_LINEBUFFERED;
6590 } else if ((newValue[0] == 'n') &&
6591 (strncmp(newValue, "none", len) == 0)) {
6592 statePtr->flags &= (~(CHANNEL_LINEBUFFERED));
6593 statePtr->flags |= CHANNEL_UNBUFFERED;
6596 Tcl_AppendResult(interp, "bad value for -buffering: ",
6597 "must be one of full, line, or none",
6603 } else if ((len > 7) && (optionName[1] == 'b') &&
6604 (strncmp(optionName, "-buffersize", len) == 0)) {
6606 if (Tcl_GetInt(interp, newValue, &newBufferSize) == TCL_ERROR) {
6609 Tcl_SetChannelBufferSize(chan, newBufferSize);
6610 } else if ((len > 2) && (optionName[1] == 'e') &&
6611 (strncmp(optionName, "-encoding", len) == 0)) {
6612 Tcl_Encoding encoding;
6614 if ((newValue[0] == '\0') || (strcmp(newValue, "binary") == 0)) {
6617 encoding = Tcl_GetEncoding(interp, newValue);
6618 if (encoding == NULL) {
6623 * When the channel has an escape sequence driven encoding such as
6624 * iso2022, the terminated escape sequence must write to the buffer.
6626 if ((statePtr->encoding != NULL) && (statePtr->curOutPtr != NULL)
6627 && (CheckChannelErrors(statePtr, TCL_WRITABLE) == 0)) {
6628 statePtr->outputEncodingFlags |= TCL_ENCODING_END;
6629 WriteChars(chanPtr, "", 0);
6631 Tcl_FreeEncoding(statePtr->encoding);
6632 statePtr->encoding = encoding;
6633 statePtr->inputEncodingState = NULL;
6634 statePtr->inputEncodingFlags = TCL_ENCODING_START;
6635 statePtr->outputEncodingState = NULL;
6636 statePtr->outputEncodingFlags = TCL_ENCODING_START;
6637 statePtr->flags &= ~CHANNEL_NEED_MORE_DATA;
6638 UpdateInterest(chanPtr);
6639 } else if ((len > 2) && (optionName[1] == 'e') &&
6640 (strncmp(optionName, "-eofchar", len) == 0)) {
6641 if (Tcl_SplitList(interp, newValue, &argc, &argv) == TCL_ERROR) {
6645 statePtr->inEofChar = 0;
6646 statePtr->outEofChar = 0;
6647 } else if (argc == 1) {
6648 if (statePtr->flags & TCL_WRITABLE) {
6649 statePtr->outEofChar = (int) argv[0][0];
6651 if (statePtr->flags & TCL_READABLE) {
6652 statePtr->inEofChar = (int) argv[0][0];
6654 } else if (argc != 2) {
6656 Tcl_AppendResult(interp,
6657 "bad value for -eofchar: should be a list of zero,",
6658 " one, or two elements", (char *) NULL);
6660 ckfree((char *) argv);
6663 if (statePtr->flags & TCL_READABLE) {
6664 statePtr->inEofChar = (int) argv[0][0];
6666 if (statePtr->flags & TCL_WRITABLE) {
6667 statePtr->outEofChar = (int) argv[1][0];
6671 ckfree((char *) argv);
6675 * [SF Tcl Bug 930851] Reset EOF and BLOCKED flags. Changing
6676 * the character which signals eof can transform a current eof
6677 * condition into a 'go ahead'. Ditto for blocked.
6680 statePtr->flags &= (~(CHANNEL_EOF | CHANNEL_STICKY_EOF | CHANNEL_BLOCKED));
6683 } else if ((len > 1) && (optionName[1] == 't') &&
6684 (strncmp(optionName, "-translation", len) == 0)) {
6685 CONST char *readMode, *writeMode;
6687 if (Tcl_SplitList(interp, newValue, &argc, &argv) == TCL_ERROR) {
6692 readMode = (statePtr->flags & TCL_READABLE) ? argv[0] : NULL;
6693 writeMode = (statePtr->flags & TCL_WRITABLE) ? argv[0] : NULL;
6694 } else if (argc == 2) {
6695 readMode = (statePtr->flags & TCL_READABLE) ? argv[0] : NULL;
6696 writeMode = (statePtr->flags & TCL_WRITABLE) ? argv[1] : NULL;
6699 Tcl_AppendResult(interp,
6700 "bad value for -translation: must be a one or two",
6701 " element list", (char *) NULL);
6703 ckfree((char *) argv);
6708 TclEolTranslation translation;
6709 if (*readMode == '\0') {
6710 translation = statePtr->inputTranslation;
6711 } else if (strcmp(readMode, "auto") == 0) {
6712 translation = TCL_TRANSLATE_AUTO;
6713 } else if (strcmp(readMode, "binary") == 0) {
6714 translation = TCL_TRANSLATE_LF;
6715 statePtr->inEofChar = 0;
6716 Tcl_FreeEncoding(statePtr->encoding);
6717 statePtr->encoding = NULL;
6718 } else if (strcmp(readMode, "lf") == 0) {
6719 translation = TCL_TRANSLATE_LF;
6720 } else if (strcmp(readMode, "cr") == 0) {
6721 translation = TCL_TRANSLATE_CR;
6722 } else if (strcmp(readMode, "crlf") == 0) {
6723 translation = TCL_TRANSLATE_CRLF;
6724 } else if (strcmp(readMode, "platform") == 0) {
6725 translation = TCL_PLATFORM_TRANSLATION;
6728 Tcl_AppendResult(interp,
6729 "bad value for -translation: ",
6730 "must be one of auto, binary, cr, lf, crlf,",
6731 " or platform", (char *) NULL);
6733 ckfree((char *) argv);
6738 * Reset the EOL flags since we need to look at any buffered
6739 * data to see if the new translation mode allows us to
6740 * complete the line.
6743 if (translation != statePtr->inputTranslation) {
6744 statePtr->inputTranslation = translation;
6745 statePtr->flags &= ~(INPUT_SAW_CR);
6746 statePtr->flags &= ~(CHANNEL_NEED_MORE_DATA);
6747 UpdateInterest(chanPtr);
6751 if (*writeMode == '\0') {
6753 } else if (strcmp(writeMode, "auto") == 0) {
6755 * This is a hack to get TCP sockets to produce output
6756 * in CRLF mode if they are being set into AUTO mode.
6757 * A better solution for achieving this effect will be
6761 if (strcmp(Tcl_ChannelName(chanPtr->typePtr), "tcp") == 0) {
6762 statePtr->outputTranslation = TCL_TRANSLATE_CRLF;
6764 statePtr->outputTranslation = TCL_PLATFORM_TRANSLATION;
6766 } else if (strcmp(writeMode, "binary") == 0) {
6767 statePtr->outEofChar = 0;
6768 statePtr->outputTranslation = TCL_TRANSLATE_LF;
6769 Tcl_FreeEncoding(statePtr->encoding);
6770 statePtr->encoding = NULL;
6771 } else if (strcmp(writeMode, "lf") == 0) {
6772 statePtr->outputTranslation = TCL_TRANSLATE_LF;
6773 } else if (strcmp(writeMode, "cr") == 0) {
6774 statePtr->outputTranslation = TCL_TRANSLATE_CR;
6775 } else if (strcmp(writeMode, "crlf") == 0) {
6776 statePtr->outputTranslation = TCL_TRANSLATE_CRLF;
6777 } else if (strcmp(writeMode, "platform") == 0) {
6778 statePtr->outputTranslation = TCL_PLATFORM_TRANSLATION;
6781 Tcl_AppendResult(interp,
6782 "bad value for -translation: ",
6783 "must be one of auto, binary, cr, lf, crlf,",
6784 " or platform", (char *) NULL);
6786 ckfree((char *) argv);
6790 ckfree((char *) argv);
6792 } else if (chanPtr->typePtr->setOptionProc != NULL) {
6793 return (*chanPtr->typePtr->setOptionProc)(chanPtr->instanceData,
6794 interp, optionName, newValue);
6796 return Tcl_BadChannelOption(interp, optionName, (char *) NULL);
6800 * If bufsize changes, need to get rid of old utility buffer.
6803 if (statePtr->saveInBufPtr != NULL) {
6804 RecycleBuffer(statePtr, statePtr->saveInBufPtr, 1);
6805 statePtr->saveInBufPtr = NULL;
6807 if (statePtr->inQueueHead != NULL) {
6808 if ((statePtr->inQueueHead->nextPtr == NULL)
6809 && (statePtr->inQueueHead->nextAdded ==
6810 statePtr->inQueueHead->nextRemoved)) {
6811 RecycleBuffer(statePtr, statePtr->inQueueHead, 1);
6812 statePtr->inQueueHead = NULL;
6813 statePtr->inQueueTail = NULL;
6818 * If encoding or bufsize changes, need to update output staging buffer.
6821 if (statePtr->outputStage != NULL) {
6822 ckfree((char *) statePtr->outputStage);
6823 statePtr->outputStage = NULL;
6825 if ((statePtr->encoding != NULL) && (statePtr->flags & TCL_WRITABLE)) {
6826 statePtr->outputStage = (char *)
6827 ckalloc((unsigned) (statePtr->bufSize + 2));
6833 *----------------------------------------------------------------------
6835 * CleanupChannelHandlers --
6837 * Removes channel handlers that refer to the supplied interpreter,
6838 * so that if the actual channel is not closed now, these handlers
6839 * will not run on subsequent events on the channel. This would be
6840 * erroneous, because the interpreter no longer has a reference to
6847 * Removes channel handlers.
6849 *----------------------------------------------------------------------
6853 CleanupChannelHandlers(interp, chanPtr)
6857 ChannelState *statePtr = chanPtr->state; /* state info for channel */
6858 EventScriptRecord *sPtr, *prevPtr, *nextPtr;
6861 * Remove fileevent records on this channel that refer to the
6862 * given interpreter.
6865 for (sPtr = statePtr->scriptRecordPtr,
6866 prevPtr = (EventScriptRecord *) NULL;
6867 sPtr != (EventScriptRecord *) NULL;
6869 nextPtr = sPtr->nextPtr;
6870 if (sPtr->interp == interp) {
6871 if (prevPtr == (EventScriptRecord *) NULL) {
6872 statePtr->scriptRecordPtr = nextPtr;
6874 prevPtr->nextPtr = nextPtr;
6877 Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
6878 TclChannelEventScriptInvoker, (ClientData) sPtr);
6880 Tcl_DecrRefCount(sPtr->scriptPtr);
6881 ckfree((char *) sPtr);
6889 *----------------------------------------------------------------------
6891 * Tcl_NotifyChannel --
6893 * This procedure is called by a channel driver when a driver
6894 * detects an event on a channel. This procedure is responsible
6895 * for actually handling the event by invoking any channel
6896 * handler callbacks.
6902 * Whatever the channel handler callback procedure does.
6904 *----------------------------------------------------------------------
6908 Tcl_NotifyChannel(channel, mask)
6909 Tcl_Channel channel; /* Channel that detected an event. */
6910 int mask; /* OR'ed combination of TCL_READABLE,
6911 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
6912 * which events were detected. */
6914 Channel *chanPtr = (Channel *) channel;
6915 ChannelState *statePtr = chanPtr->state; /* state info for channel */
6916 ChannelHandler *chPtr;
6917 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
6918 NextChannelHandler nh;
6920 Tcl_ChannelType* upTypePtr;
6922 #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
6923 /* [SF Tcl Bug 943274]
6924 * For a non-blocking channel without blockmodeproc we keep track
6925 * of actual input coming from the OS so that we can do a credible
6926 * imitation of non-blocking behaviour.
6929 if ((mask & TCL_READABLE) &&
6930 (statePtr->flags & CHANNEL_NONBLOCKING) &&
6931 (Tcl_ChannelBlockModeProc(chanPtr->typePtr) == NULL) &&
6932 !(statePtr->flags & CHANNEL_TIMER_FEV)) {
6934 statePtr->flags |= CHANNEL_HAS_MORE_DATA;
6936 #endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
6939 * In contrast to the other API functions this procedure walks towards
6940 * the top of a stack and not down from it.
6942 * The channel calling this procedure is the one who generated the event,
6943 * and thus does not take part in handling it. IOW, its HandlerProc is
6944 * not called, instead we begin with the channel above it.
6946 * This behaviour also allows the transformation channels to
6947 * generate their own events and pass them upward.
6950 while (mask && (chanPtr->upChanPtr != ((Channel*) NULL))) {
6951 Tcl_DriverHandlerProc* upHandlerProc;
6953 upChanPtr = chanPtr->upChanPtr;
6954 upTypePtr = upChanPtr->typePtr;
6955 upHandlerProc = Tcl_ChannelHandlerProc(upTypePtr);
6956 if (upHandlerProc != NULL) {
6957 mask = (*upHandlerProc) (upChanPtr->instanceData, mask);
6961 * Ignore transformations which are unable to handle the event
6962 * coming from below. Assume that they don't change the mask and
6966 chanPtr = upChanPtr;
6969 channel = (Tcl_Channel) chanPtr;
6972 * Here we have either reached the top of the stack or the mask is
6973 * empty. We break out of the procedure if it is the latter.
6981 * We are now above the topmost channel in a stack and have events
6982 * left. Now call the channel handlers as usual.
6984 * Preserve the channel struct in case the script closes it.
6987 Tcl_Preserve((ClientData) channel);
6988 Tcl_Preserve((ClientData) statePtr);
6991 * If we are flushing in the background, be sure to call FlushChannel
6992 * for writable events. Note that we have to discard the writable
6993 * event so we don't call any write handlers before the flush is
6997 if ((statePtr->flags & BG_FLUSH_SCHEDULED) && (mask & TCL_WRITABLE)) {
6998 FlushChannel(NULL, chanPtr, 1);
6999 mask &= ~TCL_WRITABLE;
7003 * Add this invocation to the list of recursive invocations of
7004 * ChannelHandlerEventProc.
7007 nh.nextHandlerPtr = (ChannelHandler *) NULL;
7008 nh.nestedHandlerPtr = tsdPtr->nestedHandlerPtr;
7009 tsdPtr->nestedHandlerPtr = &nh;
7011 for (chPtr = statePtr->chPtr; chPtr != (ChannelHandler *) NULL; ) {
7013 * If this channel handler is interested in any of the events that
7014 * have occurred on the channel, invoke its procedure.
7017 if ((chPtr->mask & mask) != 0) {
7018 nh.nextHandlerPtr = chPtr->nextPtr;
7019 (*(chPtr->proc))(chPtr->clientData, mask);
7020 chPtr = nh.nextHandlerPtr;
7022 chPtr = chPtr->nextPtr;
7027 * Update the notifier interest, since it may have changed after
7028 * invoking event handlers. Skip that if the channel was deleted
7029 * in the call to the channel handler.
7032 if (chanPtr->typePtr != NULL) {
7033 UpdateInterest(chanPtr);
7036 Tcl_Release((ClientData) statePtr);
7037 Tcl_Release((ClientData) channel);
7039 tsdPtr->nestedHandlerPtr = nh.nestedHandlerPtr;
7043 *----------------------------------------------------------------------
7047 * Arrange for the notifier to call us back at appropriate times
7048 * based on the current state of the channel.
7054 * May schedule a timer or driver handler.
7056 *----------------------------------------------------------------------
7060 UpdateInterest(chanPtr)
7061 Channel *chanPtr; /* Channel to update. */
7063 ChannelState *statePtr = chanPtr->state; /* state info for channel */
7064 int mask = statePtr->interestMask;
7067 * If there are flushed buffers waiting to be written, then
7068 * we need to watch for the channel to become writable.
7071 if (statePtr->flags & BG_FLUSH_SCHEDULED) {
7072 mask |= TCL_WRITABLE;
7076 * If there is data in the input queue, and we aren't waiting for more
7077 * data, then we need to schedule a timer so we don't block in the
7078 * notifier. Also, cancel the read interest so we don't get duplicate
7082 if (mask & TCL_READABLE) {
7083 if (!(statePtr->flags & CHANNEL_NEED_MORE_DATA)
7084 && (statePtr->inQueueHead != (ChannelBuffer *) NULL)
7085 && (statePtr->inQueueHead->nextRemoved <
7086 statePtr->inQueueHead->nextAdded)) {
7087 mask &= ~TCL_READABLE;
7090 * Andreas Kupries, April 11, 2003
7092 * Some operating systems (Solaris 2.6 and higher (but not
7093 * Solaris 2.5, go figure)) generate READABLE and
7094 * EXCEPTION events when select()'ing [*] on a plain file,
7095 * even if EOF was not yet reached. This is a problem in
7096 * the following situation:
7098 * - An extension asks to get both READABLE and EXCEPTION
7100 * - It reads data into a buffer smaller than the buffer
7101 * used by Tcl itself.
7102 * - It does not process all events in the event queue, but
7103 * only only one, at least in some situations.
7105 * In that case we can get into a situation where
7107 * - Tcl drops READABLE here, because it has data in its own
7108 * buffers waiting to be read by the extension.
7109 * - A READABLE event is syntesized via timer.
7110 * - The OS still reports the EXCEPTION condition on the file.
7111 * - And the extension gets the EXCPTION event first, and
7112 * handles this as EOF.
7114 * End result ==> Premature end of reading from a file.
7116 * The concrete example is 'Expect', and its [expect]
7117 * command (and at the C-level, deep in the bowels of
7118 * Expect, 'exp_get_next_event'. See marker 'SunOS' for
7119 * commentary in that function too).
7121 * [*] As the Tcl notifier does. See also for marker
7122 * 'SunOS' in file 'exp_event.c' of Expect.
7124 * Our solution here is to drop the interest in the
7125 * EXCEPTION events too. This compiles on all platforms,
7126 * and also passes the testsuite on all of them.
7129 mask &= ~TCL_EXCEPTION;
7131 if (!statePtr->timer) {
7132 statePtr->timer = Tcl_CreateTimerHandler(0, ChannelTimerProc,
7133 (ClientData) chanPtr);
7137 (chanPtr->typePtr->watchProc)(chanPtr->instanceData, mask);
7141 *----------------------------------------------------------------------
7143 * ChannelTimerProc --
7145 * Timer handler scheduled by UpdateInterest to monitor the
7146 * channel buffers until they are empty.
7152 * May invoke channel handlers.
7154 *----------------------------------------------------------------------
7158 ChannelTimerProc(clientData)
7159 ClientData clientData;
7161 Channel *chanPtr = (Channel *) clientData;
7162 ChannelState *statePtr = chanPtr->state; /* state info for channel */
7164 if (!(statePtr->flags & CHANNEL_NEED_MORE_DATA)
7165 && (statePtr->interestMask & TCL_READABLE)
7166 && (statePtr->inQueueHead != (ChannelBuffer *) NULL)
7167 && (statePtr->inQueueHead->nextRemoved <
7168 statePtr->inQueueHead->nextAdded)) {
7170 * Restart the timer in case a channel handler reenters the
7171 * event loop before UpdateInterest gets called by Tcl_NotifyChannel.
7174 statePtr->timer = Tcl_CreateTimerHandler(0, ChannelTimerProc,
7175 (ClientData) chanPtr);
7177 #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
7178 /* Set the TIMER flag to notify the higher levels that the
7179 * driver might have no data for us. We do this only if we are
7180 * in non-blocking mode and the driver has no BlockModeProc
7181 * because only then we really don't know if the driver will
7182 * block or not. A similar test is done in "PeekAhead".
7185 if ((statePtr->flags & CHANNEL_NONBLOCKING) &&
7186 (Tcl_ChannelBlockModeProc(chanPtr->typePtr) == NULL)) {
7187 statePtr->flags |= CHANNEL_TIMER_FEV;
7189 #endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
7191 Tcl_Preserve((ClientData) statePtr);
7192 Tcl_NotifyChannel((Tcl_Channel)chanPtr, TCL_READABLE);
7194 #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
7195 statePtr->flags &= ~CHANNEL_TIMER_FEV;
7196 #endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
7198 Tcl_Release((ClientData) statePtr);
7200 statePtr->timer = NULL;
7201 UpdateInterest(chanPtr);
7206 *----------------------------------------------------------------------
7208 * Tcl_CreateChannelHandler --
7210 * Arrange for a given procedure to be invoked whenever the
7211 * channel indicated by the chanPtr arg becomes readable or
7218 * From now on, whenever the I/O channel given by chanPtr becomes
7219 * ready in the way indicated by mask, proc will be invoked.
7220 * See the manual entry for details on the calling sequence
7221 * to proc. If there is already an event handler for chan, proc
7222 * and clientData, then the mask will be updated.
7224 *----------------------------------------------------------------------
7228 Tcl_CreateChannelHandler(chan, mask, proc, clientData)
7229 Tcl_Channel chan; /* The channel to create the handler for. */
7230 int mask; /* OR'ed combination of TCL_READABLE,
7231 * TCL_WRITABLE, and TCL_EXCEPTION:
7232 * indicates conditions under which
7233 * proc should be called. Use 0 to
7234 * disable a registered handler. */
7235 Tcl_ChannelProc *proc; /* Procedure to call for each
7236 * selected event. */
7237 ClientData clientData; /* Arbitrary data to pass to proc. */
7239 ChannelHandler *chPtr;
7240 Channel *chanPtr = (Channel *) chan;
7241 ChannelState *statePtr = chanPtr->state; /* state info for channel */
7244 * Check whether this channel handler is not already registered. If
7245 * it is not, create a new record, else reuse existing record (smash
7249 for (chPtr = statePtr->chPtr;
7250 chPtr != (ChannelHandler *) NULL;
7251 chPtr = chPtr->nextPtr) {
7252 if ((chPtr->chanPtr == chanPtr) && (chPtr->proc == proc) &&
7253 (chPtr->clientData == clientData)) {
7257 if (chPtr == (ChannelHandler *) NULL) {
7258 chPtr = (ChannelHandler *) ckalloc((unsigned) sizeof(ChannelHandler));
7261 chPtr->clientData = clientData;
7262 chPtr->chanPtr = chanPtr;
7263 chPtr->nextPtr = statePtr->chPtr;
7264 statePtr->chPtr = chPtr;
7268 * The remainder of the initialization below is done regardless of
7269 * whether or not this is a new record or a modification of an old
7276 * Recompute the interest mask for the channel - this call may actually
7277 * be disabling an existing handler.
7280 statePtr->interestMask = 0;
7281 for (chPtr = statePtr->chPtr;
7282 chPtr != (ChannelHandler *) NULL;
7283 chPtr = chPtr->nextPtr) {
7284 statePtr->interestMask |= chPtr->mask;
7287 UpdateInterest(statePtr->topChanPtr);
7291 *----------------------------------------------------------------------
7293 * Tcl_DeleteChannelHandler --
7295 * Cancel a previously arranged callback arrangement for an IO
7302 * If a callback was previously registered for this chan, proc and
7303 * clientData , it is removed and the callback will no longer be called
7304 * when the channel becomes ready for IO.
7306 *----------------------------------------------------------------------
7310 Tcl_DeleteChannelHandler(chan, proc, clientData)
7311 Tcl_Channel chan; /* The channel for which to remove the
7313 Tcl_ChannelProc *proc; /* The procedure in the callback to delete. */
7314 ClientData clientData; /* The client data in the callback
7318 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
7319 ChannelHandler *chPtr, *prevChPtr;
7320 Channel *chanPtr = (Channel *) chan;
7321 ChannelState *statePtr = chanPtr->state; /* state info for channel */
7322 NextChannelHandler *nhPtr;
7325 * Find the entry and the previous one in the list.
7328 for (prevChPtr = (ChannelHandler *) NULL, chPtr = statePtr->chPtr;
7329 chPtr != (ChannelHandler *) NULL;
7330 chPtr = chPtr->nextPtr) {
7331 if ((chPtr->chanPtr == chanPtr) && (chPtr->clientData == clientData)
7332 && (chPtr->proc == proc)) {
7339 * If not found, return without doing anything.
7342 if (chPtr == (ChannelHandler *) NULL) {
7347 * If ChannelHandlerEventProc is about to process this handler, tell it to
7348 * process the next one instead - we are going to delete *this* one.
7351 for (nhPtr = tsdPtr->nestedHandlerPtr;
7352 nhPtr != (NextChannelHandler *) NULL;
7353 nhPtr = nhPtr->nestedHandlerPtr) {
7354 if (nhPtr->nextHandlerPtr == chPtr) {
7355 nhPtr->nextHandlerPtr = chPtr->nextPtr;
7360 * Splice it out of the list of channel handlers.
7363 if (prevChPtr == (ChannelHandler *) NULL) {
7364 statePtr->chPtr = chPtr->nextPtr;
7366 prevChPtr->nextPtr = chPtr->nextPtr;
7368 ckfree((char *) chPtr);
7371 * Recompute the interest list for the channel, so that infinite loops
7372 * will not result if Tcl_DeleteChannelHandler is called inside an
7376 statePtr->interestMask = 0;
7377 for (chPtr = statePtr->chPtr;
7378 chPtr != (ChannelHandler *) NULL;
7379 chPtr = chPtr->nextPtr) {
7380 statePtr->interestMask |= chPtr->mask;
7383 UpdateInterest(statePtr->topChanPtr);
7387 *----------------------------------------------------------------------
7389 * DeleteScriptRecord --
7391 * Delete a script record for this combination of channel, interp
7398 * Deletes a script record and cancels a channel event handler.
7400 *----------------------------------------------------------------------
7404 DeleteScriptRecord(interp, chanPtr, mask)
7405 Tcl_Interp *interp; /* Interpreter in which script was to be
7407 Channel *chanPtr; /* The channel for which to delete the
7408 * script record (if any). */
7409 int mask; /* Events in mask must exactly match mask
7410 * of script to delete. */
7412 ChannelState *statePtr = chanPtr->state; /* state info for channel */
7413 EventScriptRecord *esPtr, *prevEsPtr;
7415 for (esPtr = statePtr->scriptRecordPtr,
7416 prevEsPtr = (EventScriptRecord *) NULL;
7417 esPtr != (EventScriptRecord *) NULL;
7418 prevEsPtr = esPtr, esPtr = esPtr->nextPtr) {
7419 if ((esPtr->interp == interp) && (esPtr->mask == mask)) {
7420 if (esPtr == statePtr->scriptRecordPtr) {
7421 statePtr->scriptRecordPtr = esPtr->nextPtr;
7423 prevEsPtr->nextPtr = esPtr->nextPtr;
7426 Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
7427 TclChannelEventScriptInvoker, (ClientData) esPtr);
7429 Tcl_DecrRefCount(esPtr->scriptPtr);
7430 ckfree((char *) esPtr);
7438 *----------------------------------------------------------------------
7440 * CreateScriptRecord --
7442 * Creates a record to store a script to be executed when a specific
7443 * event fires on a specific channel.
7449 * Causes the script to be stored for later execution.
7451 *----------------------------------------------------------------------
7455 CreateScriptRecord(interp, chanPtr, mask, scriptPtr)
7456 Tcl_Interp *interp; /* Interpreter in which to execute
7457 * the stored script. */
7458 Channel *chanPtr; /* Channel for which script is to
7460 int mask; /* Set of events for which script
7461 * will be invoked. */
7462 Tcl_Obj *scriptPtr; /* Pointer to script object. */
7464 ChannelState *statePtr = chanPtr->state; /* state info for channel */
7465 EventScriptRecord *esPtr;
7467 for (esPtr = statePtr->scriptRecordPtr;
7468 esPtr != (EventScriptRecord *) NULL;
7469 esPtr = esPtr->nextPtr) {
7470 if ((esPtr->interp == interp) && (esPtr->mask == mask)) {
7471 Tcl_DecrRefCount(esPtr->scriptPtr);
7472 esPtr->scriptPtr = (Tcl_Obj *) NULL;
7476 if (esPtr == (EventScriptRecord *) NULL) {
7477 esPtr = (EventScriptRecord *) ckalloc((unsigned)
7478 sizeof(EventScriptRecord));
7479 Tcl_CreateChannelHandler((Tcl_Channel) chanPtr, mask,
7480 TclChannelEventScriptInvoker, (ClientData) esPtr);
7481 esPtr->nextPtr = statePtr->scriptRecordPtr;
7482 statePtr->scriptRecordPtr = esPtr;
7484 esPtr->chanPtr = chanPtr;
7485 esPtr->interp = interp;
7487 Tcl_IncrRefCount(scriptPtr);
7488 esPtr->scriptPtr = scriptPtr;
7492 *----------------------------------------------------------------------
7494 * TclChannelEventScriptInvoker --
7496 * Invokes a script scheduled by "fileevent" for when the channel
7497 * becomes ready for IO. This function is invoked by the channel
7498 * handler which was created by the Tcl "fileevent" command.
7504 * Whatever the script does.
7506 *----------------------------------------------------------------------
7510 TclChannelEventScriptInvoker(clientData, mask)
7511 ClientData clientData; /* The script+interp record. */
7512 int mask; /* Not used. */
7514 Tcl_Interp *interp; /* Interpreter in which to eval the script. */
7515 Channel *chanPtr; /* The channel for which this handler is
7517 EventScriptRecord *esPtr; /* The event script + interpreter to eval it
7519 int result; /* Result of call to eval script. */
7521 esPtr = (EventScriptRecord *) clientData;
7522 chanPtr = esPtr->chanPtr;
7524 interp = esPtr->interp;
7527 * We must preserve the interpreter so we can report errors on it
7528 * later. Note that we do not need to preserve the channel because
7529 * that is done by Tcl_NotifyChannel before calling channel handlers.
7532 Tcl_Preserve((ClientData) interp);
7533 result = Tcl_EvalObjEx(interp, esPtr->scriptPtr, TCL_EVAL_GLOBAL);
7536 * On error, cause a background error and remove the channel handler
7537 * and the script record.
7539 * NOTE: Must delete channel handler before causing the background error
7540 * because the background error may want to reinstall the handler.
7543 if (result != TCL_OK) {
7544 if (chanPtr->typePtr != NULL) {
7545 DeleteScriptRecord(interp, chanPtr, mask);
7547 Tcl_BackgroundError(interp);
7549 Tcl_Release((ClientData) interp);
7553 *----------------------------------------------------------------------
7555 * Tcl_FileEventObjCmd --
7557 * This procedure implements the "fileevent" Tcl command. See the
7558 * user documentation for details on what it does. This command is
7559 * based on the Tk command "fileevent" which in turn is based on work
7560 * contributed by Mark Diekhans.
7563 * A standard Tcl result.
7566 * May create a channel handler for the specified channel.
7568 *----------------------------------------------------------------------
7573 Tcl_FileEventObjCmd(clientData, interp, objc, objv)
7574 ClientData clientData; /* Not used. */
7575 Tcl_Interp *interp; /* Interpreter in which the channel
7576 * for which to create the handler
7578 int objc; /* Number of arguments. */
7579 Tcl_Obj *CONST objv[]; /* Argument objects. */
7581 Channel *chanPtr; /* The channel to create
7582 * the handler for. */
7583 ChannelState *statePtr; /* state info for channel */
7584 Tcl_Channel chan; /* The opaque type for the channel. */
7586 int modeIndex; /* Index of mode argument. */
7588 static CONST char *modeOptions[] = {"readable", "writable", NULL};
7589 static int maskArray[] = {TCL_READABLE, TCL_WRITABLE};
7591 if ((objc != 3) && (objc != 4)) {
7592 Tcl_WrongNumArgs(interp, 1, objv, "channelId event ?script?");
7595 if (Tcl_GetIndexFromObj(interp, objv[2], modeOptions, "event name", 0,
7596 &modeIndex) != TCL_OK) {
7599 mask = maskArray[modeIndex];
7601 chanName = Tcl_GetString(objv[1]);
7602 chan = Tcl_GetChannel(interp, chanName, NULL);
7603 if (chan == (Tcl_Channel) NULL) {
7606 chanPtr = (Channel *) chan;
7607 statePtr = chanPtr->state;
7608 if ((statePtr->flags & mask) == 0) {
7609 Tcl_AppendResult(interp, "channel is not ",
7610 (mask == TCL_READABLE) ? "readable" : "writable",
7616 * If we are supposed to return the script, do so.
7620 EventScriptRecord *esPtr;
7621 for (esPtr = statePtr->scriptRecordPtr;
7622 esPtr != (EventScriptRecord *) NULL;
7623 esPtr = esPtr->nextPtr) {
7624 if ((esPtr->interp == interp) && (esPtr->mask == mask)) {
7625 Tcl_SetObjResult(interp, esPtr->scriptPtr);
7633 * If we are supposed to delete a stored script, do so.
7636 if (*(Tcl_GetString(objv[3])) == '\0') {
7637 DeleteScriptRecord(interp, chanPtr, mask);
7642 * Make the script record that will link between the event and the
7643 * script to invoke. This also creates a channel event handler which
7644 * will evaluate the script in the supplied interpreter.
7647 CreateScriptRecord(interp, chanPtr, mask, objv[3]);
7653 *----------------------------------------------------------------------
7657 * This routine copies data from one channel to another, either
7658 * synchronously or asynchronously. If a command script is
7659 * supplied, the operation runs in the background. The script
7660 * is invoked when the copy completes. Otherwise the function
7661 * waits until the copy is completed before returning.
7664 * A standard Tcl result.
7667 * May schedule a background copy operation that causes both
7668 * channels to be marked busy.
7670 *----------------------------------------------------------------------
7674 TclCopyChannel(interp, inChan, outChan, toRead, cmdPtr)
7675 Tcl_Interp *interp; /* Current interpreter. */
7676 Tcl_Channel inChan; /* Channel to read from. */
7677 Tcl_Channel outChan; /* Channel to write to. */
7678 int toRead; /* Amount of data to copy, or -1 for all. */
7679 Tcl_Obj *cmdPtr; /* Pointer to script to execute or NULL. */
7681 Channel *inPtr = (Channel *) inChan;
7682 Channel *outPtr = (Channel *) outChan;
7683 ChannelState *inStatePtr, *outStatePtr;
7684 int readFlags, writeFlags;
7686 int nonBlocking = (cmdPtr) ? CHANNEL_NONBLOCKING : 0;
7688 inStatePtr = inPtr->state;
7689 outStatePtr = outPtr->state;
7691 if (inStatePtr->csPtr) {
7693 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"",
7694 Tcl_GetChannelName(inChan), "\" is busy", NULL);
7698 if (outStatePtr->csPtr) {
7700 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"",
7701 Tcl_GetChannelName(outChan), "\" is busy", NULL);
7706 readFlags = inStatePtr->flags;
7707 writeFlags = outStatePtr->flags;
7710 * Set up the blocking mode appropriately. Background copies need
7711 * non-blocking channels. Foreground copies need blocking channels.
7712 * If there is an error, restore the old blocking mode.
7715 if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) {
7716 if (SetBlockMode(interp, inPtr,
7717 nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING)
7722 if (inPtr != outPtr) {
7723 if (nonBlocking != (writeFlags & CHANNEL_NONBLOCKING)) {
7724 if (SetBlockMode(NULL, outPtr,
7725 nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING)
7727 if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) {
7728 SetBlockMode(NULL, inPtr,
7729 (readFlags & CHANNEL_NONBLOCKING)
7730 ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING);
7738 * Make sure the output side is unbuffered.
7741 outStatePtr->flags = (outStatePtr->flags & ~(CHANNEL_LINEBUFFERED))
7742 | CHANNEL_UNBUFFERED;
7745 * Allocate a new CopyState to maintain info about the current copy in
7746 * progress. This structure will be deallocated when the copy is
7750 csPtr = (CopyState*) ckalloc(sizeof(CopyState) + inStatePtr->bufSize);
7751 csPtr->bufSize = inStatePtr->bufSize;
7752 csPtr->readPtr = inPtr;
7753 csPtr->writePtr = outPtr;
7754 csPtr->readFlags = readFlags;
7755 csPtr->writeFlags = writeFlags;
7756 csPtr->toRead = toRead;
7758 csPtr->interp = interp;
7760 Tcl_IncrRefCount(cmdPtr);
7762 csPtr->cmdPtr = cmdPtr;
7763 inStatePtr->csPtr = csPtr;
7764 outStatePtr->csPtr = csPtr;
7767 * Start copying data between the channels.
7770 return CopyData(csPtr, 0);
7774 *----------------------------------------------------------------------
7778 * This function implements the lowest level of the copying
7779 * mechanism for TclCopyChannel.
7782 * Returns TCL_OK on success, else TCL_ERROR.
7785 * Moves data between channels, may create channel handlers.
7787 *----------------------------------------------------------------------
7791 CopyData(csPtr, mask)
7792 CopyState *csPtr; /* State of copy operation. */
7793 int mask; /* Current channel event flags. */
7796 Tcl_Obj *cmdPtr, *errObj = NULL, *bufObj = NULL;
7797 Tcl_Channel inChan, outChan;
7798 ChannelState *inStatePtr, *outStatePtr;
7799 int result = TCL_OK, size, total, sizeb;
7802 int inBinary, outBinary, sameEncoding; /* Encoding control */
7803 int underflow; /* input underflow */
7805 inChan = (Tcl_Channel) csPtr->readPtr;
7806 outChan = (Tcl_Channel) csPtr->writePtr;
7807 inStatePtr = csPtr->readPtr->state;
7808 outStatePtr = csPtr->writePtr->state;
7809 interp = csPtr->interp;
7810 cmdPtr = csPtr->cmdPtr;
7813 * Copy the data the slow way, using the translation mechanism.
7815 * Note: We have make sure that we use the topmost channel in a stack
7816 * for the copying. The caller uses Tcl_GetChannel to access it, and
7817 * thus gets the bottom of the stack.
7820 inBinary = (inStatePtr->encoding == NULL);
7821 outBinary = (outStatePtr->encoding == NULL);
7822 sameEncoding = (inStatePtr->encoding == outStatePtr->encoding);
7824 if (!(inBinary || sameEncoding)) {
7825 bufObj = Tcl_NewObj ();
7826 Tcl_IncrRefCount (bufObj);
7829 while (csPtr->toRead != 0) {
7831 * Check for unreported background errors.
7834 if (inStatePtr->unreportedError != 0) {
7835 Tcl_SetErrno(inStatePtr->unreportedError);
7836 inStatePtr->unreportedError = 0;
7839 if (outStatePtr->unreportedError != 0) {
7840 Tcl_SetErrno(outStatePtr->unreportedError);
7841 outStatePtr->unreportedError = 0;
7846 * Read up to bufSize bytes.
7849 if ((csPtr->toRead == -1) || (csPtr->toRead > csPtr->bufSize)) {
7850 sizeb = csPtr->bufSize;
7852 sizeb = csPtr->toRead;
7855 if (inBinary || sameEncoding) {
7856 size = DoRead(inStatePtr->topChanPtr, csPtr->buffer, sizeb);
7858 size = DoReadChars(inStatePtr->topChanPtr, bufObj, sizeb, 0 /* No append */);
7860 underflow = (size >= 0) && (size < sizeb); /* input underflow */
7864 errObj = Tcl_NewObj();
7865 Tcl_AppendStringsToObj(errObj, "error reading \"",
7866 Tcl_GetChannelName(inChan), "\": ",
7867 Tcl_PosixError(interp), (char *) NULL);
7869 } else if (underflow) {
7871 * We had an underflow on the read side. If we are at EOF,
7872 * then the copying is done, otherwise set up a channel
7873 * handler to detect when the channel becomes readable again.
7876 if ((size == 0) && Tcl_Eof(inChan)) {
7879 if (! Tcl_Eof(inChan) && !(mask & TCL_READABLE)) {
7880 if (mask & TCL_WRITABLE) {
7881 Tcl_DeleteChannelHandler(outChan, CopyEventProc,
7882 (ClientData) csPtr);
7884 Tcl_CreateChannelHandler(inChan, TCL_READABLE,
7885 CopyEventProc, (ClientData) csPtr);
7888 if (bufObj != (Tcl_Obj*) NULL) {
7889 Tcl_DecrRefCount (bufObj);
7890 bufObj = (Tcl_Obj*) NULL;
7897 * Now write the buffer out.
7900 if (inBinary || sameEncoding) {
7901 buffer = csPtr->buffer;
7904 buffer = Tcl_GetStringFromObj (bufObj, &sizeb);
7907 if (outBinary || sameEncoding) {
7908 sizeb = DoWrite(outStatePtr->topChanPtr, buffer, sizeb);
7910 sizeb = DoWriteChars(outStatePtr->topChanPtr, buffer, sizeb);
7913 if (inBinary || sameEncoding) {
7914 /* Both read and write counted bytes */
7916 } /* else : Read counted characters, write counted bytes, i.e. size != sizeb */
7920 errObj = Tcl_NewObj();
7921 Tcl_AppendStringsToObj(errObj, "error writing \"",
7922 Tcl_GetChannelName(outChan), "\": ",
7923 Tcl_PosixError(interp), (char *) NULL);
7928 * Update the current byte count. Do it now so the count is
7929 * valid before a return or break takes us out of the loop.
7930 * The invariant at the top of the loop should be that
7931 * csPtr->toRead holds the number of bytes left to copy.
7934 if (csPtr->toRead != -1) {
7935 csPtr->toRead -= size;
7937 csPtr->total += size;
7940 * Break loop if EOF && (size>0)
7943 if (Tcl_Eof(inChan)) {
7948 * Check to see if the write is happening in the background. If so,
7949 * stop copying and wait for the channel to become writable again.
7950 * After input underflow we already installed a readable handler
7951 * therefore we don't need a writable handler.
7954 if ( ! underflow && (outStatePtr->flags & BG_FLUSH_SCHEDULED) ) {
7955 if (!(mask & TCL_WRITABLE)) {
7956 if (mask & TCL_READABLE) {
7957 Tcl_DeleteChannelHandler(inChan, CopyEventProc,
7958 (ClientData) csPtr);
7960 Tcl_CreateChannelHandler(outChan, TCL_WRITABLE,
7961 CopyEventProc, (ClientData) csPtr);
7963 if (bufObj != (Tcl_Obj*) NULL) {
7964 Tcl_DecrRefCount (bufObj);
7965 bufObj = (Tcl_Obj*) NULL;
7971 * For background copies, we only do one buffer per invocation so
7972 * we don't starve the rest of the system.
7977 * The first time we enter this code, there won't be a
7978 * channel handler established yet, so do it here.
7982 Tcl_CreateChannelHandler(outChan, TCL_WRITABLE,
7983 CopyEventProc, (ClientData) csPtr);
7985 if (bufObj != (Tcl_Obj*) NULL) {
7986 Tcl_DecrRefCount (bufObj);
7987 bufObj = (Tcl_Obj*) NULL;
7993 if (bufObj != (Tcl_Obj*) NULL) {
7994 Tcl_DecrRefCount (bufObj);
7995 bufObj = (Tcl_Obj*) NULL;
7999 * Make the callback or return the number of bytes transferred.
8000 * The local total is used because StopCopy frees csPtr.
8003 total = csPtr->total;
8004 if (cmdPtr && interp) {
8006 * Get a private copy of the command so we can mutate it
8007 * by adding arguments. Note that StopCopy frees our saved
8008 * reference to the original command obj.
8011 cmdPtr = Tcl_DuplicateObj(cmdPtr);
8012 Tcl_IncrRefCount(cmdPtr);
8014 Tcl_Preserve((ClientData) interp);
8016 Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewIntObj(total));
8018 Tcl_ListObjAppendElement(interp, cmdPtr, errObj);
8020 if (Tcl_EvalObjEx(interp, cmdPtr, TCL_EVAL_GLOBAL) != TCL_OK) {
8021 Tcl_BackgroundError(interp);
8024 Tcl_DecrRefCount(cmdPtr);
8025 Tcl_Release((ClientData) interp);
8030 Tcl_SetObjResult(interp, errObj);
8033 Tcl_ResetResult(interp);
8034 Tcl_SetIntObj(Tcl_GetObjResult(interp), total);
8042 *----------------------------------------------------------------------
8046 * Reads a given number of bytes from a channel.
8048 * No encoding conversions are applied to the bytes being read.
8051 * The number of characters read, or -1 on error. Use Tcl_GetErrno()
8052 * to retrieve the error code for the error that occurred.
8055 * May cause input to be buffered.
8057 *----------------------------------------------------------------------
8061 DoRead(chanPtr, bufPtr, toRead)
8062 Channel *chanPtr; /* The channel from which to read. */
8063 char *bufPtr; /* Where to store input read. */
8064 int toRead; /* Maximum number of bytes to read. */
8066 ChannelState *statePtr = chanPtr->state; /* state info for channel */
8067 int copied; /* How many characters were copied into
8068 * the result string? */
8069 int copiedNow; /* How many characters were copied from
8070 * the current input buffer? */
8071 int result; /* Of calling GetInput. */
8074 * If we have not encountered a sticky EOF, clear the EOF bit. Either
8075 * way clear the BLOCKED bit. We want to discover these anew during
8079 if (!(statePtr->flags & CHANNEL_STICKY_EOF)) {
8080 statePtr->flags &= ~CHANNEL_EOF;
8082 statePtr->flags &= ~(CHANNEL_BLOCKED | CHANNEL_NEED_MORE_DATA);
8084 for (copied = 0; copied < toRead; copied += copiedNow) {
8085 copiedNow = CopyAndTranslateBuffer(statePtr, bufPtr + copied,
8087 if (copiedNow == 0) {
8088 if (statePtr->flags & CHANNEL_EOF) {
8091 if (statePtr->flags & CHANNEL_BLOCKED) {
8092 if (statePtr->flags & CHANNEL_NONBLOCKING) {
8095 statePtr->flags &= (~(CHANNEL_BLOCKED));
8097 result = GetInput(chanPtr);
8099 if (result != EAGAIN) {
8107 statePtr->flags &= (~(CHANNEL_BLOCKED));
8111 * Update the notifier state so we don't block while there is still
8112 * data in the buffers.
8115 UpdateInterest(chanPtr);
8120 *----------------------------------------------------------------------
8122 * CopyAndTranslateBuffer --
8124 * Copy at most one buffer of input to the result space, doing
8125 * eol translations according to mode in effect currently.
8128 * Number of bytes stored in the result buffer (as opposed to the
8129 * number of bytes read from the channel). May return
8130 * zero if no input is available to be translated.
8133 * Consumes buffered input. May deallocate one buffer.
8135 *----------------------------------------------------------------------
8139 CopyAndTranslateBuffer(statePtr, result, space)
8140 ChannelState *statePtr; /* Channel state from which to read input. */
8141 char *result; /* Where to store the copied input. */
8142 int space; /* How many bytes are available in result
8143 * to store the copied input? */
8145 ChannelBuffer *bufPtr; /* The buffer from which to copy bytes. */
8146 int bytesInBuffer; /* How many bytes are available to be
8147 * copied in the current input buffer? */
8148 int copied; /* How many characters were already copied
8149 * into the destination space? */
8150 int i; /* Iterates over the copied input looking
8151 * for the input eofChar. */
8154 * If there is no input at all, return zero. The invariant is that either
8155 * there is no buffer in the queue, or if the first buffer is empty, it
8156 * is also the last buffer (and thus there is no input in the queue).
8157 * Note also that if the buffer is empty, we leave it in the queue.
8160 if (statePtr->inQueueHead == (ChannelBuffer *) NULL) {
8163 bufPtr = statePtr->inQueueHead;
8164 bytesInBuffer = bufPtr->nextAdded - bufPtr->nextRemoved;
8167 switch (statePtr->inputTranslation) {
8168 case TCL_TRANSLATE_LF: {
8169 if (bytesInBuffer == 0) {
8174 * Copy the current chunk into the result buffer.
8177 if (bytesInBuffer < space) {
8178 space = bytesInBuffer;
8180 memcpy((VOID *) result,
8181 (VOID *) (bufPtr->buf + bufPtr->nextRemoved),
8183 bufPtr->nextRemoved += space;
8187 case TCL_TRANSLATE_CR: {
8190 if (bytesInBuffer == 0) {
8195 * Copy the current chunk into the result buffer, then
8196 * replace all \r with \n.
8199 if (bytesInBuffer < space) {
8200 space = bytesInBuffer;
8202 memcpy((VOID *) result,
8203 (VOID *) (bufPtr->buf + bufPtr->nextRemoved),
8205 bufPtr->nextRemoved += space;
8208 for (end = result + copied; result < end; result++) {
8209 if (*result == '\r') {
8215 case TCL_TRANSLATE_CRLF: {
8216 char *src, *end, *dst;
8220 * If there is a held-back "\r" at EOF, produce it now.
8223 if (bytesInBuffer == 0) {
8224 if ((statePtr->flags & (INPUT_SAW_CR | CHANNEL_EOF)) ==
8225 (INPUT_SAW_CR | CHANNEL_EOF)) {
8227 statePtr->flags &= ~INPUT_SAW_CR;
8234 * Copy the current chunk and replace "\r\n" with "\n"
8235 * (but not standalone "\r"!).
8238 if (bytesInBuffer < space) {
8239 space = bytesInBuffer;
8241 memcpy((VOID *) result,
8242 (VOID *) (bufPtr->buf + bufPtr->nextRemoved),
8244 bufPtr->nextRemoved += space;
8247 end = result + copied;
8249 for (src = result; src < end; src++) {
8251 if (curByte == '\n') {
8252 statePtr->flags &= ~INPUT_SAW_CR;
8253 } else if (statePtr->flags & INPUT_SAW_CR) {
8254 statePtr->flags &= ~INPUT_SAW_CR;
8258 if (curByte == '\r') {
8259 statePtr->flags |= INPUT_SAW_CR;
8261 *dst = (char) curByte;
8265 copied = dst - result;
8268 case TCL_TRANSLATE_AUTO: {
8269 char *src, *end, *dst;
8272 if (bytesInBuffer == 0) {
8277 * Loop over the current buffer, converting "\r" and "\r\n"
8281 if (bytesInBuffer < space) {
8282 space = bytesInBuffer;
8284 memcpy((VOID *) result,
8285 (VOID *) (bufPtr->buf + bufPtr->nextRemoved),
8287 bufPtr->nextRemoved += space;
8290 end = result + copied;
8292 for (src = result; src < end; src++) {
8294 if (curByte == '\r') {
8295 statePtr->flags |= INPUT_SAW_CR;
8299 if ((curByte != '\n') ||
8300 !(statePtr->flags & INPUT_SAW_CR)) {
8301 *dst = (char) curByte;
8304 statePtr->flags &= ~INPUT_SAW_CR;
8307 copied = dst - result;
8311 panic("unknown eol translation mode");
8316 * If an in-stream EOF character is set for this channel, check that
8317 * the input we copied so far does not contain the EOF char. If it does,
8318 * copy only up to and excluding that character.
8321 if (statePtr->inEofChar != 0) {
8322 for (i = 0; i < copied; i++) {
8323 if (result[i] == (char) statePtr->inEofChar) {
8325 * Set sticky EOF so that no further input is presented
8329 statePtr->flags |= (CHANNEL_EOF | CHANNEL_STICKY_EOF);
8330 statePtr->inputEncodingFlags |= TCL_ENCODING_END;
8338 * If the current buffer is empty recycle it.
8341 if (bufPtr->nextRemoved == bufPtr->nextAdded) {
8342 statePtr->inQueueHead = bufPtr->nextPtr;
8343 if (statePtr->inQueueHead == (ChannelBuffer *) NULL) {
8344 statePtr->inQueueTail = (ChannelBuffer *) NULL;
8346 RecycleBuffer(statePtr, bufPtr, 0);
8350 * Return the number of characters copied into the result buffer.
8351 * This may be different from the number of bytes consumed, because
8352 * of EOL translations.
8359 *----------------------------------------------------------------------
8363 * Copy at most one buffer of input to the result space.
8366 * Number of bytes stored in the result buffer. May return
8367 * zero if no input is available.
8370 * Consumes buffered input. May deallocate one buffer.
8372 *----------------------------------------------------------------------
8376 CopyBuffer(chanPtr, result, space)
8377 Channel *chanPtr; /* Channel from which to read input. */
8378 char *result; /* Where to store the copied input. */
8379 int space; /* How many bytes are available in result
8380 * to store the copied input? */
8382 ChannelBuffer *bufPtr; /* The buffer from which to copy bytes. */
8383 int bytesInBuffer; /* How many bytes are available to be
8384 * copied in the current input buffer? */
8385 int copied; /* How many characters were already copied
8386 * into the destination space? */
8389 * If there is no input at all, return zero. The invariant is that
8390 * either there is no buffer in the queue, or if the first buffer
8391 * is empty, it is also the last buffer (and thus there is no
8392 * input in the queue). Note also that if the buffer is empty, we
8393 * don't leave it in the queue, but recycle it.
8396 if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) {
8399 bufPtr = chanPtr->inQueueHead;
8400 bytesInBuffer = bufPtr->nextAdded - bufPtr->nextRemoved;
8404 if (bytesInBuffer == 0) {
8405 RecycleBuffer(chanPtr->state, bufPtr, 0);
8406 chanPtr->inQueueHead = (ChannelBuffer*) NULL;
8407 chanPtr->inQueueTail = (ChannelBuffer*) NULL;
8412 * Copy the current chunk into the result buffer.
8415 if (bytesInBuffer < space) {
8416 space = bytesInBuffer;
8419 memcpy((VOID *) result,
8420 (VOID *) (bufPtr->buf + bufPtr->nextRemoved),
8422 bufPtr->nextRemoved += space;
8426 * We don't care about in-stream EOF characters here as the data
8427 * read here may still flow through one or more transformations,
8428 * i.e. is not in its final state yet.
8432 * If the current buffer is empty recycle it.
8435 if (bufPtr->nextRemoved == bufPtr->nextAdded) {
8436 chanPtr->inQueueHead = bufPtr->nextPtr;
8437 if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) {
8438 chanPtr->inQueueTail = (ChannelBuffer *) NULL;
8440 RecycleBuffer(chanPtr->state, bufPtr, 0);
8444 * Return the number of characters copied into the result buffer.
8451 *----------------------------------------------------------------------
8455 * Puts a sequence of characters into an output buffer, may queue the
8456 * buffer for output if it gets full, and also remembers whether the
8457 * current buffer is ready e.g. if it contains a newline and we are in
8458 * line buffering mode.
8461 * The number of bytes written or -1 in case of error. If -1,
8462 * Tcl_GetErrno will return the error code.
8465 * May buffer up output and may cause output to be produced on the
8468 *----------------------------------------------------------------------
8472 DoWrite(chanPtr, src, srcLen)
8473 Channel *chanPtr; /* The channel to buffer output for. */
8474 CONST char *src; /* Data to write. */
8475 int srcLen; /* Number of bytes to write. */
8477 ChannelState *statePtr = chanPtr->state; /* state info for channel */
8478 ChannelBuffer *outBufPtr; /* Current output buffer. */
8479 int foundNewline; /* Did we find a newline in output? */
8481 CONST char *sPtr; /* Search variables for newline. */
8482 int crsent; /* In CRLF eol translation mode,
8483 * remember the fact that a CR was
8484 * output to the channel without
8485 * its following NL. */
8486 int i; /* Loop index for newline search. */
8487 int destCopied; /* How many bytes were used in this
8488 * destination buffer to hold the
8490 int totalDestCopied; /* How many bytes total were
8491 * copied to the channel buffer? */
8492 int srcCopied; /* How many bytes were copied from
8493 * the source string? */
8494 char *destPtr; /* Where in line to copy to? */
8497 * If we are in network (or windows) translation mode, record the fact
8498 * that we have not yet sent a CR to the channel.
8504 * Loop filling buffers and flushing them until all output has been
8509 totalDestCopied = 0;
8511 while (srcLen > 0) {
8514 * Make sure there is a current output buffer to accept output.
8517 if (statePtr->curOutPtr == (ChannelBuffer *) NULL) {
8518 statePtr->curOutPtr = AllocChannelBuffer(statePtr->bufSize);
8521 outBufPtr = statePtr->curOutPtr;
8523 destCopied = outBufPtr->bufLength - outBufPtr->nextAdded;
8524 if (destCopied > srcLen) {
8525 destCopied = srcLen;
8528 destPtr = outBufPtr->buf + outBufPtr->nextAdded;
8529 switch (statePtr->outputTranslation) {
8530 case TCL_TRANSLATE_LF:
8531 srcCopied = destCopied;
8532 memcpy((VOID *) destPtr, (VOID *) src, (size_t) destCopied);
8534 case TCL_TRANSLATE_CR:
8535 srcCopied = destCopied;
8536 memcpy((VOID *) destPtr, (VOID *) src, (size_t) destCopied);
8537 for (dPtr = destPtr; dPtr < destPtr + destCopied; dPtr++) {
8538 if (*dPtr == '\n') {
8543 case TCL_TRANSLATE_CRLF:
8544 for (srcCopied = 0, dPtr = destPtr, sPtr = src;
8545 dPtr < destPtr + destCopied;
8546 dPtr++, sPtr++, srcCopied++) {
8547 if (*sPtr == '\n') {
8554 sPtr--, srcCopied--;
8561 case TCL_TRANSLATE_AUTO:
8562 panic("Tcl_Write: AUTO output translation mode not supported");
8564 panic("Tcl_Write: unknown output translation mode");
8568 * The current buffer is ready for output if it is full, or if it
8569 * contains a newline and this channel is line-buffered, or if it
8570 * contains any output and this channel is unbuffered.
8573 outBufPtr->nextAdded += destCopied;
8574 if (!(statePtr->flags & BUFFER_READY)) {
8575 if (outBufPtr->nextAdded == outBufPtr->bufLength) {
8576 statePtr->flags |= BUFFER_READY;
8577 } else if (statePtr->flags & CHANNEL_LINEBUFFERED) {
8578 for (sPtr = src, i = 0, foundNewline = 0;
8579 (i < srcCopied) && (!foundNewline);
8581 if (*sPtr == '\n') {
8587 statePtr->flags |= BUFFER_READY;
8589 } else if (statePtr->flags & CHANNEL_UNBUFFERED) {
8590 statePtr->flags |= BUFFER_READY;
8594 totalDestCopied += srcCopied;
8596 srcLen -= srcCopied;
8598 if (statePtr->flags & BUFFER_READY) {
8599 if (FlushChannel(NULL, chanPtr, 0) != 0) {
8603 } /* Closes "while" */
8605 return totalDestCopied;
8609 *----------------------------------------------------------------------
8613 * This routine is invoked as a channel event handler for
8614 * the background copy operation. It is just a trivial wrapper
8615 * around the CopyData routine.
8623 *----------------------------------------------------------------------
8627 CopyEventProc(clientData, mask)
8628 ClientData clientData;
8631 (void) CopyData((CopyState *)clientData, mask);
8635 *----------------------------------------------------------------------
8639 * This routine halts a copy that is in progress.
8645 * Removes any pending channel handlers and restores the blocking
8646 * and buffering modes of the channels. The CopyState is freed.
8648 *----------------------------------------------------------------------
8653 CopyState *csPtr; /* State for bg copy to stop . */
8655 ChannelState *inStatePtr, *outStatePtr;
8662 inStatePtr = csPtr->readPtr->state;
8663 outStatePtr = csPtr->writePtr->state;
8666 * Restore the old blocking mode and output buffering mode.
8669 nonBlocking = (csPtr->readFlags & CHANNEL_NONBLOCKING);
8670 if (nonBlocking != (inStatePtr->flags & CHANNEL_NONBLOCKING)) {
8671 SetBlockMode(NULL, csPtr->readPtr,
8672 nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING);
8674 if (csPtr->readPtr != csPtr->writePtr) {
8675 nonBlocking = (csPtr->writeFlags & CHANNEL_NONBLOCKING);
8676 if (nonBlocking != (outStatePtr->flags & CHANNEL_NONBLOCKING)) {
8677 SetBlockMode(NULL, csPtr->writePtr,
8678 nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING);
8681 outStatePtr->flags &= ~(CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED);
8682 outStatePtr->flags |=
8683 csPtr->writeFlags & (CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED);
8685 if (csPtr->cmdPtr) {
8686 Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->readPtr, CopyEventProc,
8688 if (csPtr->readPtr != csPtr->writePtr) {
8689 Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->writePtr,
8690 CopyEventProc, (ClientData)csPtr);
8692 Tcl_DecrRefCount(csPtr->cmdPtr);
8694 inStatePtr->csPtr = NULL;
8695 outStatePtr->csPtr = NULL;
8696 ckfree((char*) csPtr);
8700 *----------------------------------------------------------------------
8702 * StackSetBlockMode --
8704 * This function sets the blocking mode for a channel, iterating
8705 * through each channel in a stack and updates the state flags.
8708 * 0 if OK, result code from failed blockModeProc otherwise.
8711 * Modifies the blocking mode of the channel and possibly generates
8714 *----------------------------------------------------------------------
8718 StackSetBlockMode(chanPtr, mode)
8719 Channel *chanPtr; /* Channel to modify. */
8720 int mode; /* One of TCL_MODE_BLOCKING or
8721 * TCL_MODE_NONBLOCKING. */
8724 Tcl_DriverBlockModeProc *blockModeProc;
8727 * Start at the top of the channel stack
8730 chanPtr = chanPtr->state->topChanPtr;
8731 while (chanPtr != (Channel *) NULL) {
8732 blockModeProc = Tcl_ChannelBlockModeProc(chanPtr->typePtr);
8733 if (blockModeProc != NULL) {
8734 result = (*blockModeProc) (chanPtr->instanceData, mode);
8736 Tcl_SetErrno(result);
8740 chanPtr = chanPtr->downChanPtr;
8746 *----------------------------------------------------------------------
8750 * This function sets the blocking mode for a channel and updates
8754 * A standard Tcl result.
8757 * Modifies the blocking mode of the channel and possibly generates
8760 *----------------------------------------------------------------------
8764 SetBlockMode(interp, chanPtr, mode)
8765 Tcl_Interp *interp; /* Interp for error reporting. */
8766 Channel *chanPtr; /* Channel to modify. */
8767 int mode; /* One of TCL_MODE_BLOCKING or
8768 * TCL_MODE_NONBLOCKING. */
8770 ChannelState *statePtr = chanPtr->state; /* state info for channel */
8773 result = StackSetBlockMode(chanPtr, mode);
8775 if (interp != (Tcl_Interp *) NULL) {
8776 Tcl_AppendResult(interp, "error setting blocking mode: ",
8777 Tcl_PosixError(interp), (char *) NULL);
8781 if (mode == TCL_MODE_BLOCKING) {
8782 statePtr->flags &= (~(CHANNEL_NONBLOCKING | BG_FLUSH_SCHEDULED));
8784 statePtr->flags |= CHANNEL_NONBLOCKING;
8790 *----------------------------------------------------------------------
8792 * Tcl_GetChannelNames --
8794 * Return the names of all open channels in the interp.
8797 * TCL_OK or TCL_ERROR.
8800 * Interp result modified with list of channel names.
8802 *----------------------------------------------------------------------
8806 Tcl_GetChannelNames(interp)
8807 Tcl_Interp *interp; /* Interp for error reporting. */
8809 return Tcl_GetChannelNamesEx(interp, (char *) NULL);
8813 *----------------------------------------------------------------------
8815 * Tcl_GetChannelNamesEx --
8817 * Return the names of open channels in the interp filtered
8818 * filtered through a pattern. If pattern is NULL, it returns
8819 * all the open channels.
8822 * TCL_OK or TCL_ERROR.
8825 * Interp result modified with list of channel names.
8827 *----------------------------------------------------------------------
8831 Tcl_GetChannelNamesEx(interp, pattern)
8832 Tcl_Interp *interp; /* Interp for error reporting. */
8833 CONST char *pattern; /* pattern to filter on. */
8835 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
8836 ChannelState *statePtr;
8837 CONST char *name; /* name for channel */
8838 Tcl_Obj *resultPtr; /* pointer to result object */
8839 Tcl_HashTable *hTblPtr; /* Hash table of channels. */
8840 Tcl_HashEntry *hPtr; /* Search variable. */
8841 Tcl_HashSearch hSearch; /* Search variable. */
8843 if (interp == (Tcl_Interp *) NULL) {
8848 * Get the channel table that stores the channels registered
8849 * for this interpreter.
8851 hTblPtr = GetChannelTable(interp);
8852 resultPtr = Tcl_GetObjResult(interp);
8854 for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
8855 hPtr != (Tcl_HashEntry *) NULL;
8856 hPtr = Tcl_NextHashEntry(&hSearch)) {
8858 statePtr = ((Channel *) Tcl_GetHashValue(hPtr))->state;
8859 if (statePtr->topChanPtr == (Channel *) tsdPtr->stdinChannel) {
8861 } else if (statePtr->topChanPtr == (Channel *) tsdPtr->stdoutChannel) {
8863 } else if (statePtr->topChanPtr == (Channel *) tsdPtr->stderrChannel) {
8867 * This is also stored in Tcl_GetHashKey(hTblPtr, hPtr),
8868 * but it's simpler to just grab the name from the statePtr.
8870 name = statePtr->channelName;
8873 if (((pattern == NULL) || Tcl_StringMatch(name, pattern)) &&
8874 (Tcl_ListObjAppendElement(interp, resultPtr,
8875 Tcl_NewStringObj(name, -1)) != TCL_OK)) {
8883 *----------------------------------------------------------------------
8885 * Tcl_IsChannelRegistered --
8887 * Checks whether the channel is associated with the interp.
8888 * See also Tcl_RegisterChannel and Tcl_UnregisterChannel.
8891 * 0 if the channel is not registered in the interpreter, 1 else.
8896 *----------------------------------------------------------------------
8900 Tcl_IsChannelRegistered (interp, chan)
8901 Tcl_Interp* interp; /* The interp to query of the channel */
8902 Tcl_Channel chan; /* The channel to check */
8904 Tcl_HashTable *hTblPtr; /* Hash table of channels. */
8905 Tcl_HashEntry *hPtr; /* Search variable. */
8906 Channel *chanPtr; /* The real IO channel. */
8907 ChannelState *statePtr; /* State of the real channel. */
8910 * Always check bottom-most channel in the stack. This is the one
8911 * that gets registered.
8913 chanPtr = ((Channel *) chan)->state->bottomChanPtr;
8914 statePtr = chanPtr->state;
8916 hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);
8917 if (hTblPtr == (Tcl_HashTable *) NULL) {
8920 hPtr = Tcl_FindHashEntry(hTblPtr, statePtr->channelName);
8921 if (hPtr == (Tcl_HashEntry *) NULL) {
8924 if ((Channel *) Tcl_GetHashValue(hPtr) != chanPtr) {
8932 *----------------------------------------------------------------------
8934 * Tcl_IsChannelShared --
8936 * Checks whether the channel is shared by multiple interpreters.
8939 * A boolean value (0 = Not shared, 1 = Shared).
8944 *----------------------------------------------------------------------
8948 Tcl_IsChannelShared (chan)
8949 Tcl_Channel chan; /* The channel to query */
8951 ChannelState *statePtr = ((Channel *) chan)->state;
8952 /* State of real channel structure. */
8954 return ((statePtr->refCount > 1) ? 1 : 0);
8958 *----------------------------------------------------------------------
8960 * Tcl_IsChannelExisting --
8962 * Checks whether a channel of the given name exists in the
8963 * (thread)-global list of all channels.
8964 * See Tcl_GetChannelNamesEx for function exposed at the Tcl level.
8967 * A boolean value (0 = Does not exist, 1 = Does exist).
8972 *----------------------------------------------------------------------
8976 Tcl_IsChannelExisting(chanName)
8977 CONST char* chanName; /* The name of the channel to look for. */
8979 ChannelState *statePtr;
8980 ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
8984 chanNameLen = strlen(chanName);
8985 for (statePtr = tsdPtr->firstCSPtr;
8987 statePtr = statePtr->nextCSPtr) {
8988 if (statePtr->topChanPtr == (Channel *) tsdPtr->stdinChannel) {
8990 } else if (statePtr->topChanPtr == (Channel *) tsdPtr->stdoutChannel) {
8992 } else if (statePtr->topChanPtr == (Channel *) tsdPtr->stderrChannel) {
8995 name = statePtr->channelName;
8998 if ((*chanName == *name) &&
8999 (memcmp(name, chanName, (size_t) chanNameLen) == 0)) {
9008 *----------------------------------------------------------------------
9010 * Tcl_ChannelName --
9012 * Return the name of the channel type.
9015 * A pointer the name of the channel type.
9020 *----------------------------------------------------------------------
9023 EXPORT_C CONST char *
9024 Tcl_ChannelName(chanTypePtr)
9025 Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
9027 return chanTypePtr->typeName;
9031 *----------------------------------------------------------------------
9033 * Tcl_ChannelVersion --
9035 * Return the of version of the channel type.
9038 * One of the TCL_CHANNEL_VERSION_* constants from tcl.h
9043 *----------------------------------------------------------------------
9046 EXPORT_C Tcl_ChannelTypeVersion
9047 Tcl_ChannelVersion(chanTypePtr)
9048 Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
9050 if (chanTypePtr->version == TCL_CHANNEL_VERSION_2) {
9051 return TCL_CHANNEL_VERSION_2;
9052 } else if (chanTypePtr->version == TCL_CHANNEL_VERSION_3) {
9053 return TCL_CHANNEL_VERSION_3;
9054 } else if (chanTypePtr->version == TCL_CHANNEL_VERSION_4) {
9055 return TCL_CHANNEL_VERSION_4;
9058 * In <v2 channel versions, the version field is occupied
9059 * by the Tcl_DriverBlockModeProc
9061 return TCL_CHANNEL_VERSION_1;
9066 *----------------------------------------------------------------------
9070 * Return whether a channel type is (at least) of a given version.
9073 * True if the minimum version is exceeded by the version actually
9079 *----------------------------------------------------------------------
9083 HaveVersion(chanTypePtr, minimumVersion)
9084 Tcl_ChannelType *chanTypePtr;
9085 Tcl_ChannelTypeVersion minimumVersion;
9087 Tcl_ChannelTypeVersion actualVersion = Tcl_ChannelVersion(chanTypePtr);
9089 return ((int)actualVersion) >= ((int)minimumVersion);
9093 *----------------------------------------------------------------------
9095 * Tcl_ChannelBlockModeProc --
9097 * Return the Tcl_DriverBlockModeProc of the channel type.
9100 * A pointer to the proc.
9105 *---------------------------------------------------------------------- */
9107 EXPORT_C Tcl_DriverBlockModeProc *
9108 Tcl_ChannelBlockModeProc(chanTypePtr)
9109 Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
9111 if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_2)) {
9112 return chanTypePtr->blockModeProc;
9115 * The v1 structure had the blockModeProc in a different place.
9117 return (Tcl_DriverBlockModeProc *) (chanTypePtr->version);
9122 *----------------------------------------------------------------------
9124 * Tcl_ChannelCloseProc --
9126 * Return the Tcl_DriverCloseProc of the channel type.
9129 * A pointer to the proc.
9134 *----------------------------------------------------------------------
9137 EXPORT_C Tcl_DriverCloseProc *
9138 Tcl_ChannelCloseProc(chanTypePtr)
9139 Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
9141 return chanTypePtr->closeProc;
9145 *----------------------------------------------------------------------
9147 * Tcl_ChannelClose2Proc --
9149 * Return the Tcl_DriverClose2Proc of the channel type.
9152 * A pointer to the proc.
9157 *----------------------------------------------------------------------
9160 EXPORT_C Tcl_DriverClose2Proc *
9161 Tcl_ChannelClose2Proc(chanTypePtr)
9162 Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
9164 return chanTypePtr->close2Proc;
9168 *----------------------------------------------------------------------
9170 * Tcl_ChannelInputProc --
9172 * Return the Tcl_DriverInputProc of the channel type.
9175 * A pointer to the proc.
9180 *----------------------------------------------------------------------
9183 EXPORT_C Tcl_DriverInputProc *
9184 Tcl_ChannelInputProc(chanTypePtr)
9185 Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
9187 return chanTypePtr->inputProc;
9191 *----------------------------------------------------------------------
9193 * Tcl_ChannelOutputProc --
9195 * Return the Tcl_DriverOutputProc of the channel type.
9198 * A pointer to the proc.
9203 *----------------------------------------------------------------------
9206 EXPORT_C Tcl_DriverOutputProc *
9207 Tcl_ChannelOutputProc(chanTypePtr)
9208 Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
9210 return chanTypePtr->outputProc;
9214 *----------------------------------------------------------------------
9216 * Tcl_ChannelSeekProc --
9218 * Return the Tcl_DriverSeekProc of the channel type.
9221 * A pointer to the proc.
9226 *----------------------------------------------------------------------
9229 EXPORT_C Tcl_DriverSeekProc *
9230 Tcl_ChannelSeekProc(chanTypePtr)
9231 Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
9233 return chanTypePtr->seekProc;
9237 *----------------------------------------------------------------------
9239 * Tcl_ChannelSetOptionProc --
9241 * Return the Tcl_DriverSetOptionProc of the channel type.
9244 * A pointer to the proc.
9249 *----------------------------------------------------------------------
9252 EXPORT_C Tcl_DriverSetOptionProc *
9253 Tcl_ChannelSetOptionProc(chanTypePtr)
9254 Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
9256 return chanTypePtr->setOptionProc;
9260 *----------------------------------------------------------------------
9262 * Tcl_ChannelGetOptionProc --
9264 * Return the Tcl_DriverGetOptionProc of the channel type.
9267 * A pointer to the proc.
9272 *----------------------------------------------------------------------
9275 EXPORT_C Tcl_DriverGetOptionProc *
9276 Tcl_ChannelGetOptionProc(chanTypePtr)
9277 Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
9279 return chanTypePtr->getOptionProc;
9283 *----------------------------------------------------------------------
9285 * Tcl_ChannelWatchProc --
9287 * Return the Tcl_DriverWatchProc of the channel type.
9290 * A pointer to the proc.
9295 *----------------------------------------------------------------------
9298 EXPORT_C Tcl_DriverWatchProc *
9299 Tcl_ChannelWatchProc(chanTypePtr)
9300 Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
9302 return chanTypePtr->watchProc;
9306 *----------------------------------------------------------------------
9308 * Tcl_ChannelGetHandleProc --
9310 * Return the Tcl_DriverGetHandleProc of the channel type.
9313 * A pointer to the proc.
9318 *----------------------------------------------------------------------
9321 EXPORT_C Tcl_DriverGetHandleProc *
9322 Tcl_ChannelGetHandleProc(chanTypePtr)
9323 Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
9325 return chanTypePtr->getHandleProc;
9329 *----------------------------------------------------------------------
9331 * Tcl_ChannelFlushProc --
9333 * Return the Tcl_DriverFlushProc of the channel type.
9336 * A pointer to the proc.
9341 *----------------------------------------------------------------------
9344 EXPORT_C Tcl_DriverFlushProc *
9345 Tcl_ChannelFlushProc(chanTypePtr)
9346 Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
9348 if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_2)) {
9349 return chanTypePtr->flushProc;
9356 *----------------------------------------------------------------------
9358 * Tcl_ChannelHandlerProc --
9360 * Return the Tcl_DriverHandlerProc of the channel type.
9363 * A pointer to the proc.
9368 *----------------------------------------------------------------------
9371 EXPORT_C Tcl_DriverHandlerProc *
9372 Tcl_ChannelHandlerProc(chanTypePtr)
9373 Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
9375 if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_2)) {
9376 return chanTypePtr->handlerProc;
9383 *----------------------------------------------------------------------
9385 * Tcl_ChannelWideSeekProc --
9387 * Return the Tcl_DriverWideSeekProc of the channel type.
9390 * A pointer to the proc.
9395 *----------------------------------------------------------------------
9398 EXPORT_C Tcl_DriverWideSeekProc *
9399 Tcl_ChannelWideSeekProc(chanTypePtr)
9400 Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
9402 if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_3)) {
9403 return chanTypePtr->wideSeekProc;
9410 *----------------------------------------------------------------------
9412 * Tcl_ChannelThreadActionProc --
9414 * Return the Tcl_DriverThreadActionProc of the channel type.
9417 * A pointer to the proc.
9422 *----------------------------------------------------------------------
9425 EXPORT_C Tcl_DriverThreadActionProc *
9426 Tcl_ChannelThreadActionProc(chanTypePtr)
9427 Tcl_ChannelType *chanTypePtr; /* Pointer to channel type. */
9429 if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_4)) {
9430 return chanTypePtr->threadActionProc;
9437 /* For future debugging work, a simple function to print the flags of
9438 * a channel in semi-readable form.
9442 DumpFlags (str, flags)
9449 if (flags & TCL_READABLE) {buf[i] = 'r';} else {buf [i]='_';}; i++;
9450 if (flags & TCL_WRITABLE) {buf[i] = 'w';} else {buf [i]='_';}; i++;
9451 if (flags & CHANNEL_NONBLOCKING) {buf[i] = 'n';} else {buf [i]='_';}; i++;
9452 if (flags & CHANNEL_LINEBUFFERED) {buf[i] = 'l';} else {buf [i]='_';}; i++;
9453 if (flags & CHANNEL_UNBUFFERED) {buf[i] = 'u';} else {buf [i]='_';}; i++;
9454 if (flags & BUFFER_READY) {buf[i] = 'R';} else {buf [i]='_';}; i++;
9455 if (flags & BG_FLUSH_SCHEDULED) {buf[i] = 'F';} else {buf [i]='_';}; i++;
9456 if (flags & CHANNEL_CLOSED) {buf[i] = 'c';} else {buf [i]='_';}; i++;
9457 if (flags & CHANNEL_EOF) {buf[i] = 'E';} else {buf [i]='_';}; i++;
9458 if (flags & CHANNEL_STICKY_EOF) {buf[i] = 'S';} else {buf [i]='_';}; i++;
9459 if (flags & CHANNEL_BLOCKED) {buf[i] = 'B';} else {buf [i]='_';}; i++;
9460 if (flags & INPUT_SAW_CR) {buf[i] = '/';} else {buf [i]='_';}; i++;
9461 if (flags & INPUT_NEED_NL) {buf[i] = '*';} else {buf [i]='_';}; i++;
9462 if (flags & CHANNEL_DEAD) {buf[i] = 'D';} else {buf [i]='_';}; i++;
9463 if (flags & CHANNEL_RAW_MODE) {buf[i] = 'R';} else {buf [i]='_';}; i++;
9464 #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
9465 if (flags & CHANNEL_TIMER_FEV) {buf[i] = 'T';} else {buf [i]='_';}; i++;
9466 if (flags & CHANNEL_HAS_MORE_DATA) {buf[i] = 'H';} else {buf [i]='_';}; i++;
9467 #endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
9468 if (flags & CHANNEL_INCLOSE) {buf[i] = 'x';} else {buf [i]='_';}; i++;
9471 fprintf (stderr,"%s: %s\n", str, buf); fflush(stderr);