mirror of
				https://github.com/lunarmodules/luasocket.git
				synced 2025-10-31 18:35:45 +01:00 
			
		
		
		
	Compiles and runs on linux and windows, using DLLs!
This commit is contained in:
		
							
								
								
									
										19
									
								
								src/inet.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								src/inet.c
									
									
									
									
									
								
							| @@ -19,10 +19,6 @@ static int inet_global_tohostname(lua_State *L); | ||||
|  | ||||
| static void inet_pushresolved(lua_State *L, struct hostent *hp); | ||||
|  | ||||
| #ifdef INET_ATON | ||||
| static int inet_aton(const char *cp, struct in_addr *inp); | ||||
| #endif | ||||
|  | ||||
| static luaL_reg func[] = { | ||||
|     { "toip", inet_global_toip }, | ||||
|     { "tohostname", inet_global_tohostname }, | ||||
| @@ -196,9 +192,11 @@ static void inet_pushresolved(lua_State *L, struct hostent *hp) | ||||
| * Returns | ||||
| *   NULL in case of success, error message otherwise | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| const char *inet_tryconnect(p_sock ps, const char *address, ushort port) | ||||
| const char *inet_tryconnect(p_sock ps, const char *address,  | ||||
|         unsigned short port) | ||||
| { | ||||
|     struct sockaddr_in remote; | ||||
|     const char *err; | ||||
|     memset(&remote, 0, sizeof(remote)); | ||||
|     remote.sin_family = AF_INET; | ||||
|     remote.sin_port = htons(port); | ||||
| @@ -213,7 +211,7 @@ const char *inet_tryconnect(p_sock ps, const char *address, ushort port) | ||||
|         } | ||||
|     } else remote.sin_family = AF_UNSPEC; | ||||
|     sock_setblocking(ps); | ||||
|     const char *err = sock_connect(ps, (SA *) &remote, sizeof(remote)); | ||||
|     err = sock_connect(ps, (SA *) &remote, sizeof(remote)); | ||||
|     if (err) { | ||||
|         sock_destroy(ps); | ||||
|         *ps = SOCK_INVALID; | ||||
| @@ -233,10 +231,11 @@ const char *inet_tryconnect(p_sock ps, const char *address, ushort port) | ||||
| * Returns | ||||
| *   NULL in case of success, error message otherwise | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| const char *inet_trybind(p_sock ps, const char *address, ushort port,  | ||||
| const char *inet_trybind(p_sock ps, const char *address, unsigned short port,  | ||||
|         int backlog) | ||||
| { | ||||
|     struct sockaddr_in local; | ||||
|     const char *err; | ||||
|     memset(&local, 0, sizeof(local)); | ||||
|     /* address is either wildcard or a valid ip address */ | ||||
|     local.sin_addr.s_addr = htonl(INADDR_ANY); | ||||
| @@ -251,7 +250,7 @@ const char *inet_trybind(p_sock ps, const char *address, ushort port, | ||||
|         memcpy(&local.sin_addr, *addr, sizeof(struct in_addr)); | ||||
|     } | ||||
|     sock_setblocking(ps); | ||||
|     const char *err = sock_bind(ps, (SA *) &local, sizeof(local)); | ||||
|     err = sock_bind(ps, (SA *) &local, sizeof(local)); | ||||
|     if (err) { | ||||
|         sock_destroy(ps); | ||||
|         *ps = SOCK_INVALID; | ||||
| @@ -279,8 +278,8 @@ const char *inet_trycreate(p_sock ps, int type) | ||||
| * Some systems do not provide this so that we provide our own. It's not | ||||
| * marvelously fast, but it works just fine. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| #ifdef COMPAT_INETATON | ||||
| static int inet_aton(const char *cp, struct in_addr *inp) | ||||
| #ifdef INET_ATON | ||||
| int inet_aton(const char *cp, struct in_addr *inp) | ||||
| { | ||||
|     unsigned int a = 0, b = 0, c = 0, d = 0; | ||||
|     int n = 0, r; | ||||
|   | ||||
| @@ -23,4 +23,8 @@ const char *inet_trycreate(p_sock ps, int type); | ||||
| int inet_meth_getpeername(lua_State *L, p_sock ps); | ||||
| int inet_meth_getsockname(lua_State *L, p_sock ps); | ||||
|  | ||||
| #ifdef INET_ATON | ||||
| int inet_aton(const char *cp, struct in_addr *inp); | ||||
| #endif | ||||
|  | ||||
| #endif /* INET_H_ */ | ||||
|   | ||||
| @@ -154,7 +154,7 @@ static int meth_connect(lua_State *L) | ||||
| { | ||||
|     p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); | ||||
|     const char *address =  luaL_checkstring(L, 2); | ||||
|     unsigned short port = (ushort) luaL_checknumber(L, 3); | ||||
|     unsigned short port = (unsigned short) luaL_checknumber(L, 3); | ||||
|     const char *err = inet_tryconnect(&tcp->sock, address, port); | ||||
|     if (err) { | ||||
|         lua_pushnil(L); | ||||
| @@ -174,7 +174,7 @@ static int meth_bind(lua_State *L) | ||||
| { | ||||
|     p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); | ||||
|     const char *address =  luaL_checkstring(L, 2); | ||||
|     unsigned short port = (ushort) luaL_checknumber(L, 3); | ||||
|     unsigned short port = (unsigned short) luaL_checknumber(L, 3); | ||||
|     int backlog = (int) luaL_optnumber(L, 4, 1); | ||||
|     const char *err = inet_trybind(&tcp->sock, address, port, backlog); | ||||
|     if (err) { | ||||
| @@ -227,12 +227,13 @@ static int meth_accept(lua_State *L) | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int global_create(lua_State *L) | ||||
| { | ||||
|     const char *err; | ||||
|     /* allocate tcp object */ | ||||
|     p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); | ||||
|     /* set its type as master object */ | ||||
|     aux_setclass(L, "tcp{master}", -1); | ||||
|     /* try to allocate a system socket */ | ||||
|     const char *err = inet_trycreate(&tcp->sock, SOCK_STREAM); | ||||
|     err = inet_trycreate(&tcp->sock, SOCK_STREAM); | ||||
|     if (err) { /* get rid of object on stack and push error */ | ||||
|         lua_pop(L, 1); | ||||
|         lua_pushnil(L); | ||||
|   | ||||
							
								
								
									
										10
									
								
								src/udp.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/udp.c
									
									
									
									
									
								
							| @@ -104,7 +104,7 @@ static int meth_sendto(lua_State *L) | ||||
|     size_t count, sent = 0; | ||||
|     const char *data = luaL_checklstring(L, 2, &count); | ||||
|     const char *ip = luaL_checkstring(L, 3); | ||||
|     ushort port = (ushort) luaL_checknumber(L, 4); | ||||
|     unsigned short port = (unsigned short) luaL_checknumber(L, 4); | ||||
|     p_tm tm = &udp->tm; | ||||
|     struct sockaddr_in addr; | ||||
|     int err; | ||||
| @@ -220,7 +220,8 @@ static int meth_setpeername(lua_State *L) | ||||
|     const char *address =  luaL_checkstring(L, 2); | ||||
|     int connecting = strcmp(address, "*"); | ||||
|     unsigned short port = connecting ?  | ||||
|         (ushort) luaL_checknumber(L, 3) : (ushort) luaL_optnumber(L, 3, 0); | ||||
|         (unsigned short) luaL_checknumber(L, 3) :  | ||||
|         (unsigned short) luaL_optnumber(L, 3, 0); | ||||
|     const char *err = inet_tryconnect(&udp->sock, address, port); | ||||
|     if (err) { | ||||
|         lua_pushnil(L); | ||||
| @@ -251,7 +252,7 @@ static int meth_setsockname(lua_State *L) | ||||
| { | ||||
|     p_udp udp = (p_udp) aux_checkclass(L, "udp{master}", 1); | ||||
|     const char *address =  luaL_checkstring(L, 2); | ||||
|     unsigned short port = (ushort) luaL_checknumber(L, 3); | ||||
|     unsigned short port = (unsigned short) luaL_checknumber(L, 3); | ||||
|     const char *err = inet_trybind(&udp->sock, address, port, -1); | ||||
|     if (err) { | ||||
|         lua_pushnil(L); | ||||
| @@ -270,12 +271,13 @@ static int meth_setsockname(lua_State *L) | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int global_create(lua_State *L) | ||||
| { | ||||
|     const char *err; | ||||
|     /* allocate udp object */ | ||||
|     p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); | ||||
|     /* set its type as master object */ | ||||
|     aux_setclass(L, "udp{unconnected}", -1); | ||||
|     /* try to allocate a system socket */ | ||||
|     const char *err = inet_trycreate(&udp->sock, SOCK_DGRAM); | ||||
|     err = inet_trycreate(&udp->sock, SOCK_DGRAM); | ||||
|     if (err) { | ||||
|         /* get rid of object on stack and push error */ | ||||
|         lua_pop(L, 1); | ||||
|   | ||||
| @@ -3,8 +3,8 @@ | ||||
| * | ||||
| * RCS ID: $Id$ | ||||
| \*=========================================================================*/ | ||||
| #ifndef UNIX_H | ||||
| #define UNIX_H | ||||
| #ifndef USOCKET_H | ||||
| #define USOCKET_H | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * BSD include files | ||||
| @@ -41,4 +41,4 @@ typedef t_sock *p_sock; | ||||
|  | ||||
| #define SOCK_INVALID (-1) | ||||
|  | ||||
| #endif /* UNIX_H */ | ||||
| #endif /* USOCKET_H */ | ||||
|   | ||||
							
								
								
									
										261
									
								
								src/wsocket.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								src/wsocket.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,261 @@ | ||||
| #include <string.h> | ||||
|  | ||||
| #include "socket.h" | ||||
|  | ||||
| int sock_open(void) | ||||
| { | ||||
|     WORD wVersionRequested; | ||||
|     WSADATA wsaData; | ||||
|     int err;  | ||||
|     wVersionRequested = MAKEWORD(2, 0);  | ||||
|     err = WSAStartup(wVersionRequested, &wsaData ); | ||||
|     if (err != 0) return 0; | ||||
|     if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) { | ||||
|         WSACleanup(); | ||||
|         return 0;  | ||||
|     } | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| void sock_destroy(p_sock ps) | ||||
| { | ||||
|     closesocket(*ps); | ||||
| } | ||||
|  | ||||
| const char *sock_create(p_sock ps, int domain, int type, int protocol) | ||||
| { | ||||
|     t_sock sock = socket(domain, type, protocol); | ||||
|     if (sock == SOCK_INVALID) return sock_createstrerror();  | ||||
|     *ps = sock; | ||||
|     sock_setnonblocking(ps); | ||||
|     sock_setreuseaddr(ps); | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len) | ||||
| { | ||||
|     if (connect(*ps, addr, addr_len) < 0) return sock_connectstrerror(); | ||||
|     else return NULL; | ||||
| } | ||||
|  | ||||
| const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len) | ||||
| { | ||||
|     if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror(); | ||||
|     else return NULL; | ||||
| } | ||||
|  | ||||
| void sock_listen(p_sock ps, int backlog) | ||||
| { | ||||
|     listen(*ps, backlog); | ||||
| } | ||||
|  | ||||
| int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len,  | ||||
|         int timeout) | ||||
| { | ||||
|     t_sock sock = *ps; | ||||
|     struct timeval tv; | ||||
|     SA dummy_addr; | ||||
|     socklen_t dummy_len; | ||||
|     fd_set fds; | ||||
|     tv.tv_sec = timeout / 1000; | ||||
|     tv.tv_usec = (timeout % 1000) * 1000; | ||||
|     FD_ZERO(&fds); | ||||
|     FD_SET(sock, &fds); | ||||
|     if (select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL) <= 0) | ||||
|         return IO_TIMEOUT; | ||||
|     if (!addr) addr = &dummy_addr; | ||||
|     if (!addr_len) addr_len = &dummy_len; | ||||
|     *pa = accept(sock, addr, addr_len); | ||||
|     if (*pa == SOCK_INVALID) return IO_ERROR; | ||||
|     else return IO_DONE; | ||||
| } | ||||
|  | ||||
| int sock_send(p_sock ps, const char *data, size_t count, size_t *sent,  | ||||
|         int timeout) | ||||
| { | ||||
|     t_sock sock = *ps; | ||||
|     struct timeval tv; | ||||
|     fd_set fds; | ||||
|     ssize_t put = 0; | ||||
|     int err; | ||||
|     int ret; | ||||
|     tv.tv_sec = timeout / 1000; | ||||
|     tv.tv_usec = (timeout % 1000) * 1000; | ||||
|     FD_ZERO(&fds); | ||||
|     FD_SET(sock, &fds); | ||||
|     ret = select(sock+1, NULL, &fds, NULL, timeout >= 0 ? &tv : NULL); | ||||
|     if (ret > 0) { | ||||
|        put = send(sock, data, count, 0);   | ||||
|        if (put <= 0) { | ||||
|            /* a bug in WinSock forces us to do a busy wait until we manage | ||||
|            ** to write, because select returns immediately even though it | ||||
|            ** should have blocked us until we could write... */ | ||||
|            if (WSAGetLastError() == WSAEWOULDBLOCK) err = IO_DONE; | ||||
|            else err = IO_CLOSED; | ||||
|            *sent = 0; | ||||
|        } else { | ||||
|            *sent = put; | ||||
|            err = IO_DONE; | ||||
|        } | ||||
|        return err; | ||||
|     } else { | ||||
|         *sent = 0; | ||||
|         return IO_TIMEOUT; | ||||
|     } | ||||
| } | ||||
|  | ||||
| int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent,  | ||||
|         SA *addr, socklen_t addr_len, int timeout) | ||||
| { | ||||
|     t_sock sock = *ps; | ||||
|     struct timeval tv; | ||||
|     fd_set fds; | ||||
|     ssize_t put = 0; | ||||
|     int err; | ||||
|     int ret; | ||||
|     tv.tv_sec = timeout / 1000; | ||||
|     tv.tv_usec = (timeout % 1000) * 1000; | ||||
|     FD_ZERO(&fds); | ||||
|     FD_SET(sock, &fds); | ||||
|     ret = select(sock+1, NULL, &fds, NULL, timeout >= 0 ? &tv : NULL); | ||||
|     if (ret > 0) { | ||||
|        put = sendto(sock, data, count, 0, addr, addr_len);   | ||||
|        if (put <= 0) { | ||||
|            /* a bug in WinSock forces us to do a busy wait until we manage | ||||
|            ** to write, because select returns immediately even though it | ||||
|            ** should have blocked us until we could write... */ | ||||
|            if (WSAGetLastError() == WSAEWOULDBLOCK) err = IO_DONE; | ||||
|            else err = IO_CLOSED; | ||||
|            *sent = 0; | ||||
|        } else { | ||||
|            *sent = put; | ||||
|            err = IO_DONE; | ||||
|        } | ||||
|        return err; | ||||
|     } else { | ||||
|         *sent = 0; | ||||
|         return IO_TIMEOUT; | ||||
|     } | ||||
| } | ||||
|  | ||||
| int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) | ||||
| { | ||||
|     t_sock sock = *ps; | ||||
|     struct timeval tv; | ||||
|     fd_set fds; | ||||
|     int ret; | ||||
|     ssize_t taken = 0; | ||||
|     tv.tv_sec = timeout / 1000; | ||||
|     tv.tv_usec = (timeout % 1000) * 1000; | ||||
|     FD_ZERO(&fds); | ||||
|     FD_SET(sock, &fds); | ||||
|     ret = select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL); | ||||
|     if (ret > 0) { | ||||
|        taken = recv(sock, data, count, 0);   | ||||
|        if (taken <= 0) { | ||||
|            *got = 0; | ||||
|            return IO_CLOSED; | ||||
|        } else { | ||||
|            *got = taken; | ||||
|            return IO_DONE; | ||||
|        } | ||||
|     } else { | ||||
|         *got = 0; | ||||
|         return IO_TIMEOUT; | ||||
|     } | ||||
| } | ||||
|  | ||||
| int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got,  | ||||
|         SA *addr, socklen_t *addr_len, int timeout) | ||||
| { | ||||
|     t_sock sock = *ps; | ||||
|     struct timeval tv; | ||||
|     fd_set fds; | ||||
|     int ret; | ||||
|     ssize_t taken = 0; | ||||
|     tv.tv_sec = timeout / 1000; | ||||
|     tv.tv_usec = (timeout % 1000) * 1000; | ||||
|     FD_ZERO(&fds); | ||||
|     FD_SET(sock, &fds); | ||||
|     ret = select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL); | ||||
|     if (ret > 0) { | ||||
|        taken = recvfrom(sock, data, count, 0, addr, addr_len);   | ||||
|        if (taken <= 0) { | ||||
|            *got = 0; | ||||
|            return IO_CLOSED; | ||||
|        } else { | ||||
|            *got = taken; | ||||
|            return IO_DONE; | ||||
|        } | ||||
|     } else { | ||||
|         *got = 0; | ||||
|         return IO_TIMEOUT; | ||||
|     } | ||||
| } | ||||
|  | ||||
| const char *sock_hoststrerror(void) | ||||
| { | ||||
|     switch (WSAGetLastError()) { | ||||
|         case HOST_NOT_FOUND: return "host not found"; | ||||
|         case NO_ADDRESS: return "unable to resolve host name"; | ||||
|         case NO_RECOVERY: return "name server error"; | ||||
|         case TRY_AGAIN: return "name server unavailable, try again later."; | ||||
|         default: return "unknown error"; | ||||
|     } | ||||
| } | ||||
|  | ||||
| const char *sock_createstrerror(void) | ||||
| { | ||||
|     switch (WSAGetLastError()) { | ||||
|         case WSANOTINITIALISED: return "not initialized"; | ||||
|         case WSAENETDOWN: return "network is down"; | ||||
|         case WSAEMFILE: return "descriptor table is full"; | ||||
|         case WSAENOBUFS: return "insufficient buffer space"; | ||||
|         default: return "unknown error"; | ||||
|     } | ||||
| } | ||||
|  | ||||
| const char *sock_bindstrerror(void) | ||||
| { | ||||
|     switch (WSAGetLastError()) { | ||||
|         case WSANOTINITIALISED: return "not initialized"; | ||||
|         case WSAENETDOWN: return "network is down"; | ||||
|         case WSAEADDRINUSE: return "address already in use"; | ||||
|         case WSAEINVAL: return "socket already bound"; | ||||
|         case WSAENOBUFS: return "too many connections"; | ||||
|         case WSAEFAULT: return "invalid address"; | ||||
|         case WSAENOTSOCK: return "not a socket descriptor"; | ||||
|         default: return "unknown error"; | ||||
|     } | ||||
| } | ||||
|  | ||||
| const char *sock_connectstrerror(void) | ||||
| { | ||||
|     switch (WSAGetLastError()) { | ||||
|         case WSANOTINITIALISED: return "not initialized"; | ||||
|         case WSAENETDOWN: return "network is down"; | ||||
|         case WSAEADDRINUSE: return "address already in use"; | ||||
|         case WSAEADDRNOTAVAIL: return "address unavailable"; | ||||
|         case WSAECONNREFUSED: return "connection refused"; | ||||
|         case WSAENETUNREACH: return "network is unreachable"; | ||||
|         default: return "unknown error"; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void sock_setreuseaddr(p_sock ps) | ||||
| { | ||||
|     int val = 1; | ||||
|     setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); | ||||
| } | ||||
|  | ||||
| void sock_setblocking(p_sock ps) | ||||
| { | ||||
|     u_long argp = 0; | ||||
|     ioctlsocket(*ps, FIONBIO, &argp); | ||||
| } | ||||
|  | ||||
| void sock_setnonblocking(p_sock ps) | ||||
| { | ||||
|     u_long argp = 1; | ||||
|     ioctlsocket(*ps, FIONBIO, &argp); | ||||
| } | ||||
							
								
								
									
										22
									
								
								src/wsocket.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/wsocket.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| /*=========================================================================*\ | ||||
| * Socket compatibilization module for Win32 | ||||
| * | ||||
| * RCS ID: $Id$ | ||||
| \*=========================================================================*/ | ||||
| #ifndef WSOCKET_H | ||||
| #define WSOCKET_H | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * WinSock2 include files | ||||
| \*=========================================================================*/ | ||||
| #include <winsock2.h> | ||||
| #include <winbase.h> | ||||
|  | ||||
| typedef int socklen_t; | ||||
| typedef int ssize_t; | ||||
| typedef SOCKET t_sock; | ||||
| typedef t_sock *p_sock; | ||||
|  | ||||
| #define SOCK_INVALID (INVALID_SOCKET) | ||||
|  | ||||
| #endif /* WSOCKET_H */ | ||||
		Reference in New Issue
	
	Block a user