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

📄 tclwinsock.c

📁 这是leon3处理器的交叉编译链
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  * tclWinSock.c -- * *	This file contains Windows-specific socket related code. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclWinSock.c,v 1.26 2002/05/24 18:57:09 andreas_kupries Exp $ */#include "tclWinInt.h"/* * The following variable is used to tell whether this module has been * initialized. */static int initialized = 0;static int  hostnameInitialized = 0;static char hostname[255];	/* This buffer should be big enough for                                 * hostname plus domain name. */TCL_DECLARE_MUTEX(socketMutex)/* * The following structure contains pointers to all of the WinSock API entry * points used by Tcl.  It is initialized by InitSockets.  Since we * dynamically load Winsock.dll on demand, we must use this function table * to refer to functions in the socket API. */static struct {    HINSTANCE hInstance;	/* Handle to WinSock library. */    SOCKET (PASCAL FAR *accept)(SOCKET s, struct sockaddr FAR *addr,	    int FAR *addrlen);    int (PASCAL FAR *bind)(SOCKET s, const struct sockaddr FAR *addr,	    int namelen);    int (PASCAL FAR *closesocket)(SOCKET s);    int (PASCAL FAR *connect)(SOCKET s, const struct sockaddr FAR *name,	    int namelen);    int (PASCAL FAR *ioctlsocket)(SOCKET s, long cmd, u_long FAR *argp);    int (PASCAL FAR *getsockopt)(SOCKET s, int level, int optname,	    char FAR * optval, int FAR *optlen);    u_short (PASCAL FAR *htons)(u_short hostshort);    unsigned long (PASCAL FAR *inet_addr)(const char FAR * cp);    char FAR * (PASCAL FAR *inet_ntoa)(struct in_addr in);    int (PASCAL FAR *listen)(SOCKET s, int backlog);    u_short (PASCAL FAR *ntohs)(u_short netshort);    int (PASCAL FAR *recv)(SOCKET s, char FAR * buf, int len, int flags);    int (PASCAL FAR *select)(int nfds, fd_set FAR * readfds,	    fd_set FAR * writefds, fd_set FAR * exceptfds,	    const struct timeval FAR * tiemout);    int (PASCAL FAR *send)(SOCKET s, const char FAR * buf, int len, int flags);    int (PASCAL FAR *setsockopt)(SOCKET s, int level, int optname,	    const char FAR * optval, int optlen);    int (PASCAL FAR *shutdown)(SOCKET s, int how);    SOCKET (PASCAL FAR *socket)(int af, int type, int protocol);    struct hostent FAR * (PASCAL FAR *gethostbyname)(const char FAR * name);    struct hostent FAR * (PASCAL FAR *gethostbyaddr)(const char FAR *addr,            int addrlen, int addrtype);    int (PASCAL FAR *gethostname)(char FAR * name, int namelen);    int (PASCAL FAR *getpeername)(SOCKET sock, struct sockaddr FAR *name,            int FAR *namelen);    struct servent FAR * (PASCAL FAR *getservbyname)(const char FAR * name,	    const char FAR * proto);    int (PASCAL FAR *getsockname)(SOCKET sock, struct sockaddr FAR *name,            int FAR *namelen);    int (PASCAL FAR *WSAStartup)(WORD wVersionRequired, LPWSADATA lpWSAData);    int (PASCAL FAR *WSACleanup)(void);    int (PASCAL FAR *WSAGetLastError)(void);    int (PASCAL FAR *WSAAsyncSelect)(SOCKET s, HWND hWnd, u_int wMsg,	    long lEvent);} winSock;/* * The following defines declare the messages used on socket windows. */#define SOCKET_MESSAGE	WM_USER+1#define SOCKET_SELECT	WM_USER+2#define SOCKET_TERMINATE WM_USER+3#define SELECT          TRUE#define UNSELECT	FALSE/* * The following structure is used to store the data associated with * each socket. */typedef struct SocketInfo {    Tcl_Channel channel;	   /* Channel associated with this socket. */    SOCKET socket;		   /* Windows SOCKET handle. */    int flags;			   /* Bit field comprised of the flags				    * described below.  */    int watchEvents;		   /* OR'ed combination of FD_READ, FD_WRITE,                                    * FD_CLOSE, FD_ACCEPT and FD_CONNECT that				    * indicate which events are interesting. */    int readyEvents;		   /* OR'ed combination of FD_READ, FD_WRITE,                                    * FD_CLOSE, FD_ACCEPT and FD_CONNECT that				    * indicate which events have occurred. */    int selectEvents;		   /* OR'ed combination of FD_READ, FD_WRITE,                                    * FD_CLOSE, FD_ACCEPT and FD_CONNECT that				    * indicate which events are currently				    * being selected. */    int acceptEventCount;          /* Count of the current number of FD_ACCEPTs				    * that have arrived and not processed. */    Tcl_TcpAcceptProc *acceptProc; /* Proc to call on accept. */    ClientData acceptProcData;	   /* The data for the accept proc. */    int lastError;		   /* Error code from last message. */    struct SocketInfo *nextPtr;	   /* The next socket on the global socket				    * list. */} SocketInfo;/* * The following structure is what is added to the Tcl event queue when * a socket event occurs. */typedef struct SocketEvent {    Tcl_Event header;		/* Information that is standard for				 * all events. */    SOCKET socket;		/* Socket descriptor that is ready.  Used				 * to find the SocketInfo structure for				 * the file (can't point directly to the				 * SocketInfo structure because it could				 * go away while the event is queued). */} SocketEvent;/* * This defines the minimum buffersize maintained by the kernel. */#define TCP_BUFFER_SIZE 4096/* * The following macros may be used to set the flags field of * a SocketInfo structure. */#define SOCKET_ASYNC		(1<<0)	/* The socket is in blocking mode. */#define SOCKET_EOF		(1<<1)	/* A zero read happened on					 * the socket. */#define SOCKET_ASYNC_CONNECT	(1<<2)	/* This socket uses async connect. */#define SOCKET_PENDING		(1<<3)	/* A message has been sent					 * for this socket */typedef struct ThreadSpecificData {    /*     * Every open socket has an entry on the following list.     */        HWND hwnd;		    /* Handle to window for socket messages. */    HANDLE socketThread;    /* Thread handling the window */    Tcl_ThreadId threadId;  /* Parent thread. */    HANDLE readyEvent;      /* Event indicating that a socket event is ready.			     * Also used to indicate that the socketThread has			     * been initialized and has started. */    HANDLE socketListLock;  /* Win32 Event to lock the socketList */    SocketInfo *socketList;} ThreadSpecificData;static Tcl_ThreadDataKey dataKey;static WNDCLASSA windowClass;/* * Static functions defined in this file. */static SocketInfo *	CreateSocket _ANSI_ARGS_((Tcl_Interp *interp,			    int port, CONST char *host, int server,			    CONST char *myaddr, int myport, int async));static int		CreateSocketAddress _ANSI_ARGS_(			    (struct sockaddr_in *sockaddrPtr,			    CONST char *host, int port));static void		InitSockets _ANSI_ARGS_((void));static SocketInfo *	NewSocketInfo _ANSI_ARGS_((SOCKET socket));static void		SocketCheckProc _ANSI_ARGS_((ClientData clientData,			    int flags));static int		SocketEventProc _ANSI_ARGS_((Tcl_Event *evPtr,			    int flags));static void		SocketExitHandler _ANSI_ARGS_((ClientData clientData));static LRESULT CALLBACK	SocketProc _ANSI_ARGS_((HWND hwnd, UINT message,			    WPARAM wParam, LPARAM lParam));static void		SocketSetupProc _ANSI_ARGS_((ClientData clientData,			    int flags));static void		SocketThreadExitHandler _ANSI_ARGS_((ClientData clientData));static int		SocketsEnabled _ANSI_ARGS_((void));static void		TcpAccept _ANSI_ARGS_((SocketInfo *infoPtr));static int		TcpBlockProc _ANSI_ARGS_((ClientData instanceData,			    int mode));static int		TcpCloseProc _ANSI_ARGS_((ClientData instanceData,	            	    Tcl_Interp *interp));static int		TcpGetOptionProc _ANSI_ARGS_((ClientData instanceData,		            Tcl_Interp *interp, CONST char *optionName,			    Tcl_DString *optionValue));static int		TcpInputProc _ANSI_ARGS_((ClientData instanceData,	            	    char *buf, int toRead, int *errorCode));static int		TcpOutputProc _ANSI_ARGS_((ClientData instanceData,	            	    CONST char *buf, int toWrite, int *errorCode));static void		TcpWatchProc _ANSI_ARGS_((ClientData instanceData,		            int mask));static int		TcpGetHandleProc _ANSI_ARGS_((ClientData instanceData,		            int direction, ClientData *handlePtr));static int		WaitForSocketEvent _ANSI_ARGS_((SocketInfo *infoPtr,		            int events, int *errorCodePtr));static DWORD WINAPI     SocketThread _ANSI_ARGS_((LPVOID arg));/* * This structure describes the channel type structure for TCP socket * based IO. */static Tcl_ChannelType tcpChannelType = {    "tcp",			/* Type name. */    TCL_CHANNEL_VERSION_2,	/* v2 channel */    TcpCloseProc,		/* Close proc. */    TcpInputProc,		/* Input proc. */    TcpOutputProc,		/* Output proc. */    NULL,			/* Seek proc. */    NULL,			/* Set option proc. */    TcpGetOptionProc,		/* Get option proc. */    TcpWatchProc,		/* Set up notifier to watch this channel. */    TcpGetHandleProc,		/* Get an OS handle from channel. */    NULL,			/* close2proc. */    TcpBlockProc,		/* Set socket into (non-)blocking mode. */    NULL,			/* flush proc. */    NULL,			/* handler proc. */};/* * Define version of Winsock required by Tcl. */#define WSA_VERSION_REQD MAKEWORD(1,1)/* *---------------------------------------------------------------------- * * InitSockets -- * *	Initialize the socket module.  Attempts to load the wsock32.dll *	library and set up the winSock function table.  If successful, *	registers the event window for the socket notifier code. * *	Assumes Mutex is held. * * Results: *	None. * * Side effects: *	Dynamically loads wsock32.dll, and registers a new window *	class and creates a window for use in asynchronous socket *	notification. * *---------------------------------------------------------------------- */static voidInitSockets(){    DWORD id;    WSADATA wsaData;    ThreadSpecificData *tsdPtr = 	(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);    if (! initialized) {	initialized = 1;	Tcl_CreateExitHandler(SocketExitHandler, (ClientData) NULL);	winSock.hInstance = LoadLibraryA("wsock32.dll");	/*	 * Initialize the function table.	 */	if (!SocketsEnabled()) {	    return;	}    	winSock.accept = (SOCKET (PASCAL FAR *)(SOCKET s,		struct sockaddr FAR *addr, int FAR *addrlen))	    GetProcAddress(winSock.hInstance, "accept");	winSock.bind = (int (PASCAL FAR *)(SOCKET s,		const struct sockaddr FAR *addr, int namelen))	    GetProcAddress(winSock.hInstance, "bind");	winSock.closesocket = (int (PASCAL FAR *)(SOCKET s))	    GetProcAddress(winSock.hInstance, "closesocket");	winSock.connect = (int (PASCAL FAR *)(SOCKET s,		const struct sockaddr FAR *name, int namelen))	    GetProcAddress(winSock.hInstance, "connect");	winSock.ioctlsocket = (int (PASCAL FAR *)(SOCKET s, long cmd,		u_long FAR *argp))	    GetProcAddress(winSock.hInstance, "ioctlsocket");	winSock.getsockopt = (int (PASCAL FAR *)(SOCKET s,		int level, int optname, char FAR * optval, int FAR *optlen))	    GetProcAddress(winSock.hInstance, "getsockopt");	winSock.htons = (u_short (PASCAL FAR *)(u_short hostshort))	    GetProcAddress(winSock.hInstance, "htons");	winSock.inet_addr = (unsigned long (PASCAL FAR *)(const char FAR *cp))	    GetProcAddress(winSock.hInstance, "inet_addr");	winSock.inet_ntoa = (char FAR * (PASCAL FAR *)(struct in_addr in))	    GetProcAddress(winSock.hInstance, "inet_ntoa");	winSock.listen = (int (PASCAL FAR *)(SOCKET s, int backlog))	    GetProcAddress(winSock.hInstance, "listen");	winSock.ntohs = (u_short (PASCAL FAR *)(u_short netshort))	    GetProcAddress(winSock.hInstance, "ntohs");	winSock.recv = (int (PASCAL FAR *)(SOCKET s, char FAR * buf,		int len, int flags)) GetProcAddress(winSock.hInstance, "recv");	winSock.select = (int (PASCAL FAR *)(int nfds, fd_set FAR * readfds,		fd_set FAR * writefds, fd_set FAR * exceptfds,		const struct timeval FAR * tiemout))	    GetProcAddress(winSock.hInstance, "select");	winSock.send = (int (PASCAL FAR *)(SOCKET s, const char FAR * buf,		int len, int flags)) GetProcAddress(winSock.hInstance, "send");	winSock.setsockopt = (int (PASCAL FAR *)(SOCKET s, int level,		int optname, const char FAR * optval, int optlen))	    GetProcAddress(winSock.hInstance, "setsockopt");	winSock.shutdown = (int (PASCAL FAR *)(SOCKET s, int how))	    GetProcAddress(winSock.hInstance, "shutdown");	winSock.socket = (SOCKET (PASCAL FAR *)(int af, int type,		int protocol)) GetProcAddress(winSock.hInstance, "socket");	winSock.gethostbyaddr = (struct hostent FAR * (PASCAL FAR *)		(const char FAR *addr, int addrlen, int addrtype))	    GetProcAddress(winSock.hInstance, "gethostbyaddr");	winSock.gethostbyname = (struct hostent FAR * (PASCAL FAR *)		(const char FAR *name))	    GetProcAddress(winSock.hInstance, "gethostbyname");	winSock.gethostname = (int (PASCAL FAR *)(char FAR * name,		int namelen)) GetProcAddress(winSock.hInstance, "gethostname");	winSock.getpeername = (int (PASCAL FAR *)(SOCKET sock,		struct sockaddr FAR *name, int FAR *namelen))	    GetProcAddress(winSock.hInstance, "getpeername");	winSock.getservbyname = (struct servent FAR * (PASCAL FAR *)		(const char FAR * name, const char FAR * proto))	    GetProcAddress(winSock.hInstance, "getservbyname");	winSock.getsockname = (int (PASCAL FAR *)(SOCKET sock,		struct sockaddr FAR *name, int FAR *namelen))	    GetProcAddress(winSock.hInstance, "getsockname");	winSock.WSAStartup = (int (PASCAL FAR *)(WORD wVersionRequired,		LPWSADATA lpWSAData)) GetProcAddress(winSock.hInstance, "WSAStartup");	winSock.WSACleanup = (int (PASCAL FAR *)(void))	    GetProcAddress(winSock.hInstance, "WSACleanup");	winSock.WSAGetLastError = (int (PASCAL FAR *)(void))	    GetProcAddress(winSock.hInstance, "WSAGetLastError");	winSock.WSAAsyncSelect = (int (PASCAL FAR *)(SOCKET s, HWND hWnd,		u_int wMsg, long lEvent))	    GetProcAddress(winSock.hInstance, "WSAAsyncSelect");    	/*	 * Now check that all fields are properly initialized. If not, return	 * zero to indicate that we failed to initialize properly.	 */    	if ((winSock.hInstance == NULL) ||		(winSock.accept == NULL) ||		(winSock.bind == NULL) ||		(winSock.closesocket == NULL) ||		(winSock.connect == NULL) ||		(winSock.ioctlsocket == NULL) ||		(winSock.getsockopt == NULL) ||		(winSock.htons == NULL) ||		(winSock.inet_addr == NULL) ||		(winSock.inet_ntoa == NULL) ||		(winSock.listen == NULL) ||		(winSock.ntohs == NULL) ||		(winSock.recv == NULL) ||		(winSock.select == NULL) ||		(winSock.send == NULL) ||		(winSock.setsockopt == NULL) ||		(winSock.socket == NULL) ||		(winSock.gethostbyname == NULL) ||		(winSock.gethostbyaddr == NULL) ||		(winSock.gethostname == NULL) ||		(winSock.getpeername == NULL) ||		(winSock.getservbyname == NULL) ||		(winSock.getsockname == NULL) ||		(winSock.WSAStartup == NULL) ||		(winSock.WSACleanup == NULL) ||		(winSock.WSAGetLastError == NULL) ||		(winSock.WSAAsyncSelect == NULL)) {	    goto unloadLibrary;	}		/*	 * Create the async notification window with a new class.  We	 * must create a new class to avoid a Windows 95 bug that causes	 * us to get the wrong message number for socket events if the	 * message window is a subclass of a static control.	 */    	windowClass.style = 0;	windowClass.cbClsExtra = 0;	windowClass.cbWndExtra = 0;	windowClass.hInstance = TclWinGetTclInstance();	windowClass.hbrBackground = NULL;	windowClass.lpszMenuName = NULL;	windowClass.lpszClassName = "TclSocket";	windowClass.lpfnWndProc = SocketProc;	windowClass.hIcon = NULL;	windowClass.hCursor = NULL;	if (!RegisterClassA(&windowClass)) {	    TclWinConvertError(GetLastError());	    (*winSock.WSACleanup)();	    goto unloadLibrary;	}		/*	 * Initialize the winsock library and check the version number.	 */    	if ((*winSock.WSAStartup)(WSA_VERSION_REQD, &wsaData) != 0) {	    goto unloadLibrary;	}	if (wsaData.wVersion != WSA_VERSION_REQD) {	    (*winSock.WSACleanup)();	    goto unloadLibrary;	}    }    /*     * Check for per-thread initialization.     */    if (tsdPtr == NULL) {	tsdPtr = TCL_TSD_INIT(&dataKey);	tsdPtr->socketList = NULL;	tsdPtr->hwnd = NULL;	tsdPtr->threadId = Tcl_GetCurrentThread();		tsdPtr->readyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);	tsdPtr->socketListLock = CreateEvent(NULL, FALSE, TRUE, NULL);	tsdPtr->socketThread = CreateThread(NULL, 8000, SocketThread,		tsdPtr, 0, &id);	SetThreadPriority(tsdPtr->socketThread, THREAD_PRIORITY_HIGHEST); 	if (tsdPtr->socketThread == NULL) {	    goto unloadLibrary;	}		/*	 * Wait for the thread to signal that the window has	 * been created and is ready to go.  Timeout after twenty	 * seconds.	 */		if (WaitForSingleObject(tsdPtr->readyEvent, 20000) == WAIT_TIMEOUT) {	    goto unloadLibrary;	}

⌨️ 快捷键说明

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