summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/luasocket/src/select.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/luasocket/src/select.c')
-rw-r--r--Build/source/texk/web2c/luatexdir/luasocket/src/select.c64
1 files changed, 40 insertions, 24 deletions
diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/select.c b/Build/source/texk/web2c/luatexdir/luasocket/src/select.c
index d70f662713a..51fb198611a 100644
--- a/Build/source/texk/web2c/luatexdir/luasocket/src/select.c
+++ b/Build/source/texk/web2c/luatexdir/luasocket/src/select.c
@@ -1,8 +1,6 @@
/*=========================================================================*\
* Select implementation
* LuaSocket toolkit
-*
-* RCS ID: $Id: select.c,v 1.22 2005/11/20 07:20:23 diego Exp $
\*=========================================================================*/
#include <string.h>
@@ -18,8 +16,8 @@
\*=========================================================================*/
static t_socket getfd(lua_State *L);
static int dirty(lua_State *L);
-static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd,
- int itab, fd_set *set);
+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,
int itab, int tab, int start);
@@ -27,7 +25,7 @@ static void make_assoc(lua_State *L, int tab);
static int global_select(lua_State *L);
/* functions in library namespace */
-static luaL_reg func[] = {
+static luaL_Reg func[] = {
{"select", global_select},
{NULL, NULL}
};
@@ -39,6 +37,9 @@ static luaL_reg func[] = {
* Initializes module
\*-------------------------------------------------------------------------*/
int select_open(lua_State *L) {
+ lua_pushstring(L, "_SETSIZE");
+ lua_pushnumber(L, FD_SETSIZE);
+ lua_rawset(L, -3);
luaL_openlib(L, NULL, func, 0);
return 0;
}
@@ -51,7 +52,7 @@ int select_open(lua_State *L) {
\*-------------------------------------------------------------------------*/
static int global_select(lua_State *L) {
int rtab, wtab, itab, ret, ndirty;
- t_socket max_fd;
+ t_socket max_fd = SOCKET_INVALID;
fd_set rset, wset;
t_timeout tm;
double t = luaL_optnumber(L, 3, -1);
@@ -60,12 +61,12 @@ static int global_select(lua_State *L) {
lua_newtable(L); itab = lua_gettop(L);
lua_newtable(L); rtab = lua_gettop(L);
lua_newtable(L); wtab = lua_gettop(L);
- max_fd = collect_fd(L, 1, SOCKET_INVALID, itab, &rset);
+ collect_fd(L, 1, itab, &rset, &max_fd);
+ collect_fd(L, 2, itab, &wset, &max_fd);
ndirty = check_dirty(L, 1, rtab, &rset);
t = ndirty > 0? 0.0: t;
timeout_init(&tm, t, -1);
timeout_markstart(&tm);
- max_fd = collect_fd(L, 2, max_fd, itab, &wset);
ret = socket_select(max_fd+1, &rset, &wset, NULL, &tm);
if (ret > 0 || ndirty > 0) {
return_fd(L, &rset, max_fd+1, itab, rtab, ndirty);
@@ -77,7 +78,7 @@ static int global_select(lua_State *L) {
lua_pushstring(L, "timeout");
return 3;
} else {
- lua_pushstring(L, "error");
+ luaL_error(L, "select failed");
return 3;
}
}
@@ -92,8 +93,10 @@ static t_socket getfd(lua_State *L) {
if (!lua_isnil(L, -1)) {
lua_pushvalue(L, -2);
lua_call(L, 1, 1);
- if (lua_isnumber(L, -1))
- fd = (t_socket) lua_tonumber(L, -1);
+ if (lua_isnumber(L, -1)) {
+ double numfd = lua_tonumber(L, -1);
+ fd = (numfd >= 0.0)? (t_socket) numfd: SOCKET_INVALID;
+ }
}
lua_pop(L, 1);
return fd;
@@ -112,12 +115,14 @@ static int dirty(lua_State *L) {
return is;
}
-static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd,
- int itab, fd_set *set) {
- int i = 1;
- if (lua_isnil(L, tab))
- return max_fd;
- while (1) {
+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 */
+ if (lua_isnil(L, tab)) return;
+ /* otherwise we need it to be a table */
+ luaL_checktype(L, tab, LUA_TTABLE);
+ for ( ;; ) {
t_socket fd;
lua_pushnumber(L, i);
lua_gettable(L, tab);
@@ -125,26 +130,37 @@ static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd,
lua_pop(L, 1);
break;
}
+ /* getfd figures out if this is a socket */
fd = getfd(L);
if (fd != SOCKET_INVALID) {
+ /* make sure we don't overflow the fd_set */
+#ifdef _WIN32
+ if (n >= FD_SETSIZE)
+ luaL_argerror(L, tab, "too many sockets");
+#else
+ if (fd >= FD_SETSIZE)
+ luaL_argerror(L, tab, "descriptor too large for set size");
+#endif
FD_SET(fd, set);
- if (max_fd == SOCKET_INVALID || max_fd < fd)
- max_fd = fd;
- lua_pushnumber(L, fd);
+ n++;
+ /* keep track of the largest descriptor so far */
+ 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);
lua_pushvalue(L, -2);
lua_settable(L, itab);
}
lua_pop(L, 1);
i = i + 1;
}
- return max_fd;
}
static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set) {
int ndirty = 0, i = 1;
if (lua_isnil(L, tab))
return 0;
- while (1) {
+ for ( ;; ) {
t_socket fd;
lua_pushnumber(L, i);
lua_gettable(L, tab);
@@ -171,7 +187,7 @@ static void return_fd(lua_State *L, fd_set *set, t_socket max_fd,
for (fd = 0; fd < max_fd; fd++) {
if (FD_ISSET(fd, set)) {
lua_pushnumber(L, ++start);
- lua_pushnumber(L, fd);
+ lua_pushnumber(L, (lua_Number) fd);
lua_gettable(L, itab);
lua_settable(L, tab);
}
@@ -181,7 +197,7 @@ static void return_fd(lua_State *L, fd_set *set, t_socket max_fd,
static void make_assoc(lua_State *L, int tab) {
int i = 1, atab;
lua_newtable(L); atab = lua_gettop(L);
- while (1) {
+ for ( ;; ) {
lua_pushnumber(L, i);
lua_gettable(L, tab);
if (!lua_isnil(L, -1)) {