mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-11-08 14:28:21 +01:00
New compat.h module implements luaL_setfuncs.
Makes initialization code simpler everywhere.
This commit is contained in:
parent
321c0c9b1f
commit
e75444ccd1
@ -26,7 +26,7 @@ void auxiliar_newclass(lua_State *L, const char *classname, luaL_Reg *func) {
|
||||
luaL_newmetatable(L, classname); /* mt */
|
||||
/* create __index table to place methods */
|
||||
lua_pushstring(L, "__index"); /* mt,"__index" */
|
||||
lua_newtable(L); /* mt,"__index",it */
|
||||
lua_newtable(L); /* mt,"__index",it */
|
||||
/* put class name into class metatable */
|
||||
lua_pushstring(L, "class"); /* mt,"__index",it,"class" */
|
||||
lua_pushstring(L, classname); /* mt,"__index",it,"class",classname */
|
||||
@ -84,7 +84,7 @@ int auxiliar_checkboolean(lua_State *L, int objidx) {
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Return userdata pointer if object belongs to a given class, abort with
|
||||
* Return userdata pointer if object belongs to a given class, abort with
|
||||
* error otherwise
|
||||
\*-------------------------------------------------------------------------*/
|
||||
void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx) {
|
||||
@ -98,7 +98,7 @@ void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx) {
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Return userdata pointer if object belongs to a given group, abort with
|
||||
* Return userdata pointer if object belongs to a given group, abort with
|
||||
* error otherwise
|
||||
\*-------------------------------------------------------------------------*/
|
||||
void *auxiliar_checkgroup(lua_State *L, const char *groupname, int objidx) {
|
||||
@ -121,7 +121,7 @@ void auxiliar_setclass(lua_State *L, const char *classname, int objidx) {
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Get a userdata pointer if object belongs to a given group. Return NULL
|
||||
* Get a userdata pointer if object belongs to a given group. Return NULL
|
||||
* otherwise
|
||||
\*-------------------------------------------------------------------------*/
|
||||
void *auxiliar_getgroupudata(lua_State *L, const char *groupname, int objidx) {
|
||||
@ -139,7 +139,7 @@ void *auxiliar_getgroupudata(lua_State *L, const char *groupname, int objidx) {
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Get a userdata pointer if object belongs to a given class. Return NULL
|
||||
* Get a userdata pointer if object belongs to a given class. Return NULL
|
||||
* otherwise
|
||||
\*-------------------------------------------------------------------------*/
|
||||
void *auxiliar_getclassudata(lua_State *L, const char *classname, int objidx) {
|
||||
@ -151,7 +151,7 @@ void *auxiliar_getclassudata(lua_State *L, const char *classname, int objidx) {
|
||||
* Used to be part of lauxlib in Lua 5.1, was dropped from 5.2.
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int auxiliar_typeerror (lua_State *L, int narg, const char *tname) {
|
||||
const char *msg = lua_pushfstring(L, "%s expected, got %s", tname,
|
||||
const char *msg = lua_pushfstring(L, "%s expected, got %s", tname,
|
||||
luaL_typename(L, narg));
|
||||
return luaL_argerror(L, narg, msg);
|
||||
}
|
||||
|
@ -4,12 +4,12 @@
|
||||
* Auxiliar routines for class hierarchy manipulation
|
||||
* LuaSocket toolkit (but completely independent of other LuaSocket modules)
|
||||
*
|
||||
* A LuaSocket class is a name associated with Lua metatables. A LuaSocket
|
||||
* group is a name associated with a class. A class can belong to any number
|
||||
* A LuaSocket class is a name associated with Lua metatables. A LuaSocket
|
||||
* group is a name associated with a class. A class can belong to any number
|
||||
* of groups. This module provides the functionality to:
|
||||
*
|
||||
* - create new classes
|
||||
* - add classes to groups
|
||||
* - create new classes
|
||||
* - add classes to groups
|
||||
* - set the class of objects
|
||||
* - check if an object belongs to a given class or group
|
||||
* - get the userdata associated to objects
|
||||
@ -26,11 +26,12 @@
|
||||
* "class" with the class name.
|
||||
*
|
||||
* The mapping from class name to the corresponding metatable and the
|
||||
* reverse mapping are done using lauxlib.
|
||||
* reverse mapping are done using lauxlib.
|
||||
\*=========================================================================*/
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "compat.h"
|
||||
|
||||
int auxiliar_open(lua_State *L);
|
||||
void auxiliar_newclass(lua_State *L, const char *classname, luaL_Reg *func);
|
||||
|
@ -4,6 +4,7 @@
|
||||
\*=========================================================================*/
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "compat.h"
|
||||
|
||||
#include "buffer.h"
|
||||
|
||||
|
19
src/compat.c
Normal file
19
src/compat.c
Normal file
@ -0,0 +1,19 @@
|
||||
#include "compat.h"
|
||||
|
||||
#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM==501
|
||||
/*
|
||||
** Adapted from Lua 5.2
|
||||
*/
|
||||
void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
|
||||
luaL_checkstack(L, nup+1, "too many upvalues");
|
||||
for (; l->name != NULL; l++) { /* fill the table with given functions */
|
||||
int i;
|
||||
lua_pushstring(L, l->name);
|
||||
for (i = 0; i < nup; i++) /* copy upvalues to the top */
|
||||
lua_pushvalue(L, -(nup+1));
|
||||
lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
|
||||
lua_settable(L, -(nup + 3));
|
||||
}
|
||||
lua_pop(L, nup); /* remove upvalues */
|
||||
}
|
||||
#endif
|
11
src/compat.h
Normal file
11
src/compat.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef COMPAT_H
|
||||
#define COMPAT_H
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
#if LUA_VERSION_NUM==501
|
||||
void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);
|
||||
#endif
|
||||
|
||||
#endif
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "compat.h"
|
||||
|
||||
#include "except.h"
|
||||
|
||||
@ -117,10 +118,6 @@ static int global_protect(lua_State *L) {
|
||||
* Init module
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int except_open(lua_State *L) {
|
||||
#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE)
|
||||
luaL_setfuncs(L, func, 0);
|
||||
#else
|
||||
luaL_openlib(L, NULL, func, 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "compat.h"
|
||||
|
||||
#include "inet.h"
|
||||
|
||||
@ -41,11 +42,7 @@ int inet_open(lua_State *L)
|
||||
{
|
||||
lua_pushstring(L, "dns");
|
||||
lua_newtable(L);
|
||||
#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE)
|
||||
luaL_setfuncs(L, func, 0);
|
||||
#else
|
||||
luaL_openlib(L, NULL, func, 0);
|
||||
#endif
|
||||
lua_settable(L, -3);
|
||||
return 0;
|
||||
}
|
||||
|
2
src/io.c
2
src/io.c
@ -25,6 +25,6 @@ const char *io_strerror(int err) {
|
||||
case IO_DONE: return NULL;
|
||||
case IO_CLOSED: return "closed";
|
||||
case IO_TIMEOUT: return "timeout";
|
||||
default: return "unknown error";
|
||||
default: return "unknown error";
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
\*=========================================================================*/
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "compat.h"
|
||||
|
||||
/*=========================================================================*\
|
||||
* LuaSocket includes
|
||||
@ -83,12 +84,8 @@ static int global_unload(lua_State *L) {
|
||||
static int base_open(lua_State *L) {
|
||||
if (socket_open()) {
|
||||
/* export functions (and leave namespace table on top of stack) */
|
||||
#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE)
|
||||
lua_newtable(L);
|
||||
luaL_setfuncs(L, func, 0);
|
||||
#else
|
||||
luaL_openlib(L, "socket", func, 0);
|
||||
#endif
|
||||
#ifdef LUASOCKET_DEBUG
|
||||
lua_pushstring(L, "_DEBUG");
|
||||
lua_pushboolean(L, 1);
|
||||
|
@ -260,6 +260,7 @@ SOCKET_OBJS= \
|
||||
buffer.$(O) \
|
||||
io.$(O) \
|
||||
auxiliar.$(O) \
|
||||
compat.$(O) \
|
||||
options.$(O) \
|
||||
inet.$(O) \
|
||||
$(SOCKET) \
|
||||
@ -272,7 +273,8 @@ SOCKET_OBJS= \
|
||||
# Modules belonging mime-core
|
||||
#
|
||||
MIME_OBJS= \
|
||||
mime.$(O)
|
||||
mime.$(O) \
|
||||
compat.$(O)
|
||||
|
||||
#------
|
||||
# Modules belonging unix (local domain sockets)
|
||||
@ -383,6 +385,7 @@ clean:
|
||||
#------
|
||||
# List of dependencies
|
||||
#
|
||||
compat.$(O): compat.c compat.h
|
||||
auxiliar.$(O): auxiliar.c auxiliar.h
|
||||
buffer.$(O): buffer.c buffer.h io.h timeout.h
|
||||
except.$(O): except.c except.h
|
||||
|
@ -6,10 +6,7 @@
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501)
|
||||
#include "compat-5.1.h"
|
||||
#endif
|
||||
#include "compat.h"
|
||||
|
||||
#include "mime.h"
|
||||
|
||||
@ -81,12 +78,8 @@ static UC b64unbase[256];
|
||||
\*-------------------------------------------------------------------------*/
|
||||
MIME_API int luaopen_mime_core(lua_State *L)
|
||||
{
|
||||
#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE)
|
||||
lua_newtable(L);
|
||||
luaL_setfuncs(L, func, 0);
|
||||
#else
|
||||
luaL_openlib(L, "mime", func, 0);
|
||||
#endif
|
||||
/* make version string available to scripts */
|
||||
lua_pushstring(L, "_VERSION");
|
||||
lua_pushstring(L, MIME_VERSION);
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*=========================================================================*\
|
||||
* Common option interface
|
||||
* Common option interface
|
||||
* LuaSocket toolkit
|
||||
\*=========================================================================*/
|
||||
#include <string.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lauxlib.h"
|
||||
|
||||
@ -20,9 +20,9 @@ static int opt_setboolean(lua_State *L, p_socket ps, int level, int name);
|
||||
static int opt_getboolean(lua_State *L, p_socket ps, int level, int name);
|
||||
static int opt_setint(lua_State *L, p_socket ps, int level, int name);
|
||||
static int opt_getint(lua_State *L, p_socket ps, int level, int name);
|
||||
static int opt_set(lua_State *L, p_socket ps, int level, int name,
|
||||
static int opt_set(lua_State *L, p_socket ps, int level, int name,
|
||||
void *val, int len);
|
||||
static int opt_get(lua_State *L, p_socket ps, int level, int name,
|
||||
static int opt_get(lua_State *L, p_socket ps, int level, int name,
|
||||
void *val, int* len);
|
||||
|
||||
/*=========================================================================*\
|
||||
@ -60,29 +60,29 @@ int opt_meth_getoption(lua_State *L, p_opt opt, p_socket ps)
|
||||
/* enables reuse of local address */
|
||||
int opt_set_reuseaddr(lua_State *L, p_socket ps)
|
||||
{
|
||||
return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEADDR);
|
||||
return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEADDR);
|
||||
}
|
||||
|
||||
int opt_get_reuseaddr(lua_State *L, p_socket ps)
|
||||
{
|
||||
return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEADDR);
|
||||
return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEADDR);
|
||||
}
|
||||
|
||||
/* enables reuse of local port */
|
||||
int opt_set_reuseport(lua_State *L, p_socket ps)
|
||||
{
|
||||
return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEPORT);
|
||||
return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEPORT);
|
||||
}
|
||||
|
||||
int opt_get_reuseport(lua_State *L, p_socket ps)
|
||||
{
|
||||
return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEPORT);
|
||||
return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEPORT);
|
||||
}
|
||||
|
||||
/* disables the Naggle algorithm */
|
||||
int opt_set_tcp_nodelay(lua_State *L, p_socket ps)
|
||||
{
|
||||
return opt_setboolean(L, ps, IPPROTO_TCP, TCP_NODELAY);
|
||||
return opt_setboolean(L, ps, IPPROTO_TCP, TCP_NODELAY);
|
||||
}
|
||||
|
||||
int opt_get_tcp_nodelay(lua_State *L, p_socket ps)
|
||||
@ -92,12 +92,12 @@ int opt_get_tcp_nodelay(lua_State *L, p_socket ps)
|
||||
|
||||
int opt_set_keepalive(lua_State *L, p_socket ps)
|
||||
{
|
||||
return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE);
|
||||
return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE);
|
||||
}
|
||||
|
||||
int opt_get_keepalive(lua_State *L, p_socket ps)
|
||||
{
|
||||
return opt_getboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE);
|
||||
return opt_getboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE);
|
||||
}
|
||||
|
||||
int opt_set_dontroute(lua_State *L, p_socket ps)
|
||||
@ -156,12 +156,12 @@ int opt_set_linger(lua_State *L, p_socket ps)
|
||||
if (!lua_istable(L, 3)) auxiliar_typeerror(L,3,lua_typename(L, LUA_TTABLE));
|
||||
lua_pushstring(L, "on");
|
||||
lua_gettable(L, 3);
|
||||
if (!lua_isboolean(L, -1))
|
||||
if (!lua_isboolean(L, -1))
|
||||
luaL_argerror(L, 3, "boolean 'on' field expected");
|
||||
li.l_onoff = (u_short) lua_toboolean(L, -1);
|
||||
lua_pushstring(L, "timeout");
|
||||
lua_gettable(L, 3);
|
||||
if (!lua_isnumber(L, -1))
|
||||
if (!lua_isnumber(L, -1))
|
||||
luaL_argerror(L, 3, "number 'timeout' field expected");
|
||||
li.l_linger = (u_short) lua_tonumber(L, -1);
|
||||
return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &li, sizeof(li));
|
||||
@ -194,7 +194,7 @@ int opt_set_ip_multicast_if(lua_State *L, p_socket ps)
|
||||
val.s_addr = htonl(INADDR_ANY);
|
||||
if (strcmp(address, "*") && !inet_aton(address, &val))
|
||||
luaL_argerror(L, 3, "ip expected");
|
||||
return opt_set(L, ps, IPPROTO_IP, IP_MULTICAST_IF,
|
||||
return opt_set(L, ps, IPPROTO_IP, IP_MULTICAST_IF,
|
||||
(char *) &val, sizeof(val));
|
||||
}
|
||||
|
||||
@ -250,17 +250,17 @@ static int opt_setmembership(lua_State *L, p_socket ps, int level, int name)
|
||||
if (!lua_istable(L, 3)) auxiliar_typeerror(L,3,lua_typename(L, LUA_TTABLE));
|
||||
lua_pushstring(L, "multiaddr");
|
||||
lua_gettable(L, 3);
|
||||
if (!lua_isstring(L, -1))
|
||||
if (!lua_isstring(L, -1))
|
||||
luaL_argerror(L, 3, "string 'multiaddr' field expected");
|
||||
if (!inet_aton(lua_tostring(L, -1), &val.imr_multiaddr))
|
||||
if (!inet_aton(lua_tostring(L, -1), &val.imr_multiaddr))
|
||||
luaL_argerror(L, 3, "invalid 'multiaddr' ip address");
|
||||
lua_pushstring(L, "interface");
|
||||
lua_gettable(L, 3);
|
||||
if (!lua_isstring(L, -1))
|
||||
if (!lua_isstring(L, -1))
|
||||
luaL_argerror(L, 3, "string 'interface' field expected");
|
||||
val.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
if (strcmp(lua_tostring(L, -1), "*") &&
|
||||
!inet_aton(lua_tostring(L, -1), &val.imr_interface))
|
||||
!inet_aton(lua_tostring(L, -1), &val.imr_interface))
|
||||
luaL_argerror(L, 3, "invalid 'interface' ip address");
|
||||
return opt_set(L, ps, level, name, (char *) &val, sizeof(val));
|
||||
}
|
||||
@ -272,14 +272,14 @@ static int opt_ip6_setmembership(lua_State *L, p_socket ps, int level, int name)
|
||||
if (!lua_istable(L, 3)) auxiliar_typeerror(L,3,lua_typename(L, LUA_TTABLE));
|
||||
lua_pushstring(L, "multiaddr");
|
||||
lua_gettable(L, 3);
|
||||
if (!lua_isstring(L, -1))
|
||||
if (!lua_isstring(L, -1))
|
||||
luaL_argerror(L, 3, "string 'multiaddr' field expected");
|
||||
if (!inet_pton(AF_INET6, lua_tostring(L, -1), &val.ipv6mr_multiaddr))
|
||||
if (!inet_pton(AF_INET6, lua_tostring(L, -1), &val.ipv6mr_multiaddr))
|
||||
luaL_argerror(L, 3, "invalid 'multiaddr' ip address");
|
||||
lua_pushstring(L, "interface");
|
||||
lua_gettable(L, 3);
|
||||
/* By default we listen to interface on default route
|
||||
* (sigh). However, interface= can override it. We should
|
||||
* (sigh). However, interface= can override it. We should
|
||||
* support either number, or name for it. Waiting for
|
||||
* windows port of if_nametoindex */
|
||||
if (!lua_isnil(L, -1)) {
|
||||
@ -291,7 +291,7 @@ static int opt_ip6_setmembership(lua_State *L, p_socket ps, int level, int name)
|
||||
return opt_set(L, ps, level, name, (char *) &val, sizeof(val));
|
||||
}
|
||||
|
||||
static
|
||||
static
|
||||
int opt_get(lua_State *L, p_socket ps, int level, int name, void *val, int* len)
|
||||
{
|
||||
socklen_t socklen = *len;
|
||||
@ -304,7 +304,7 @@ int opt_get(lua_State *L, p_socket ps, int level, int name, void *val, int* len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
static
|
||||
int opt_set(lua_State *L, p_socket ps, int level, int name, void *val, int len)
|
||||
{
|
||||
if (setsockopt(*ps, level, name, (char *) val, len) < 0) {
|
||||
|
29
src/select.c
29
src/select.c
@ -6,6 +6,7 @@
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "compat.h"
|
||||
|
||||
#include "socket.h"
|
||||
#include "timeout.h"
|
||||
@ -16,10 +17,10 @@
|
||||
\*=========================================================================*/
|
||||
static t_socket getfd(lua_State *L);
|
||||
static int dirty(lua_State *L);
|
||||
static void collect_fd(lua_State *L, int tab, int itab,
|
||||
static void collect_fd(lua_State *L, int tab, int itab,
|
||||
fd_set *set, t_socket *max_fd);
|
||||
static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set);
|
||||
static void return_fd(lua_State *L, fd_set *set, t_socket max_fd,
|
||||
static void return_fd(lua_State *L, fd_set *set, t_socket max_fd,
|
||||
int itab, int tab, int start);
|
||||
static void make_assoc(lua_State *L, int tab);
|
||||
static int global_select(lua_State *L);
|
||||
@ -40,11 +41,7 @@ int select_open(lua_State *L) {
|
||||
lua_pushstring(L, "_SETSIZE");
|
||||
lua_pushnumber(L, FD_SETSIZE);
|
||||
lua_rawset(L, -3);
|
||||
#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE)
|
||||
luaL_setfuncs(L, func, 0);
|
||||
#else
|
||||
luaL_openlib(L, NULL, func, 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -98,10 +95,10 @@ static t_socket getfd(lua_State *L) {
|
||||
lua_pushvalue(L, -2);
|
||||
lua_call(L, 1, 1);
|
||||
if (lua_isnumber(L, -1)) {
|
||||
double numfd = lua_tonumber(L, -1);
|
||||
double numfd = lua_tonumber(L, -1);
|
||||
fd = (numfd >= 0.0)? (t_socket) numfd: SOCKET_INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
return fd;
|
||||
}
|
||||
@ -114,12 +111,12 @@ static int dirty(lua_State *L) {
|
||||
lua_pushvalue(L, -2);
|
||||
lua_call(L, 1, 1);
|
||||
is = lua_toboolean(L, -1);
|
||||
}
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
return is;
|
||||
}
|
||||
|
||||
static void collect_fd(lua_State *L, int tab, int itab,
|
||||
static void collect_fd(lua_State *L, int tab, int itab,
|
||||
fd_set *set, t_socket *max_fd) {
|
||||
int i = 1, n = 0;
|
||||
/* nil is the same as an empty table */
|
||||
@ -139,16 +136,16 @@ static void collect_fd(lua_State *L, int tab, int itab,
|
||||
if (fd != SOCKET_INVALID) {
|
||||
/* make sure we don't overflow the fd_set */
|
||||
#ifdef _WIN32
|
||||
if (n >= FD_SETSIZE)
|
||||
if (n >= FD_SETSIZE)
|
||||
luaL_argerror(L, tab, "too many sockets");
|
||||
#else
|
||||
if (fd >= FD_SETSIZE)
|
||||
if (fd >= FD_SETSIZE)
|
||||
luaL_argerror(L, tab, "descriptor too large for set size");
|
||||
#endif
|
||||
FD_SET(fd, set);
|
||||
n++;
|
||||
/* keep track of the largest descriptor so far */
|
||||
if (*max_fd == SOCKET_INVALID || *max_fd < fd)
|
||||
if (*max_fd == SOCKET_INVALID || *max_fd < fd)
|
||||
*max_fd = fd;
|
||||
/* make sure we can map back from descriptor to the object */
|
||||
lua_pushnumber(L, (lua_Number) fd);
|
||||
@ -162,9 +159,9 @@ static void collect_fd(lua_State *L, int tab, int itab,
|
||||
|
||||
static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set) {
|
||||
int ndirty = 0, i = 1;
|
||||
if (lua_isnil(L, tab))
|
||||
if (lua_isnil(L, tab))
|
||||
return 0;
|
||||
for ( ;; ) {
|
||||
for ( ;; ) {
|
||||
t_socket fd;
|
||||
lua_pushnumber(L, i);
|
||||
lua_gettable(L, tab);
|
||||
@ -185,7 +182,7 @@ static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set) {
|
||||
return ndirty;
|
||||
}
|
||||
|
||||
static void return_fd(lua_State *L, fd_set *set, t_socket max_fd,
|
||||
static void return_fd(lua_State *L, fd_set *set, t_socket max_fd,
|
||||
int itab, int tab, int start) {
|
||||
t_socket fd;
|
||||
for (fd = 0; fd < max_fd; fd++) {
|
||||
|
14
src/serial.c
14
src/serial.c
@ -2,7 +2,7 @@
|
||||
* Serial stream
|
||||
* LuaSocket toolkit
|
||||
\*=========================================================================*/
|
||||
#include <string.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
@ -11,7 +11,7 @@
|
||||
#include "socket.h"
|
||||
#include "options.h"
|
||||
#include "unix.h"
|
||||
#include <sys/un.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
/*
|
||||
Reuses userdata definition from unix.h, since it is useful for all
|
||||
@ -55,7 +55,7 @@ static luaL_Reg serial_methods[] = {
|
||||
};
|
||||
|
||||
/* our socket creation function */
|
||||
/* this is an ad-hoc module that returns a single function
|
||||
/* this is an ad-hoc module that returns a single function
|
||||
* as such, do not include other functions in this array. */
|
||||
static luaL_Reg func[] = {
|
||||
{"serial", global_create},
|
||||
@ -120,7 +120,7 @@ static int meth_getfd(lua_State *L) {
|
||||
/* this is very dangerous, but can be handy for those that are brave enough */
|
||||
static int meth_setfd(lua_State *L) {
|
||||
p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
|
||||
un->sock = (t_socket) luaL_checknumber(L, 2);
|
||||
un->sock = (t_socket) luaL_checknumber(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ static int meth_dirty(lua_State *L) {
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Closes socket used by object
|
||||
* Closes socket used by object
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static int meth_close(lua_State *L)
|
||||
{
|
||||
@ -156,7 +156,7 @@ static int meth_settimeout(lua_State *L) {
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Creates a serial object
|
||||
* Creates a serial object
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static int global_create(lua_State *L) {
|
||||
const char* path = luaL_checkstring(L, 1);
|
||||
@ -180,7 +180,7 @@ static int global_create(lua_State *L) {
|
||||
/* initialize remaining structure fields */
|
||||
socket_setnonblocking(&sock);
|
||||
un->sock = sock;
|
||||
io_init(&un->io, (p_send) socket_write, (p_recv) socket_read,
|
||||
io_init(&un->io, (p_send) socket_write, (p_recv) socket_read,
|
||||
(p_error) socket_ioerror, &un->sock);
|
||||
timeout_init(&un->tm, -1, -1);
|
||||
buffer_init(&un->buf, &un->io, &un->tm);
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "compat.h"
|
||||
|
||||
#include "auxiliar.h"
|
||||
#include "socket.h"
|
||||
@ -108,11 +109,7 @@ int tcp_open(lua_State *L)
|
||||
auxiliar_add2group(L, "tcp{client}", "tcp{any}");
|
||||
auxiliar_add2group(L, "tcp{server}", "tcp{any}");
|
||||
/* define library functions */
|
||||
#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE)
|
||||
luaL_setfuncs(L, func, 0);
|
||||
#else
|
||||
luaL_openlib(L, NULL, func, 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "compat.h"
|
||||
|
||||
#include "auxiliar.h"
|
||||
#include "timeout.h"
|
||||
@ -52,7 +53,7 @@ void timeout_init(p_timeout tm, double block, double total) {
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Determines how much time we have left for the next system call,
|
||||
* if the previous call was successful
|
||||
* if the previous call was successful
|
||||
* Input
|
||||
* tm: timeout control structure
|
||||
* Returns
|
||||
@ -107,7 +108,7 @@ double timeout_getretry(p_timeout tm) {
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Marks the operation start time in structure
|
||||
* Marks the operation start time in structure
|
||||
* Input
|
||||
* tm: timeout control structure
|
||||
\*-------------------------------------------------------------------------*/
|
||||
@ -117,7 +118,7 @@ p_timeout timeout_markstart(p_timeout tm) {
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Gets time in s, relative to January 1, 1970 (UTC)
|
||||
* Gets time in s, relative to January 1, 1970 (UTC)
|
||||
* Returns
|
||||
* time in s.
|
||||
\*-------------------------------------------------------------------------*/
|
||||
@ -144,11 +145,7 @@ double timeout_gettime(void) {
|
||||
* Initializes module
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int timeout_open(lua_State *L) {
|
||||
#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE)
|
||||
luaL_setfuncs(L, func, 0);
|
||||
#else
|
||||
luaL_openlib(L, NULL, func, 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -163,7 +160,7 @@ int timeout_meth_settimeout(lua_State *L, p_timeout tm) {
|
||||
const char *mode = luaL_optstring(L, 3, "b");
|
||||
switch (*mode) {
|
||||
case 'b':
|
||||
tm->block = t;
|
||||
tm->block = t;
|
||||
break;
|
||||
case 'r': case 't':
|
||||
tm->total = t;
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "compat.h"
|
||||
|
||||
#include "auxiliar.h"
|
||||
#include "socket.h"
|
||||
@ -120,11 +121,7 @@ int udp_open(lua_State *L)
|
||||
auxiliar_add2group(L, "udp{connected}", "select{able}");
|
||||
auxiliar_add2group(L, "udp{unconnected}", "select{able}");
|
||||
/* define library functions */
|
||||
#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE)
|
||||
luaL_setfuncs(L, func, 0);
|
||||
#else
|
||||
luaL_openlib(L, NULL, func, 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
56
src/unix.c
56
src/unix.c
@ -1,8 +1,8 @@
|
||||
/*=========================================================================*\
|
||||
* Unix domain socket
|
||||
* Unix domain socket
|
||||
* LuaSocket toolkit
|
||||
\*=========================================================================*/
|
||||
#include <string.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
@ -11,7 +11,7 @@
|
||||
#include "socket.h"
|
||||
#include "options.h"
|
||||
#include "unix.h"
|
||||
#include <sys/un.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
/*=========================================================================*\
|
||||
* Internal function prototypes
|
||||
@ -68,15 +68,6 @@ static t_opt optset[] = {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
/* our socket creation function */
|
||||
/* this is an ad-hoc module that returns a single function
|
||||
* as such, do not include other functions in this array. */
|
||||
static luaL_Reg func[] = {
|
||||
{"unix", global_create},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Initializes module
|
||||
\*-------------------------------------------------------------------------*/
|
||||
@ -89,15 +80,8 @@ int luaopen_socket_unix(lua_State *L) {
|
||||
auxiliar_add2group(L, "unix{master}", "unix{any}");
|
||||
auxiliar_add2group(L, "unix{client}", "unix{any}");
|
||||
auxiliar_add2group(L, "unix{server}", "unix{any}");
|
||||
#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE)
|
||||
lua_pushcfunction(L, global_create);
|
||||
(void) func;
|
||||
#else
|
||||
/* set function into socket namespace */
|
||||
luaL_openlib(L, "socket", func, 0);
|
||||
lua_pushcfunction(L, global_create);
|
||||
#endif
|
||||
/* return the function instead of the 'socket' table */
|
||||
lua_pushcfunction(L, global_create);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -147,7 +131,7 @@ static int meth_getfd(lua_State *L) {
|
||||
/* this is very dangerous, but can be handy for those that are brave enough */
|
||||
static int meth_setfd(lua_State *L) {
|
||||
p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1);
|
||||
un->sock = (t_socket) luaL_checknumber(L, 2);
|
||||
un->sock = (t_socket) luaL_checknumber(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -158,8 +142,8 @@ static int meth_dirty(lua_State *L) {
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Waits for and returns a client object attempting connection to the
|
||||
* server object
|
||||
* Waits for and returns a client object attempting connection to the
|
||||
* server object
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static int meth_accept(lua_State *L) {
|
||||
p_unix server = (p_unix) auxiliar_checkclass(L, "unix{server}", 1);
|
||||
@ -173,20 +157,20 @@ static int meth_accept(lua_State *L) {
|
||||
/* initialize structure fields */
|
||||
socket_setnonblocking(&sock);
|
||||
clnt->sock = sock;
|
||||
io_init(&clnt->io, (p_send)socket_send, (p_recv)socket_recv,
|
||||
io_init(&clnt->io, (p_send)socket_send, (p_recv)socket_recv,
|
||||
(p_error) socket_ioerror, &clnt->sock);
|
||||
timeout_init(&clnt->tm, -1, -1);
|
||||
buffer_init(&clnt->buf, &clnt->io, &clnt->tm);
|
||||
return 1;
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, socket_strerror(err));
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Binds an object to an address
|
||||
* Binds an object to an address
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static const char *unix_trybind(p_unix un, const char *path) {
|
||||
struct sockaddr_un local;
|
||||
@ -197,16 +181,16 @@ static const char *unix_trybind(p_unix un, const char *path) {
|
||||
strcpy(local.sun_path, path);
|
||||
local.sun_family = AF_UNIX;
|
||||
#ifdef UNIX_HAS_SUN_LEN
|
||||
local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len)
|
||||
local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len)
|
||||
+ len + 1;
|
||||
err = socket_bind(&un->sock, (SA *) &local, local.sun_len);
|
||||
|
||||
#else
|
||||
err = socket_bind(&un->sock, (SA *) &local,
|
||||
#else
|
||||
err = socket_bind(&un->sock, (SA *) &local,
|
||||
sizeof(local.sun_family) + len);
|
||||
#endif
|
||||
if (err != IO_DONE) socket_destroy(&un->sock);
|
||||
return socket_strerror(err);
|
||||
return socket_strerror(err);
|
||||
}
|
||||
|
||||
static int meth_bind(lua_State *L) {
|
||||
@ -236,11 +220,11 @@ static const char *unix_tryconnect(p_unix un, const char *path)
|
||||
remote.sun_family = AF_UNIX;
|
||||
timeout_markstart(&un->tm);
|
||||
#ifdef UNIX_HAS_SUN_LEN
|
||||
remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len)
|
||||
remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len)
|
||||
+ len + 1;
|
||||
err = socket_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm);
|
||||
#else
|
||||
err = socket_connect(&un->sock, (SA *) &remote,
|
||||
err = socket_connect(&un->sock, (SA *) &remote,
|
||||
sizeof(remote.sun_family) + len, &un->tm);
|
||||
#endif
|
||||
if (err != IO_DONE) socket_destroy(&un->sock);
|
||||
@ -264,7 +248,7 @@ static int meth_connect(lua_State *L)
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Closes socket used by object
|
||||
* Closes socket used by object
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static int meth_close(lua_State *L)
|
||||
{
|
||||
@ -319,13 +303,13 @@ static int meth_settimeout(lua_State *L) {
|
||||
* Library functions
|
||||
\*=========================================================================*/
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Creates a master unix object
|
||||
* Creates a master unix object
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static int global_create(lua_State *L) {
|
||||
t_socket sock;
|
||||
int err = socket_create(&sock, AF_UNIX, SOCK_STREAM, 0);
|
||||
/* try to allocate a system socket */
|
||||
if (err == IO_DONE) {
|
||||
if (err == IO_DONE) {
|
||||
/* allocate unix object */
|
||||
p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix));
|
||||
/* set its type as master object */
|
||||
@ -333,7 +317,7 @@ static int global_create(lua_State *L) {
|
||||
/* initialize remaining structure fields */
|
||||
socket_setnonblocking(&sock);
|
||||
un->sock = sock;
|
||||
io_init(&un->io, (p_send) socket_send, (p_recv) socket_recv,
|
||||
io_init(&un->io, (p_send) socket_send, (p_recv) socket_recv,
|
||||
(p_error) socket_ioerror, &un->sock);
|
||||
timeout_init(&un->tm, -1, -1);
|
||||
buffer_init(&un->buf, &un->io, &un->tm);
|
||||
|
@ -3,7 +3,7 @@
|
||||
* LuaSocket toolkit
|
||||
*
|
||||
* The penalty of calling select to avoid busy-wait is only paid when
|
||||
* the I/O call fail in the first place.
|
||||
* the I/O call fail in the first place.
|
||||
\*=========================================================================*/
|
||||
#include <string.h>
|
||||
|
||||
@ -14,23 +14,23 @@
|
||||
static const char *wstrerror(int err);
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Initializes module
|
||||
* Initializes module
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int socket_open(void) {
|
||||
WSADATA wsaData;
|
||||
WORD wVersionRequested = MAKEWORD(2, 0);
|
||||
WORD wVersionRequested = MAKEWORD(2, 0);
|
||||
int err = WSAStartup(wVersionRequested, &wsaData );
|
||||
if (err != 0) return 0;
|
||||
if ((LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) &&
|
||||
(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)) {
|
||||
WSACleanup();
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Close module
|
||||
* Close module
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int socket_close(void) {
|
||||
WSACleanup();
|
||||
@ -51,10 +51,10 @@ int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
|
||||
struct timeval tv, *tp = NULL;
|
||||
double t;
|
||||
if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */
|
||||
if (sw & WAITFD_R) {
|
||||
FD_ZERO(&rfds);
|
||||
if (sw & WAITFD_R) {
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(*ps, &rfds);
|
||||
rp = &rfds;
|
||||
rp = &rfds;
|
||||
}
|
||||
if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }
|
||||
if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(*ps, &efds); ep = &efds; }
|
||||
@ -73,9 +73,9 @@ int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Select with int timeout in ms
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
|
||||
int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
|
||||
p_timeout tm) {
|
||||
struct timeval tv;
|
||||
struct timeval tv;
|
||||
double t = timeout_get(tm);
|
||||
tv.tv_sec = (int) t;
|
||||
tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6);
|
||||
@ -97,7 +97,7 @@ void socket_destroy(p_socket ps) {
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
*
|
||||
*
|
||||
\*-------------------------------------------------------------------------*/
|
||||
void socket_shutdown(p_socket ps, int how) {
|
||||
socket_setblocking(ps);
|
||||
@ -135,10 +135,10 @@ int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) {
|
||||
/* give windows time to set the error (yes, disgusting) */
|
||||
Sleep(10);
|
||||
/* find out why we failed */
|
||||
getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
|
||||
getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
|
||||
/* we KNOW there was an error. if 'why' is 0, we will return
|
||||
* "unknown error", but it's not really our fault */
|
||||
return err > 0? err: IO_UNKNOWN;
|
||||
return err > 0? err: IO_UNKNOWN;
|
||||
} else return err;
|
||||
|
||||
}
|
||||
@ -155,7 +155,7 @@ int socket_bind(p_socket ps, SA *addr, socklen_t len) {
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
*
|
||||
*
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int socket_listen(p_socket ps, int backlog) {
|
||||
int err = IO_DONE;
|
||||
@ -168,7 +168,7 @@ int socket_listen(p_socket ps, int backlog) {
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Accept with timeout
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len,
|
||||
int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len,
|
||||
p_timeout tm) {
|
||||
if (*ps == SOCKET_INVALID) return IO_CLOSED;
|
||||
for ( ;; ) {
|
||||
@ -176,21 +176,21 @@ int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len,
|
||||
/* try to get client socket */
|
||||
if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE;
|
||||
/* find out why we failed */
|
||||
err = WSAGetLastError();
|
||||
err = WSAGetLastError();
|
||||
/* if we failed because there was no connectoin, keep trying */
|
||||
if (err != WSAEWOULDBLOCK && err != WSAECONNABORTED) return err;
|
||||
/* call select to avoid busy wait */
|
||||
if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Send with timeout
|
||||
* On windows, if you try to send 10MB, the OS will buffer EVERYTHING
|
||||
* this can take an awful lot of time and we will end up blocked.
|
||||
* On windows, if you try to send 10MB, the OS will buffer EVERYTHING
|
||||
* this can take an awful lot of time and we will end up blocked.
|
||||
* Therefore, whoever calls this function should not pass a huge buffer.
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int socket_send(p_socket ps, const char *data, size_t count,
|
||||
int socket_send(p_socket ps, const char *data, size_t count,
|
||||
size_t *sent, p_timeout tm)
|
||||
{
|
||||
int err;
|
||||
@ -207,18 +207,18 @@ int socket_send(p_socket ps, const char *data, size_t count,
|
||||
return IO_DONE;
|
||||
}
|
||||
/* deal with failure */
|
||||
err = WSAGetLastError();
|
||||
err = WSAGetLastError();
|
||||
/* we can only proceed if there was no serious error */
|
||||
if (err != WSAEWOULDBLOCK) return err;
|
||||
/* avoid busy wait */
|
||||
if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Sendto with timeout
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
|
||||
int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
|
||||
SA *addr, socklen_t len, p_timeout tm)
|
||||
{
|
||||
int err;
|
||||
@ -230,17 +230,17 @@ int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
|
||||
*sent = put;
|
||||
return IO_DONE;
|
||||
}
|
||||
err = WSAGetLastError();
|
||||
err = WSAGetLastError();
|
||||
if (err != WSAEWOULDBLOCK) return err;
|
||||
if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Receive with timeout
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int socket_recv(p_socket ps, char *data, size_t count, size_t *got,
|
||||
p_timeout tm)
|
||||
int socket_recv(p_socket ps, char *data, size_t count, size_t *got,
|
||||
p_timeout tm)
|
||||
{
|
||||
int err, prev = IO_DONE;
|
||||
*got = 0;
|
||||
@ -253,9 +253,9 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got,
|
||||
}
|
||||
if (taken == 0) return IO_CLOSED;
|
||||
err = WSAGetLastError();
|
||||
/* On UDP, a connreset simply means the previous send failed.
|
||||
* So we try again.
|
||||
* On TCP, it means our socket is now useless, so the error passes.
|
||||
/* On UDP, a connreset simply means the previous send failed.
|
||||
* So we try again.
|
||||
* On TCP, it means our socket is now useless, so the error passes.
|
||||
* (We will loop again, exiting because the same error will happen) */
|
||||
if (err != WSAEWOULDBLOCK) {
|
||||
if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
|
||||
@ -268,8 +268,8 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got,
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Recvfrom with timeout
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
|
||||
SA *addr, socklen_t *len, p_timeout tm)
|
||||
int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
|
||||
SA *addr, socklen_t *len, p_timeout tm)
|
||||
{
|
||||
int err, prev = IO_DONE;
|
||||
*got = 0;
|
||||
@ -282,8 +282,8 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
|
||||
}
|
||||
if (taken == 0) return IO_CLOSED;
|
||||
err = WSAGetLastError();
|
||||
/* On UDP, a connreset simply means the previous send failed.
|
||||
* So we try again.
|
||||
/* On UDP, a connreset simply means the previous send failed.
|
||||
* So we try again.
|
||||
* On TCP, it means our socket is now useless, so the error passes.
|
||||
* (We will loop again, exiting because the same error will happen) */
|
||||
if (err != WSAEWOULDBLOCK) {
|
||||
@ -311,7 +311,7 @@ void socket_setnonblocking(p_socket ps) {
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* DNS helpers
|
||||
* DNS helpers
|
||||
\*-------------------------------------------------------------------------*/
|
||||
int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) {
|
||||
*hp = gethostbyaddr(addr, len, AF_INET);
|
||||
@ -332,7 +332,7 @@ const char *socket_hoststrerror(int err) {
|
||||
if (err <= 0) return io_strerror(err);
|
||||
switch (err) {
|
||||
case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND;
|
||||
default: return wstrerror(err);
|
||||
default: return wstrerror(err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -374,7 +374,7 @@ static const char *wstrerror(int err) {
|
||||
case WSAESOCKTNOSUPPORT: return PIE_SOCKTYPE; // "Socket type not supported";
|
||||
case WSAEOPNOTSUPP: return "Operation not supported";
|
||||
case WSAEPFNOSUPPORT: return "Protocol family not supported";
|
||||
case WSAEAFNOSUPPORT: return PIE_FAMILY; // "Address family not supported by protocol family";
|
||||
case WSAEAFNOSUPPORT: return PIE_FAMILY; // "Address family not supported by protocol family";
|
||||
case WSAEADDRINUSE: return PIE_ADDRINUSE; // "Address already in use";
|
||||
case WSAEADDRNOTAVAIL: return "Cannot assign requested address";
|
||||
case WSAENETDOWN: return "Network is down";
|
||||
@ -393,19 +393,19 @@ static const char *wstrerror(int err) {
|
||||
case WSAEPROCLIM: return "Too many processes";
|
||||
case WSASYSNOTREADY: return "Network subsystem is unavailable";
|
||||
case WSAVERNOTSUPPORTED: return "Winsock.dll version out of range";
|
||||
case WSANOTINITIALISED:
|
||||
case WSANOTINITIALISED:
|
||||
return "Successful WSAStartup not yet performed";
|
||||
case WSAEDISCON: return "Graceful shutdown in progress";
|
||||
case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; // "Host not found";
|
||||
case WSATRY_AGAIN: return "Nonauthoritative host not found";
|
||||
case WSANO_RECOVERY: return PIE_FAIL; // "Nonrecoverable name lookup error";
|
||||
case WSANO_RECOVERY: return PIE_FAIL; // "Nonrecoverable name lookup error";
|
||||
case WSANO_DATA: return "Valid name, no data record of requested type";
|
||||
default: return "Unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
const char *socket_gaistrerror(int err) {
|
||||
if (err == 0) return NULL;
|
||||
if (err == 0) return NULL;
|
||||
switch (err) {
|
||||
case EAI_AGAIN: return PIE_AGAIN;
|
||||
case EAI_BADFLAGS: return PIE_BADFLAGS;
|
||||
@ -425,7 +425,7 @@ const char *socket_gaistrerror(int err) {
|
||||
case EAI_SERVICE: return PIE_SERVICE;
|
||||
case EAI_SOCKTYPE: return PIE_SOCKTYPE;
|
||||
#ifdef EAI_SYSTEM
|
||||
case EAI_SYSTEM: return strerror(errno);
|
||||
case EAI_SYSTEM: return strerror(errno);
|
||||
#endif
|
||||
default: return gai_strerror(err);
|
||||
}
|
||||
|
@ -590,7 +590,7 @@ function test_writeafterclose()
|
||||
data = nil
|
||||
]]))
|
||||
local sent, err, errsent
|
||||
while not err do
|
||||
while not err do
|
||||
sent, err, errsent, time = data:send(str)
|
||||
end
|
||||
assert(err == "closed", "should have returned 'closed'")
|
||||
|
Loading…
Reference in New Issue
Block a user