diff options
author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2003-06-09 18:23:40 +0000 |
---|---|---|
committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2003-06-09 18:23:40 +0000 |
commit | 58bdb658aaa1c30a8f3bed46eef880d308fae582 (patch) | |
tree | 5bf880c715daff79c1a2062f2f3ae8336858c83f /src | |
parent | b2724ad2d1cc3768a04270ed3f8014ec65ad133b (diff) | |
download | luasocket-58bdb658aaa1c30a8f3bed46eef880d308fae582.tar.gz luasocket-58bdb658aaa1c30a8f3bed46eef880d308fae582.tar.bz2 luasocket-58bdb658aaa1c30a8f3bed46eef880d308fae582.zip |
Select re-implemented in a nicer way.
Few changes in internal class and group registration.
Lua modules are compiled and built into library.
Dynamic library tested in Linux and Mac OS X.
Diffstat (limited to 'src')
-rw-r--r-- | src/auxiliar.c | 75 | ||||
-rw-r--r-- | src/auxiliar.h | 2 | ||||
-rw-r--r-- | src/buffer.c | 4 | ||||
-rw-r--r-- | src/buffer.h | 2 | ||||
-rw-r--r-- | src/inet.c | 5 | ||||
-rw-r--r-- | src/inet.h | 2 | ||||
-rw-r--r-- | src/io.h | 12 | ||||
-rw-r--r-- | src/luasocket.c | 31 | ||||
-rw-r--r-- | src/select.c | 191 | ||||
-rw-r--r-- | src/select.h | 7 | ||||
-rw-r--r-- | src/socket.h | 23 | ||||
-rw-r--r-- | src/tcp.c | 97 | ||||
-rw-r--r-- | src/tcp.h | 6 | ||||
-rw-r--r-- | src/timeout.c | 5 | ||||
-rw-r--r-- | src/udp.c | 98 | ||||
-rw-r--r-- | src/udp.h | 4 | ||||
-rw-r--r-- | src/usocket.c | 119 | ||||
-rw-r--r-- | src/usocket.h | 5 |
18 files changed, 344 insertions, 344 deletions
diff --git a/src/auxiliar.c b/src/auxiliar.c index 5e5ba1a..96138f1 100644 --- a/src/auxiliar.c +++ b/src/auxiliar.c | |||
@@ -3,12 +3,7 @@ | |||
3 | * | 3 | * |
4 | * RCS ID: $Id$ | 4 | * RCS ID: $Id$ |
5 | \*=========================================================================*/ | 5 | \*=========================================================================*/ |
6 | #include "aux.h" | 6 | #include "auxiliar.h" |
7 | |||
8 | /*=========================================================================*\ | ||
9 | * Internal function prototypes | ||
10 | \*=========================================================================*/ | ||
11 | static void *aux_getgroupudata(lua_State *L, const char *group, int objidx); | ||
12 | 7 | ||
13 | /*=========================================================================*\ | 8 | /*=========================================================================*\ |
14 | * Exported functions | 9 | * Exported functions |
@@ -20,18 +15,19 @@ static void *aux_getgroupudata(lua_State *L, const char *group, int objidx); | |||
20 | \*-------------------------------------------------------------------------*/ | 15 | \*-------------------------------------------------------------------------*/ |
21 | void aux_newclass(lua_State *L, const char *name, luaL_reg *func) | 16 | void aux_newclass(lua_State *L, const char *name, luaL_reg *func) |
22 | { | 17 | { |
23 | luaL_newmetatable(L, name); | 18 | lua_pushstring(L, name); |
19 | lua_newtable(L); | ||
24 | lua_pushstring(L, "__index"); | 20 | lua_pushstring(L, "__index"); |
25 | lua_newtable(L); | 21 | lua_newtable(L); |
26 | luaL_openlib(L, NULL, func, 0); | 22 | luaL_openlib(L, NULL, func, 0); |
27 | lua_pushstring(L, "class"); | 23 | lua_pushstring(L, "class"); |
28 | lua_pushstring(L, name); | 24 | lua_pushstring(L, name); |
29 | lua_settable(L, -3); | 25 | lua_rawset(L, -3); |
30 | lua_settable(L, -3); | ||
31 | lua_pushstring(L, "group"); | 26 | lua_pushstring(L, "group"); |
32 | lua_newtable(L); | 27 | lua_newtable(L); |
33 | lua_settable(L, -3); | 28 | lua_rawset(L, -3); |
34 | lua_pop(L, 1); | 29 | lua_rawset(L, -3); |
30 | lua_rawset(L, LUA_REGISTRYINDEX); | ||
35 | } | 31 | } |
36 | 32 | ||
37 | /*-------------------------------------------------------------------------*\ | 33 | /*-------------------------------------------------------------------------*\ |
@@ -39,13 +35,16 @@ void aux_newclass(lua_State *L, const char *name, luaL_reg *func) | |||
39 | \*-------------------------------------------------------------------------*/ | 35 | \*-------------------------------------------------------------------------*/ |
40 | void aux_add2group(lua_State *L, const char *name, const char *group) | 36 | void aux_add2group(lua_State *L, const char *name, const char *group) |
41 | { | 37 | { |
42 | luaL_getmetatable(L, name); | 38 | lua_pushstring(L, name); |
39 | lua_rawget(L, LUA_REGISTRYINDEX); | ||
40 | lua_pushstring(L, "__index"); | ||
41 | lua_rawget(L, -2); | ||
43 | lua_pushstring(L, "group"); | 42 | lua_pushstring(L, "group"); |
44 | lua_gettable(L, -2); | 43 | lua_rawget(L, -2); |
45 | lua_pushstring(L, group); | 44 | lua_pushstring(L, group); |
46 | lua_pushnumber(L, 1); | 45 | lua_pushnumber(L, 1); |
47 | lua_settable(L, -3); | 46 | lua_rawset(L, -3); |
48 | lua_pop(L, 2); | 47 | lua_pop(L, 3); |
49 | } | 48 | } |
50 | 49 | ||
51 | /*-------------------------------------------------------------------------*\ | 50 | /*-------------------------------------------------------------------------*\ |
@@ -53,7 +52,7 @@ void aux_add2group(lua_State *L, const char *name, const char *group) | |||
53 | \*-------------------------------------------------------------------------*/ | 52 | \*-------------------------------------------------------------------------*/ |
54 | void *aux_checkclass(lua_State *L, const char *name, int objidx) | 53 | void *aux_checkclass(lua_State *L, const char *name, int objidx) |
55 | { | 54 | { |
56 | void *data = luaL_checkudata(L, objidx, name); | 55 | void *data = aux_getclassudata(L, name, objidx); |
57 | if (!data) { | 56 | if (!data) { |
58 | char msg[45]; | 57 | char msg[45]; |
59 | sprintf(msg, "%.35s expected", name); | 58 | sprintf(msg, "%.35s expected", name); |
@@ -81,7 +80,8 @@ void *aux_checkgroup(lua_State *L, const char *group, int objidx) | |||
81 | \*-------------------------------------------------------------------------*/ | 80 | \*-------------------------------------------------------------------------*/ |
82 | void aux_setclass(lua_State *L, const char *name, int objidx) | 81 | void aux_setclass(lua_State *L, const char *name, int objidx) |
83 | { | 82 | { |
84 | luaL_getmetatable(L, name); | 83 | lua_pushstring(L, name); |
84 | lua_rawget(L, LUA_REGISTRYINDEX); | ||
85 | if (objidx < 0) objidx--; | 85 | if (objidx < 0) objidx--; |
86 | lua_setmetatable(L, objidx); | 86 | lua_setmetatable(L, objidx); |
87 | } | 87 | } |
@@ -92,17 +92,47 @@ void aux_setclass(lua_State *L, const char *name, int objidx) | |||
92 | /*-------------------------------------------------------------------------*\ | 92 | /*-------------------------------------------------------------------------*\ |
93 | * Get a userdata if object belongs to a given group. | 93 | * Get a userdata if object belongs to a given group. |
94 | \*-------------------------------------------------------------------------*/ | 94 | \*-------------------------------------------------------------------------*/ |
95 | static void *aux_getgroupudata(lua_State *L, const char *group, int objidx) | 95 | void *aux_getgroupudata(lua_State *L, const char *group, int objidx) |
96 | { | 96 | { |
97 | if (!lua_getmetatable(L, objidx)) return NULL; | 97 | if (!lua_getmetatable(L, objidx)) |
98 | return NULL; | ||
99 | lua_pushstring(L, "__index"); | ||
100 | lua_rawget(L, -2); | ||
101 | if (!lua_istable(L, -1)) { | ||
102 | lua_pop(L, 2); | ||
103 | return NULL; | ||
104 | } | ||
98 | lua_pushstring(L, "group"); | 105 | lua_pushstring(L, "group"); |
99 | lua_gettable(L, -2); | 106 | lua_rawget(L, -2); |
107 | if (!lua_istable(L, -1)) { | ||
108 | lua_pop(L, 3); | ||
109 | return NULL; | ||
110 | } | ||
111 | lua_pushstring(L, group); | ||
112 | lua_rawget(L, -2); | ||
100 | if (lua_isnil(L, -1)) { | 113 | if (lua_isnil(L, -1)) { |
114 | lua_pop(L, 4); | ||
115 | return NULL; | ||
116 | } | ||
117 | lua_pop(L, 4); | ||
118 | return lua_touserdata(L, objidx); | ||
119 | } | ||
120 | |||
121 | /*-------------------------------------------------------------------------*\ | ||
122 | * Get a userdata if object belongs to a given class. | ||
123 | \*-------------------------------------------------------------------------*/ | ||
124 | void *aux_getclassudata(lua_State *L, const char *group, int objidx) | ||
125 | { | ||
126 | if (!lua_getmetatable(L, objidx)) | ||
127 | return NULL; | ||
128 | lua_pushstring(L, "__index"); | ||
129 | lua_rawget(L, -2); | ||
130 | if (!lua_istable(L, -1)) { | ||
101 | lua_pop(L, 2); | 131 | lua_pop(L, 2); |
102 | return NULL; | 132 | return NULL; |
103 | } | 133 | } |
104 | lua_pushstring(L, group); | 134 | lua_pushstring(L, "class"); |
105 | lua_gettable(L, -2); | 135 | lua_rawget(L, -2); |
106 | if (lua_isnil(L, -1)) { | 136 | if (lua_isnil(L, -1)) { |
107 | lua_pop(L, 3); | 137 | lua_pop(L, 3); |
108 | return NULL; | 138 | return NULL; |
@@ -110,4 +140,3 @@ static void *aux_getgroupudata(lua_State *L, const char *group, int objidx) | |||
110 | lua_pop(L, 3); | 140 | lua_pop(L, 3); |
111 | return lua_touserdata(L, objidx); | 141 | return lua_touserdata(L, objidx); |
112 | } | 142 | } |
113 | |||
diff --git a/src/auxiliar.h b/src/auxiliar.h index 2681a84..66be31d 100644 --- a/src/auxiliar.h +++ b/src/auxiliar.h | |||
@@ -13,6 +13,8 @@ void aux_newclass(lua_State *L, const char *name, luaL_reg *func); | |||
13 | void aux_add2group(lua_State *L, const char *name, const char *group); | 13 | void aux_add2group(lua_State *L, const char *name, const char *group); |
14 | void *aux_checkclass(lua_State *L, const char *name, int objidx); | 14 | void *aux_checkclass(lua_State *L, const char *name, int objidx); |
15 | void *aux_checkgroup(lua_State *L, const char *group, int objidx); | 15 | void *aux_checkgroup(lua_State *L, const char *group, int objidx); |
16 | void *aux_getclassudata(lua_State *L, const char *group, int objidx); | ||
17 | void *aux_getgroupudata(lua_State *L, const char *group, int objidx); | ||
16 | void aux_setclass(lua_State *L, const char *name, int objidx); | 18 | void aux_setclass(lua_State *L, const char *name, int objidx); |
17 | 19 | ||
18 | /* min and max macros */ | 20 | /* min and max macros */ |
diff --git a/src/buffer.c b/src/buffer.c index c5ef66c..ab059bb 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
@@ -7,8 +7,8 @@ | |||
7 | #include <lauxlib.h> | 7 | #include <lauxlib.h> |
8 | 8 | ||
9 | #include "error.h" | 9 | #include "error.h" |
10 | #include "aux.h" | 10 | #include "auxiliar.h" |
11 | #include "buf.h" | 11 | #include "buffer.h" |
12 | 12 | ||
13 | /*=========================================================================*\ | 13 | /*=========================================================================*\ |
14 | * Internal function prototypes | 14 | * Internal function prototypes |
diff --git a/src/buffer.h b/src/buffer.h index 3ffc145..1502ef0 100644 --- a/src/buffer.h +++ b/src/buffer.h | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | #include <lua.h> | 9 | #include <lua.h> |
10 | #include "io.h" | 10 | #include "io.h" |
11 | #include "tm.h" | 11 | #include "timeout.h" |
12 | 12 | ||
13 | /* buffer size in bytes */ | 13 | /* buffer size in bytes */ |
14 | #define BUF_SIZE 8192 | 14 | #define BUF_SIZE 8192 |
@@ -38,6 +38,7 @@ static luaL_reg func[] = { | |||
38 | void inet_open(lua_State *L) | 38 | void inet_open(lua_State *L) |
39 | { | 39 | { |
40 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); | 40 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); |
41 | lua_pop(L, 1); | ||
41 | } | 42 | } |
42 | 43 | ||
43 | /*=========================================================================*\ | 44 | /*=========================================================================*\ |
@@ -114,7 +115,7 @@ static int inet_global_tohostname(lua_State *L) | |||
114 | int inet_meth_getpeername(lua_State *L, p_sock ps) | 115 | int inet_meth_getpeername(lua_State *L, p_sock ps) |
115 | { | 116 | { |
116 | struct sockaddr_in peer; | 117 | struct sockaddr_in peer; |
117 | size_t peer_len = sizeof(peer); | 118 | socklen_t peer_len = sizeof(peer); |
118 | if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) { | 119 | if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) { |
119 | lua_pushnil(L); | 120 | lua_pushnil(L); |
120 | return 1; | 121 | return 1; |
@@ -135,7 +136,7 @@ int inet_meth_getpeername(lua_State *L, p_sock ps) | |||
135 | int inet_meth_getsockname(lua_State *L, p_sock ps) | 136 | int inet_meth_getsockname(lua_State *L, p_sock ps) |
136 | { | 137 | { |
137 | struct sockaddr_in local; | 138 | struct sockaddr_in local; |
138 | size_t local_len = sizeof(local); | 139 | socklen_t local_len = sizeof(local); |
139 | if (getsockname(*ps, (SA *) &local, &local_len) < 0) { | 140 | if (getsockname(*ps, (SA *) &local, &local_len) < 0) { |
140 | lua_pushnil(L); | 141 | lua_pushnil(L); |
141 | return 1; | 142 | return 1; |
@@ -7,7 +7,7 @@ | |||
7 | #define INET_H | 7 | #define INET_H |
8 | 8 | ||
9 | #include <lua.h> | 9 | #include <lua.h> |
10 | #include "sock.h" | 10 | #include "socket.h" |
11 | 11 | ||
12 | /*-------------------------------------------------------------------------*\ | 12 | /*-------------------------------------------------------------------------*\ |
13 | * Exported functions | 13 | * Exported functions |
@@ -1,7 +1,17 @@ | |||
1 | #ifndef IO_H | 1 | #ifndef IO_H |
2 | #define IO_H | 2 | #define IO_H |
3 | 3 | ||
4 | #include "error.h" | 4 | #include <stdio.h> |
5 | |||
6 | /* IO error codes */ | ||
7 | enum { | ||
8 | IO_DONE, /* operation completed successfully */ | ||
9 | IO_TIMEOUT, /* operation timed out */ | ||
10 | IO_CLOSED, /* the connection has been closed */ | ||
11 | IO_ERROR, /* something wrong... */ | ||
12 | IO_REFUSED, /* transfer has been refused */ | ||
13 | IO_LIMITED /* maximum number of bytes reached */ | ||
14 | }; | ||
5 | 15 | ||
6 | /* interface to send function */ | 16 | /* interface to send function */ |
7 | typedef int (*p_send) ( | 17 | typedef int (*p_send) ( |
diff --git a/src/luasocket.c b/src/luasocket.c index 53f8c21..5541d7f 100644 --- a/src/luasocket.c +++ b/src/luasocket.c | |||
@@ -24,12 +24,13 @@ | |||
24 | \*=========================================================================*/ | 24 | \*=========================================================================*/ |
25 | #include "luasocket.h" | 25 | #include "luasocket.h" |
26 | 26 | ||
27 | #include "tm.h" | 27 | #include "timeout.h" |
28 | #include "buf.h" | 28 | #include "buffer.h" |
29 | #include "sock.h" | 29 | #include "socket.h" |
30 | #include "inet.h" | 30 | #include "inet.h" |
31 | #include "tcp.h" | 31 | #include "tcp.h" |
32 | #include "udp.h" | 32 | #include "udp.h" |
33 | #include "select.h" | ||
33 | 34 | ||
34 | /*=========================================================================*\ | 35 | /*=========================================================================*\ |
35 | * Exported functions | 36 | * Exported functions |
@@ -39,6 +40,7 @@ | |||
39 | \*-------------------------------------------------------------------------*/ | 40 | \*-------------------------------------------------------------------------*/ |
40 | LUASOCKET_API int luaopen_socketlib(lua_State *L) | 41 | LUASOCKET_API int luaopen_socketlib(lua_State *L) |
41 | { | 42 | { |
43 | if (!sock_open()) return 0; | ||
42 | /* create namespace table */ | 44 | /* create namespace table */ |
43 | lua_pushstring(L, LUASOCKET_LIBNAME); | 45 | lua_pushstring(L, LUASOCKET_LIBNAME); |
44 | lua_newtable(L); | 46 | lua_newtable(L); |
@@ -53,13 +55,28 @@ LUASOCKET_API int luaopen_socketlib(lua_State *L) | |||
53 | lua_pushstring(L, LUASOCKET_LIBNAME); | 55 | lua_pushstring(L, LUASOCKET_LIBNAME); |
54 | lua_settable(L, LUA_GLOBALSINDEX); | 56 | lua_settable(L, LUA_GLOBALSINDEX); |
55 | /* initialize all modules */ | 57 | /* initialize all modules */ |
56 | sock_open(L); | ||
57 | tm_open(L); | 58 | tm_open(L); |
58 | buf_open(L); | 59 | buf_open(L); |
59 | inet_open(L); | 60 | inet_open(L); |
60 | tcp_open(L); | 61 | tcp_open(L); |
61 | udp_open(L); | 62 | udp_open(L); |
62 | /* load all Lua code */ | 63 | select_open(L); |
63 | lua_dofile(L, "luasocket.lua"); | 64 | #ifdef LUASOCKET_COMPILED |
64 | return 0; | 65 | #include "auxiliar.lch" |
66 | #include "concat.lch" | ||
67 | #include "code.lch" | ||
68 | #include "url.lch" | ||
69 | #include "smtp.lch" | ||
70 | #include "ftp.lch" | ||
71 | #include "http.lch" | ||
72 | #else | ||
73 | lua_dofile(L, "auxiliar.lua"); | ||
74 | lua_dofile(L, "concat.lua"); | ||
75 | lua_dofile(L, "code.lua"); | ||
76 | lua_dofile(L, "url.lua"); | ||
77 | lua_dofile(L, "smtp.lua"); | ||
78 | lua_dofile(L, "ftp.lua"); | ||
79 | lua_dofile(L, "http.lua"); | ||
80 | #endif | ||
81 | return 1; | ||
65 | } | 82 | } |
diff --git a/src/select.c b/src/select.c index 9f56b47..3cabbd1 100644 --- a/src/select.c +++ b/src/select.c | |||
@@ -1,154 +1,129 @@ | |||
1 | /*=========================================================================*\ | 1 | /*=========================================================================*\ |
2 | * Select implementation | 2 | * Select implementation |
3 | * Global Lua fuctions: | ||
4 | * select: waits until socket ready | ||
5 | * RCS ID: $Id$ | 3 | * RCS ID: $Id$ |
6 | \*=========================================================================*/ | 4 | \*=========================================================================*/ |
7 | #include <string.h> | 5 | #include <string.h> |
6 | |||
8 | #include <lua.h> | 7 | #include <lua.h> |
9 | #include <lauxlib.h> | 8 | #include <lauxlib.h> |
10 | 9 | ||
11 | #include "luasocket.h" | 10 | #include "luasocket.h" |
12 | #include "lspriv.h" | 11 | #include "socket.h" |
13 | #include "lsselect.h" | 12 | #include "auxiliar.h" |
14 | #include "lsfd.h" | 13 | #include "select.h" |
15 | 14 | ||
16 | /* auxiliar functions */ | 15 | static int meth_set(lua_State *L); |
17 | static int local_select(lua_State *L); | 16 | static int meth_isset(lua_State *L); |
18 | static int local_getfd(lua_State *L); | 17 | static int c_select(lua_State *L); |
19 | static int local_pending(lua_State *L); | 18 | static int global_select(lua_State *L); |
20 | static int local_FD_SET(lua_State *L); | 19 | static void check_obj_tab(lua_State *L, int tabidx); |
21 | static int local_FD_ISSET(lua_State *L); | ||
22 | 20 | ||
23 | static int select_lua_select(lua_State *L); | 21 | /* fd_set object methods */ |
22 | static luaL_reg set[] = { | ||
23 | {"set", meth_set}, | ||
24 | {"isset", meth_isset}, | ||
25 | {NULL, NULL} | ||
26 | }; | ||
24 | 27 | ||
25 | /*-------------------------------------------------------------------------*\ | 28 | /* functions in library namespace */ |
26 | * Marks type as selectable | 29 | static luaL_reg func[] = { |
27 | * Input | 30 | {"select", global_select}, |
28 | * name: type name | 31 | {NULL, NULL} |
29 | \*-------------------------------------------------------------------------*/ | 32 | }; |
30 | void select_addclass(lua_State *L, cchar *lsclass) | ||
31 | { | ||
32 | lua_pushstring(L, "luasocket(select)"); | ||
33 | lua_gettable(L, LUA_REGISTRYINDEX); | ||
34 | lua_pushstring(L, lsclass); | ||
35 | lua_pushnumber(L, 1); | ||
36 | lua_settable(L, -3); | ||
37 | lua_pop(L, 1); | ||
38 | } | ||
39 | 33 | ||
40 | void select_open(lua_State *L) | 34 | void select_open(lua_State *L) |
41 | { | 35 | { |
42 | /* push select auxiliar lua function and register | 36 | /* get select auxiliar lua function from lua code and register |
43 | * select_lua_select with it as an upvalue */ | 37 | * pass it as an upvalue to global_select */ |
44 | #ifdef LUASOCKET_DOFILE | 38 | #ifdef LUASOCKET_COMPILED |
45 | lua_dofile(L, "lsselect.lua"); | 39 | #include "select.lch" |
46 | #else | 40 | #else |
47 | #include "lsselect.loh" | 41 | lua_dofile(L, "select.lua"); |
48 | #endif | 42 | #endif |
49 | lua_getglobal(L, LUASOCKET_LIBNAME); | 43 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 1); |
50 | lua_pushstring(L, "_select"); | ||
51 | lua_gettable(L, -2); | ||
52 | lua_pushcclosure(L, select_lua_select, 1); | ||
53 | priv_newglobal(L, "select"); | ||
54 | lua_pop(L, 1); | 44 | lua_pop(L, 1); |
55 | /* create luasocket(select) table */ | 45 | aux_newclass(L, "select{fd_set}", set); |
56 | lua_pushstring(L, "luasocket(select)"); | ||
57 | lua_newtable(L); | ||
58 | lua_settable(L, LUA_REGISTRYINDEX); | ||
59 | } | 46 | } |
60 | 47 | ||
61 | /*-------------------------------------------------------------------------*\ | 48 | /*-------------------------------------------------------------------------*\ |
62 | * Waits for a set of sockets until a condition is met or timeout. | 49 | * Waits for a set of sockets until a condition is met or timeout. |
63 | * Lua Input: {input}, {output} [, timeout] | ||
64 | * {input}: table of sockets to be tested for input | ||
65 | * {output}: table of sockets to be tested for output | ||
66 | * timeout: maximum amount of time to wait for condition, in seconds | ||
67 | * Lua Returns: {input}, {output}, err | ||
68 | * {input}: table with sockets ready for input | ||
69 | * {output}: table with sockets ready for output | ||
70 | * err: "timeout" or nil | ||
71 | \*-------------------------------------------------------------------------*/ | 50 | \*-------------------------------------------------------------------------*/ |
72 | static int select_lua_select(lua_State *L) | 51 | static int global_select(lua_State *L) |
73 | { | 52 | { |
74 | fd_set read, write; | 53 | fd_set *read_fd_set, *write_fd_set; |
75 | FD_ZERO(&read); | ||
76 | FD_ZERO(&write); | ||
77 | /* push select lua auxiliar function */ | ||
78 | lua_pushvalue(L, lua_upvalueindex(1)); lua_insert(L, 1); | ||
79 | /* make sure we have enough arguments (nil is the default) */ | 54 | /* make sure we have enough arguments (nil is the default) */ |
80 | lua_settop(L, 4); | 55 | lua_settop(L, 3); |
81 | /* pass FD_SET and manipulation functions */ | 56 | /* check object tables */ |
82 | lua_boxpointer(L, &read); | 57 | check_obj_tab(L, 1); |
83 | lua_boxpointer(L, &write); | 58 | check_obj_tab(L, 2); |
84 | lua_pushcfunction(L, local_FD_SET); | 59 | /* check timeout */ |
85 | lua_pushcfunction(L, local_FD_ISSET); | 60 | if (!lua_isnil(L, 3) && !lua_isnumber(L, 3)) |
86 | /* pass getfd function with selectable table as upvalue */ | 61 | luaL_argerror(L, 3, "number or nil expected"); |
87 | lua_pushstring(L, "luasocket(select)"); lua_gettable(L, LUA_REGISTRYINDEX); | 62 | /* select auxiliar lua function to be called comes first */ |
88 | lua_pushcclosure(L, local_getfd, 1); | 63 | lua_pushvalue(L, lua_upvalueindex(1)); |
89 | /* pass pending function */ | 64 | lua_insert(L, 1); |
90 | lua_pushstring(L, "luasocket(select)"); lua_gettable(L, LUA_REGISTRYINDEX); | 65 | /* pass fd_set objects */ |
91 | lua_pushcclosure(L, local_pending, 1); | 66 | read_fd_set = lua_newuserdata(L, sizeof(fd_set)); |
67 | FD_ZERO(read_fd_set); | ||
68 | aux_setclass(L, "select{fd_set}", -1); | ||
69 | write_fd_set = lua_newuserdata(L, sizeof(fd_set)); | ||
70 | FD_ZERO(write_fd_set); | ||
71 | aux_setclass(L, "select{fd_set}", -1); | ||
92 | /* pass select auxiliar C function */ | 72 | /* pass select auxiliar C function */ |
93 | lua_pushcfunction(L, local_select); | 73 | lua_pushcfunction(L, c_select); |
94 | /* call select auxiliar lua function */ | 74 | /* call select auxiliar lua function */ |
95 | lua_call(L, 10, 3); | 75 | lua_call(L, 6, 3); |
96 | return 3; | 76 | return 3; |
97 | } | 77 | } |
98 | 78 | ||
99 | static int local_getfd(lua_State *L) | 79 | static int c_select(lua_State *L) |
100 | { | ||
101 | priv_pushclass(L, 1); | ||
102 | lua_gettable(L, lua_upvalueindex(1)); | ||
103 | if (!lua_isnil(L, -1)) { | ||
104 | p_fd sock = (p_fd) lua_touserdata(L, 1); | ||
105 | lua_pushnumber(L, sock->fd); | ||
106 | } | ||
107 | return 1; | ||
108 | } | ||
109 | |||
110 | static int local_pending(lua_State *L) | ||
111 | { | ||
112 | priv_pushclass(L, 1); | ||
113 | lua_gettable(L, lua_upvalueindex(1)); | ||
114 | if (!lua_isnil(L, -1)) { | ||
115 | p_fd sock = (p_fd) lua_touserdata(L, 1); | ||
116 | if (sock->fd_pending(L, sock)) lua_pushnumber(L, 1); | ||
117 | else lua_pushnil(L); | ||
118 | } | ||
119 | return 1; | ||
120 | } | ||
121 | |||
122 | static int local_select(lua_State *L) | ||
123 | { | 80 | { |
124 | int max_fd = (int) lua_tonumber(L, 1); | 81 | int max_fd = (int) lua_tonumber(L, 1); |
125 | fd_set *read_set = (fd_set *) lua_touserdata(L, 2); | 82 | fd_set *read_fd_set = (fd_set *) aux_checkclass(L, "select{fd_set}", 2); |
126 | fd_set *write_set = (fd_set *) lua_touserdata(L, 3); | 83 | fd_set *write_fd_set = (fd_set *) aux_checkclass(L, "select{fd_set}", 3); |
127 | int deadline = lua_isnil(L, 4) ? -1 : (int)(lua_tonumber(L, 4) * 1000); | 84 | int timeout = lua_isnil(L, 4) ? -1 : (int)(lua_tonumber(L, 4) * 1000); |
128 | struct timeval tv; | 85 | struct timeval tv; |
129 | if (deadline >= 0) { | 86 | tv.tv_sec = timeout / 1000; |
130 | tv.tv_sec = deadline / 1000; | 87 | tv.tv_usec = (timeout % 1000) * 1000; |
131 | tv.tv_usec = (deadline % 1000) * 1000; | 88 | lua_pushnumber(L, select(max_fd, read_fd_set, write_fd_set, NULL, |
132 | lua_pushnumber(L, select(max_fd, read_set, write_set, NULL, &tv)); | 89 | timeout < 0 ? NULL : &tv)); |
133 | } else { | ||
134 | lua_pushnumber(L, select(max_fd, read_set, write_set, NULL, NULL)); | ||
135 | } | ||
136 | return 1; | 90 | return 1; |
137 | } | 91 | } |
138 | 92 | ||
139 | static int local_FD_SET(lua_State *L) | 93 | static int meth_set(lua_State *L) |
140 | { | 94 | { |
141 | COMPAT_FD fd = (COMPAT_FD) lua_tonumber(L, 1); | 95 | fd_set *set = (fd_set *) aux_checkclass(L, "select{fd_set}", 1); |
142 | fd_set *set = (fd_set *) lua_topointer(L, 2); | 96 | t_sock fd = (t_sock) lua_tonumber(L, 2); |
143 | if (fd >= 0) FD_SET(fd, set); | 97 | if (fd >= 0) FD_SET(fd, set); |
144 | return 0; | 98 | return 0; |
145 | } | 99 | } |
146 | 100 | ||
147 | static int local_FD_ISSET(lua_State *L) | 101 | static int meth_isset(lua_State *L) |
148 | { | 102 | { |
149 | COMPAT_FD fd = (COMPAT_FD) lua_tonumber(L, 1); | 103 | fd_set *set = (fd_set *) aux_checkclass(L, "select{fd_set}", 1); |
150 | fd_set *set = (fd_set *) lua_topointer(L, 2); | 104 | t_sock fd = (t_sock) lua_tonumber(L, 2); |
151 | if (fd >= 0 && FD_ISSET(fd, set)) lua_pushnumber(L, 1); | 105 | if (fd >= 0 && FD_ISSET(fd, set)) lua_pushnumber(L, 1); |
152 | else lua_pushnil(L); | 106 | else lua_pushnil(L); |
153 | return 1; | 107 | return 1; |
154 | } | 108 | } |
109 | |||
110 | static void check_obj_tab(lua_State *L, int tabidx) | ||
111 | { | ||
112 | if (tabidx < 0) tabidx = lua_gettop(L) + tabidx + 1; | ||
113 | if (lua_istable(L, tabidx)) { | ||
114 | lua_pushnil(L); | ||
115 | while (lua_next(L, tabidx) != 0) { | ||
116 | if (aux_getgroupudata(L, "select{able}", -1) == NULL) { | ||
117 | char msg[45]; | ||
118 | if (lua_isnumber(L, -2)) | ||
119 | sprintf(msg, "table entry #%g is invalid", | ||
120 | lua_tonumber(L, -2)); | ||
121 | else | ||
122 | sprintf(msg, "invalid entry found in table"); | ||
123 | luaL_argerror(L, tabidx, msg); | ||
124 | } | ||
125 | lua_pop(L, 1); | ||
126 | } | ||
127 | } else if (!lua_isnil(L, tabidx)) | ||
128 | luaL_argerror(L, tabidx, "table or nil expected"); | ||
129 | } | ||
diff --git a/src/select.h b/src/select.h index 2b2ed19..9521fae 100644 --- a/src/select.h +++ b/src/select.h | |||
@@ -2,10 +2,9 @@ | |||
2 | * Select implementation | 2 | * Select implementation |
3 | * RCS ID: $Id$ | 3 | * RCS ID: $Id$ |
4 | \*=========================================================================*/ | 4 | \*=========================================================================*/ |
5 | #ifndef SLCT_H_ | 5 | #ifndef SELECT_H |
6 | #define SLCT_H_ | 6 | #define SELECT_H |
7 | 7 | ||
8 | void select_addclass(lua_State *L, cchar *lsclass); | ||
9 | void select_open(lua_State *L); | 8 | void select_open(lua_State *L); |
10 | 9 | ||
11 | #endif | 10 | #endif /* SELECT_H */ |
diff --git a/src/socket.h b/src/socket.h index f8c5d8f..70ebc52 100644 --- a/src/socket.h +++ b/src/socket.h | |||
@@ -6,16 +6,15 @@ | |||
6 | #ifndef SOCK_H | 6 | #ifndef SOCK_H |
7 | #define SOCK_H | 7 | #define SOCK_H |
8 | 8 | ||
9 | #include <lua.h> | 9 | #include "io.h" |
10 | #include "error.h" | ||
11 | 10 | ||
12 | /*=========================================================================*\ | 11 | /*=========================================================================*\ |
13 | * Platform specific compatibilization | 12 | * Platform specific compatibilization |
14 | \*=========================================================================*/ | 13 | \*=========================================================================*/ |
15 | #ifdef WIN32 | 14 | #ifdef WIN32 |
16 | #include "sockwin32.h" | 15 | #include "wsocket.h" |
17 | #else | 16 | #else |
18 | #include "sockunix.h" | 17 | #include "usocket.h" |
19 | #endif | 18 | #endif |
20 | 19 | ||
21 | /* we are lazy... */ | 20 | /* we are lazy... */ |
@@ -25,13 +24,13 @@ typedef struct sockaddr SA; | |||
25 | * Functions bellow implement a comfortable platform independent | 24 | * Functions bellow implement a comfortable platform independent |
26 | * interface to sockets | 25 | * interface to sockets |
27 | \*=========================================================================*/ | 26 | \*=========================================================================*/ |
28 | int sock_open(lua_State *L); | 27 | int sock_open(void); |
29 | |||
30 | const char *sock_create(p_sock ps, int domain, int type, int protocol); | 28 | const char *sock_create(p_sock ps, int domain, int type, int protocol); |
31 | void sock_destroy(p_sock ps); | 29 | void sock_destroy(p_sock ps); |
32 | void sock_accept(p_sock ps, p_sock pa, SA *addr, size_t *addr_len, int timeout); | 30 | int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, |
33 | const char *sock_connect(p_sock ps, SA *addr, size_t addr_len); | 31 | int timeout); |
34 | const char *sock_bind(p_sock ps, SA *addr, size_t addr_len); | 32 | const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len); |
33 | const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len); | ||
35 | void sock_listen(p_sock ps, int backlog); | 34 | void sock_listen(p_sock ps, int backlog); |
36 | 35 | ||
37 | int sock_send(p_sock ps, const char *data, size_t count, | 36 | int sock_send(p_sock ps, const char *data, size_t count, |
@@ -39,9 +38,9 @@ int sock_send(p_sock ps, const char *data, size_t count, | |||
39 | int sock_recv(p_sock ps, char *data, size_t count, | 38 | int sock_recv(p_sock ps, char *data, size_t count, |
40 | size_t *got, int timeout); | 39 | size_t *got, int timeout); |
41 | int sock_sendto(p_sock ps, const char *data, size_t count, | 40 | int sock_sendto(p_sock ps, const char *data, size_t count, |
42 | size_t *sent, SA *addr, size_t addr_len, int timeout); | 41 | size_t *sent, SA *addr, socklen_t addr_len, int timeout); |
43 | int sock_recvfrom(p_sock ps, char *data, size_t count, | 42 | int sock_recvfrom(p_sock ps, char *data, size_t count, |
44 | size_t *got, SA *addr, size_t *addr_len, int timeout); | 43 | size_t *got, SA *addr, socklen_t *addr_len, int timeout); |
45 | 44 | ||
46 | void sock_setnonblocking(p_sock ps); | 45 | void sock_setnonblocking(p_sock ps); |
47 | void sock_setblocking(p_sock ps); | 46 | void sock_setblocking(p_sock ps); |
@@ -52,6 +51,4 @@ const char *sock_createstrerror(void); | |||
52 | const char *sock_bindstrerror(void); | 51 | const char *sock_bindstrerror(void); |
53 | const char *sock_connectstrerror(void); | 52 | const char *sock_connectstrerror(void); |
54 | 53 | ||
55 | const char *sock_trysetoptions(lua_State *L, p_sock ps); | ||
56 | |||
57 | #endif /* SOCK_H */ | 54 | #endif /* SOCK_H */ |
@@ -10,43 +10,49 @@ | |||
10 | 10 | ||
11 | #include "luasocket.h" | 11 | #include "luasocket.h" |
12 | 12 | ||
13 | #include "aux.h" | 13 | #include "auxiliar.h" |
14 | #include "socket.h" | ||
14 | #include "inet.h" | 15 | #include "inet.h" |
16 | #include "error.h" | ||
15 | #include "tcp.h" | 17 | #include "tcp.h" |
16 | 18 | ||
17 | /*=========================================================================*\ | 19 | /*=========================================================================*\ |
18 | * Internal function prototypes | 20 | * Internal function prototypes |
19 | \*=========================================================================*/ | 21 | \*=========================================================================*/ |
20 | static int tcp_global_create(lua_State *L); | 22 | static int global_create(lua_State *L); |
21 | static int tcp_meth_connect(lua_State *L); | 23 | static int meth_connect(lua_State *L); |
22 | static int tcp_meth_bind(lua_State *L); | 24 | static int meth_bind(lua_State *L); |
23 | static int tcp_meth_send(lua_State *L); | 25 | static int meth_send(lua_State *L); |
24 | static int tcp_meth_getsockname(lua_State *L); | 26 | static int meth_getsockname(lua_State *L); |
25 | static int tcp_meth_getpeername(lua_State *L); | 27 | static int meth_getpeername(lua_State *L); |
26 | static int tcp_meth_receive(lua_State *L); | 28 | static int meth_receive(lua_State *L); |
27 | static int tcp_meth_accept(lua_State *L); | 29 | static int meth_accept(lua_State *L); |
28 | static int tcp_meth_close(lua_State *L); | 30 | static int meth_close(lua_State *L); |
29 | static int tcp_meth_timeout(lua_State *L); | 31 | static int meth_timeout(lua_State *L); |
32 | static int meth_fd(lua_State *L); | ||
33 | static int meth_dirty(lua_State *L); | ||
30 | 34 | ||
31 | /* tcp object methods */ | 35 | /* tcp object methods */ |
32 | static luaL_reg tcp[] = { | 36 | static luaL_reg tcp[] = { |
33 | {"connect", tcp_meth_connect}, | 37 | {"connect", meth_connect}, |
34 | {"send", tcp_meth_send}, | 38 | {"send", meth_send}, |
35 | {"receive", tcp_meth_receive}, | 39 | {"receive", meth_receive}, |
36 | {"bind", tcp_meth_bind}, | 40 | {"bind", meth_bind}, |
37 | {"accept", tcp_meth_accept}, | 41 | {"accept", meth_accept}, |
38 | {"setpeername", tcp_meth_connect}, | 42 | {"setpeername", meth_connect}, |
39 | {"setsockname", tcp_meth_bind}, | 43 | {"setsockname", meth_bind}, |
40 | {"getpeername", tcp_meth_getpeername}, | 44 | {"getpeername", meth_getpeername}, |
41 | {"getsockname", tcp_meth_getsockname}, | 45 | {"getsockname", meth_getsockname}, |
42 | {"timeout", tcp_meth_timeout}, | 46 | {"timeout", meth_timeout}, |
43 | {"close", tcp_meth_close}, | 47 | {"close", meth_close}, |
48 | {"fd", meth_fd}, | ||
49 | {"dirty", meth_dirty}, | ||
44 | {NULL, NULL} | 50 | {NULL, NULL} |
45 | }; | 51 | }; |
46 | 52 | ||
47 | /* functions in library namespace */ | 53 | /* functions in library namespace */ |
48 | static luaL_reg func[] = { | 54 | static luaL_reg func[] = { |
49 | {"tcp", tcp_global_create}, | 55 | {"tcp", global_create}, |
50 | {NULL, NULL} | 56 | {NULL, NULL} |
51 | }; | 57 | }; |
52 | 58 | ||
@@ -60,11 +66,13 @@ void tcp_open(lua_State *L) | |||
60 | aux_newclass(L, "tcp{client}", tcp); | 66 | aux_newclass(L, "tcp{client}", tcp); |
61 | aux_newclass(L, "tcp{server}", tcp); | 67 | aux_newclass(L, "tcp{server}", tcp); |
62 | /* create class groups */ | 68 | /* create class groups */ |
63 | aux_add2group(L, "tcp{client}", "tcp{client, server}"); | ||
64 | aux_add2group(L, "tcp{server}", "tcp{client, server}"); | ||
65 | aux_add2group(L, "tcp{master}", "tcp{any}"); | 69 | aux_add2group(L, "tcp{master}", "tcp{any}"); |
66 | aux_add2group(L, "tcp{client}", "tcp{any}"); | 70 | aux_add2group(L, "tcp{client}", "tcp{any}"); |
67 | aux_add2group(L, "tcp{server}", "tcp{any}"); | 71 | aux_add2group(L, "tcp{server}", "tcp{any}"); |
72 | aux_add2group(L, "tcp{client}", "tcp{client, server}"); | ||
73 | aux_add2group(L, "tcp{server}", "tcp{client, server}"); | ||
74 | aux_add2group(L, "tcp{client}", "select{able}"); | ||
75 | aux_add2group(L, "tcp{server}", "select{able}"); | ||
68 | /* define library functions */ | 76 | /* define library functions */ |
69 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); | 77 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); |
70 | lua_pop(L, 1); | 78 | lua_pop(L, 1); |
@@ -76,28 +84,45 @@ void tcp_open(lua_State *L) | |||
76 | /*-------------------------------------------------------------------------*\ | 84 | /*-------------------------------------------------------------------------*\ |
77 | * Just call buffered IO methods | 85 | * Just call buffered IO methods |
78 | \*-------------------------------------------------------------------------*/ | 86 | \*-------------------------------------------------------------------------*/ |
79 | static int tcp_meth_send(lua_State *L) | 87 | static int meth_send(lua_State *L) |
80 | { | 88 | { |
81 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1); | 89 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1); |
82 | return buf_meth_send(L, &tcp->buf); | 90 | return buf_meth_send(L, &tcp->buf); |
83 | } | 91 | } |
84 | 92 | ||
85 | static int tcp_meth_receive(lua_State *L) | 93 | static int meth_receive(lua_State *L) |
86 | { | 94 | { |
87 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1); | 95 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1); |
88 | return buf_meth_receive(L, &tcp->buf); | 96 | return buf_meth_receive(L, &tcp->buf); |
89 | } | 97 | } |
90 | 98 | ||
91 | /*-------------------------------------------------------------------------*\ | 99 | /*-------------------------------------------------------------------------*\ |
100 | * Select support methods | ||
101 | \*-------------------------------------------------------------------------*/ | ||
102 | static int meth_fd(lua_State *L) | ||
103 | { | ||
104 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client, server}", 1); | ||
105 | lua_pushnumber(L, tcp->sock); | ||
106 | return 1; | ||
107 | } | ||
108 | |||
109 | static int meth_dirty(lua_State *L) | ||
110 | { | ||
111 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client, server}", 1); | ||
112 | lua_pushboolean(L, !buf_isempty(&tcp->buf)); | ||
113 | return 1; | ||
114 | } | ||
115 | |||
116 | /*-------------------------------------------------------------------------*\ | ||
92 | * Just call inet methods | 117 | * Just call inet methods |
93 | \*-------------------------------------------------------------------------*/ | 118 | \*-------------------------------------------------------------------------*/ |
94 | static int tcp_meth_getpeername(lua_State *L) | 119 | static int meth_getpeername(lua_State *L) |
95 | { | 120 | { |
96 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1); | 121 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1); |
97 | return inet_meth_getpeername(L, &tcp->sock); | 122 | return inet_meth_getpeername(L, &tcp->sock); |
98 | } | 123 | } |
99 | 124 | ||
100 | static int tcp_meth_getsockname(lua_State *L) | 125 | static int meth_getsockname(lua_State *L) |
101 | { | 126 | { |
102 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client, server}", 1); | 127 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client, server}", 1); |
103 | return inet_meth_getsockname(L, &tcp->sock); | 128 | return inet_meth_getsockname(L, &tcp->sock); |
@@ -106,7 +131,7 @@ static int tcp_meth_getsockname(lua_State *L) | |||
106 | /*-------------------------------------------------------------------------*\ | 131 | /*-------------------------------------------------------------------------*\ |
107 | * Just call tm methods | 132 | * Just call tm methods |
108 | \*-------------------------------------------------------------------------*/ | 133 | \*-------------------------------------------------------------------------*/ |
109 | static int tcp_meth_timeout(lua_State *L) | 134 | static int meth_timeout(lua_State *L) |
110 | { | 135 | { |
111 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); | 136 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); |
112 | return tm_meth_timeout(L, &tcp->tm); | 137 | return tm_meth_timeout(L, &tcp->tm); |
@@ -115,7 +140,7 @@ static int tcp_meth_timeout(lua_State *L) | |||
115 | /*-------------------------------------------------------------------------*\ | 140 | /*-------------------------------------------------------------------------*\ |
116 | * Closes socket used by object | 141 | * Closes socket used by object |
117 | \*-------------------------------------------------------------------------*/ | 142 | \*-------------------------------------------------------------------------*/ |
118 | static int tcp_meth_close(lua_State *L) | 143 | static int meth_close(lua_State *L) |
119 | { | 144 | { |
120 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); | 145 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); |
121 | sock_destroy(&tcp->sock); | 146 | sock_destroy(&tcp->sock); |
@@ -125,7 +150,7 @@ static int tcp_meth_close(lua_State *L) | |||
125 | /*-------------------------------------------------------------------------*\ | 150 | /*-------------------------------------------------------------------------*\ |
126 | * Turns a master tcp object into a client object. | 151 | * Turns a master tcp object into a client object. |
127 | \*-------------------------------------------------------------------------*/ | 152 | \*-------------------------------------------------------------------------*/ |
128 | static int tcp_meth_connect(lua_State *L) | 153 | static int meth_connect(lua_State *L) |
129 | { | 154 | { |
130 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); | 155 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); |
131 | const char *address = luaL_checkstring(L, 2); | 156 | const char *address = luaL_checkstring(L, 2); |
@@ -145,7 +170,7 @@ static int tcp_meth_connect(lua_State *L) | |||
145 | /*-------------------------------------------------------------------------*\ | 170 | /*-------------------------------------------------------------------------*\ |
146 | * Turns a master object into a server object | 171 | * Turns a master object into a server object |
147 | \*-------------------------------------------------------------------------*/ | 172 | \*-------------------------------------------------------------------------*/ |
148 | static int tcp_meth_bind(lua_State *L) | 173 | static int meth_bind(lua_State *L) |
149 | { | 174 | { |
150 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); | 175 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); |
151 | const char *address = luaL_checkstring(L, 2); | 176 | const char *address = luaL_checkstring(L, 2); |
@@ -167,10 +192,10 @@ static int tcp_meth_bind(lua_State *L) | |||
167 | * Waits for and returns a client object attempting connection to the | 192 | * Waits for and returns a client object attempting connection to the |
168 | * server object | 193 | * server object |
169 | \*-------------------------------------------------------------------------*/ | 194 | \*-------------------------------------------------------------------------*/ |
170 | static int tcp_meth_accept(lua_State *L) | 195 | static int meth_accept(lua_State *L) |
171 | { | 196 | { |
172 | struct sockaddr_in addr; | 197 | struct sockaddr_in addr; |
173 | size_t addr_len = sizeof(addr); | 198 | socklen_t addr_len = sizeof(addr); |
174 | p_tcp server = (p_tcp) aux_checkclass(L, "tcp{server}", 1); | 199 | p_tcp server = (p_tcp) aux_checkclass(L, "tcp{server}", 1); |
175 | p_tm tm = &server->tm; | 200 | p_tm tm = &server->tm; |
176 | p_tcp client = lua_newuserdata(L, sizeof(t_tcp)); | 201 | p_tcp client = lua_newuserdata(L, sizeof(t_tcp)); |
@@ -200,7 +225,7 @@ static int tcp_meth_accept(lua_State *L) | |||
200 | /*-------------------------------------------------------------------------*\ | 225 | /*-------------------------------------------------------------------------*\ |
201 | * Creates a master tcp object | 226 | * Creates a master tcp object |
202 | \*-------------------------------------------------------------------------*/ | 227 | \*-------------------------------------------------------------------------*/ |
203 | int tcp_global_create(lua_State *L) | 228 | int global_create(lua_State *L) |
204 | { | 229 | { |
205 | /* allocate tcp object */ | 230 | /* allocate tcp object */ |
206 | p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); | 231 | p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); |
@@ -3,9 +3,9 @@ | |||
3 | 3 | ||
4 | #include <lua.h> | 4 | #include <lua.h> |
5 | 5 | ||
6 | #include "buf.h" | 6 | #include "buffer.h" |
7 | #include "tm.h" | 7 | #include "timeout.h" |
8 | #include "sock.h" | 8 | #include "socket.h" |
9 | 9 | ||
10 | typedef struct t_tcp_ { | 10 | typedef struct t_tcp_ { |
11 | t_sock sock; | 11 | t_sock sock; |
diff --git a/src/timeout.c b/src/timeout.c index 17878aa..1553069 100644 --- a/src/timeout.c +++ b/src/timeout.c | |||
@@ -12,8 +12,8 @@ | |||
12 | #include <lauxlib.h> | 12 | #include <lauxlib.h> |
13 | 13 | ||
14 | #include "luasocket.h" | 14 | #include "luasocket.h" |
15 | #include "aux.h" | 15 | #include "auxiliar.h" |
16 | #include "tm.h" | 16 | #include "timeout.h" |
17 | 17 | ||
18 | #ifdef WIN32 | 18 | #ifdef WIN32 |
19 | #include <windows.h> | 19 | #include <windows.h> |
@@ -118,6 +118,7 @@ int tm_gettime(void) | |||
118 | void tm_open(lua_State *L) | 118 | void tm_open(lua_State *L) |
119 | { | 119 | { |
120 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); | 120 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); |
121 | lua_pop(L, 1); | ||
121 | } | 122 | } |
122 | 123 | ||
123 | /*-------------------------------------------------------------------------*\ | 124 | /*-------------------------------------------------------------------------*\ |
@@ -10,43 +10,49 @@ | |||
10 | 10 | ||
11 | #include "luasocket.h" | 11 | #include "luasocket.h" |
12 | 12 | ||
13 | #include "aux.h" | 13 | #include "auxiliar.h" |
14 | #include "socket.h" | ||
14 | #include "inet.h" | 15 | #include "inet.h" |
16 | #include "error.h" | ||
15 | #include "udp.h" | 17 | #include "udp.h" |
16 | 18 | ||
17 | /*=========================================================================*\ | 19 | /*=========================================================================*\ |
18 | * Internal function prototypes | 20 | * Internal function prototypes |
19 | \*=========================================================================*/ | 21 | \*=========================================================================*/ |
20 | static int udp_global_create(lua_State *L); | 22 | static int global_create(lua_State *L); |
21 | static int udp_meth_send(lua_State *L); | 23 | static int meth_send(lua_State *L); |
22 | static int udp_meth_sendto(lua_State *L); | 24 | static int meth_sendto(lua_State *L); |
23 | static int udp_meth_receive(lua_State *L); | 25 | static int meth_receive(lua_State *L); |
24 | static int udp_meth_receivefrom(lua_State *L); | 26 | static int meth_receivefrom(lua_State *L); |
25 | static int udp_meth_getsockname(lua_State *L); | 27 | static int meth_getsockname(lua_State *L); |
26 | static int udp_meth_getpeername(lua_State *L); | 28 | static int meth_getpeername(lua_State *L); |
27 | static int udp_meth_setsockname(lua_State *L); | 29 | static int meth_setsockname(lua_State *L); |
28 | static int udp_meth_setpeername(lua_State *L); | 30 | static int meth_setpeername(lua_State *L); |
29 | static int udp_meth_close(lua_State *L); | 31 | static int meth_close(lua_State *L); |
30 | static int udp_meth_timeout(lua_State *L); | 32 | static int meth_timeout(lua_State *L); |
33 | static int meth_fd(lua_State *L); | ||
34 | static int meth_dirty(lua_State *L); | ||
31 | 35 | ||
32 | /* udp object methods */ | 36 | /* udp object methods */ |
33 | static luaL_reg udp[] = { | 37 | static luaL_reg udp[] = { |
34 | {"setpeername", udp_meth_setpeername}, | 38 | {"setpeername", meth_setpeername}, |
35 | {"setsockname", udp_meth_setsockname}, | 39 | {"setsockname", meth_setsockname}, |
36 | {"getsockname", udp_meth_getsockname}, | 40 | {"getsockname", meth_getsockname}, |
37 | {"getpeername", udp_meth_getpeername}, | 41 | {"getpeername", meth_getpeername}, |
38 | {"send", udp_meth_send}, | 42 | {"send", meth_send}, |
39 | {"sendto", udp_meth_sendto}, | 43 | {"sendto", meth_sendto}, |
40 | {"receive", udp_meth_receive}, | 44 | {"receive", meth_receive}, |
41 | {"receivefrom", udp_meth_receivefrom}, | 45 | {"receivefrom", meth_receivefrom}, |
42 | {"timeout", udp_meth_timeout}, | 46 | {"timeout", meth_timeout}, |
43 | {"close", udp_meth_close}, | 47 | {"close", meth_close}, |
48 | {"fd", meth_fd}, | ||
49 | {"dirty", meth_dirty}, | ||
44 | {NULL, NULL} | 50 | {NULL, NULL} |
45 | }; | 51 | }; |
46 | 52 | ||
47 | /* functions in library namespace */ | 53 | /* functions in library namespace */ |
48 | static luaL_reg func[] = { | 54 | static luaL_reg func[] = { |
49 | {"udp", udp_global_create}, | 55 | {"udp", global_create}, |
50 | {NULL, NULL} | 56 | {NULL, NULL} |
51 | }; | 57 | }; |
52 | 58 | ||
@@ -59,8 +65,10 @@ void udp_open(lua_State *L) | |||
59 | aux_newclass(L, "udp{connected}", udp); | 65 | aux_newclass(L, "udp{connected}", udp); |
60 | aux_newclass(L, "udp{unconnected}", udp); | 66 | aux_newclass(L, "udp{unconnected}", udp); |
61 | /* create class groups */ | 67 | /* create class groups */ |
62 | aux_add2group(L, "udp{connected}", "udp{any}"); | 68 | aux_add2group(L, "udp{connected}", "udp{any}"); |
63 | aux_add2group(L, "udp{unconnected}", "udp{any}"); | 69 | aux_add2group(L, "udp{unconnected}", "udp{any}"); |
70 | aux_add2group(L, "udp{connected}", "select{able}"); | ||
71 | aux_add2group(L, "udp{unconnected}", "select{able}"); | ||
64 | /* define library functions */ | 72 | /* define library functions */ |
65 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); | 73 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); |
66 | lua_pop(L, 1); | 74 | lua_pop(L, 1); |
@@ -72,7 +80,7 @@ void udp_open(lua_State *L) | |||
72 | /*-------------------------------------------------------------------------*\ | 80 | /*-------------------------------------------------------------------------*\ |
73 | * Send data through connected udp socket | 81 | * Send data through connected udp socket |
74 | \*-------------------------------------------------------------------------*/ | 82 | \*-------------------------------------------------------------------------*/ |
75 | static int udp_meth_send(lua_State *L) | 83 | static int meth_send(lua_State *L) |
76 | { | 84 | { |
77 | p_udp udp = (p_udp) aux_checkclass(L, "udp{connected}", 1); | 85 | p_udp udp = (p_udp) aux_checkclass(L, "udp{connected}", 1); |
78 | p_tm tm = &udp->tm; | 86 | p_tm tm = &udp->tm; |
@@ -90,7 +98,7 @@ static int udp_meth_send(lua_State *L) | |||
90 | /*-------------------------------------------------------------------------*\ | 98 | /*-------------------------------------------------------------------------*\ |
91 | * Send data through unconnected udp socket | 99 | * Send data through unconnected udp socket |
92 | \*-------------------------------------------------------------------------*/ | 100 | \*-------------------------------------------------------------------------*/ |
93 | static int udp_meth_sendto(lua_State *L) | 101 | static int meth_sendto(lua_State *L) |
94 | { | 102 | { |
95 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); | 103 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); |
96 | size_t count, sent = 0; | 104 | size_t count, sent = 0; |
@@ -117,7 +125,7 @@ static int udp_meth_sendto(lua_State *L) | |||
117 | /*-------------------------------------------------------------------------*\ | 125 | /*-------------------------------------------------------------------------*\ |
118 | * Receives data from a UDP socket | 126 | * Receives data from a UDP socket |
119 | \*-------------------------------------------------------------------------*/ | 127 | \*-------------------------------------------------------------------------*/ |
120 | static int udp_meth_receive(lua_State *L) | 128 | static int meth_receive(lua_State *L) |
121 | { | 129 | { |
122 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | 130 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
123 | char buffer[UDP_DATAGRAMSIZE]; | 131 | char buffer[UDP_DATAGRAMSIZE]; |
@@ -136,11 +144,11 @@ static int udp_meth_receive(lua_State *L) | |||
136 | /*-------------------------------------------------------------------------*\ | 144 | /*-------------------------------------------------------------------------*\ |
137 | * Receives data and sender from a UDP socket | 145 | * Receives data and sender from a UDP socket |
138 | \*-------------------------------------------------------------------------*/ | 146 | \*-------------------------------------------------------------------------*/ |
139 | static int udp_meth_receivefrom(lua_State *L) | 147 | static int meth_receivefrom(lua_State *L) |
140 | { | 148 | { |
141 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); | 149 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); |
142 | struct sockaddr_in addr; | 150 | struct sockaddr_in addr; |
143 | size_t addr_len = sizeof(addr); | 151 | socklen_t addr_len = sizeof(addr); |
144 | char buffer[UDP_DATAGRAMSIZE]; | 152 | char buffer[UDP_DATAGRAMSIZE]; |
145 | size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); | 153 | size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); |
146 | int err; | 154 | int err; |
@@ -162,15 +170,33 @@ static int udp_meth_receivefrom(lua_State *L) | |||
162 | } | 170 | } |
163 | 171 | ||
164 | /*-------------------------------------------------------------------------*\ | 172 | /*-------------------------------------------------------------------------*\ |
173 | * Select support methods | ||
174 | \*-------------------------------------------------------------------------*/ | ||
175 | static int meth_fd(lua_State *L) | ||
176 | { | ||
177 | p_udp udp = (p_udp) aux_checkclass(L, "udp{any}", 1); | ||
178 | lua_pushnumber(L, udp->sock); | ||
179 | return 1; | ||
180 | } | ||
181 | |||
182 | static int meth_dirty(lua_State *L) | ||
183 | { | ||
184 | p_udp udp = (p_udp) aux_checkclass(L, "udp{any}", 1); | ||
185 | (void) udp; | ||
186 | lua_pushboolean(L, 0); | ||
187 | return 1; | ||
188 | } | ||
189 | |||
190 | /*-------------------------------------------------------------------------*\ | ||
165 | * Just call inet methods | 191 | * Just call inet methods |
166 | \*-------------------------------------------------------------------------*/ | 192 | \*-------------------------------------------------------------------------*/ |
167 | static int udp_meth_getpeername(lua_State *L) | 193 | static int meth_getpeername(lua_State *L) |
168 | { | 194 | { |
169 | p_udp udp = (p_udp) aux_checkclass(L, "udp{connected}", 1); | 195 | p_udp udp = (p_udp) aux_checkclass(L, "udp{connected}", 1); |
170 | return inet_meth_getpeername(L, &udp->sock); | 196 | return inet_meth_getpeername(L, &udp->sock); |
171 | } | 197 | } |
172 | 198 | ||
173 | static int udp_meth_getsockname(lua_State *L) | 199 | static int meth_getsockname(lua_State *L) |
174 | { | 200 | { |
175 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | 201 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
176 | return inet_meth_getsockname(L, &udp->sock); | 202 | return inet_meth_getsockname(L, &udp->sock); |
@@ -179,7 +205,7 @@ static int udp_meth_getsockname(lua_State *L) | |||
179 | /*-------------------------------------------------------------------------*\ | 205 | /*-------------------------------------------------------------------------*\ |
180 | * Just call tm methods | 206 | * Just call tm methods |
181 | \*-------------------------------------------------------------------------*/ | 207 | \*-------------------------------------------------------------------------*/ |
182 | static int udp_meth_timeout(lua_State *L) | 208 | static int meth_timeout(lua_State *L) |
183 | { | 209 | { |
184 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | 210 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
185 | return tm_meth_timeout(L, &udp->tm); | 211 | return tm_meth_timeout(L, &udp->tm); |
@@ -188,7 +214,7 @@ static int udp_meth_timeout(lua_State *L) | |||
188 | /*-------------------------------------------------------------------------*\ | 214 | /*-------------------------------------------------------------------------*\ |
189 | * Turns a master udp object into a client object. | 215 | * Turns a master udp object into a client object. |
190 | \*-------------------------------------------------------------------------*/ | 216 | \*-------------------------------------------------------------------------*/ |
191 | static int udp_meth_setpeername(lua_State *L) | 217 | static int meth_setpeername(lua_State *L) |
192 | { | 218 | { |
193 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); | 219 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); |
194 | const char *address = luaL_checkstring(L, 2); | 220 | const char *address = luaL_checkstring(L, 2); |
@@ -211,7 +237,7 @@ static int udp_meth_setpeername(lua_State *L) | |||
211 | /*-------------------------------------------------------------------------*\ | 237 | /*-------------------------------------------------------------------------*\ |
212 | * Closes socket used by object | 238 | * Closes socket used by object |
213 | \*-------------------------------------------------------------------------*/ | 239 | \*-------------------------------------------------------------------------*/ |
214 | static int udp_meth_close(lua_State *L) | 240 | static int meth_close(lua_State *L) |
215 | { | 241 | { |
216 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | 242 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
217 | sock_destroy(&udp->sock); | 243 | sock_destroy(&udp->sock); |
@@ -221,7 +247,7 @@ static int udp_meth_close(lua_State *L) | |||
221 | /*-------------------------------------------------------------------------*\ | 247 | /*-------------------------------------------------------------------------*\ |
222 | * Turns a master object into a server object | 248 | * Turns a master object into a server object |
223 | \*-------------------------------------------------------------------------*/ | 249 | \*-------------------------------------------------------------------------*/ |
224 | static int udp_meth_setsockname(lua_State *L) | 250 | static int meth_setsockname(lua_State *L) |
225 | { | 251 | { |
226 | p_udp udp = (p_udp) aux_checkclass(L, "udp{master}", 1); | 252 | p_udp udp = (p_udp) aux_checkclass(L, "udp{master}", 1); |
227 | const char *address = luaL_checkstring(L, 2); | 253 | const char *address = luaL_checkstring(L, 2); |
@@ -242,7 +268,7 @@ static int udp_meth_setsockname(lua_State *L) | |||
242 | /*-------------------------------------------------------------------------*\ | 268 | /*-------------------------------------------------------------------------*\ |
243 | * Creates a master udp object | 269 | * Creates a master udp object |
244 | \*-------------------------------------------------------------------------*/ | 270 | \*-------------------------------------------------------------------------*/ |
245 | int udp_global_create(lua_State *L) | 271 | int global_create(lua_State *L) |
246 | { | 272 | { |
247 | /* allocate udp object */ | 273 | /* allocate udp object */ |
248 | p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); | 274 | p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); |
@@ -3,8 +3,8 @@ | |||
3 | 3 | ||
4 | #include <lua.h> | 4 | #include <lua.h> |
5 | 5 | ||
6 | #include "tm.h" | 6 | #include "timeout.h" |
7 | #include "sock.h" | 7 | #include "socket.h" |
8 | 8 | ||
9 | #define UDP_DATAGRAMSIZE 576 | 9 | #define UDP_DATAGRAMSIZE 576 |
10 | 10 | ||
diff --git a/src/usocket.c b/src/usocket.c index b4b8d5a..062a0ff 100644 --- a/src/usocket.c +++ b/src/usocket.c | |||
@@ -1,24 +1,8 @@ | |||
1 | /*=========================================================================*\ | ||
2 | * Socket compatibilization module for Unix | ||
3 | * | ||
4 | * RCS ID: $Id$ | ||
5 | \*=========================================================================*/ | ||
6 | #include <lua.h> | ||
7 | #include <lauxlib.h> | ||
8 | #include <string.h> | 1 | #include <string.h> |
9 | 2 | ||
10 | #include "sock.h" | 3 | #include "socket.h" |
11 | 4 | ||
12 | /*=========================================================================*\ | 5 | int sock_open(void) |
13 | * Internal function prototypes | ||
14 | \*=========================================================================*/ | ||
15 | static const char *try_setoption(lua_State *L, p_sock ps); | ||
16 | static const char *try_setbooloption(lua_State *L, p_sock ps, int name); | ||
17 | |||
18 | /*=========================================================================*\ | ||
19 | * Exported functions. | ||
20 | \*=========================================================================*/ | ||
21 | int sock_open(lua_State *L) | ||
22 | { | 6 | { |
23 | /* instals a handler to ignore sigpipe. */ | 7 | /* instals a handler to ignore sigpipe. */ |
24 | struct sigaction new; | 8 | struct sigaction new; |
@@ -43,13 +27,13 @@ const char *sock_create(p_sock ps, int domain, int type, int protocol) | |||
43 | return NULL; | 27 | return NULL; |
44 | } | 28 | } |
45 | 29 | ||
46 | const char *sock_connect(p_sock ps, SA *addr, size_t addr_len) | 30 | const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len) |
47 | { | 31 | { |
48 | if (connect(*ps, addr, addr_len) < 0) return sock_connectstrerror(); | 32 | if (connect(*ps, addr, addr_len) < 0) return sock_connectstrerror(); |
49 | else return NULL; | 33 | else return NULL; |
50 | } | 34 | } |
51 | 35 | ||
52 | const char *sock_bind(p_sock ps, SA *addr, size_t addr_len) | 36 | const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len) |
53 | { | 37 | { |
54 | if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror(); | 38 | if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror(); |
55 | else return NULL; | 39 | else return NULL; |
@@ -60,17 +44,25 @@ void sock_listen(p_sock ps, int backlog) | |||
60 | listen(*ps, backlog); | 44 | listen(*ps, backlog); |
61 | } | 45 | } |
62 | 46 | ||
63 | void sock_accept(p_sock ps, p_sock pa, SA *addr, size_t *addr_len, int timeout) | 47 | int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, |
48 | int timeout) | ||
64 | { | 49 | { |
65 | t_sock sock = *ps; | 50 | t_sock sock = *ps; |
66 | struct timeval tv; | 51 | struct timeval tv; |
52 | SA dummy_addr; | ||
53 | socklen_t dummy_len; | ||
67 | fd_set fds; | 54 | fd_set fds; |
68 | tv.tv_sec = timeout / 1000; | 55 | tv.tv_sec = timeout / 1000; |
69 | tv.tv_usec = (timeout % 1000) * 1000; | 56 | tv.tv_usec = (timeout % 1000) * 1000; |
70 | FD_ZERO(&fds); | 57 | FD_ZERO(&fds); |
71 | FD_SET(sock, &fds); | 58 | FD_SET(sock, &fds); |
72 | select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL); | 59 | if (select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL) <= 0) |
60 | return IO_TIMEOUT; | ||
61 | if (!addr) addr = &dummy_addr; | ||
62 | if (!addr_len) addr_len = &dummy_len; | ||
73 | *pa = accept(sock, addr, addr_len); | 63 | *pa = accept(sock, addr, addr_len); |
64 | if (*pa == SOCK_INVALID) return IO_ERROR; | ||
65 | else return IO_DONE; | ||
74 | } | 66 | } |
75 | 67 | ||
76 | int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, | 68 | int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, |
@@ -108,7 +100,7 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, | |||
108 | } | 100 | } |
109 | 101 | ||
110 | int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, | 102 | int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, |
111 | SA *addr, size_t addr_len, int timeout) | 103 | SA *addr, socklen_t addr_len, int timeout) |
112 | { | 104 | { |
113 | t_sock sock = *ps; | 105 | t_sock sock = *ps; |
114 | struct timeval tv; | 106 | struct timeval tv; |
@@ -169,7 +161,7 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) | |||
169 | } | 161 | } |
170 | 162 | ||
171 | int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, | 163 | int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, |
172 | SA *addr, size_t *addr_len, int timeout) | 164 | SA *addr, socklen_t *addr_len, int timeout) |
173 | { | 165 | { |
174 | t_sock sock = *ps; | 166 | t_sock sock = *ps; |
175 | struct timeval tv; | 167 | struct timeval tv; |
@@ -196,9 +188,6 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, | |||
196 | } | 188 | } |
197 | } | 189 | } |
198 | 190 | ||
199 | /*-------------------------------------------------------------------------*\ | ||
200 | * Returns a string describing the last host manipulation error. | ||
201 | \*-------------------------------------------------------------------------*/ | ||
202 | const char *sock_hoststrerror(void) | 191 | const char *sock_hoststrerror(void) |
203 | { | 192 | { |
204 | switch (h_errno) { | 193 | switch (h_errno) { |
@@ -210,9 +199,6 @@ const char *sock_hoststrerror(void) | |||
210 | } | 199 | } |
211 | } | 200 | } |
212 | 201 | ||
213 | /*-------------------------------------------------------------------------*\ | ||
214 | * Returns a string describing the last socket manipulation error. | ||
215 | \*-------------------------------------------------------------------------*/ | ||
216 | const char *sock_createstrerror(void) | 202 | const char *sock_createstrerror(void) |
217 | { | 203 | { |
218 | switch (errno) { | 204 | switch (errno) { |
@@ -224,9 +210,6 @@ const char *sock_createstrerror(void) | |||
224 | } | 210 | } |
225 | } | 211 | } |
226 | 212 | ||
227 | /*-------------------------------------------------------------------------*\ | ||
228 | * Returns a string describing the last bind command error. | ||
229 | \*-------------------------------------------------------------------------*/ | ||
230 | const char *sock_bindstrerror(void) | 213 | const char *sock_bindstrerror(void) |
231 | { | 214 | { |
232 | switch (errno) { | 215 | switch (errno) { |
@@ -241,9 +224,6 @@ const char *sock_bindstrerror(void) | |||
241 | } | 224 | } |
242 | } | 225 | } |
243 | 226 | ||
244 | /*-------------------------------------------------------------------------*\ | ||
245 | * Returns a string describing the last connect error. | ||
246 | \*-------------------------------------------------------------------------*/ | ||
247 | const char *sock_connectstrerror(void) | 227 | const char *sock_connectstrerror(void) |
248 | { | 228 | { |
249 | switch (errno) { | 229 | switch (errno) { |
@@ -259,20 +239,12 @@ const char *sock_connectstrerror(void) | |||
259 | } | 239 | } |
260 | } | 240 | } |
261 | 241 | ||
262 | /*-------------------------------------------------------------------------*\ | ||
263 | * Sets the SO_REUSEADDR socket option | ||
264 | * Input | ||
265 | * sock: socket descriptor | ||
266 | \*-------------------------------------------------------------------------*/ | ||
267 | void sock_setreuseaddr(p_sock ps) | 242 | void sock_setreuseaddr(p_sock ps) |
268 | { | 243 | { |
269 | int val = 1; | 244 | int val = 1; |
270 | setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); | 245 | setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); |
271 | } | 246 | } |
272 | 247 | ||
273 | /*-------------------------------------------------------------------------*\ | ||
274 | * Put socket into blocking mode. | ||
275 | \*-------------------------------------------------------------------------*/ | ||
276 | void sock_setblocking(p_sock ps) | 248 | void sock_setblocking(p_sock ps) |
277 | { | 249 | { |
278 | int flags = fcntl(*ps, F_GETFL, 0); | 250 | int flags = fcntl(*ps, F_GETFL, 0); |
@@ -280,68 +252,9 @@ void sock_setblocking(p_sock ps) | |||
280 | fcntl(*ps, F_SETFL, flags); | 252 | fcntl(*ps, F_SETFL, flags); |
281 | } | 253 | } |
282 | 254 | ||
283 | /*-------------------------------------------------------------------------*\ | ||
284 | * Put socket into non-blocking mode. | ||
285 | \*-------------------------------------------------------------------------*/ | ||
286 | void sock_setnonblocking(p_sock ps) | 255 | void sock_setnonblocking(p_sock ps) |
287 | { | 256 | { |
288 | int flags = fcntl(*ps, F_GETFL, 0); | 257 | int flags = fcntl(*ps, F_GETFL, 0); |
289 | flags |= O_NONBLOCK; | 258 | flags |= O_NONBLOCK; |
290 | fcntl(*ps, F_SETFL, flags); | 259 | fcntl(*ps, F_SETFL, flags); |
291 | } | 260 | } |
292 | |||
293 | /*-------------------------------------------------------------------------*\ | ||
294 | * Tries to set extended udp socket options | ||
295 | * Input | ||
296 | * udp: udp structure | ||
297 | * oldtop: top of stack | ||
298 | * Returns | ||
299 | * NULL if successfull, error message on error | ||
300 | \*-------------------------------------------------------------------------*/ | ||
301 | const char *sock_trysetoptions(lua_State *L, p_sock ps) | ||
302 | { | ||
303 | if (!lua_istable(L, 1)) luaL_argerror(L, 1, "invalid options table"); | ||
304 | lua_pushnil(L); | ||
305 | while (lua_next(L, 1)) { | ||
306 | const char *err = try_setoption(L, ps); | ||
307 | lua_pop(L, 1); | ||
308 | if (err) return err; | ||
309 | } | ||
310 | return NULL; | ||
311 | } | ||
312 | |||
313 | /*-------------------------------------------------------------------------*\ | ||
314 | * Set socket options from a table on top of Lua stack. | ||
315 | * Supports SO_KEEPALIVE, SO_DONTROUTE, and SO_BROADCAST options. | ||
316 | * Input | ||
317 | * sock: socket | ||
318 | * Returns | ||
319 | * 1 if successful, 0 otherwise | ||
320 | \*-------------------------------------------------------------------------*/ | ||
321 | static const char *try_setoption(lua_State *L, p_sock ps) | ||
322 | { | ||
323 | static const char *options[] = { | ||
324 | "SO_KEEPALIVE", "SO_DONTROUTE", "SO_BROADCAST", NULL | ||
325 | }; | ||
326 | const char *option = lua_tostring(L, -2); | ||
327 | if (!lua_isstring(L, -2)) return "invalid option"; | ||
328 | switch (luaL_findstring(option, options)) { | ||
329 | case 0: return try_setbooloption(L, ps, SO_KEEPALIVE); | ||
330 | case 1: return try_setbooloption(L, ps, SO_DONTROUTE); | ||
331 | case 2: return try_setbooloption(L, ps, SO_BROADCAST); | ||
332 | default: return "unsupported option"; | ||
333 | } | ||
334 | } | ||
335 | |||
336 | /*=========================================================================*\ | ||
337 | * Internal functions. | ||
338 | \*=========================================================================*/ | ||
339 | static const char *try_setbooloption(lua_State *L, p_sock ps, int name) | ||
340 | { | ||
341 | int bool, res; | ||
342 | if (!lua_isnumber(L, -1)) luaL_error(L, "invalid option value"); | ||
343 | bool = (int) lua_tonumber(L, -1); | ||
344 | res = setsockopt(*ps, SOL_SOCKET, name, (char *) &bool, sizeof(bool)); | ||
345 | if (res < 0) return "error setting option"; | ||
346 | else return NULL; | ||
347 | } | ||
diff --git a/src/usocket.h b/src/usocket.h index f124bce..9e4b75a 100644 --- a/src/usocket.h +++ b/src/usocket.h | |||
@@ -31,6 +31,11 @@ | |||
31 | #include <netinet/in.h> | 31 | #include <netinet/in.h> |
32 | #include <arpa/inet.h> | 32 | #include <arpa/inet.h> |
33 | 33 | ||
34 | #ifdef __APPLE__ | ||
35 | /* for some reason socklen_t is not defined in mac os x */ | ||
36 | typedef int socklen_t; | ||
37 | #endif | ||
38 | |||
34 | typedef int t_sock; | 39 | typedef int t_sock; |
35 | typedef t_sock *p_sock; | 40 | typedef t_sock *p_sock; |
36 | 41 | ||