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 | |
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.
-rw-r--r-- | etc/check-links.lua | 2 | ||||
-rw-r--r-- | etc/dict.lua | 2 | ||||
-rw-r--r-- | etc/get.lua | 2 | ||||
-rw-r--r-- | makefile.dist | 79 | ||||
-rw-r--r-- | samples/daytimeclnt.lua | 6 | ||||
-rw-r--r-- | samples/echoclnt.lua | 6 | ||||
-rw-r--r-- | samples/echosrvr.lua | 6 | ||||
-rw-r--r-- | samples/listener.lua | 4 | ||||
-rw-r--r-- | samples/talker.lua | 6 | ||||
-rw-r--r-- | samples/tinyirc.lua | 90 | ||||
-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 |
28 files changed, 495 insertions, 396 deletions
diff --git a/etc/check-links.lua b/etc/check-links.lua index 705c0ce..4c96fdc 100644 --- a/etc/check-links.lua +++ b/etc/check-links.lua | |||
@@ -1,6 +1,8 @@ | |||
1 | ----------------------------------------------------------------------------- | 1 | ----------------------------------------------------------------------------- |
2 | -- Little program that checks links in HTML files | 2 | -- Little program that checks links in HTML files |
3 | -- LuaSocket 1.5 sample files. | 3 | -- LuaSocket 1.5 sample files. |
4 | -- Author: Diego Nehab | ||
5 | -- RCS ID: $Id$ | ||
4 | ----------------------------------------------------------------------------- | 6 | ----------------------------------------------------------------------------- |
5 | socket.http.TIMEOUT = 10 | 7 | socket.http.TIMEOUT = 10 |
6 | 8 | ||
diff --git a/etc/dict.lua b/etc/dict.lua index 6790cab..89bdb4f 100644 --- a/etc/dict.lua +++ b/etc/dict.lua | |||
@@ -1,6 +1,8 @@ | |||
1 | ----------------------------------------------------------------------------- | 1 | ----------------------------------------------------------------------------- |
2 | -- Little program to download DICT word definitions | 2 | -- Little program to download DICT word definitions |
3 | -- LuaSocket 1.5 sample files | 3 | -- LuaSocket 1.5 sample files |
4 | -- Author: Diego Nehab | ||
5 | -- RCS ID: $Id$ | ||
4 | ----------------------------------------------------------------------------- | 6 | ----------------------------------------------------------------------------- |
5 | function get_status(sock, valid) | 7 | function get_status(sock, valid) |
6 | local line, err = sock:receive() | 8 | local line, err = sock:receive() |
diff --git a/etc/get.lua b/etc/get.lua index af46c16..e972d16 100644 --- a/etc/get.lua +++ b/etc/get.lua | |||
@@ -1,6 +1,8 @@ | |||
1 | ----------------------------------------------------------------------------- | 1 | ----------------------------------------------------------------------------- |
2 | -- Little program to download files from URLs | 2 | -- Little program to download files from URLs |
3 | -- LuaSocket 1.5 sample files | 3 | -- LuaSocket 1.5 sample files |
4 | -- Author: Diego Nehab | ||
5 | -- RCS ID: $Id$ | ||
4 | ----------------------------------------------------------------------------- | 6 | ----------------------------------------------------------------------------- |
5 | -- formats a number of seconds into human readable form | 7 | -- formats a number of seconds into human readable form |
6 | function nicetime(s) | 8 | function nicetime(s) |
diff --git a/makefile.dist b/makefile.dist index 90ef7c2..e493305 100644 --- a/makefile.dist +++ b/makefile.dist | |||
@@ -2,22 +2,81 @@ | |||
2 | # Distribution makefile | 2 | # Distribution makefile |
3 | #-------------------------------------------------------------------------- | 3 | #-------------------------------------------------------------------------- |
4 | 4 | ||
5 | DIST = luasocket-1.5-work | 5 | DIST = luasocket-1.5-alpha |
6 | 6 | ||
7 | LUA = concat.lua code.lua url.lua http.lua smtp.lua ftp.lua lsselect.lua \ | 7 | LUA = \ |
8 | cl-compat.lua | 8 | concat.lua \ |
9 | code.lua \ | ||
10 | url.lua \ | ||
11 | http.lua \ | ||
12 | smtp.lua \ | ||
13 | ftp.lua \ | ||
14 | select.lua \ | ||
15 | luasocket.lua | ||
9 | 16 | ||
10 | TESTS = testclnt.lua testsrvr.lua testcmd.lua codetest.lua \ | 17 | TESTS = \ |
11 | urltest.lua concattest.lua | 18 | testclnt.lua \ |
19 | testsrvr.lua \ | ||
20 | testcmd.lua \ | ||
21 | codetest.lua \ | ||
22 | urltest.lua \ | ||
23 | concattest.lua \ | ||
24 | ftptest.lua \ | ||
25 | httptest.lua \ | ||
26 | smtptest.lua \ | ||
27 | mbox.lua \ | ||
28 | udptest.lua | ||
12 | 29 | ||
13 | EXAMPLES = check-links.lua daytimeclnt.lua dict.lua echoclnt.lua \ | 30 | EXAMPLES = \ |
14 | echosrvr.lua get.lua listener.lua talker.lua tinyirc.lua tftpclnt.lua | 31 | check-links.lua \ |
32 | daytimeclnt.lua \ | ||
33 | echoclnt.lua \ | ||
34 | echosrvr.lua \ | ||
35 | get.lua \ | ||
36 | listener.lua \ | ||
37 | talker.lua \ | ||
38 | tinyirc.lua | ||
39 | |||
40 | ETC = \ | ||
41 | cl-compat.lua \ | ||
42 | tftp.lua \ | ||
43 | dict.lua | ||
44 | |||
45 | MAIN = \ | ||
46 | auxiliar.c \ | ||
47 | auxiliar.h \ | ||
48 | buffer.c \ | ||
49 | buffer.h \ | ||
50 | error.c \ | ||
51 | error.h \ | ||
52 | inet.c \ | ||
53 | inet.h \ | ||
54 | io.c \ | ||
55 | io.h \ | ||
56 | lua.c \ | ||
57 | luasocket.c \ | ||
58 | luasocket.h \ | ||
59 | makefile \ | ||
60 | select.c \ | ||
61 | select.h \ | ||
62 | socket.h \ | ||
63 | tcp.c \ | ||
64 | tcp.h \ | ||
65 | timeout.c \ | ||
66 | timeout.h \ | ||
67 | udp.c \ | ||
68 | udp.h \ | ||
69 | usocket.c \ | ||
70 | usocket.h \ | ||
71 | wsocket.c \ | ||
72 | wsocket.h \ | ||
15 | 73 | ||
16 | dist: | 74 | dist: |
17 | mkdir -p $(DIST)/examples | 75 | mkdir -p $(DIST)/examples |
18 | mkdir -p $(DIST)/tests | 76 | mkdir -p $(DIST)/tests |
19 | cp -vf *.c $(DIST) | 77 | mkdir -p $(DIST)/etc |
20 | cp -vf *.h $(DIST) | 78 | mkdir -p $(DIST)/lua |
79 | cp -vf $(MAIN) $(DIST) | ||
21 | cp -vf $(LUA) $(DIST) | 80 | cp -vf $(LUA) $(DIST) |
22 | cp -vf makefile $(DIST) | 81 | cp -vf makefile $(DIST) |
23 | cp -vf README $(DIST) | 82 | cp -vf README $(DIST) |
@@ -25,6 +84,8 @@ dist: | |||
25 | cp -vf README.examples $(DIST)/examples/README | 84 | cp -vf README.examples $(DIST)/examples/README |
26 | cp -vf $(TESTS) $(DIST)/tests | 85 | cp -vf $(TESTS) $(DIST)/tests |
27 | cp -vf README.tests $(DIST)/tests/README | 86 | cp -vf README.tests $(DIST)/tests/README |
87 | cp -vf $(ETC) $(DIST)/etc | ||
88 | cp -vf README.etc $(DIST)/etc/README | ||
28 | tar -zcvf $(DIST).tar.gz $(DIST) | 89 | tar -zcvf $(DIST).tar.gz $(DIST) |
29 | zip -r $(DIST).zip $(DIST) | 90 | zip -r $(DIST).zip $(DIST) |
30 | 91 | ||
diff --git a/samples/daytimeclnt.lua b/samples/daytimeclnt.lua index 4debc81..85ddca1 100644 --- a/samples/daytimeclnt.lua +++ b/samples/daytimeclnt.lua | |||
@@ -1,3 +1,9 @@ | |||
1 | ----------------------------------------------------------------------------- | ||
2 | -- UDP sample: daytime protocol client | ||
3 | -- LuaSocket 1.5 sample files. | ||
4 | -- Author: Diego Nehab | ||
5 | -- RCS ID: $Id$ | ||
6 | ----------------------------------------------------------------------------- | ||
1 | host = host or "127.0.0.1" | 7 | host = host or "127.0.0.1" |
2 | port = port or 13 | 8 | port = port or 13 |
3 | if arg then | 9 | if arg then |
diff --git a/samples/echoclnt.lua b/samples/echoclnt.lua index cd8b450..bca0b4d 100644 --- a/samples/echoclnt.lua +++ b/samples/echoclnt.lua | |||
@@ -1,3 +1,9 @@ | |||
1 | ----------------------------------------------------------------------------- | ||
2 | -- UDP sample: echo protocol client | ||
3 | -- LuaSocket 1.5 sample files | ||
4 | -- Author: Diego Nehab | ||
5 | -- RCS ID: $Id$ | ||
6 | ----------------------------------------------------------------------------- | ||
1 | host = host or "localhost" | 7 | host = host or "localhost" |
2 | port = port or 7 | 8 | port = port or 7 |
3 | if arg then | 9 | if arg then |
diff --git a/samples/echosrvr.lua b/samples/echosrvr.lua index 6117557..18bd84e 100644 --- a/samples/echosrvr.lua +++ b/samples/echosrvr.lua | |||
@@ -1,3 +1,9 @@ | |||
1 | ----------------------------------------------------------------------------- | ||
2 | -- UDP sample: echo protocol server | ||
3 | -- LuaSocket 1.5 sample files | ||
4 | -- Author: Diego Nehab | ||
5 | -- RCS ID: $Id$ | ||
6 | ----------------------------------------------------------------------------- | ||
1 | host = host or "127.0.0.1" | 7 | host = host or "127.0.0.1" |
2 | port = port or 7 | 8 | port = port or 7 |
3 | if arg then | 9 | if arg then |
diff --git a/samples/listener.lua b/samples/listener.lua index c035ab2..4846419 100644 --- a/samples/listener.lua +++ b/samples/listener.lua | |||
@@ -1,6 +1,8 @@ | |||
1 | ----------------------------------------------------------------------------- | 1 | ----------------------------------------------------------------------------- |
2 | -- Little program to dump lines received at a given port | 2 | -- TCP sample: Little program to dump lines received at a given port |
3 | -- LuaSocket 1.5 sample files | 3 | -- LuaSocket 1.5 sample files |
4 | -- Author: Diego Nehab | ||
5 | -- RCS ID: $Id$ | ||
4 | ----------------------------------------------------------------------------- | 6 | ----------------------------------------------------------------------------- |
5 | host = host or "*" | 7 | host = host or "*" |
6 | port = port or 8080 | 8 | port = port or 8080 |
diff --git a/samples/talker.lua b/samples/talker.lua index 688824f..c7a239a 100644 --- a/samples/talker.lua +++ b/samples/talker.lua | |||
@@ -1,3 +1,9 @@ | |||
1 | ----------------------------------------------------------------------------- | ||
2 | -- TCP sample: Little program to send text lines to a given host/port | ||
3 | -- LuaSocket 1.5 sample files | ||
4 | -- Author: Diego Nehab | ||
5 | -- RCS ID: $Id$ | ||
6 | ----------------------------------------------------------------------------- | ||
1 | host = host or "localhost" | 7 | host = host or "localhost" |
2 | port = port or 8080 | 8 | port = port or 8080 |
3 | if arg then | 9 | if arg then |
diff --git a/samples/tinyirc.lua b/samples/tinyirc.lua index d3e56e7..0b20303 100644 --- a/samples/tinyirc.lua +++ b/samples/tinyirc.lua | |||
@@ -1,16 +1,9 @@ | |||
1 | function set_add(set, sock) | 1 | ----------------------------------------------------------------------------- |
2 | table.insert(set, sock) | 2 | -- Select sample: simple text line server |
3 | end | 3 | -- LuaSocket 1.5 sample files. |
4 | 4 | -- Author: Diego Nehab | |
5 | function set_remove(set, sock) | 5 | -- RCS ID: $Id$ |
6 | for i = 1, table.getn(set) do | 6 | ----------------------------------------------------------------------------- |
7 | if set[i] == sock then | ||
8 | table.remove(set, i) | ||
9 | break | ||
10 | end | ||
11 | end | ||
12 | end | ||
13 | |||
14 | host = host or "*" | 7 | host = host or "*" |
15 | port1 = port1 or 8080 | 8 | port1 = port1 or 8080 |
16 | port2 = port2 or 8081 | 9 | port2 = port2 or 8081 |
@@ -21,49 +14,62 @@ if arg then | |||
21 | end | 14 | end |
22 | 15 | ||
23 | server1, error = socket.bind(host, port1) | 16 | server1, error = socket.bind(host, port1) |
24 | if not server1 then print(error) exit() end | 17 | assert(server1, error) |
25 | server1:timeout(1) | 18 | server1:timeout(1) |
26 | server2, error = socket.bind(host, port2) | 19 | server2, error = socket.bind(host, port2) |
27 | if not server2 then print(error) exit() end | 20 | assert(server2, error) |
28 | server2:timeout(1) | 21 | server2:timeout(1) |
29 | 22 | ||
30 | sock_set = {server1, server2} | 23 | function newset() |
24 | local reverse = {} | ||
25 | local set = {} | ||
26 | setmetatable(set, { __index = { | ||
27 | insert = function(set, value) | ||
28 | table.insert(set, value) | ||
29 | reverse[value] = table.getn(set) | ||
30 | end, | ||
31 | remove = function(set, value) | ||
32 | table.remove(set, reverse[value]) | ||
33 | reverse[value] = nil | ||
34 | end, | ||
35 | id = function(set, value) | ||
36 | return reverse[value] | ||
37 | end | ||
38 | }}) | ||
39 | return set | ||
40 | end | ||
41 | |||
42 | sockets = newset() | ||
31 | 43 | ||
32 | sock_id = {} | 44 | sockets:insert(server1) |
33 | sock_id[server1] = 1 | 45 | sockets:insert(server2) |
34 | sock_id[server2] = 2 | ||
35 | next_id = 3 | ||
36 | 46 | ||
37 | while 1 do | 47 | while 1 do |
38 | local readable, _, error = socket.select(sock_set, nil) | 48 | local readable, _, error = socket.select(sockets, nil) |
39 | for _, sock in readable do | 49 | for _, input in readable do |
40 | -- is it a server socket | 50 | -- is it a server socket? |
41 | if sock_id[sock] < 3 then | 51 | local id = sockets:id(input) |
42 | local incomming = sock:accept() | 52 | if input == server1 or input == server2 then |
43 | if incomming then | 53 | local new = input:accept() |
44 | incomming:timeout(1) | 54 | if new then |
45 | sock_id[incomming] = next_id | 55 | new:timeout(1) |
46 | set_add(sock_set, incomming) | 56 | sockets:insert(new) |
47 | io.write("Added client id ", next_id, ". ", | 57 | io.write("Server ", id, " got client ", sockets:id(new), "\n") |
48 | table.getn(sock_set)-2, " total.\n") | ||
49 | next_id = next_id + 1 | ||
50 | end | 58 | end |
51 | -- it is a client socket | 59 | -- it is a client socket |
52 | else | 60 | else |
53 | local line, error = sock:receive() | 61 | local line, error = input:receive() |
54 | local id = sock_id[sock] | ||
55 | if error then | 62 | if error then |
56 | sock:close() | 63 | input:close() |
57 | set_remove(sock_set, sock) | 64 | io.write("Removing client ", id, "\n") |
58 | io.write("Removed client number ", id, ". ", | 65 | sockets:remove(input) |
59 | getn(sock_set)-2, " total.\n") | ||
60 | else | 66 | else |
61 | io.write("Broadcasting line '", id, "> ", line, "'.\n") | 67 | io.write("Broadcasting line '", id, "> ", line, "'.\n") |
62 | __, writable, error = socket.select(nil, sock_set, 1) | 68 | __, writable, error = socket.select(nil, sockets, 1) |
63 | if not error then | 69 | if not error then |
64 | for ___, outgoing in writable do | 70 | for ___, output in writable do |
65 | io.write("Sending to client ", sock_id[outgoing], "\n") | 71 | io.write("Sending to client ", sockets:id(output), "\n") |
66 | outgoing:send(id, "> ", line, "\r\n") | 72 | output:send(id, "> ", line, "\r\n") |
67 | end | 73 | end |
68 | else io.write("No one ready to listen!!!\n") end | 74 | else io.write("No one ready to listen!!!\n") end |
69 | end | 75 | end |
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 | ||