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

📄 tclwinchan.c

📁 这是leon3处理器的交叉编译链
💻 C
📖 第 1 页 / 共 3 页
字号:
    channel = NULL;    switch (type) {    case FILE_TYPE_SERIAL:	/*	 * Reopen channel for OVERLAPPED operation	 * Normally this shouldn't fail, because the channel exists	 */	handle = TclWinSerialReopen(handle, nativeName, accessMode);	if (handle == INVALID_HANDLE_VALUE) {	    TclWinConvertError(GetLastError());	    if (interp != (Tcl_Interp *) NULL) {		Tcl_AppendResult(interp, "couldn't reopen serial \"",			Tcl_GetString(pathPtr), "\": ",			Tcl_PosixError(interp), (char *) NULL);	    }	    return NULL;	}	channel = TclWinOpenSerialChannel(handle, channelName,	        channelPermissions);	break;    case FILE_TYPE_CONSOLE:	channel = TclWinOpenConsoleChannel(handle, channelName,	        channelPermissions);	break;    case FILE_TYPE_PIPE:	if (channelPermissions & TCL_READABLE) {	    readFile = TclWinMakeFile(handle);	}	if (channelPermissions & TCL_WRITABLE) {	    writeFile = TclWinMakeFile(handle);	}	channel = TclpCreateCommandChannel(readFile, writeFile, NULL, 0, NULL);	break;    case FILE_TYPE_CHAR:    case FILE_TYPE_DISK:    case FILE_TYPE_UNKNOWN:	channel = TclWinOpenFileChannel(handle, channelName,					channelPermissions,					(mode & O_APPEND) ? FILE_APPEND : 0);	break;    default:	/*	 * The handle is of an unknown type, probably /dev/nul equivalent	 * or possibly a closed handle.  	 */		channel = NULL;	Tcl_AppendResult(interp, "couldn't open \"", 			 Tcl_GetString(pathPtr), "\": ",			 "bad file type", (char *) NULL);	break;    }    return channel;}/* *---------------------------------------------------------------------- * * Tcl_MakeFileChannel -- * *	Creates a Tcl_Channel from an existing platform specific file *	handle. * * Results: *	The Tcl_Channel created around the preexisting file. * * Side effects: *	None. * *---------------------------------------------------------------------- */Tcl_ChannelTcl_MakeFileChannel(rawHandle, mode)    ClientData rawHandle;	/* OS level handle */    int mode;			/* ORed combination of TCL_READABLE and                                 * TCL_WRITABLE to indicate file mode. */{    char channelName[16 + TCL_INTEGER_SPACE];    Tcl_Channel channel = NULL;    HANDLE handle = (HANDLE) rawHandle;    HANDLE dupedHandle;    DCB dcb;    DWORD consoleParams, type;    TclFile readFile = NULL;    TclFile writeFile = NULL;    BOOL result;    if (mode == 0) {	return NULL;    }    /*     * GetFileType() returns FILE_TYPE_UNKNOWN for invalid handles.     */    type = GetFileType(handle);    /*     * If the file is a character device, we need to try to figure out     * whether it is a serial port, a console, or something else.  We     * test for the console case first because this is more common.     */    if (type == FILE_TYPE_CHAR) {	if (GetConsoleMode(handle, &consoleParams)) {	    type = FILE_TYPE_CONSOLE;	} else {	    dcb.DCBlength = sizeof( DCB ) ;	    if (GetCommState(handle, &dcb)) {		type = FILE_TYPE_SERIAL;	    }	}    }    switch (type)    {    case FILE_TYPE_SERIAL:	channel = TclWinOpenSerialChannel(handle, channelName, mode);	break;    case FILE_TYPE_CONSOLE:	channel = TclWinOpenConsoleChannel(handle, channelName, mode);	break;    case FILE_TYPE_PIPE:	if (mode & TCL_READABLE)	{	    readFile = TclWinMakeFile(handle);	}	if (mode & TCL_WRITABLE)	{	    writeFile = TclWinMakeFile(handle);	}	channel = TclpCreateCommandChannel(readFile, writeFile, NULL, 0, NULL);	break;    case FILE_TYPE_DISK:    case FILE_TYPE_CHAR:	channel = TclWinOpenFileChannel(handle, channelName, mode, 0);	break;	    case FILE_TYPE_UNKNOWN:    default:	/*	 * The handle is of an unknown type.  Test the validity of this OS	 * handle by duplicating it, then closing the dupe.  The Win32 API	 * doesn't provide an IsValidHandle() function, so we have to emulate	 * it here.  This test will not work on a console handle reliably,	 * which is why we can't test every handle that comes into this	 * function in this way.	 */	result = DuplicateHandle(GetCurrentProcess(), handle,		GetCurrentProcess(), &dupedHandle, 0, FALSE,		DUPLICATE_SAME_ACCESS);	if (result != 0) {	    /* 	     * Unable to make a duplicate. It's definately invalid at this	     * point.	     */	    return NULL;	}	/*	 * Use structured exception handling (Win32 SEH) to protect the close	 * of this duped handle which might throw EXCEPTION_INVALID_HANDLE.	 */#ifdef HAVE_NO_SEH        __asm__ __volatile__ (                "movl  %esp, _ESP" "\n\t"                "movl  %ebp, _EBP");        __asm__ __volatile__ (                "pushl $__except_makefilechannel_handler" "\n\t"                "pushl %fs:0" "\n\t"                "mov   %esp, %fs:0");        result = 0;#else	__try {#endif /* HAVE_NO_SEH */	    CloseHandle(dupedHandle);#ifdef HAVE_NO_SEH        __asm__ __volatile__ (                "jmp   makefilechannel_pop" "\n"                "makefilechannel_reentry:" "\n\t"                "movl  _ESP, %esp" "\n\t"                "movl  _EBP, %ebp");        result = 1;  /* True when exception was raised */        __asm__ __volatile__ (                "makefilechannel_pop:" "\n\t"                "mov   (%esp), %eax" "\n\t"                "mov   %eax, %fs:0" "\n\t"                "add   $8, %esp");        if (result)            return NULL;#else	}	__except (EXCEPTION_EXECUTE_HANDLER) {	    /*	     * Definately an invalid handle.  So, therefore, the original	     * is invalid also.	     */	    return NULL;	}#endif /* HAVE_NO_SEH */	/* Fall through, the handle is valid. */	/*	 * Create the undefined channel, anyways, because we know the handle	 * is valid to something.	 */	channel = TclWinOpenFileChannel(handle, channelName, mode, 0);    }    return channel;}#ifdef HAVE_NO_SEHstatic__attribute__ ((cdecl)) __attribute__ ((used))EXCEPTION_DISPOSITION_except_makefilechannel_handler(    struct _EXCEPTION_RECORD *ExceptionRecord,    void *EstablisherFrame,    struct _CONTEXT *ContextRecord,    void *DispatcherContext){    __asm__ __volatile__ (            "jmp makefilechannel_reentry");    return 0; /* Function does not return */}#endif/* *---------------------------------------------------------------------- * * TclpGetDefaultStdChannel -- * *	Constructs a channel for the specified standard OS handle. * * Results: *	Returns the specified default standard channel, or NULL. * * Side effects: *	May cause the creation of a standard channel and the underlying *	file. * *---------------------------------------------------------------------- */Tcl_ChannelTclpGetDefaultStdChannel(type)    int type;			/* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */{    Tcl_Channel channel;    HANDLE handle;    int mode;    char *bufMode;    DWORD handleId;		/* Standard handle to retrieve. */    switch (type) {	case TCL_STDIN:	    handleId = STD_INPUT_HANDLE;	    mode = TCL_READABLE;	    bufMode = "line";	    break;	case TCL_STDOUT:	    handleId = STD_OUTPUT_HANDLE;	    mode = TCL_WRITABLE;	    bufMode = "line";	    break;	case TCL_STDERR:	    handleId = STD_ERROR_HANDLE;	    mode = TCL_WRITABLE;	    bufMode = "none";	    break;	default:	    panic("TclGetDefaultStdChannel: Unexpected channel type");	    break;    }    handle = GetStdHandle(handleId);    /*     * Note that we need to check for 0 because Windows may return 0 if this     * is not a console mode application, even though this is not a valid     * handle.     */    if ((handle == INVALID_HANDLE_VALUE) || (handle == 0)) {	return (Tcl_Channel) NULL;    }    channel = Tcl_MakeFileChannel(handle, mode);    if (channel == NULL) {	return (Tcl_Channel) NULL;    }    /*     * Set up the normal channel options for stdio handles.     */    if ((Tcl_SetChannelOption((Tcl_Interp *) NULL, channel, "-translation",            "auto") == TCL_ERROR)	    || (Tcl_SetChannelOption((Tcl_Interp *) NULL, channel, "-eofchar",		    "\032 {}") == TCL_ERROR)	    || (Tcl_SetChannelOption((Tcl_Interp *) NULL, channel,		    "-buffering", bufMode) == TCL_ERROR)) {        Tcl_Close((Tcl_Interp *) NULL, channel);        return (Tcl_Channel) NULL;    }    return channel;}/* *---------------------------------------------------------------------- * * TclWinOpenFileChannel -- * *	Constructs a File channel for the specified standard OS handle. *      This is a helper function to break up the construction of  *      channels into File, Console, or Serial. * * Results: *	Returns the new channel, or NULL. * * Side effects: *	May open the channel and may cause creation of a file on the *	file system. * *---------------------------------------------------------------------- */Tcl_ChannelTclWinOpenFileChannel(handle, channelName, permissions, appendMode)    HANDLE handle;    char *channelName;    int permissions;    int appendMode;{    FileInfo *infoPtr;    ThreadSpecificData *tsdPtr;    tsdPtr = FileInit();    /*     * See if a channel with this handle already exists.     */        for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL; 	 infoPtr = infoPtr->nextPtr) {	if (infoPtr->handle == (HANDLE) handle) {	    return (permissions == infoPtr->validMask) ? infoPtr->channel : NULL;	}    }    infoPtr = (FileInfo *) ckalloc((unsigned) sizeof(FileInfo));    infoPtr->nextPtr = tsdPtr->firstFilePtr;    tsdPtr->firstFilePtr = infoPtr;    infoPtr->validMask = permissions;    infoPtr->watchMask = 0;    infoPtr->flags = appendMode;    infoPtr->handle = handle;    infoPtr->dirty = 0;    wsprintfA(channelName, "file%lx", (int) infoPtr);        infoPtr->channel = Tcl_CreateChannel(&fileChannelType, channelName,	    (ClientData) infoPtr, permissions);        /*     * Files have default translation of AUTO and ^Z eof char, which     * means that a ^Z will be accepted as EOF when reading.     */        Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto");    Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}");    return infoPtr->channel;}/* *---------------------------------------------------------------------- * * TclWinFlushDirtyChannels -- * *	Flush all dirty channels to disk, so that requesting the *	size of any file returns the correct value. * * Results: *	None. * * Side effects: *	Information is actually written to disk now, rather than *	later.  Don't call this too often, or there will be a  *	performance hit (i.e. only call when we need to ask for *	the size of a file). * *---------------------------------------------------------------------- */voidTclWinFlushDirtyChannels (){    FileInfo *infoPtr;    ThreadSpecificData *tsdPtr;    tsdPtr = FileInit();    /*     * Flush all channels which are dirty, i.e. may have data pending     * in the OS     */        for (infoPtr = tsdPtr->firstFilePtr;	 infoPtr != NULL; 	 infoPtr = infoPtr->nextPtr) {	if (infoPtr->dirty) {	    FlushFileBuffers(infoPtr->handle);	    infoPtr->dirty = 0;	}    }}

⌨️ 快捷键说明

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