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

📄 tclwinsock.c

📁 这是leon3处理器的交叉编译链
💻 C
📖 第 1 页 / 共 5 页
字号:
	 */	error = (*winSock.WSAGetLastError)();	if (error == WSAEWOULDBLOCK) {	    infoPtr->readyEvents &= ~(FD_WRITE);	    if (infoPtr->flags & SOCKET_ASYNC) {		*errorCodePtr = EWOULDBLOCK;		bytesWritten = -1;		break;	    } 	} else {	    TclWinConvertWSAError(error);	    *errorCodePtr = Tcl_GetErrno();	    bytesWritten = -1;	    break;	}	/*	 * In the blocking case, wait until the file becomes writable	 * or closed and try again.	 */	if (!WaitForSocketEvent(infoPtr, FD_WRITE|FD_CLOSE, errorCodePtr)) {	    bytesWritten = -1;	    break;	}    }    SendMessage(tsdPtr->hwnd, SOCKET_SELECT,	    (WPARAM) SELECT, (LPARAM) infoPtr);        return bytesWritten;}/* *---------------------------------------------------------------------- * * TcpGetOptionProc -- * *	Computes an option value for a TCP socket based channel, or a *	list of all options and their values. * *	Note: This code is based on code contributed by John Haxby. * * Results: *	A standard Tcl result. The value of the specified option or a *	list of all options and	their values is returned in the *	supplied DString. * * Side effects: *	None. * *---------------------------------------------------------------------- */static intTcpGetOptionProc(instanceData, interp, optionName, dsPtr)    ClientData instanceData;		/* Socket state. */    Tcl_Interp *interp;                 /* For error reporting - can be NULL */    CONST char *optionName;		/* Name of the option to                                         * retrieve the value for, or                                         * NULL to get all options and                                         * their values. */    Tcl_DString *dsPtr;			/* Where to store the computed                                         * value; initialized by caller. */{    SocketInfo *infoPtr;    struct sockaddr_in sockname;    struct sockaddr_in peername;    struct hostent *hostEntPtr;    SOCKET sock;    int size = sizeof(struct sockaddr_in);    size_t len = 0;    char buf[TCL_INTEGER_SPACE];    /*     * Check that WinSock is initialized; do not call it if not, to     * prevent system crashes. This can happen at exit time if the exit     * handler for WinSock ran before other exit handlers that want to     * use sockets.     */    if (!SocketsEnabled()) {	if (interp) {	    Tcl_AppendResult(interp, "winsock is not initialized", NULL);	}        return TCL_ERROR;    }        infoPtr = (SocketInfo *) instanceData;    sock = (int) infoPtr->socket;    if (optionName != (char *) NULL) {        len = strlen(optionName);    }    if ((len > 1) && (optionName[1] == 'e') &&	    (strncmp(optionName, "-error", len) == 0)) {	int optlen;	int err, ret;    	optlen = sizeof(int);	ret = TclWinGetSockOpt(sock, SOL_SOCKET, SO_ERROR,		(char *)&err, &optlen);	if (ret == SOCKET_ERROR) {	    err = (*winSock.WSAGetLastError)();	}	if (err) {	    TclWinConvertWSAError(err);	    Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()), -1);	}	return TCL_OK;    }    if ((len == 0) ||            ((len > 1) && (optionName[1] == 'p') &&                    (strncmp(optionName, "-peername", len) == 0))) {        if ((*winSock.getpeername)(sock, (struct sockaddr *) &peername, &size)                == 0) {            if (len == 0) {                Tcl_DStringAppendElement(dsPtr, "-peername");                Tcl_DStringStartSublist(dsPtr);            }            Tcl_DStringAppendElement(dsPtr,                    (*winSock.inet_ntoa)(peername.sin_addr));	    if (peername.sin_addr.s_addr == 0) {	        hostEntPtr = (struct hostent *) NULL;	    } else {	        hostEntPtr = (*winSock.gethostbyaddr)(                    (char *) &(peername.sin_addr), sizeof(peername.sin_addr),		    AF_INET);	    }            if (hostEntPtr != (struct hostent *) NULL) {                Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name);            } else {                Tcl_DStringAppendElement(dsPtr,                        (*winSock.inet_ntoa)(peername.sin_addr));            }	    TclFormatInt(buf, (*winSock.ntohs)(peername.sin_port));            Tcl_DStringAppendElement(dsPtr, buf);            if (len == 0) {                Tcl_DStringEndSublist(dsPtr);            } else {                return TCL_OK;            }        } else {            /*             * getpeername failed - but if we were asked for all the options             * (len==0), don't flag an error at that point because it could             * be an fconfigure request on a server socket. (which have             * no peer). {copied from unix/tclUnixChan.c}             */            if (len) {		TclWinConvertWSAError((*winSock.WSAGetLastError)());                if (interp) {                    Tcl_AppendResult(interp, "can't get peername: ",                                     Tcl_PosixError(interp),                                     (char *) NULL);                }                return TCL_ERROR;            }        }    }    if ((len == 0) ||            ((len > 1) && (optionName[1] == 's') &&                    (strncmp(optionName, "-sockname", len) == 0))) {        if ((*winSock.getsockname)(sock, (struct sockaddr *) &sockname, &size)                == 0) {            if (len == 0) {                Tcl_DStringAppendElement(dsPtr, "-sockname");                Tcl_DStringStartSublist(dsPtr);            }            Tcl_DStringAppendElement(dsPtr,                    (*winSock.inet_ntoa)(sockname.sin_addr));	    if (sockname.sin_addr.s_addr == 0) {	        hostEntPtr = (struct hostent *) NULL;	    } else {	        hostEntPtr = (*winSock.gethostbyaddr)(                    (char *) &(sockname.sin_addr), sizeof(peername.sin_addr),		    AF_INET);	    }            if (hostEntPtr != (struct hostent *) NULL) {                Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name);            } else {                Tcl_DStringAppendElement(dsPtr,                        (*winSock.inet_ntoa)(sockname.sin_addr));            }            TclFormatInt(buf, (*winSock.ntohs)(sockname.sin_port));            Tcl_DStringAppendElement(dsPtr, buf);            if (len == 0) {                Tcl_DStringEndSublist(dsPtr);            } else {                return TCL_OK;            }        } else {	    if (interp) {		TclWinConvertWSAError((*winSock.WSAGetLastError)());		Tcl_AppendResult(interp, "can't get sockname: ",				 Tcl_PosixError(interp),				 (char *) NULL);	    }	    return TCL_ERROR;	}    }    if (len > 0) {        return Tcl_BadChannelOption(interp, optionName, "peername sockname");    }    return TCL_OK;}/* *---------------------------------------------------------------------- * * TcpWatchProc -- * *	Informs the channel driver of the events that the generic *	channel code wishes to receive on this socket. * * Results: *	None. * * Side effects: *	May cause the notifier to poll if any of the specified  *	conditions are already true. * *---------------------------------------------------------------------- */static voidTcpWatchProc(instanceData, mask)    ClientData instanceData;		/* The socket state. */    int mask;				/* Events of interest; an OR-ed                                         * combination of TCL_READABLE,                                         * TCL_WRITABLE and TCL_EXCEPTION. */{    SocketInfo *infoPtr = (SocketInfo *) instanceData;        /*     * Update the watch events mask. Only if the socket is not a     * server socket. Fix for SF Tcl Bug #557878.     */    if (!infoPtr->acceptProc) {            infoPtr->watchEvents = 0;	if (mask & TCL_READABLE) {	    infoPtr->watchEvents |= (FD_READ|FD_CLOSE|FD_ACCEPT);	}	if (mask & TCL_WRITABLE) {	    infoPtr->watchEvents |= (FD_WRITE|FD_CONNECT);	}      	/*	 * If there are any conditions already set, then tell the notifier to poll	 * rather than block.	 */	if (infoPtr->readyEvents & infoPtr->watchEvents) {	    Tcl_Time blockTime = { 0, 0 };	    Tcl_SetMaxBlockTime(&blockTime);	}    }}/* *---------------------------------------------------------------------- * * TcpGetProc -- * *	Called from Tcl_GetChannelHandle to retrieve an OS handle from inside *	a TCP socket based channel. * * Results: *	Returns TCL_OK with the socket in handlePtr. * * Side effects: *	None. * *---------------------------------------------------------------------- */static intTcpGetHandleProc(instanceData, direction, handlePtr)    ClientData instanceData;	/* The socket state. */    int direction;		/* Not used. */    ClientData *handlePtr;	/* Where to store the handle.  */{    SocketInfo *statePtr = (SocketInfo *) instanceData;    *handlePtr = (ClientData) statePtr->socket;    return TCL_OK;}/* *---------------------------------------------------------------------- * * SocketThread -- * *	Helper thread used to manage the socket event handling window. * * Results: *	1 if unable to create socket event window, 0 otherwise. * * Side effects: *	None. * *---------------------------------------------------------------------- */static DWORD WINAPISocketThread(LPVOID arg){    MSG msg;    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)(arg);    tsdPtr->hwnd = CreateWindowA("TclSocket", "TclSocket", 	    WS_TILED, 0, 0, 0, 0, NULL, NULL, windowClass.hInstance, NULL);    /*     * Signal the main thread that the window has been created     * and that the socket thread is ready to go.     */        SetEvent(tsdPtr->readyEvent);        if (tsdPtr->hwnd == NULL) {	return 1;    } else {	/*	 * store the tsdPtr, it's from a different thread, so it's	 * not directly accessible, but needed.	 */#ifdef _WIN64	SetWindowLongPtr(tsdPtr->hwnd, GWLP_USERDATA, (LONG_PTR) tsdPtr);#else	SetWindowLong(tsdPtr->hwnd, GWL_USERDATA, (LONG) tsdPtr);#endif    }    while (1) {	/*	 * Process all outstanding messages on the socket window.	 */	while (PeekMessage(&msg, tsdPtr->hwnd, 0, 0, PM_REMOVE)) {	    DispatchMessage(&msg);	}	WaitMessage();    }}/* *---------------------------------------------------------------------- * * SocketProc -- * *	This function is called when WSAAsyncSelect has been used *	to register interest in a socket event, and the event has *	occurred. * * Results: *	0 on success. * * Side effects: *	The flags for the given socket are updated to reflect the *	event that occured. * *---------------------------------------------------------------------- */static LRESULT CALLBACKSocketProc(hwnd, message, wParam, lParam)    HWND hwnd;    UINT message;    WPARAM wParam;    LPARAM lParam;{    int event, error;    SOCKET socket;    SocketInfo *infoPtr;    ThreadSpecificData *tsdPtr =#ifdef _WIN64	(ThreadSpecificData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);#else	(ThreadSpecificData *) GetWindowLong(hwnd, GWL_USERDATA);#endif    switch (message) {	default:	    return DefWindowProc(hwnd, message, wParam, lParam);	    break;	    	case SOCKET_MESSAGE:	    event = WSAGETSELECTEVENT(lParam);	    error = WSAGETSELECTERROR(lParam);	    socket = (SOCKET) wParam;	    /*	     * Find the specified socket on the socket list and update its	     * eventState flag.	     */	    WaitForSingleObject(tsdPtr->socketListLock, INFINITE);	    for (infoPtr = tsdPtr->socketList; infoPtr != NULL; 		 infoPtr = infoPtr->nextPtr) {		if (infoPtr->socket == socket) {		    /*		     * Update the socket state.		     */		    /*		     * A count of FD_ACCEPTS is stored, so if an FD_CLOSE event		     * happens, then clear the FD_ACCEPT count.  Otherwise,		     * increment the count if the current event is and		     * FD_ACCEPT.		     */		    		    if (event & FD_CLOSE) {			infoPtr->acceptEventCount = 0;			infoPtr->readyEvents &= ~(FD_WRITE|FD_ACCEPT);		    } else if (event & FD_ACCEPT) {			infoPtr->acceptEventCount++;		    }		    if (event & FD_CONNECT) {			/*			 * The socket is now connected,			 * clear the async connect flag.			 */						infoPtr->flags &= ~(SOCKET_ASYNC_CONNECT);						/*			 * Remember any error that occurred so we can report			 * connection failures.			 */						if (error != ERROR_SUCCESS) {			    TclWinConvertWSAError(error);			    infoPtr->lastError = Tcl_GetErrno();			}					    } 		    if(infoPtr->flags & SOCKET_ASYNC_CONNECT) {			infoPtr->flags &= ~(SOCKET_ASYNC_CONNECT);			if (error != ERROR_SUCCESS) {			    TclWinConvertWSAError(error);			    infoPtr->lastError = Tcl_GetErrno();			}			infoPtr->readyEvents 

⌨️ 快捷键说明

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