⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclio.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
}/* *---------------------------------------------------------------------- * * Tcl_SetStdChannel -- * *	This function is used to change the channels that are used *	for stdin/stdout/stderr in new interpreters. * * Results: *	None * * Side effects: *	None. * *---------------------------------------------------------------------- */voidTcl_SetStdChannel(channel, type)    Tcl_Channel channel;    int type;			/* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */{    switch (type) {	case TCL_STDIN:            stdinInitialized = 1;	    stdinChannel = channel;	    break;	case TCL_STDOUT:	    stdoutInitialized = 1;	    stdoutChannel = channel;	    break;	case TCL_STDERR:	    stderrInitialized = 1;	    stderrChannel = channel;	    break;    }}/* *---------------------------------------------------------------------- * * Tcl_GetStdChannel -- * *	Returns the specified standard channel. * * Results: *	Returns the specified standard channel, or NULL. * * Side effects: *	May cause the creation of a standard channel and the underlying *	file. * *---------------------------------------------------------------------- */Tcl_ChannelTcl_GetStdChannel(type)    int type;			/* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */{    Tcl_Channel channel = NULL;    /*     * If the channels were not created yet, create them now and     * store them in the static variables.  Note that we need to set     * stdinInitialized before calling TclGetDefaultStdChannel in order     * to avoid recursive loops when TclGetDefaultStdChannel calls     * Tcl_CreateChannel.     */    switch (type) {	case TCL_STDIN:	    if (!stdinInitialized) {		stdinChannel = TclGetDefaultStdChannel(TCL_STDIN);		stdinInitialized = 1;                /*                 * Artificially bump the refcount to ensure that the channel                 * is only closed on exit.                 *                 * NOTE: Must only do this if stdinChannel is not NULL. It                 * can be NULL in situations where Tcl is unable to connect                 * to the standard input.                 */                if (stdinChannel != (Tcl_Channel) NULL) {                    (void) Tcl_RegisterChannel((Tcl_Interp *) NULL,                            stdinChannel);                }	    }	    channel = stdinChannel;	    break;	case TCL_STDOUT:	    if (!stdoutInitialized) {		stdoutChannel = TclGetDefaultStdChannel(TCL_STDOUT);		stdoutInitialized = 1;                /*                 * Artificially bump the refcount to ensure that the channel                 * is only closed on exit.                 *                 * NOTE: Must only do this if stdoutChannel is not NULL. It                 * can be NULL in situations where Tcl is unable to connect                 * to the standard output.                 */                if (stdoutChannel != (Tcl_Channel) NULL) {                    (void) Tcl_RegisterChannel((Tcl_Interp *) NULL,                            stdoutChannel);                }	    }	    channel = stdoutChannel;	    break;	case TCL_STDERR:	    if (!stderrInitialized) {		stderrChannel = TclGetDefaultStdChannel(TCL_STDERR);		stderrInitialized = 1;                /*                 * Artificially bump the refcount to ensure that the channel                 * is only closed on exit.                 *                 * NOTE: Must only do this if stderrChannel is not NULL. It                 * can be NULL in situations where Tcl is unable to connect                 * to the standard error.                 */                if (stderrChannel != (Tcl_Channel) NULL) {                    (void) Tcl_RegisterChannel((Tcl_Interp *) NULL,                            stderrChannel);                }	    }	    channel = stderrChannel;	    break;    }    return channel;}/* *---------------------------------------------------------------------- * * Tcl_CreateCloseHandler * *	Creates a close callback which will be called when the channel is *	closed. * * Results: *	None. * * Side effects: *	Causes the callback to be called in the future when the channel *	will be closed. * *---------------------------------------------------------------------- */voidTcl_CreateCloseHandler(chan, proc, clientData)    Tcl_Channel chan;		/* The channel for which to create the                                 * close callback. */    Tcl_CloseProc *proc;	/* The callback routine to call when the                                 * channel will be closed. */    ClientData clientData;	/* Arbitrary data to pass to the                                 * close callback. */{    Channel *chanPtr;    CloseCallback *cbPtr;    chanPtr = (Channel *) chan;    cbPtr = (CloseCallback *) ckalloc((unsigned) sizeof(CloseCallback));    cbPtr->proc = proc;    cbPtr->clientData = clientData;    cbPtr->nextPtr = chanPtr->closeCbPtr;    chanPtr->closeCbPtr = cbPtr;}/* *---------------------------------------------------------------------- * * Tcl_DeleteCloseHandler -- * *	Removes a callback that would have been called on closing *	the channel. If there is no matching callback then this *	function has no effect. * * Results: *	None. * * Side effects: *	The callback will not be called in the future when the channel *	is eventually closed. * *---------------------------------------------------------------------- */voidTcl_DeleteCloseHandler(chan, proc, clientData)    Tcl_Channel chan;		/* The channel for which to cancel the                                 * close callback. */    Tcl_CloseProc *proc;	/* The procedure for the callback to                                 * remove. */    ClientData clientData;	/* The callback data for the callback                                 * to remove. */{    Channel *chanPtr;    CloseCallback *cbPtr, *cbPrevPtr;    chanPtr = (Channel *) chan;    for (cbPtr = chanPtr->closeCbPtr, cbPrevPtr = (CloseCallback *) NULL;             cbPtr != (CloseCallback *) NULL;             cbPtr = cbPtr->nextPtr) {        if ((cbPtr->proc == proc) && (cbPtr->clientData == clientData)) {            if (cbPrevPtr == (CloseCallback *) NULL) {                chanPtr->closeCbPtr = cbPtr->nextPtr;            }            ckfree((char *) cbPtr);            break;        } else {            cbPrevPtr = cbPtr;        }    }}/* *---------------------------------------------------------------------- * * CloseChannelsOnExit -- * *	Closes all the existing channels, on exit. This	routine is called *	during exit processing. * * Results: *	None. * * Side effects: *	Closes all channels. * *---------------------------------------------------------------------- */	/* ARGSUSED */static voidCloseChannelsOnExit(clientData)    ClientData clientData;		/* NULL - unused. */{    Channel *chanPtr;			/* Iterates over open channels. */    Channel *nextChanPtr;		/* Iterates over open channels. */    for (chanPtr = firstChanPtr; chanPtr != (Channel *) NULL;             chanPtr = nextChanPtr) {        nextChanPtr = chanPtr->nextChanPtr;        /*         * Set the channel back into blocking mode to ensure that we wait         * for all data to flush out.         */                (void) Tcl_SetChannelOption(NULL, (Tcl_Channel) chanPtr,                "-blocking", "on");        if ((chanPtr == (Channel *) stdinChannel) ||                (chanPtr == (Channel *) stdoutChannel) ||                (chanPtr == (Channel *) stderrChannel)) {            /*             * Decrement the refcount which was earlier artificially bumped             * up to keep the channel from being closed.             */            chanPtr->refCount--;        }        if (chanPtr->refCount <= 0) {	    /*             * Close it only if the refcount indicates that the channel is not             * referenced from any interpreter. If it is, that interpreter will             * close the channel when it gets destroyed.             */            (void) Tcl_Close((Tcl_Interp *) NULL, (Tcl_Channel) chanPtr);        } else {            /*             * The refcount is greater than zero, so flush the channel.             */            Tcl_Flush((Tcl_Channel) chanPtr);            /*             * Call the device driver to actually close the underlying             * device for this channel.             */                        (chanPtr->typePtr->closeProc) (chanPtr->instanceData,                    (Tcl_Interp *) NULL);            /*             * Finally, we clean up the fields in the channel data structure             * since all of them have been deleted already. We mark the             * channel with CHANNEL_DEAD to prevent any further IO operations             * on it.             */            chanPtr->instanceData = (ClientData) NULL;            chanPtr->flags |= CHANNEL_DEAD;        }    }    /*     * Reinitialize all the variables to the initial state:     */        firstChanPtr = (Channel *) NULL;    nestedHandlerPtr = (NextChannelHandler *) NULL;    channelExitHandlerCreated = 0;    stdinChannel = NULL;    stdinInitialized = 0;    stdoutChannel = NULL;    stdoutInitialized = 0;    stderrChannel = NULL;    stderrInitialized = 0;}/* *---------------------------------------------------------------------- * * GetChannelTable -- * *	Gets and potentially initializes the channel table for an *	interpreter. If it is initializing the table it also inserts *	channels for stdin, stdout and stderr if the interpreter is *	trusted. * * Results: *	A pointer to the hash table created, for use by the caller. * * Side effects: *	Initializes the channel table for an interpreter. May create *	channels for stdin, stdout and stderr. * *---------------------------------------------------------------------- */static Tcl_HashTable *GetChannelTable(interp)    Tcl_Interp *interp;{    Tcl_HashTable *hTblPtr;	/* Hash table of channels. */    Tcl_Channel stdinChan, stdoutChan, stderrChan;    hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);    if (hTblPtr == (Tcl_HashTable *) NULL) {        hTblPtr = (Tcl_HashTable *) ckalloc((unsigned) sizeof(Tcl_HashTable));        Tcl_InitHashTable(hTblPtr, TCL_STRING_KEYS);        (void) Tcl_SetAssocData(interp, "tclIO",                (Tcl_InterpDeleteProc *) DeleteChannelTable,                (ClientData) hTblPtr);        /*         * If the interpreter is trusted (not "safe"), insert channels         * for stdin, stdout and stderr (possibly creating them in the         * process).         */        if (Tcl_IsSafe(interp) == 0) {            stdinChan = Tcl_GetStdChannel(TCL_STDIN);            if (stdinChan != NULL) {                Tcl_RegisterChannel(interp, stdinChan);            }            stdoutChan = Tcl_GetStdChannel(TCL_STDOUT);            if (stdoutChan != NULL) {                Tcl_RegisterChannel(interp, stdoutChan);            }            stderrChan = Tcl_GetStdChannel(TCL_STDERR);            if (stderrChan != NULL) {                Tcl_RegisterChannel(interp, stderrChan);            }        }    }    return hTblPtr;}/* *---------------------------------------------------------------------- * * DeleteChannelTable -- * *	Deletes the channel table for an interpreter, closing any open *	channels whose refcount reaches zero. This procedure is invoked *	when an interpreter is deleted, via the AssocData cleanup *	mechanism. * * Results: *	None. * * Side effects: *	Deletes the hash table of channels. May close channels. May flush

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -