diff options
author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2003-06-26 18:47:49 +0000 |
---|---|---|
committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2003-06-26 18:47:49 +0000 |
commit | 71f6bb60bf2b7457091c7106190f92ab7e51f7c6 (patch) | |
tree | 8ad3668667bd3da3c34f7ff7ae0a9a7a4daa4679 | |
parent | f330540576031528f0daac231c61d4dd06e8ba1e (diff) | |
download | luasocket-71f6bb60bf2b7457091c7106190f92ab7e51f7c6.tar.gz luasocket-71f6bb60bf2b7457091c7106190f92ab7e51f7c6.tar.bz2 luasocket-71f6bb60bf2b7457091c7106190f92ab7e51f7c6.zip |
Finished implementation of LuaSocket 2.0 alpha on Linux.
Some testing still needed.
41 files changed, 692 insertions, 331 deletions
@@ -8,7 +8,9 @@ a given domain/family and protocol. Then connect or bind if needed. Then | |||
8 | use IO functions. | 8 | use IO functions. |
9 | 9 | ||
10 | All functions return a non-nil value as first return value if successful. | 10 | All functions return a non-nil value as first return value if successful. |
11 | All functions return nil followed by error message in case of error. | 11 | All functions return whatever could be retrieved followed by error message |
12 | in case of error. The best way to check for errors is to check for the | ||
13 | presence of an error message. | ||
12 | WARNING: The send function was affected. | 14 | WARNING: The send function was affected. |
13 | 15 | ||
14 | Better error messages and parameter checking. | 16 | Better error messages and parameter checking. |
@@ -1,24 +1,26 @@ | |||
1 | - Melhorar a interface de setoptions (aceitar nada como true, por exemplo) | ||
1 | - Inicializaccao das classes pode falhar? | 2 | - Inicializaccao das classes pode falhar? |
2 | - Ajeitar melhor a hierarquia de classes. Ajeitar o file... | 3 | - Ajeitar melhor a hierarquia de classes. Ajeitar o file... |
4 | - GARBAGE COLLECTOR! | ||
5 | - Adicionar um método sock:setoption??? | ||
6 | - testar em várias plataformas | ||
7 | - adicionar exemplos de expansão: pipe, local, named pipe | ||
3 | 8 | ||
4 | * Como mostrar um erro em lua_socketlibopen()... | 9 | * Como mostrar um erro em lua_socketlibopen()... |
5 | * O location do "redirect" pode ser relativo ao servidor atual (não pode, | 10 | * O location do "redirect" pode ser relativo ao servidor atual (não pode, |
6 | mas os servidores fazem merda...) | 11 | mas os servidores fazem merda...) |
7 | * - Ajeitar para Lua 4.1 | 12 | * Ajeitar para Lua 5.0 |
13 | * Padronizar os retornos de funccao | ||
14 | * Separar as classes em arquivos | ||
15 | * Retorno de sendto em datagram sockets pode ser refused | ||
16 | * Fazer compilar com g++ | ||
8 | 17 | ||
9 | - Padronizar os retornos de funccao | ||
10 | - Thread-safe | 18 | - Thread-safe |
11 | - proteger gethostby*.* com um mutex GLOBAL! | 19 | - proteger gethostby*.* com um mutex GLOBAL! |
12 | - proteger o atomizar o conjunto (timedout, receive), (timedout, send) | 20 | - proteger ou atomizar o conjunto (timedout, receive), (timedout, send) |
13 | - Usar "require" nos módulos | 21 | - inet_ntoa também é uma merda. |
14 | - SSL | 22 | - SSL |
15 | - Fazer compilar com g++ | 23 | - Proxy support pro http |
16 | - usar lua_verror | ||
17 | - separar as classes em arquivos | ||
18 | - criar mais uma classe, a de stream, entre p_sock e p_client | ||
19 | - criar um internal include file ls.h | ||
20 | - impedir que voe quando chamar accept(udpsocket()) | ||
21 | - trocar recv and send por read e write (ver se funciona) | ||
22 | 24 | ||
23 | - checar operações em closed sockets | 25 | - checar operações em closed sockets |
24 | - checar teste de writable socket com select | 26 | - checar teste de writable socket com select |
@@ -34,6 +36,4 @@ | |||
34 | - unix 92 bytes maximo no endereço, incluindo o zero | 36 | - unix 92 bytes maximo no endereço, incluindo o zero |
35 | - unix 9216 maximo de datagram size | 37 | - unix 9216 maximo de datagram size |
36 | 38 | ||
37 | - retorno de send/receive em datagram sockets pode ser refused... | ||
38 | 39 | ||
39 | - adicionar um método sock:setoption??? | ||
diff --git a/etc/check-links.lua b/etc/check-links.lua index 4c96fdc..c45131c 100644 --- a/etc/check-links.lua +++ b/etc/check-links.lua | |||
@@ -1,6 +1,6 @@ | |||
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 sample files |
4 | -- Author: Diego Nehab | 4 | -- Author: Diego Nehab |
5 | -- RCS ID: $Id$ | 5 | -- RCS ID: $Id$ |
6 | ----------------------------------------------------------------------------- | 6 | ----------------------------------------------------------------------------- |
diff --git a/etc/dict.lua b/etc/dict.lua index 89bdb4f..9926538 100644 --- a/etc/dict.lua +++ b/etc/dict.lua | |||
@@ -1,6 +1,6 @@ | |||
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 sample files |
4 | -- Author: Diego Nehab | 4 | -- Author: Diego Nehab |
5 | -- RCS ID: $Id$ | 5 | -- RCS ID: $Id$ |
6 | ----------------------------------------------------------------------------- | 6 | ----------------------------------------------------------------------------- |
diff --git a/etc/get.lua b/etc/get.lua index e972d16..caaa607 100644 --- a/etc/get.lua +++ b/etc/get.lua | |||
@@ -1,6 +1,6 @@ | |||
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 sample files |
4 | -- Author: Diego Nehab | 4 | -- Author: Diego Nehab |
5 | -- RCS ID: $Id$ | 5 | -- RCS ID: $Id$ |
6 | ----------------------------------------------------------------------------- | 6 | ----------------------------------------------------------------------------- |
diff --git a/etc/tftp.lua b/etc/tftp.lua index a0db68e..d1b5594 100644 --- a/etc/tftp.lua +++ b/etc/tftp.lua | |||
@@ -1,6 +1,6 @@ | |||
1 | ----------------------------------------------------------------------------- | 1 | ----------------------------------------------------------------------------- |
2 | -- TFTP support for the Lua language | 2 | -- TFTP support for the Lua language |
3 | -- LuaSocket 1.5 toolkit. | 3 | -- LuaSocket toolkit. |
4 | -- Author: Diego Nehab | 4 | -- Author: Diego Nehab |
5 | -- Conforming to: RFC 783, LTN7 | 5 | -- Conforming to: RFC 783, LTN7 |
6 | -- RCS ID: $Id$ | 6 | -- RCS ID: $Id$ |
diff --git a/samples/daytimeclnt.lua b/samples/daytimeclnt.lua index 85ddca1..5064fff 100644 --- a/samples/daytimeclnt.lua +++ b/samples/daytimeclnt.lua | |||
@@ -1,6 +1,6 @@ | |||
1 | ----------------------------------------------------------------------------- | 1 | ----------------------------------------------------------------------------- |
2 | -- UDP sample: daytime protocol client | 2 | -- UDP sample: daytime protocol client |
3 | -- LuaSocket 1.5 sample files. | 3 | -- LuaSocket sample files |
4 | -- Author: Diego Nehab | 4 | -- Author: Diego Nehab |
5 | -- RCS ID: $Id$ | 5 | -- RCS ID: $Id$ |
6 | ----------------------------------------------------------------------------- | 6 | ----------------------------------------------------------------------------- |
diff --git a/samples/echoclnt.lua b/samples/echoclnt.lua index bca0b4d..e028b86 100644 --- a/samples/echoclnt.lua +++ b/samples/echoclnt.lua | |||
@@ -1,6 +1,6 @@ | |||
1 | ----------------------------------------------------------------------------- | 1 | ----------------------------------------------------------------------------- |
2 | -- UDP sample: echo protocol client | 2 | -- UDP sample: echo protocol client |
3 | -- LuaSocket 1.5 sample files | 3 | -- LuaSocket sample files |
4 | -- Author: Diego Nehab | 4 | -- Author: Diego Nehab |
5 | -- RCS ID: $Id$ | 5 | -- RCS ID: $Id$ |
6 | ----------------------------------------------------------------------------- | 6 | ----------------------------------------------------------------------------- |
diff --git a/samples/echosrvr.lua b/samples/echosrvr.lua index 18bd84e..127ccb8 100644 --- a/samples/echosrvr.lua +++ b/samples/echosrvr.lua | |||
@@ -1,6 +1,6 @@ | |||
1 | ----------------------------------------------------------------------------- | 1 | ----------------------------------------------------------------------------- |
2 | -- UDP sample: echo protocol server | 2 | -- UDP sample: echo protocol server |
3 | -- LuaSocket 1.5 sample files | 3 | -- LuaSocket sample files |
4 | -- Author: Diego Nehab | 4 | -- Author: Diego Nehab |
5 | -- RCS ID: $Id$ | 5 | -- RCS ID: $Id$ |
6 | ----------------------------------------------------------------------------- | 6 | ----------------------------------------------------------------------------- |
diff --git a/samples/listener.lua b/samples/listener.lua index 4846419..dff4d25 100644 --- a/samples/listener.lua +++ b/samples/listener.lua | |||
@@ -1,6 +1,6 @@ | |||
1 | ----------------------------------------------------------------------------- | 1 | ----------------------------------------------------------------------------- |
2 | -- TCP sample: 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 sample files |
4 | -- Author: Diego Nehab | 4 | -- Author: Diego Nehab |
5 | -- RCS ID: $Id$ | 5 | -- RCS ID: $Id$ |
6 | ----------------------------------------------------------------------------- | 6 | ----------------------------------------------------------------------------- |
diff --git a/samples/talker.lua b/samples/talker.lua index c7a239a..1b0652f 100644 --- a/samples/talker.lua +++ b/samples/talker.lua | |||
@@ -1,6 +1,6 @@ | |||
1 | ----------------------------------------------------------------------------- | 1 | ----------------------------------------------------------------------------- |
2 | -- TCP sample: Little program to send text lines to a given host/port | 2 | -- TCP sample: Little program to send text lines to a given host/port |
3 | -- LuaSocket 1.5 sample files | 3 | -- LuaSocket sample files |
4 | -- Author: Diego Nehab | 4 | -- Author: Diego Nehab |
5 | -- RCS ID: $Id$ | 5 | -- RCS ID: $Id$ |
6 | ----------------------------------------------------------------------------- | 6 | ----------------------------------------------------------------------------- |
diff --git a/samples/tinyirc.lua b/samples/tinyirc.lua index 0b20303..0ad00ab 100644 --- a/samples/tinyirc.lua +++ b/samples/tinyirc.lua | |||
@@ -1,6 +1,6 @@ | |||
1 | ----------------------------------------------------------------------------- | 1 | ----------------------------------------------------------------------------- |
2 | -- Select sample: simple text line server | 2 | -- Select sample: simple text line server |
3 | -- LuaSocket 1.5 sample files. | 3 | -- LuaSocket sample files. |
4 | -- Author: Diego Nehab | 4 | -- Author: Diego Nehab |
5 | -- RCS ID: $Id$ | 5 | -- RCS ID: $Id$ |
6 | ----------------------------------------------------------------------------- | 6 | ----------------------------------------------------------------------------- |
diff --git a/src/auxiliar.c b/src/auxiliar.c index 96138f1..8b2fa37 100644 --- a/src/auxiliar.c +++ b/src/auxiliar.c | |||
@@ -1,142 +1,167 @@ | |||
1 | /*=========================================================================*\ | 1 | /*=========================================================================*\ |
2 | * Auxiliar routines for class hierarchy manipulation | 2 | * Auxiliar routines for class hierarchy manipulation |
3 | * LuaSocket toolkit | ||
3 | * | 4 | * |
4 | * RCS ID: $Id$ | 5 | * RCS ID: $Id$ |
5 | \*=========================================================================*/ | 6 | \*=========================================================================*/ |
7 | #include <string.h> | ||
8 | |||
9 | #include "luasocket.h" | ||
6 | #include "auxiliar.h" | 10 | #include "auxiliar.h" |
7 | 11 | ||
8 | /*=========================================================================*\ | 12 | /*=========================================================================*\ |
9 | * Exported functions | 13 | * Exported functions |
10 | \*=========================================================================*/ | 14 | \*=========================================================================*/ |
11 | /*-------------------------------------------------------------------------*\ | 15 | /*-------------------------------------------------------------------------*\ |
12 | * Creates a new class. A class has methods given by the func array and the | 16 | * Initializes the module |
13 | * field 'class' tells the object class. The table 'group' list the class | ||
14 | * groups the object belongs to. | ||
15 | \*-------------------------------------------------------------------------*/ | 17 | \*-------------------------------------------------------------------------*/ |
16 | void aux_newclass(lua_State *L, const char *name, luaL_reg *func) | 18 | void aux_open(lua_State *L) |
17 | { | 19 | { |
18 | lua_pushstring(L, name); | 20 | /* create namespace table */ |
19 | lua_newtable(L); | 21 | lua_pushstring(L, LUASOCKET_LIBNAME); |
20 | lua_pushstring(L, "__index"); | ||
21 | lua_newtable(L); | 22 | lua_newtable(L); |
22 | luaL_openlib(L, NULL, func, 0); | 23 | #ifdef LUASOCKET_DEBUG |
23 | lua_pushstring(L, "class"); | 24 | lua_pushstring(L, "debug"); |
24 | lua_pushstring(L, name); | 25 | lua_pushnumber(L, 1); |
25 | lua_rawset(L, -3); | ||
26 | lua_pushstring(L, "group"); | ||
27 | lua_newtable(L); | ||
28 | lua_rawset(L, -3); | ||
29 | lua_rawset(L, -3); | 26 | lua_rawset(L, -3); |
30 | lua_rawset(L, LUA_REGISTRYINDEX); | 27 | #endif |
28 | lua_settable(L, LUA_GLOBALSINDEX); | ||
29 | /* make sure modules know what is our namespace */ | ||
30 | lua_pushstring(L, "LUASOCKET_LIBNAME"); | ||
31 | lua_pushstring(L, LUASOCKET_LIBNAME); | ||
32 | lua_settable(L, LUA_GLOBALSINDEX); | ||
31 | } | 33 | } |
32 | 34 | ||
33 | /*-------------------------------------------------------------------------*\ | 35 | /*-------------------------------------------------------------------------*\ |
34 | * Add group to object list of groups. | 36 | * Creates a new class with given methods |
35 | \*-------------------------------------------------------------------------*/ | 37 | \*-------------------------------------------------------------------------*/ |
36 | void aux_add2group(lua_State *L, const char *name, const char *group) | 38 | void aux_newclass(lua_State *L, const char *classname, luaL_reg *func) |
37 | { | 39 | { |
38 | lua_pushstring(L, name); | 40 | luaL_newmetatable(L, classname); /* mt */ |
39 | lua_rawget(L, LUA_REGISTRYINDEX); | 41 | lua_pushstring(L, "__index"); /* mt,"__index" */ |
40 | lua_pushstring(L, "__index"); | 42 | lua_newtable(L); /* mt,"__index",it */ |
41 | lua_rawget(L, -2); | 43 | luaL_openlib(L, NULL, func, 0); |
42 | lua_pushstring(L, "group"); | 44 | #ifdef LUASOCKET_DEBUG |
43 | lua_rawget(L, -2); | 45 | lua_pushstring(L, "class"); /* mt,"__index",it,"class" */ |
44 | lua_pushstring(L, group); | 46 | lua_pushstring(L, classname); /* mt,"__index",it,"class",classname */ |
45 | lua_pushnumber(L, 1); | 47 | lua_rawset(L, -3); /* mt,"__index",it */ |
48 | #endif | ||
49 | /* get __gc method from class and use it for garbage collection */ | ||
50 | lua_pushstring(L, "__gc"); /* mt,"__index",it,"__gc" */ | ||
51 | lua_pushstring(L, "__gc"); /* mt,"__index",it,"__gc","__gc" */ | ||
52 | lua_rawget(L, -3); /* mt,"__index",it,"__gc",fn */ | ||
53 | lua_rawset(L, -5); /* mt,"__index",it */ | ||
54 | lua_rawset(L, -3); /* mt */ | ||
55 | lua_pop(L, 1); | ||
56 | } | ||
57 | |||
58 | /*-------------------------------------------------------------------------*\ | ||
59 | * Insert class into group | ||
60 | \*-------------------------------------------------------------------------*/ | ||
61 | void aux_add2group(lua_State *L, const char *classname, const char *groupname) | ||
62 | { | ||
63 | luaL_getmetatable(L, classname); | ||
64 | lua_pushstring(L, groupname); | ||
65 | lua_pushboolean(L, 1); | ||
46 | lua_rawset(L, -3); | 66 | lua_rawset(L, -3); |
47 | lua_pop(L, 3); | 67 | lua_pop(L, 1); |
68 | } | ||
69 | |||
70 | /*-------------------------------------------------------------------------*\ | ||
71 | * Make sure argument is a boolean | ||
72 | \*-------------------------------------------------------------------------*/ | ||
73 | int aux_checkboolean(lua_State *L, int objidx) | ||
74 | { | ||
75 | if (!lua_isboolean(L, objidx)) | ||
76 | luaL_typerror(L, objidx, lua_typename(L, LUA_TBOOLEAN)); | ||
77 | return lua_toboolean(L, objidx); | ||
48 | } | 78 | } |
49 | 79 | ||
50 | /*-------------------------------------------------------------------------*\ | 80 | /*-------------------------------------------------------------------------*\ |
51 | * Get a userdata making sure the object belongs to a given class. | 81 | * Calls appropriate option handler |
52 | \*-------------------------------------------------------------------------*/ | 82 | \*-------------------------------------------------------------------------*/ |
53 | void *aux_checkclass(lua_State *L, const char *name, int objidx) | 83 | int aux_meth_setoption(lua_State *L, luaL_reg *opt) |
54 | { | 84 | { |
55 | void *data = aux_getclassudata(L, name, objidx); | 85 | const char *name = luaL_checkstring(L, 2); /* obj, name, args */ |
86 | while (opt->name && strcmp(name, opt->name)) | ||
87 | opt++; | ||
88 | if (!opt->func) { | ||
89 | char msg[45]; | ||
90 | sprintf(msg, "unknown option `%.35s'", name); | ||
91 | luaL_argerror(L, 2, msg); | ||
92 | } | ||
93 | lua_remove(L, 2); /* obj, args */ | ||
94 | lua_pushcfunction(L, opt->func); /* obj, args, func */ | ||
95 | lua_insert(L, 1); /* func, obj, args */ | ||
96 | lua_call(L, lua_gettop(L)-1, LUA_MULTRET); | ||
97 | return lua_gettop(L); | ||
98 | } | ||
99 | |||
100 | /*-------------------------------------------------------------------------*\ | ||
101 | * Return userdata pointer if object belongs to a given class, abort with | ||
102 | * error otherwise | ||
103 | \*-------------------------------------------------------------------------*/ | ||
104 | void *aux_checkclass(lua_State *L, const char *classname, int objidx) | ||
105 | { | ||
106 | void *data = aux_getclassudata(L, classname, objidx); | ||
56 | if (!data) { | 107 | if (!data) { |
57 | char msg[45]; | 108 | char msg[45]; |
58 | sprintf(msg, "%.35s expected", name); | 109 | sprintf(msg, "%.35s expected", classname); |
59 | luaL_argerror(L, objidx, msg); | 110 | luaL_argerror(L, objidx, msg); |
60 | } | 111 | } |
61 | return data; | 112 | return data; |
62 | } | 113 | } |
63 | 114 | ||
64 | /*-------------------------------------------------------------------------*\ | 115 | /*-------------------------------------------------------------------------*\ |
65 | * Get a userdata making sure the object belongs to a given group. | 116 | * Return userdata pointer if object belongs to a given group, abort with |
117 | * error otherwise | ||
66 | \*-------------------------------------------------------------------------*/ | 118 | \*-------------------------------------------------------------------------*/ |
67 | void *aux_checkgroup(lua_State *L, const char *group, int objidx) | 119 | void *aux_checkgroup(lua_State *L, const char *groupname, int objidx) |
68 | { | 120 | { |
69 | void *data = aux_getgroupudata(L, group, objidx); | 121 | void *data = aux_getgroupudata(L, groupname, objidx); |
70 | if (!data) { | 122 | if (!data) { |
71 | char msg[45]; | 123 | char msg[45]; |
72 | sprintf(msg, "%.35s expected", group); | 124 | sprintf(msg, "%.35s expected", groupname); |
73 | luaL_argerror(L, objidx, msg); | 125 | luaL_argerror(L, objidx, msg); |
74 | } | 126 | } |
75 | return data; | 127 | return data; |
76 | } | 128 | } |
77 | 129 | ||
78 | /*-------------------------------------------------------------------------*\ | 130 | /*-------------------------------------------------------------------------*\ |
79 | * Set object class. | 131 | * Set object class |
80 | \*-------------------------------------------------------------------------*/ | 132 | \*-------------------------------------------------------------------------*/ |
81 | void aux_setclass(lua_State *L, const char *name, int objidx) | 133 | void aux_setclass(lua_State *L, const char *classname, int objidx) |
82 | { | 134 | { |
83 | lua_pushstring(L, name); | 135 | luaL_getmetatable(L, classname); |
84 | lua_rawget(L, LUA_REGISTRYINDEX); | ||
85 | if (objidx < 0) objidx--; | 136 | if (objidx < 0) objidx--; |
86 | lua_setmetatable(L, objidx); | 137 | lua_setmetatable(L, objidx); |
87 | } | 138 | } |
88 | 139 | ||
89 | /*=========================================================================*\ | ||
90 | * Internal functions | ||
91 | \*=========================================================================*/ | ||
92 | /*-------------------------------------------------------------------------*\ | 140 | /*-------------------------------------------------------------------------*\ |
93 | * Get a userdata if object belongs to a given group. | 141 | * Get a userdata pointer if object belongs to a given group. Return NULL |
142 | * otherwise | ||
94 | \*-------------------------------------------------------------------------*/ | 143 | \*-------------------------------------------------------------------------*/ |
95 | void *aux_getgroupudata(lua_State *L, const char *group, int objidx) | 144 | void *aux_getgroupudata(lua_State *L, const char *groupname, int objidx) |
96 | { | 145 | { |
97 | if (!lua_getmetatable(L, objidx)) | 146 | 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 | } | ||
105 | lua_pushstring(L, "group"); | ||
106 | lua_rawget(L, -2); | ||
107 | if (!lua_istable(L, -1)) { | ||
108 | lua_pop(L, 3); | ||
109 | return NULL; | 147 | return NULL; |
110 | } | 148 | lua_pushstring(L, groupname); |
111 | lua_pushstring(L, group); | ||
112 | lua_rawget(L, -2); | 149 | lua_rawget(L, -2); |
113 | if (lua_isnil(L, -1)) { | 150 | if (lua_isnil(L, -1)) { |
114 | lua_pop(L, 4); | 151 | lua_pop(L, 2); |
115 | return NULL; | 152 | return NULL; |
153 | } else { | ||
154 | lua_pop(L, 2); | ||
155 | return lua_touserdata(L, objidx); | ||
116 | } | 156 | } |
117 | lua_pop(L, 4); | ||
118 | return lua_touserdata(L, objidx); | ||
119 | } | 157 | } |
120 | 158 | ||
121 | /*-------------------------------------------------------------------------*\ | 159 | /*-------------------------------------------------------------------------*\ |
122 | * Get a userdata if object belongs to a given class. | 160 | * Get a userdata pointer if object belongs to a given class. Return NULL |
161 | * otherwise | ||
123 | \*-------------------------------------------------------------------------*/ | 162 | \*-------------------------------------------------------------------------*/ |
124 | void *aux_getclassudata(lua_State *L, const char *group, int objidx) | 163 | void *aux_getclassudata(lua_State *L, const char *classname, int objidx) |
125 | { | 164 | { |
126 | if (!lua_getmetatable(L, objidx)) | 165 | return luaL_checkudata(L, objidx, classname); |
127 | return NULL; | ||
128 | lua_pushstring(L, "__index"); | ||
129 | lua_rawget(L, -2); | ||
130 | if (!lua_istable(L, -1)) { | ||
131 | lua_pop(L, 2); | ||
132 | return NULL; | ||
133 | } | ||
134 | lua_pushstring(L, "class"); | ||
135 | lua_rawget(L, -2); | ||
136 | if (lua_isnil(L, -1)) { | ||
137 | lua_pop(L, 3); | ||
138 | return NULL; | ||
139 | } | ||
140 | lua_pop(L, 3); | ||
141 | return lua_touserdata(L, objidx); | ||
142 | } | 166 | } |
167 | |||
diff --git a/src/auxiliar.h b/src/auxiliar.h index 66be31d..324e800 100644 --- a/src/auxiliar.h +++ b/src/auxiliar.h | |||
@@ -1,22 +1,37 @@ | |||
1 | #ifndef AUX_H | ||
2 | #define AUX_H | ||
1 | /*=========================================================================*\ | 3 | /*=========================================================================*\ |
2 | * Auxiliar routines for class hierarchy manipulation | 4 | * Auxiliar routines for class hierarchy manipulation |
5 | * LuaSocket toolkit | ||
6 | * | ||
7 | * A LuaSocket class is a name associated with Lua metatables. A LuaSocket | ||
8 | * group is a name associated to a class. A class can belong to any number | ||
9 | * of groups. This module provides the functionality to: | ||
10 | * | ||
11 | * - create new classes | ||
12 | * - add classes to groups | ||
13 | * - set the class of object | ||
14 | * - check if an object belongs to a given class or group | ||
15 | * | ||
16 | * LuaSocket class names follow the convention <module>{<class>}. Modules | ||
17 | * can define any number of classes and groups. The module tcp.c, for | ||
18 | * example, defines the classes tcp{master}, tcp{client} and tcp{server} and | ||
19 | * the groups tcp{client, server} and tcp{any}. Module functions can then | ||
20 | * perform type-checking on it's arguments by either class or group. | ||
21 | * | ||
22 | * LuaSocket metatables define the __index metamethod as being a table. This | ||
23 | * table has one field for each method supported by the class. In DEBUG | ||
24 | * mode, it also has one field with the class name. | ||
25 | * | ||
26 | * The mapping from class name to the corresponding metatable and the | ||
27 | * reverse mapping are done using lauxlib. | ||
3 | * | 28 | * |
4 | * RCS ID: $Id$ | 29 | * RCS ID: $Id$ |
5 | \*=========================================================================*/ | 30 | \*=========================================================================*/ |
6 | #ifndef AUX_H | ||
7 | #define AUX_H | ||
8 | 31 | ||
9 | #include <lua.h> | 32 | #include <lua.h> |
10 | #include <lauxlib.h> | 33 | #include <lauxlib.h> |
11 | 34 | ||
12 | 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); | ||
14 | void *aux_checkclass(lua_State *L, const char *name, 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); | ||
18 | void aux_setclass(lua_State *L, const char *name, int objidx); | ||
19 | |||
20 | /* min and max macros */ | 35 | /* min and max macros */ |
21 | #ifndef MIN | 36 | #ifndef MIN |
22 | #define MIN(x, y) ((x) < (y) ? x : y) | 37 | #define MIN(x, y) ((x) < (y) ? x : y) |
@@ -25,4 +40,15 @@ void aux_setclass(lua_State *L, const char *name, int objidx); | |||
25 | #define MAX(x, y) ((x) > (y) ? x : y) | 40 | #define MAX(x, y) ((x) > (y) ? x : y) |
26 | #endif | 41 | #endif |
27 | 42 | ||
28 | #endif | 43 | void aux_open(lua_State *L); |
44 | void aux_newclass(lua_State *L, const char *classname, luaL_reg *func); | ||
45 | void aux_add2group(lua_State *L, const char *classname, const char *group); | ||
46 | void aux_setclass(lua_State *L, const char *classname, int objidx); | ||
47 | void *aux_checkclass(lua_State *L, const char *classname, int objidx); | ||
48 | void *aux_checkgroup(lua_State *L, const char *groupname, int objidx); | ||
49 | void *aux_getclassudata(lua_State *L, const char *groupname, int objidx); | ||
50 | void *aux_getgroupudata(lua_State *L, const char *groupname, int objidx); | ||
51 | int aux_meth_setoption(lua_State *L, luaL_reg *opt); | ||
52 | int aux_checkboolean(lua_State *L, int objidx); | ||
53 | |||
54 | #endif /* AUX_H */ | ||
diff --git a/src/buffer.c b/src/buffer.c index ab059bb..c860f35 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
@@ -1,12 +1,12 @@ | |||
1 | /*=========================================================================*\ | 1 | /*=========================================================================*\ |
2 | * Buffered input/output routines | 2 | * Input/Output interface for Lua programs |
3 | * LuaSocket toolkit | ||
3 | * | 4 | * |
4 | * RCS ID: $Id$ | 5 | * RCS ID: $Id$ |
5 | \*=========================================================================*/ | 6 | \*=========================================================================*/ |
6 | #include <lua.h> | 7 | #include <lua.h> |
7 | #include <lauxlib.h> | 8 | #include <lauxlib.h> |
8 | 9 | ||
9 | #include "error.h" | ||
10 | #include "auxiliar.h" | 10 | #include "auxiliar.h" |
11 | #include "buffer.h" | 11 | #include "buffer.h" |
12 | 12 | ||
@@ -42,7 +42,7 @@ void buf_init(p_buf buf, p_io io, p_tm tm) | |||
42 | } | 42 | } |
43 | 43 | ||
44 | /*-------------------------------------------------------------------------*\ | 44 | /*-------------------------------------------------------------------------*\ |
45 | * Send data through buffered object | 45 | * object:send() interface |
46 | \*-------------------------------------------------------------------------*/ | 46 | \*-------------------------------------------------------------------------*/ |
47 | int buf_meth_send(lua_State *L, p_buf buf) | 47 | int buf_meth_send(lua_State *L, p_buf buf) |
48 | { | 48 | { |
@@ -59,7 +59,7 @@ int buf_meth_send(lua_State *L, p_buf buf) | |||
59 | total += sent; | 59 | total += sent; |
60 | } | 60 | } |
61 | lua_pushnumber(L, total); | 61 | lua_pushnumber(L, total); |
62 | error_push(L, err); | 62 | io_pusherror(L, err); |
63 | #ifdef LUASOCKET_DEBUG | 63 | #ifdef LUASOCKET_DEBUG |
64 | /* push time elapsed during operation as the last return value */ | 64 | /* push time elapsed during operation as the last return value */ |
65 | lua_pushnumber(L, (tm_gettime() - tm_getstart(tm))/1000.0); | 65 | lua_pushnumber(L, (tm_gettime() - tm_getstart(tm))/1000.0); |
@@ -68,7 +68,7 @@ int buf_meth_send(lua_State *L, p_buf buf) | |||
68 | } | 68 | } |
69 | 69 | ||
70 | /*-------------------------------------------------------------------------*\ | 70 | /*-------------------------------------------------------------------------*\ |
71 | * Receive data from a buffered object | 71 | * object:receive() interface |
72 | \*-------------------------------------------------------------------------*/ | 72 | \*-------------------------------------------------------------------------*/ |
73 | int buf_meth_receive(lua_State *L, p_buf buf) | 73 | int buf_meth_receive(lua_State *L, p_buf buf) |
74 | { | 74 | { |
@@ -101,13 +101,13 @@ int buf_meth_receive(lua_State *L, p_buf buf) | |||
101 | luaL_argcheck(L, 0, arg, "invalid receive pattern"); | 101 | luaL_argcheck(L, 0, arg, "invalid receive pattern"); |
102 | break; | 102 | break; |
103 | } | 103 | } |
104 | /* raw pattern */ | 104 | /* get a fixed number of bytes */ |
105 | } else err = recvraw(L, buf, (size_t) lua_tonumber(L, arg)); | 105 | } else err = recvraw(L, buf, (size_t) lua_tonumber(L, arg)); |
106 | } | 106 | } |
107 | /* push nil for each pattern after an error */ | 107 | /* push nil for each pattern after an error */ |
108 | for ( ; arg <= top; arg++) lua_pushnil(L); | 108 | for ( ; arg <= top; arg++) lua_pushnil(L); |
109 | /* last return is an error code */ | 109 | /* last return is an error code */ |
110 | error_push(L, err); | 110 | io_pusherror(L, err); |
111 | #ifdef LUASOCKET_DEBUG | 111 | #ifdef LUASOCKET_DEBUG |
112 | /* push time elapsed during operation as the last return value */ | 112 | /* push time elapsed during operation as the last return value */ |
113 | lua_pushnumber(L, (tm_gettime() - tm_getstart(tm))/1000.0); | 113 | lua_pushnumber(L, (tm_gettime() - tm_getstart(tm))/1000.0); |
@@ -127,9 +127,10 @@ int buf_isempty(p_buf buf) | |||
127 | * Internal functions | 127 | * Internal functions |
128 | \*=========================================================================*/ | 128 | \*=========================================================================*/ |
129 | /*-------------------------------------------------------------------------*\ | 129 | /*-------------------------------------------------------------------------*\ |
130 | * Sends a raw block of data through a buffered object. | 130 | * Sends a block of data (unbuffered) |
131 | \*-------------------------------------------------------------------------*/ | 131 | \*-------------------------------------------------------------------------*/ |
132 | static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent) | 132 | static |
133 | int sendraw(p_buf buf, const char *data, size_t count, size_t *sent) | ||
133 | { | 134 | { |
134 | p_io io = buf->io; | 135 | p_io io = buf->io; |
135 | p_tm tm = buf->tm; | 136 | p_tm tm = buf->tm; |
@@ -145,7 +146,7 @@ static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent) | |||
145 | } | 146 | } |
146 | 147 | ||
147 | /*-------------------------------------------------------------------------*\ | 148 | /*-------------------------------------------------------------------------*\ |
148 | * Reads a raw block of data from a buffered object. | 149 | * Reads a fixed number of bytes (buffered) |
149 | \*-------------------------------------------------------------------------*/ | 150 | \*-------------------------------------------------------------------------*/ |
150 | static | 151 | static |
151 | int recvraw(lua_State *L, p_buf buf, size_t wanted) | 152 | int recvraw(lua_State *L, p_buf buf, size_t wanted) |
@@ -167,7 +168,7 @@ int recvraw(lua_State *L, p_buf buf, size_t wanted) | |||
167 | } | 168 | } |
168 | 169 | ||
169 | /*-------------------------------------------------------------------------*\ | 170 | /*-------------------------------------------------------------------------*\ |
170 | * Reads everything until the connection is closed | 171 | * Reads everything until the connection is closed (buffered) |
171 | \*-------------------------------------------------------------------------*/ | 172 | \*-------------------------------------------------------------------------*/ |
172 | static | 173 | static |
173 | int recvall(lua_State *L, p_buf buf) | 174 | int recvall(lua_State *L, p_buf buf) |
@@ -187,12 +188,12 @@ int recvall(lua_State *L, p_buf buf) | |||
187 | 188 | ||
188 | /*-------------------------------------------------------------------------*\ | 189 | /*-------------------------------------------------------------------------*\ |
189 | * Reads a line terminated by a CR LF pair or just by a LF. The CR and LF | 190 | * Reads a line terminated by a CR LF pair or just by a LF. The CR and LF |
190 | * are not returned by the function and are discarded from the buffer. | 191 | * are not returned by the function and are discarded from the buffer |
191 | \*-------------------------------------------------------------------------*/ | 192 | \*-------------------------------------------------------------------------*/ |
192 | static | 193 | static |
193 | int recvline(lua_State *L, p_buf buf) | 194 | int recvline(lua_State *L, p_buf buf) |
194 | { | 195 | { |
195 | int err = 0; | 196 | int err = IO_DONE; |
196 | luaL_Buffer b; | 197 | luaL_Buffer b; |
197 | luaL_buffinit(L, &b); | 198 | luaL_buffinit(L, &b); |
198 | while (err == IO_DONE) { | 199 | while (err == IO_DONE) { |
@@ -215,7 +216,8 @@ int recvline(lua_State *L, p_buf buf) | |||
215 | } | 216 | } |
216 | 217 | ||
217 | /*-------------------------------------------------------------------------*\ | 218 | /*-------------------------------------------------------------------------*\ |
218 | * Skips a given number of bytes in read buffer | 219 | * Skips a given number of bytes from read buffer. No data is read from the |
220 | * transport layer | ||
219 | \*-------------------------------------------------------------------------*/ | 221 | \*-------------------------------------------------------------------------*/ |
220 | static | 222 | static |
221 | void buf_skip(p_buf buf, size_t count) | 223 | void buf_skip(p_buf buf, size_t count) |
@@ -227,7 +229,7 @@ void buf_skip(p_buf buf, size_t count) | |||
227 | 229 | ||
228 | /*-------------------------------------------------------------------------*\ | 230 | /*-------------------------------------------------------------------------*\ |
229 | * Return any data available in buffer, or get more data from transport layer | 231 | * Return any data available in buffer, or get more data from transport layer |
230 | * if buffer is empty. | 232 | * if buffer is empty |
231 | \*-------------------------------------------------------------------------*/ | 233 | \*-------------------------------------------------------------------------*/ |
232 | static | 234 | static |
233 | int buf_get(p_buf buf, const char **data, size_t *count) | 235 | int buf_get(p_buf buf, const char **data, size_t *count) |
@@ -245,3 +247,4 @@ int buf_get(p_buf buf, const char **data, size_t *count) | |||
245 | *data = buf->data + buf->first; | 247 | *data = buf->data + buf->first; |
246 | return err; | 248 | return err; |
247 | } | 249 | } |
250 | |||
diff --git a/src/buffer.h b/src/buffer.h index 1502ef0..12b90a0 100644 --- a/src/buffer.h +++ b/src/buffer.h | |||
@@ -1,21 +1,31 @@ | |||
1 | #ifndef BUF_H | ||
2 | #define BUF_H | ||
1 | /*=========================================================================*\ | 3 | /*=========================================================================*\ |
2 | * Buffered input/output routines | 4 | * Input/Output interface for Lua programs |
5 | * LuaSocket toolkit | ||
6 | * | ||
7 | * Line patterns require buffering. Reading one character at a time involves | ||
8 | * too many system calls and is very slow. This module implements the | ||
9 | * LuaSocket interface for input/output on connected objects, as seen by | ||
10 | * Lua programs. | ||
11 | * | ||
12 | * Input is buffered. Output is *not* buffered because there was no simple | ||
13 | * way of making sure the buffered output data would ever be sent. | ||
14 | * | ||
15 | * The module is built on top of the I/O abstraction defined in io.h and the | ||
16 | * timeout management is done with the timeout.h interface. | ||
3 | * | 17 | * |
4 | * RCS ID: $Id$ | 18 | * RCS ID: $Id$ |
5 | \*=========================================================================*/ | 19 | \*=========================================================================*/ |
6 | #ifndef BUF_H | ||
7 | #define BUF_H | ||
8 | |||
9 | #include <lua.h> | 20 | #include <lua.h> |
21 | |||
10 | #include "io.h" | 22 | #include "io.h" |
11 | #include "timeout.h" | 23 | #include "timeout.h" |
12 | 24 | ||
13 | /* buffer size in bytes */ | 25 | /* buffer size in bytes */ |
14 | #define BUF_SIZE 8192 | 26 | #define BUF_SIZE 8192 |
15 | 27 | ||
16 | /*-------------------------------------------------------------------------*\ | 28 | /* buffer control structure */ |
17 | * Buffer control structure | ||
18 | \*-------------------------------------------------------------------------*/ | ||
19 | typedef struct t_buf_ { | 29 | typedef struct t_buf_ { |
20 | p_io io; /* IO driver used for this buffer */ | 30 | p_io io; /* IO driver used for this buffer */ |
21 | p_tm tm; /* timeout management for this buffer */ | 31 | p_tm tm; /* timeout management for this buffer */ |
@@ -24,9 +34,6 @@ typedef struct t_buf_ { | |||
24 | } t_buf; | 34 | } t_buf; |
25 | typedef t_buf *p_buf; | 35 | typedef t_buf *p_buf; |
26 | 36 | ||
27 | /*-------------------------------------------------------------------------*\ | ||
28 | * Exported functions | ||
29 | \*-------------------------------------------------------------------------*/ | ||
30 | void buf_open(lua_State *L); | 37 | void buf_open(lua_State *L); |
31 | void buf_init(p_buf buf, p_io io, p_tm tm); | 38 | void buf_init(p_buf buf, p_io io, p_tm tm); |
32 | int buf_meth_send(lua_State *L, p_buf buf); | 39 | int buf_meth_send(lua_State *L, p_buf buf); |
diff --git a/src/ftp.lua b/src/ftp.lua index c48f2c7..9d75d2a 100644 --- a/src/ftp.lua +++ b/src/ftp.lua | |||
@@ -1,6 +1,6 @@ | |||
1 | ----------------------------------------------------------------------------- | 1 | ----------------------------------------------------------------------------- |
2 | -- FTP support for the Lua language | 2 | -- FTP support for the Lua language |
3 | -- LuaSocket 1.5 toolkit. | 3 | -- LuaSocket toolkit. |
4 | -- Author: Diego Nehab | 4 | -- Author: Diego Nehab |
5 | -- Conforming to: RFC 959, LTN7 | 5 | -- Conforming to: RFC 959, LTN7 |
6 | -- RCS ID: $Id$ | 6 | -- RCS ID: $Id$ |
diff --git a/src/http.lua b/src/http.lua index d531a2f..4ef2c87 100644 --- a/src/http.lua +++ b/src/http.lua | |||
@@ -1,6 +1,6 @@ | |||
1 | ----------------------------------------------------------------------------- | 1 | ----------------------------------------------------------------------------- |
2 | -- HTTP/1.1 client support for the Lua language. | 2 | -- HTTP/1.1 client support for the Lua language. |
3 | -- LuaSocket 1.5 toolkit. | 3 | -- LuaSocket toolkit. |
4 | -- Author: Diego Nehab | 4 | -- Author: Diego Nehab |
5 | -- Conforming to: RFC 2616, LTN7 | 5 | -- Conforming to: RFC 2616, LTN7 |
6 | -- RCS ID: $Id$ | 6 | -- RCS ID: $Id$ |
@@ -1,8 +1,10 @@ | |||
1 | /*=========================================================================*\ | 1 | /*=========================================================================*\ |
2 | * Internet domain functions | 2 | * Internet domain functions |
3 | * LuaSocket toolkit | ||
3 | * | 4 | * |
4 | * RCS ID: $Id$ | 5 | * RCS ID: $Id$ |
5 | \*=========================================================================*/ | 6 | \*=========================================================================*/ |
7 | #include <stdio.h> | ||
6 | #include <string.h> | 8 | #include <string.h> |
7 | 9 | ||
8 | #include <lua.h> | 10 | #include <lua.h> |
@@ -16,7 +18,6 @@ | |||
16 | \*=========================================================================*/ | 18 | \*=========================================================================*/ |
17 | static int inet_global_toip(lua_State *L); | 19 | static int inet_global_toip(lua_State *L); |
18 | static int inet_global_tohostname(lua_State *L); | 20 | static int inet_global_tohostname(lua_State *L); |
19 | |||
20 | static void inet_pushresolved(lua_State *L, struct hostent *hp); | 21 | static void inet_pushresolved(lua_State *L, struct hostent *hp); |
21 | 22 | ||
22 | static luaL_reg func[] = { | 23 | static luaL_reg func[] = { |
@@ -43,11 +44,6 @@ void inet_open(lua_State *L) | |||
43 | /*-------------------------------------------------------------------------*\ | 44 | /*-------------------------------------------------------------------------*\ |
44 | * Returns all information provided by the resolver given a host name | 45 | * Returns all information provided by the resolver given a host name |
45 | * or ip address | 46 | * or ip address |
46 | * Lua Input: address | ||
47 | * address: ip address or hostname to dns lookup | ||
48 | * Lua Returns | ||
49 | * On success: first IP address followed by a resolved table | ||
50 | * On error: nil, followed by an error message | ||
51 | \*-------------------------------------------------------------------------*/ | 47 | \*-------------------------------------------------------------------------*/ |
52 | static int inet_global_toip(lua_State *L) | 48 | static int inet_global_toip(lua_State *L) |
53 | { | 49 | { |
@@ -72,11 +68,6 @@ static int inet_global_toip(lua_State *L) | |||
72 | /*-------------------------------------------------------------------------*\ | 68 | /*-------------------------------------------------------------------------*\ |
73 | * Returns all information provided by the resolver given a host name | 69 | * Returns all information provided by the resolver given a host name |
74 | * or ip address | 70 | * or ip address |
75 | * Lua Input: address | ||
76 | * address: ip address or host name to reverse dns lookup | ||
77 | * Lua Returns | ||
78 | * On success: canonic name followed by a resolved table | ||
79 | * On error: nil, followed by an error message | ||
80 | \*-------------------------------------------------------------------------*/ | 71 | \*-------------------------------------------------------------------------*/ |
81 | static int inet_global_tohostname(lua_State *L) | 72 | static int inet_global_tohostname(lua_State *L) |
82 | { | 73 | { |
@@ -102,11 +93,6 @@ static int inet_global_tohostname(lua_State *L) | |||
102 | \*=========================================================================*/ | 93 | \*=========================================================================*/ |
103 | /*-------------------------------------------------------------------------*\ | 94 | /*-------------------------------------------------------------------------*\ |
104 | * Retrieves socket peer name | 95 | * Retrieves socket peer name |
105 | * Input: | ||
106 | * sock: socket | ||
107 | * Lua Returns | ||
108 | * On success: ip address and port of peer | ||
109 | * On error: nil | ||
110 | \*-------------------------------------------------------------------------*/ | 96 | \*-------------------------------------------------------------------------*/ |
111 | int inet_meth_getpeername(lua_State *L, p_sock ps) | 97 | int inet_meth_getpeername(lua_State *L, p_sock ps) |
112 | { | 98 | { |
@@ -123,11 +109,6 @@ int inet_meth_getpeername(lua_State *L, p_sock ps) | |||
123 | 109 | ||
124 | /*-------------------------------------------------------------------------*\ | 110 | /*-------------------------------------------------------------------------*\ |
125 | * Retrieves socket local name | 111 | * Retrieves socket local name |
126 | * Input: | ||
127 | * sock: socket | ||
128 | * Lua Returns | ||
129 | * On success: local ip address and port | ||
130 | * On error: nil | ||
131 | \*-------------------------------------------------------------------------*/ | 112 | \*-------------------------------------------------------------------------*/ |
132 | int inet_meth_getsockname(lua_State *L, p_sock ps) | 113 | int inet_meth_getsockname(lua_State *L, p_sock ps) |
133 | { | 114 | { |
@@ -147,8 +128,6 @@ int inet_meth_getsockname(lua_State *L, p_sock ps) | |||
147 | \*=========================================================================*/ | 128 | \*=========================================================================*/ |
148 | /*-------------------------------------------------------------------------*\ | 129 | /*-------------------------------------------------------------------------*\ |
149 | * Passes all resolver information to Lua as a table | 130 | * Passes all resolver information to Lua as a table |
150 | * Input | ||
151 | * hp: hostent structure returned by resolver | ||
152 | \*-------------------------------------------------------------------------*/ | 131 | \*-------------------------------------------------------------------------*/ |
153 | static void inet_pushresolved(lua_State *L, struct hostent *hp) | 132 | static void inet_pushresolved(lua_State *L, struct hostent *hp) |
154 | { | 133 | { |
@@ -185,12 +164,6 @@ static void inet_pushresolved(lua_State *L, struct hostent *hp) | |||
185 | 164 | ||
186 | /*-------------------------------------------------------------------------*\ | 165 | /*-------------------------------------------------------------------------*\ |
187 | * Tries to connect to remote address (address, port) | 166 | * Tries to connect to remote address (address, port) |
188 | * Input | ||
189 | * ps: pointer to socket | ||
190 | * address: host name or ip address | ||
191 | * port: port number to bind to | ||
192 | * Returns | ||
193 | * NULL in case of success, error message otherwise | ||
194 | \*-------------------------------------------------------------------------*/ | 167 | \*-------------------------------------------------------------------------*/ |
195 | const char *inet_tryconnect(p_sock ps, const char *address, | 168 | const char *inet_tryconnect(p_sock ps, const char *address, |
196 | unsigned short port) | 169 | unsigned short port) |
@@ -224,12 +197,6 @@ const char *inet_tryconnect(p_sock ps, const char *address, | |||
224 | 197 | ||
225 | /*-------------------------------------------------------------------------*\ | 198 | /*-------------------------------------------------------------------------*\ |
226 | * Tries to bind socket to (address, port) | 199 | * Tries to bind socket to (address, port) |
227 | * Input | ||
228 | * sock: pointer to socket | ||
229 | * address: host name or ip address | ||
230 | * port: port number to bind to | ||
231 | * Returns | ||
232 | * NULL in case of success, error message otherwise | ||
233 | \*-------------------------------------------------------------------------*/ | 200 | \*-------------------------------------------------------------------------*/ |
234 | const char *inet_trybind(p_sock ps, const char *address, unsigned short port, | 201 | const char *inet_trybind(p_sock ps, const char *address, unsigned short port, |
235 | int backlog) | 202 | int backlog) |
@@ -264,10 +231,6 @@ const char *inet_trybind(p_sock ps, const char *address, unsigned short port, | |||
264 | 231 | ||
265 | /*-------------------------------------------------------------------------*\ | 232 | /*-------------------------------------------------------------------------*\ |
266 | * Tries to create a new inet socket | 233 | * Tries to create a new inet socket |
267 | * Input | ||
268 | * sock: pointer to socket | ||
269 | * Returns | ||
270 | * NULL if successfull, error message on error | ||
271 | \*-------------------------------------------------------------------------*/ | 234 | \*-------------------------------------------------------------------------*/ |
272 | const char *inet_trycreate(p_sock ps, int type) | 235 | const char *inet_trycreate(p_sock ps, int type) |
273 | { | 236 | { |
@@ -299,3 +262,5 @@ int inet_aton(const char *cp, struct in_addr *inp) | |||
299 | return 1; | 262 | return 1; |
300 | } | 263 | } |
301 | #endif | 264 | #endif |
265 | |||
266 | |||
@@ -1,25 +1,30 @@ | |||
1 | #ifndef INET_H | ||
2 | #define INET_H | ||
1 | /*=========================================================================*\ | 3 | /*=========================================================================*\ |
2 | * Internet domain functions | 4 | * Internet domain functions |
5 | * LuaSocket toolkit | ||
6 | * | ||
7 | * This module implements the creation and connection of internet domain | ||
8 | * sockets, on top of the socket.h interface, and the interface of with the | ||
9 | * resolver. | ||
10 | * | ||
11 | * The function inet_aton is provided for the platforms where it is not | ||
12 | * available. The module also implements the interface of the internet | ||
13 | * getpeername and getsockname functions as seen by Lua programs. | ||
14 | * | ||
15 | * The Lua functions toip and tohostname are also implemented here. | ||
3 | * | 16 | * |
4 | * RCS ID: $Id$ | 17 | * RCS ID: $Id$ |
5 | \*=========================================================================*/ | 18 | \*=========================================================================*/ |
6 | #ifndef INET_H | ||
7 | #define INET_H | ||
8 | |||
9 | #include <lua.h> | 19 | #include <lua.h> |
10 | #include "socket.h" | 20 | #include "socket.h" |
11 | 21 | ||
12 | /*-------------------------------------------------------------------------*\ | ||
13 | * Exported functions | ||
14 | \*-------------------------------------------------------------------------*/ | ||
15 | void inet_open(lua_State *L); | 22 | void inet_open(lua_State *L); |
16 | |||
17 | const char *inet_tryconnect(p_sock ps, const char *address, | 23 | const char *inet_tryconnect(p_sock ps, const char *address, |
18 | unsigned short port); | 24 | unsigned short port); |
19 | const char *inet_trybind(p_sock ps, const char *address, | 25 | const char *inet_trybind(p_sock ps, const char *address, |
20 | unsigned short port, int backlog); | 26 | unsigned short port, int backlog); |
21 | const char *inet_trycreate(p_sock ps, int type); | 27 | const char *inet_trycreate(p_sock ps, int type); |
22 | |||
23 | int inet_meth_getpeername(lua_State *L, p_sock ps); | 28 | int inet_meth_getpeername(lua_State *L, p_sock ps); |
24 | int inet_meth_getsockname(lua_State *L, p_sock ps); | 29 | int inet_meth_getsockname(lua_State *L, p_sock ps); |
25 | 30 | ||
@@ -27,4 +32,4 @@ int inet_meth_getsockname(lua_State *L, p_sock ps); | |||
27 | int inet_aton(const char *cp, struct in_addr *inp); | 32 | int inet_aton(const char *cp, struct in_addr *inp); |
28 | #endif | 33 | #endif |
29 | 34 | ||
30 | #endif /* INET_H_ */ | 35 | #endif /* INET_H */ |
@@ -1,8 +1,48 @@ | |||
1 | /*=========================================================================*\ | ||
2 | * Input/Output abstraction | ||
3 | * LuaSocket toolkit | ||
4 | * | ||
5 | * RCS ID: $Id$ | ||
6 | \*=========================================================================*/ | ||
1 | #include "io.h" | 7 | #include "io.h" |
2 | 8 | ||
9 | /*=========================================================================*\ | ||
10 | * Exported functions | ||
11 | \*=========================================================================*/ | ||
12 | /*-------------------------------------------------------------------------*\ | ||
13 | * Initializes C structure | ||
14 | \*-------------------------------------------------------------------------*/ | ||
3 | void io_init(p_io io, p_send send, p_recv recv, void *ctx) | 15 | void io_init(p_io io, p_send send, p_recv recv, void *ctx) |
4 | { | 16 | { |
5 | io->send = send; | 17 | io->send = send; |
6 | io->recv = recv; | 18 | io->recv = recv; |
7 | io->ctx = ctx; | 19 | io->ctx = ctx; |
8 | } | 20 | } |
21 | |||
22 | /*-------------------------------------------------------------------------*\ | ||
23 | * Translate error codes to Lua | ||
24 | \*-------------------------------------------------------------------------*/ | ||
25 | void io_pusherror(lua_State *L, int code) | ||
26 | { | ||
27 | switch (code) { | ||
28 | case IO_DONE: | ||
29 | lua_pushnil(L); | ||
30 | break; | ||
31 | case IO_TIMEOUT: | ||
32 | lua_pushstring(L, "timeout"); | ||
33 | break; | ||
34 | case IO_LIMITED: | ||
35 | lua_pushstring(L, "limited"); | ||
36 | break; | ||
37 | case IO_CLOSED: | ||
38 | lua_pushstring(L, "closed"); | ||
39 | break; | ||
40 | case IO_REFUSED: | ||
41 | lua_pushstring(L, "refused"); | ||
42 | break; | ||
43 | default: | ||
44 | lua_pushstring(L, "unknown error"); | ||
45 | break; | ||
46 | } | ||
47 | } | ||
48 | |||
@@ -1,16 +1,30 @@ | |||
1 | #ifndef IO_H | 1 | #ifndef IO_H |
2 | #define IO_H | 2 | #define IO_H |
3 | 3 | /*=========================================================================*\ | |
4 | * Input/Output abstraction | ||
5 | * LuaSocket toolkit | ||
6 | * | ||
7 | * This module defines the interface that LuaSocket expects from the | ||
8 | * transport layer for streamed input/output. The idea is that if any | ||
9 | * transport implements this interface, then the buffer.c functions | ||
10 | * automatically work on it. | ||
11 | * | ||
12 | * The module socket.h implements this interface, and thus the module tcp.h | ||
13 | * is very simple. | ||
14 | * | ||
15 | * RCS ID: $Id$ | ||
16 | \*=========================================================================*/ | ||
4 | #include <stdio.h> | 17 | #include <stdio.h> |
18 | #include <lua.h> | ||
5 | 19 | ||
6 | /* IO error codes */ | 20 | /* IO error codes */ |
7 | enum { | 21 | enum { |
8 | IO_DONE, /* operation completed successfully */ | 22 | IO_DONE, /* operation completed successfully */ |
9 | IO_TIMEOUT, /* operation timed out */ | 23 | IO_TIMEOUT, /* operation timed out */ |
10 | IO_CLOSED, /* the connection has been closed */ | 24 | IO_CLOSED, /* the connection has been closed */ |
11 | IO_ERROR, /* something wrong... */ | 25 | IO_ERROR, /* something wrong... */ |
12 | IO_REFUSED, /* transfer has been refused */ | 26 | IO_REFUSED, /* transfer has been refused */ |
13 | IO_LIMITED /* maximum number of bytes reached */ | 27 | IO_LIMITED /* maximum number of bytes reached */ |
14 | }; | 28 | }; |
15 | 29 | ||
16 | /* interface to send function */ | 30 | /* interface to send function */ |
@@ -39,6 +53,7 @@ typedef struct t_io_ { | |||
39 | } t_io; | 53 | } t_io; |
40 | typedef t_io *p_io; | 54 | typedef t_io *p_io; |
41 | 55 | ||
56 | void io_pusherror(lua_State *L, int code); | ||
42 | void io_init(p_io io, p_send send, p_recv recv, void *ctx); | 57 | void io_init(p_io io, p_send send, p_recv recv, void *ctx); |
43 | 58 | ||
44 | #endif /* IO_H */ | 59 | #endif /* IO_H */ |
diff --git a/src/luasocket.c b/src/luasocket.c index 5541d7f..96deac1 100644 --- a/src/luasocket.c +++ b/src/luasocket.c | |||
@@ -1,4 +1,5 @@ | |||
1 | /*=========================================================================*\ | 1 | /*=========================================================================*\ |
2 | * LuaSocket toolkit | ||
2 | * Networking support for the Lua language | 3 | * Networking support for the Lua language |
3 | * Diego Nehab | 4 | * Diego Nehab |
4 | * 26/11/1999 | 5 | * 26/11/1999 |
@@ -7,7 +8,7 @@ | |||
7 | * connectivity of the Lua language. The Lua interface to networking | 8 | * connectivity of the Lua language. The Lua interface to networking |
8 | * functions follows the Sockets API closely, trying to simplify all tasks | 9 | * functions follows the Sockets API closely, trying to simplify all tasks |
9 | * involved in setting up both client and server connections. The provided | 10 | * involved in setting up both client and server connections. The provided |
10 | * IO routines, however, follow the Lua style, being very similar to the | 11 | * IO routines, however, follow the Lua style, being very similar to the |
11 | * standard Lua read and write functions. | 12 | * standard Lua read and write functions. |
12 | * | 13 | * |
13 | * RCS ID: $Id$ | 14 | * RCS ID: $Id$ |
@@ -24,6 +25,7 @@ | |||
24 | \*=========================================================================*/ | 25 | \*=========================================================================*/ |
25 | #include "luasocket.h" | 26 | #include "luasocket.h" |
26 | 27 | ||
28 | #include "auxiliar.h" | ||
27 | #include "timeout.h" | 29 | #include "timeout.h" |
28 | #include "buffer.h" | 30 | #include "buffer.h" |
29 | #include "socket.h" | 31 | #include "socket.h" |
@@ -38,23 +40,11 @@ | |||
38 | /*-------------------------------------------------------------------------*\ | 40 | /*-------------------------------------------------------------------------*\ |
39 | * Initializes all library modules. | 41 | * Initializes all library modules. |
40 | \*-------------------------------------------------------------------------*/ | 42 | \*-------------------------------------------------------------------------*/ |
41 | LUASOCKET_API int luaopen_socketlib(lua_State *L) | 43 | LUASOCKET_API int luaopen_socket(lua_State *L) |
42 | { | 44 | { |
43 | if (!sock_open()) return 0; | 45 | if (!sock_open()) return 0; |
44 | /* create namespace table */ | ||
45 | lua_pushstring(L, LUASOCKET_LIBNAME); | ||
46 | lua_newtable(L); | ||
47 | #ifdef LUASOCKET_DEBUG | ||
48 | lua_pushstring(L, "debug"); | ||
49 | lua_pushnumber(L, 1); | ||
50 | lua_settable(L, -3); | ||
51 | #endif | ||
52 | lua_settable(L, LUA_GLOBALSINDEX); | ||
53 | /* make sure modules know what is our namespace */ | ||
54 | lua_pushstring(L, "LUASOCKET_LIBNAME"); | ||
55 | lua_pushstring(L, LUASOCKET_LIBNAME); | ||
56 | lua_settable(L, LUA_GLOBALSINDEX); | ||
57 | /* initialize all modules */ | 46 | /* initialize all modules */ |
47 | aux_open(L); | ||
58 | tm_open(L); | 48 | tm_open(L); |
59 | buf_open(L); | 49 | buf_open(L); |
60 | inet_open(L); | 50 | inet_open(L); |
diff --git a/src/luasocket.h b/src/luasocket.h index 6c25af2..7756605 100644 --- a/src/luasocket.h +++ b/src/luasocket.h | |||
@@ -1,17 +1,19 @@ | |||
1 | #ifndef LUASOCKET_H | ||
2 | #define LUASOCKET_H | ||
1 | /*=========================================================================*\ | 3 | /*=========================================================================*\ |
4 | * LuaSocket toolkit | ||
2 | * Networking support for the Lua language | 5 | * Networking support for the Lua language |
3 | * Diego Nehab | 6 | * Diego Nehab |
4 | * 9/11/1999 | 7 | * 9/11/1999 |
5 | * | 8 | * |
6 | * RCS ID: $Id$ | 9 | * RCS ID: $Id$ |
7 | \*=========================================================================*/ | 10 | \*=========================================================================*/ |
8 | #ifndef LUASOCKET_H | 11 | #include <lua.h> |
9 | #define LUASOCKET_H | ||
10 | 12 | ||
11 | /*-------------------------------------------------------------------------*\ | 13 | /*-------------------------------------------------------------------------*\ |
12 | * Current luasocket version | 14 | * Current luasocket version |
13 | \*-------------------------------------------------------------------------*/ | 15 | \*-------------------------------------------------------------------------*/ |
14 | #define LUASOCKET_VERSION "LuaSocket 1.5 (alpha)" | 16 | #define LUASOCKET_VERSION "LuaSocket 2.0 (alpha)" |
15 | 17 | ||
16 | /*-------------------------------------------------------------------------*\ | 18 | /*-------------------------------------------------------------------------*\ |
17 | * Library's namespace | 19 | * Library's namespace |
@@ -28,6 +30,6 @@ | |||
28 | /*-------------------------------------------------------------------------*\ | 30 | /*-------------------------------------------------------------------------*\ |
29 | * Initializes the library. | 31 | * Initializes the library. |
30 | \*-------------------------------------------------------------------------*/ | 32 | \*-------------------------------------------------------------------------*/ |
31 | LUASOCKET_API int luaopen_socketlib(lua_State *L); | 33 | LUASOCKET_API int luaopen_socket(lua_State *L); |
32 | 34 | ||
33 | #endif /* LUASOCKET_H */ | 35 | #endif /* LUASOCKET_H */ |
diff --git a/src/select.c b/src/select.c index 3cabbd1..9769667 100644 --- a/src/select.c +++ b/src/select.c | |||
@@ -1,5 +1,7 @@ | |||
1 | /*=========================================================================*\ | 1 | /*=========================================================================*\ |
2 | * Select implementation | 2 | * Select implementation |
3 | * LuaSocket toolkit | ||
4 | * | ||
3 | * RCS ID: $Id$ | 5 | * RCS ID: $Id$ |
4 | \*=========================================================================*/ | 6 | \*=========================================================================*/ |
5 | #include <string.h> | 7 | #include <string.h> |
@@ -12,6 +14,9 @@ | |||
12 | #include "auxiliar.h" | 14 | #include "auxiliar.h" |
13 | #include "select.h" | 15 | #include "select.h" |
14 | 16 | ||
17 | /*=========================================================================*\ | ||
18 | * Internal function prototypes. | ||
19 | \*=========================================================================*/ | ||
15 | static int meth_set(lua_State *L); | 20 | static int meth_set(lua_State *L); |
16 | static int meth_isset(lua_State *L); | 21 | static int meth_isset(lua_State *L); |
17 | static int c_select(lua_State *L); | 22 | static int c_select(lua_State *L); |
@@ -31,6 +36,12 @@ static luaL_reg func[] = { | |||
31 | {NULL, NULL} | 36 | {NULL, NULL} |
32 | }; | 37 | }; |
33 | 38 | ||
39 | /*=========================================================================*\ | ||
40 | * Internal function prototypes. | ||
41 | \*=========================================================================*/ | ||
42 | /*-------------------------------------------------------------------------*\ | ||
43 | * Initializes module | ||
44 | \*-------------------------------------------------------------------------*/ | ||
34 | void select_open(lua_State *L) | 45 | void select_open(lua_State *L) |
35 | { | 46 | { |
36 | /* get select auxiliar lua function from lua code and register | 47 | /* get select auxiliar lua function from lua code and register |
@@ -45,6 +56,9 @@ void select_open(lua_State *L) | |||
45 | aux_newclass(L, "select{fd_set}", set); | 56 | aux_newclass(L, "select{fd_set}", set); |
46 | } | 57 | } |
47 | 58 | ||
59 | /*=========================================================================*\ | ||
60 | * Global Lua functions | ||
61 | \*=========================================================================*/ | ||
48 | /*-------------------------------------------------------------------------*\ | 62 | /*-------------------------------------------------------------------------*\ |
49 | * Waits for a set of sockets until a condition is met or timeout. | 63 | * Waits for a set of sockets until a condition is met or timeout. |
50 | \*-------------------------------------------------------------------------*/ | 64 | \*-------------------------------------------------------------------------*/ |
@@ -63,10 +77,10 @@ static int global_select(lua_State *L) | |||
63 | lua_pushvalue(L, lua_upvalueindex(1)); | 77 | lua_pushvalue(L, lua_upvalueindex(1)); |
64 | lua_insert(L, 1); | 78 | lua_insert(L, 1); |
65 | /* pass fd_set objects */ | 79 | /* pass fd_set objects */ |
66 | read_fd_set = lua_newuserdata(L, sizeof(fd_set)); | 80 | read_fd_set = (fd_set *) lua_newuserdata(L, sizeof(fd_set)); |
67 | FD_ZERO(read_fd_set); | 81 | FD_ZERO(read_fd_set); |
68 | aux_setclass(L, "select{fd_set}", -1); | 82 | aux_setclass(L, "select{fd_set}", -1); |
69 | write_fd_set = lua_newuserdata(L, sizeof(fd_set)); | 83 | write_fd_set = (fd_set *) lua_newuserdata(L, sizeof(fd_set)); |
70 | FD_ZERO(write_fd_set); | 84 | FD_ZERO(write_fd_set); |
71 | aux_setclass(L, "select{fd_set}", -1); | 85 | aux_setclass(L, "select{fd_set}", -1); |
72 | /* pass select auxiliar C function */ | 86 | /* pass select auxiliar C function */ |
@@ -76,20 +90,9 @@ static int global_select(lua_State *L) | |||
76 | return 3; | 90 | return 3; |
77 | } | 91 | } |
78 | 92 | ||
79 | static int c_select(lua_State *L) | 93 | /*=========================================================================*\ |
80 | { | 94 | * Lua methods |
81 | int max_fd = (int) lua_tonumber(L, 1); | 95 | \*=========================================================================*/ |
82 | fd_set *read_fd_set = (fd_set *) aux_checkclass(L, "select{fd_set}", 2); | ||
83 | fd_set *write_fd_set = (fd_set *) aux_checkclass(L, "select{fd_set}", 3); | ||
84 | int timeout = lua_isnil(L, 4) ? -1 : (int)(lua_tonumber(L, 4) * 1000); | ||
85 | struct timeval tv; | ||
86 | tv.tv_sec = timeout / 1000; | ||
87 | tv.tv_usec = (timeout % 1000) * 1000; | ||
88 | lua_pushnumber(L, select(max_fd, read_fd_set, write_fd_set, NULL, | ||
89 | timeout < 0 ? NULL : &tv)); | ||
90 | return 1; | ||
91 | } | ||
92 | |||
93 | static int meth_set(lua_State *L) | 96 | static int meth_set(lua_State *L) |
94 | { | 97 | { |
95 | fd_set *set = (fd_set *) aux_checkclass(L, "select{fd_set}", 1); | 98 | fd_set *set = (fd_set *) aux_checkclass(L, "select{fd_set}", 1); |
@@ -107,6 +110,23 @@ static int meth_isset(lua_State *L) | |||
107 | return 1; | 110 | return 1; |
108 | } | 111 | } |
109 | 112 | ||
113 | /*=========================================================================*\ | ||
114 | * Internal functions | ||
115 | \*=========================================================================*/ | ||
116 | static int c_select(lua_State *L) | ||
117 | { | ||
118 | int max_fd = (int) lua_tonumber(L, 1); | ||
119 | fd_set *read_fd_set = (fd_set *) aux_checkclass(L, "select{fd_set}", 2); | ||
120 | fd_set *write_fd_set = (fd_set *) aux_checkclass(L, "select{fd_set}", 3); | ||
121 | int timeout = lua_isnil(L, 4) ? -1 : (int)(lua_tonumber(L, 4) * 1000); | ||
122 | struct timeval tv; | ||
123 | tv.tv_sec = timeout / 1000; | ||
124 | tv.tv_usec = (timeout % 1000) * 1000; | ||
125 | lua_pushnumber(L, select(max_fd, read_fd_set, write_fd_set, NULL, | ||
126 | timeout < 0 ? NULL : &tv)); | ||
127 | return 1; | ||
128 | } | ||
129 | |||
110 | static void check_obj_tab(lua_State *L, int tabidx) | 130 | static void check_obj_tab(lua_State *L, int tabidx) |
111 | { | 131 | { |
112 | if (tabidx < 0) tabidx = lua_gettop(L) + tabidx + 1; | 132 | if (tabidx < 0) tabidx = lua_gettop(L) + tabidx + 1; |
diff --git a/src/select.h b/src/select.h index 9521fae..0e1eeb4 100644 --- a/src/select.h +++ b/src/select.h | |||
@@ -1,9 +1,19 @@ | |||
1 | #ifndef SELECT_H | ||
2 | #define SELECT_H | ||
1 | /*=========================================================================*\ | 3 | /*=========================================================================*\ |
2 | * Select implementation | 4 | * Select implementation |
5 | * LuaSocket toolkit | ||
6 | * | ||
7 | * To make the code as simple as possible, the select function is | ||
8 | * implemented int Lua, with a few helper functions written in C. | ||
9 | * | ||
10 | * Each object that can be passed to the select function has to be in the | ||
11 | * group select{able} and export two methods: fd() and dirty(). Fd returns | ||
12 | * the descriptor to be passed to the select function. Dirty() should return | ||
13 | * true if there is data ready for reading (required for buffered input). | ||
14 | * | ||
3 | * RCS ID: $Id$ | 15 | * RCS ID: $Id$ |
4 | \*=========================================================================*/ | 16 | \*=========================================================================*/ |
5 | #ifndef SELECT_H | ||
6 | #define SELECT_H | ||
7 | 17 | ||
8 | void select_open(lua_State *L); | 18 | void select_open(lua_State *L); |
9 | 19 | ||
diff --git a/src/smtp.lua b/src/smtp.lua index 604f79b..209825b 100644 --- a/src/smtp.lua +++ b/src/smtp.lua | |||
@@ -1,6 +1,6 @@ | |||
1 | ----------------------------------------------------------------------------- | 1 | ----------------------------------------------------------------------------- |
2 | -- SMTP support for the Lua language. | 2 | -- SMTP support for the Lua language. |
3 | -- LuaSocket 1.5 toolkit | 3 | -- LuaSocket toolkit |
4 | -- Author: Diego Nehab | 4 | -- Author: Diego Nehab |
5 | -- Conforming to: RFC 821, LTN7 | 5 | -- Conforming to: RFC 821, LTN7 |
6 | -- RCS ID: $Id$ | 6 | -- RCS ID: $Id$ |
diff --git a/src/socket.h b/src/socket.h index 70ebc52..c7db5f2 100644 --- a/src/socket.h +++ b/src/socket.h | |||
@@ -1,11 +1,16 @@ | |||
1 | #ifndef SOCK_H | ||
2 | #define SOCK_H | ||
1 | /*=========================================================================*\ | 3 | /*=========================================================================*\ |
2 | * Socket compatibilization module | 4 | * Socket compatibilization module |
5 | * LuaSocket toolkit | ||
6 | * | ||
7 | * BSD Sockets and WinSock are similar, but there are a few irritating | ||
8 | * differences. Also, not all *nix platforms behave the same. This module | ||
9 | * (and the associated usocket.h and wsocket.h) factor these differences and | ||
10 | * creates a interface compatible with the io.h module. | ||
3 | * | 11 | * |
4 | * RCS ID: $Id$ | 12 | * RCS ID: $Id$ |
5 | \*=========================================================================*/ | 13 | \*=========================================================================*/ |
6 | #ifndef SOCK_H | ||
7 | #define SOCK_H | ||
8 | |||
9 | #include "io.h" | 14 | #include "io.h" |
10 | 15 | ||
11 | /*=========================================================================*\ | 16 | /*=========================================================================*\ |
@@ -32,7 +37,6 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, | |||
32 | const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len); | 37 | 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); | 38 | const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len); |
34 | void sock_listen(p_sock ps, int backlog); | 39 | void sock_listen(p_sock ps, int backlog); |
35 | |||
36 | int sock_send(p_sock ps, const char *data, size_t count, | 40 | int sock_send(p_sock ps, const char *data, size_t count, |
37 | size_t *sent, int timeout); | 41 | size_t *sent, int timeout); |
38 | int sock_recv(p_sock ps, char *data, size_t count, | 42 | int sock_recv(p_sock ps, char *data, size_t count, |
@@ -41,11 +45,8 @@ int sock_sendto(p_sock ps, const char *data, size_t count, | |||
41 | size_t *sent, SA *addr, socklen_t addr_len, int timeout); | 45 | size_t *sent, SA *addr, socklen_t addr_len, int timeout); |
42 | int sock_recvfrom(p_sock ps, char *data, size_t count, | 46 | int sock_recvfrom(p_sock ps, char *data, size_t count, |
43 | size_t *got, SA *addr, socklen_t *addr_len, int timeout); | 47 | size_t *got, SA *addr, socklen_t *addr_len, int timeout); |
44 | |||
45 | void sock_setnonblocking(p_sock ps); | 48 | void sock_setnonblocking(p_sock ps); |
46 | void sock_setblocking(p_sock ps); | 49 | void sock_setblocking(p_sock ps); |
47 | void sock_setreuseaddr(p_sock ps); | ||
48 | |||
49 | const char *sock_hoststrerror(void); | 50 | const char *sock_hoststrerror(void); |
50 | const char *sock_createstrerror(void); | 51 | const char *sock_createstrerror(void); |
51 | const char *sock_bindstrerror(void); | 52 | const char *sock_bindstrerror(void); |
@@ -1,5 +1,6 @@ | |||
1 | /*=========================================================================*\ | 1 | /*=========================================================================*\ |
2 | * TCP object | 2 | * TCP object |
3 | * LuaSocket toolkit | ||
3 | * | 4 | * |
4 | * RCS ID: $Id$ | 5 | * RCS ID: $Id$ |
5 | \*=========================================================================*/ | 6 | \*=========================================================================*/ |
@@ -13,7 +14,6 @@ | |||
13 | #include "auxiliar.h" | 14 | #include "auxiliar.h" |
14 | #include "socket.h" | 15 | #include "socket.h" |
15 | #include "inet.h" | 16 | #include "inet.h" |
16 | #include "error.h" | ||
17 | #include "tcp.h" | 17 | #include "tcp.h" |
18 | 18 | ||
19 | /*=========================================================================*\ | 19 | /*=========================================================================*\ |
@@ -28,9 +28,13 @@ static int meth_getpeername(lua_State *L); | |||
28 | static int meth_receive(lua_State *L); | 28 | static int meth_receive(lua_State *L); |
29 | static int meth_accept(lua_State *L); | 29 | static int meth_accept(lua_State *L); |
30 | static int meth_close(lua_State *L); | 30 | static int meth_close(lua_State *L); |
31 | static int meth_setoption(lua_State *L); | ||
31 | static int meth_timeout(lua_State *L); | 32 | static int meth_timeout(lua_State *L); |
32 | static int meth_fd(lua_State *L); | 33 | static int meth_fd(lua_State *L); |
33 | static int meth_dirty(lua_State *L); | 34 | static int meth_dirty(lua_State *L); |
35 | static int opt_nodelay(lua_State *L); | ||
36 | static int opt_keepalive(lua_State *L); | ||
37 | static int opt_linger(lua_State *L); | ||
34 | 38 | ||
35 | /* tcp object methods */ | 39 | /* tcp object methods */ |
36 | static luaL_reg tcp[] = { | 40 | static luaL_reg tcp[] = { |
@@ -45,11 +49,21 @@ static luaL_reg tcp[] = { | |||
45 | {"getsockname", meth_getsockname}, | 49 | {"getsockname", meth_getsockname}, |
46 | {"timeout", meth_timeout}, | 50 | {"timeout", meth_timeout}, |
47 | {"close", meth_close}, | 51 | {"close", meth_close}, |
52 | {"setoption", meth_setoption}, | ||
53 | {"__gc", meth_close}, | ||
48 | {"fd", meth_fd}, | 54 | {"fd", meth_fd}, |
49 | {"dirty", meth_dirty}, | 55 | {"dirty", meth_dirty}, |
50 | {NULL, NULL} | 56 | {NULL, NULL} |
51 | }; | 57 | }; |
52 | 58 | ||
59 | /* socket option handlers */ | ||
60 | static luaL_reg opt[] = { | ||
61 | {"keepalive", opt_keepalive}, | ||
62 | {"nodelay", opt_nodelay}, | ||
63 | {"linger", opt_linger}, | ||
64 | {NULL, NULL} | ||
65 | }; | ||
66 | |||
53 | /* functions in library namespace */ | 67 | /* functions in library namespace */ |
54 | static luaL_reg func[] = { | 68 | static luaL_reg func[] = { |
55 | {"tcp", global_create}, | 69 | {"tcp", global_create}, |
@@ -71,6 +85,7 @@ void tcp_open(lua_State *L) | |||
71 | aux_add2group(L, "tcp{server}", "tcp{any}"); | 85 | aux_add2group(L, "tcp{server}", "tcp{any}"); |
72 | aux_add2group(L, "tcp{client}", "tcp{client, server}"); | 86 | aux_add2group(L, "tcp{client}", "tcp{client, server}"); |
73 | aux_add2group(L, "tcp{server}", "tcp{client, server}"); | 87 | aux_add2group(L, "tcp{server}", "tcp{client, server}"); |
88 | /* both server and client objects are selectable */ | ||
74 | aux_add2group(L, "tcp{client}", "select{able}"); | 89 | aux_add2group(L, "tcp{client}", "select{able}"); |
75 | aux_add2group(L, "tcp{server}", "select{able}"); | 90 | aux_add2group(L, "tcp{server}", "select{able}"); |
76 | /* define library functions */ | 91 | /* define library functions */ |
@@ -97,18 +112,80 @@ static int meth_receive(lua_State *L) | |||
97 | } | 112 | } |
98 | 113 | ||
99 | /*-------------------------------------------------------------------------*\ | 114 | /*-------------------------------------------------------------------------*\ |
115 | * Option handlers | ||
116 | \*-------------------------------------------------------------------------*/ | ||
117 | static int meth_setoption(lua_State *L) | ||
118 | { | ||
119 | return aux_meth_setoption(L, opt); | ||
120 | } | ||
121 | |||
122 | static int opt_boolean(lua_State *L, int level, int name) | ||
123 | { | ||
124 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); | ||
125 | int val = aux_checkboolean(L, 2); | ||
126 | if (setsockopt(tcp->sock, level, name, (char *) &val, sizeof(val)) < 0) { | ||
127 | lua_pushnil(L); | ||
128 | lua_pushstring(L, "setsockopt failed"); | ||
129 | return 2; | ||
130 | } | ||
131 | lua_pushnumber(L, 1); | ||
132 | return 1; | ||
133 | } | ||
134 | |||
135 | /* disables the Nagle algorithm */ | ||
136 | static int opt_nodelay(lua_State *L) | ||
137 | { | ||
138 | struct protoent *pe = getprotobyname("TCP"); | ||
139 | if (!pe) { | ||
140 | lua_pushnil(L); | ||
141 | lua_pushstring(L, "getprotobyname"); | ||
142 | return 2; | ||
143 | } | ||
144 | return opt_boolean(L, pe->p_proto, TCP_NODELAY); | ||
145 | } | ||
146 | |||
147 | static int opt_keepalive(lua_State *L) | ||
148 | { | ||
149 | return opt_boolean(L, SOL_SOCKET, SO_KEEPALIVE); | ||
150 | } | ||
151 | |||
152 | int opt_linger(lua_State *L) | ||
153 | { | ||
154 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1); | ||
155 | struct linger li; | ||
156 | if (!lua_istable(L, 2)) | ||
157 | luaL_typerror(L, 2, lua_typename(L, LUA_TTABLE)); | ||
158 | lua_pushstring(L, "onoff"); | ||
159 | lua_gettable(L, 2); | ||
160 | if (!lua_isnumber(L, -1)) luaL_argerror(L, 2, "invalid onoff field"); | ||
161 | li.l_onoff = (int) lua_tonumber(L, -1); | ||
162 | lua_pushstring(L, "linger"); | ||
163 | lua_gettable(L, 2); | ||
164 | if (!lua_isnumber(L, -1)) luaL_argerror(L, 2, "invalid linger field"); | ||
165 | li.l_linger = (int) lua_tonumber(L, -1); | ||
166 | if (setsockopt(tcp->sock, SOL_SOCKET, SO_LINGER, | ||
167 | (char *) &li, sizeof(li) < 0)) { | ||
168 | lua_pushnil(L); | ||
169 | lua_pushstring(L, "setsockopt failed"); | ||
170 | return 2; | ||
171 | } | ||
172 | lua_pushnumber(L, 1); | ||
173 | return 1; | ||
174 | } | ||
175 | |||
176 | /*-------------------------------------------------------------------------*\ | ||
100 | * Select support methods | 177 | * Select support methods |
101 | \*-------------------------------------------------------------------------*/ | 178 | \*-------------------------------------------------------------------------*/ |
102 | static int meth_fd(lua_State *L) | 179 | static int meth_fd(lua_State *L) |
103 | { | 180 | { |
104 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client, server}", 1); | 181 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client, server}", 1); |
105 | lua_pushnumber(L, tcp->sock); | 182 | lua_pushnumber(L, tcp->sock); |
106 | return 1; | 183 | return 1; |
107 | } | 184 | } |
108 | 185 | ||
109 | static int meth_dirty(lua_State *L) | 186 | static int meth_dirty(lua_State *L) |
110 | { | 187 | { |
111 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client, server}", 1); | 188 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client, server}", 1); |
112 | lua_pushboolean(L, !buf_isempty(&tcp->buf)); | 189 | lua_pushboolean(L, !buf_isempty(&tcp->buf)); |
113 | return 1; | 190 | return 1; |
114 | } | 191 | } |
@@ -207,7 +284,7 @@ static int meth_accept(lua_State *L) | |||
207 | if (client->sock == SOCK_INVALID) { | 284 | if (client->sock == SOCK_INVALID) { |
208 | if (tm_get(tm) == 0) { | 285 | if (tm_get(tm) == 0) { |
209 | lua_pushnil(L); | 286 | lua_pushnil(L); |
210 | error_push(L, IO_TIMEOUT); | 287 | io_pusherror(L, IO_TIMEOUT); |
211 | return 2; | 288 | return 2; |
212 | } | 289 | } |
213 | } else break; | 290 | } else break; |
@@ -1,6 +1,21 @@ | |||
1 | #ifndef TCP_H | 1 | #ifndef TCP_H |
2 | #define TCP_H | 2 | #define TCP_H |
3 | 3 | /*=========================================================================*\ | |
4 | * TCP object | ||
5 | * LuaSocket toolkit | ||
6 | * | ||
7 | * The tcp.h module is basicly a glue that puts together modules buffer.h, | ||
8 | * timeout.h socket.h and inet.h to provide the LuaSocket TCP (AF_INET, | ||
9 | * SOCK_STREAM) support. | ||
10 | * | ||
11 | * Three classes are defined: master, client and server. The master class is | ||
12 | * a newly created tcp object, that has not been bound or connected. Server | ||
13 | * objects are tcp objects bound to some local address. Client objects are | ||
14 | * tcp objects either connected to some address or returned by the accept | ||
15 | * method of a server object. | ||
16 | * | ||
17 | * RCS ID: $Id$ | ||
18 | \*=========================================================================*/ | ||
4 | #include <lua.h> | 19 | #include <lua.h> |
5 | 20 | ||
6 | #include "buffer.h" | 21 | #include "buffer.h" |
@@ -17,4 +32,4 @@ typedef t_tcp *p_tcp; | |||
17 | 32 | ||
18 | void tcp_open(lua_State *L); | 33 | void tcp_open(lua_State *L); |
19 | 34 | ||
20 | #endif | 35 | #endif /* TCP_H */ |
diff --git a/src/timeout.c b/src/timeout.c index 1553069..6a30e3a 100644 --- a/src/timeout.c +++ b/src/timeout.c | |||
@@ -1,8 +1,6 @@ | |||
1 | /*=========================================================================*\ | 1 | /*=========================================================================*\ |
2 | * Timeout management functions | 2 | * Timeout management functions |
3 | * Global Lua functions: | 3 | * LuaSocket toolkit |
4 | * _sleep | ||
5 | * _time | ||
6 | * | 4 | * |
7 | * RCS ID: $Id$ | 5 | * RCS ID: $Id$ |
8 | \*=========================================================================*/ | 6 | \*=========================================================================*/ |
diff --git a/src/timeout.h b/src/timeout.h index 43476cb..32eb836 100644 --- a/src/timeout.h +++ b/src/timeout.h | |||
@@ -1,11 +1,11 @@ | |||
1 | #ifndef TM_H | ||
2 | #define TM_H | ||
1 | /*=========================================================================*\ | 3 | /*=========================================================================*\ |
2 | * Timeout management functions | 4 | * Timeout management functions |
5 | * LuaSocket toolkit | ||
3 | * | 6 | * |
4 | * RCS ID: $Id$ | 7 | * RCS ID: $Id$ |
5 | \*=========================================================================*/ | 8 | \*=========================================================================*/ |
6 | #ifndef TM_H | ||
7 | #define TM_H | ||
8 | |||
9 | #include <lua.h> | 9 | #include <lua.h> |
10 | 10 | ||
11 | /* timeout control structure */ | 11 | /* timeout control structure */ |
@@ -28,4 +28,4 @@ int tm_get(p_tm tm); | |||
28 | int tm_gettime(void); | 28 | int tm_gettime(void); |
29 | int tm_meth_timeout(lua_State *L, p_tm tm); | 29 | int tm_meth_timeout(lua_State *L, p_tm tm); |
30 | 30 | ||
31 | #endif | 31 | #endif /* TM_H */ |
@@ -1,5 +1,6 @@ | |||
1 | /*=========================================================================*\ | 1 | /*=========================================================================*\ |
2 | * UDP object | 2 | * UDP object |
3 | * LuaSocket toolkit | ||
3 | * | 4 | * |
4 | * RCS ID: $Id$ | 5 | * RCS ID: $Id$ |
5 | \*=========================================================================*/ | 6 | \*=========================================================================*/ |
@@ -13,7 +14,6 @@ | |||
13 | #include "auxiliar.h" | 14 | #include "auxiliar.h" |
14 | #include "socket.h" | 15 | #include "socket.h" |
15 | #include "inet.h" | 16 | #include "inet.h" |
16 | #include "error.h" | ||
17 | #include "udp.h" | 17 | #include "udp.h" |
18 | 18 | ||
19 | /*=========================================================================*\ | 19 | /*=========================================================================*\ |
@@ -29,9 +29,12 @@ static int meth_getpeername(lua_State *L); | |||
29 | static int meth_setsockname(lua_State *L); | 29 | static int meth_setsockname(lua_State *L); |
30 | static int meth_setpeername(lua_State *L); | 30 | static int meth_setpeername(lua_State *L); |
31 | static int meth_close(lua_State *L); | 31 | static int meth_close(lua_State *L); |
32 | static int meth_setoption(lua_State *L); | ||
32 | static int meth_timeout(lua_State *L); | 33 | static int meth_timeout(lua_State *L); |
33 | static int meth_fd(lua_State *L); | 34 | static int meth_fd(lua_State *L); |
34 | static int meth_dirty(lua_State *L); | 35 | static int meth_dirty(lua_State *L); |
36 | static int opt_dontroute(lua_State *L); | ||
37 | static int opt_broadcast(lua_State *L); | ||
35 | 38 | ||
36 | /* udp object methods */ | 39 | /* udp object methods */ |
37 | static luaL_reg udp[] = { | 40 | static luaL_reg udp[] = { |
@@ -45,11 +48,20 @@ static luaL_reg udp[] = { | |||
45 | {"receivefrom", meth_receivefrom}, | 48 | {"receivefrom", meth_receivefrom}, |
46 | {"timeout", meth_timeout}, | 49 | {"timeout", meth_timeout}, |
47 | {"close", meth_close}, | 50 | {"close", meth_close}, |
51 | {"setoption", meth_setoption}, | ||
52 | {"__gc", meth_close}, | ||
48 | {"fd", meth_fd}, | 53 | {"fd", meth_fd}, |
49 | {"dirty", meth_dirty}, | 54 | {"dirty", meth_dirty}, |
50 | {NULL, NULL} | 55 | {NULL, NULL} |
51 | }; | 56 | }; |
52 | 57 | ||
58 | /* socket options */ | ||
59 | static luaL_reg opt[] = { | ||
60 | {"dontroute", opt_dontroute}, | ||
61 | {"broadcast", opt_broadcast}, | ||
62 | {NULL, NULL} | ||
63 | }; | ||
64 | |||
53 | /* functions in library namespace */ | 65 | /* functions in library namespace */ |
54 | static luaL_reg func[] = { | 66 | static luaL_reg func[] = { |
55 | {"udp", global_create}, | 67 | {"udp", global_create}, |
@@ -91,7 +103,9 @@ static int meth_send(lua_State *L) | |||
91 | err = sock_send(&udp->sock, data, count, &sent, tm_get(tm)); | 103 | err = sock_send(&udp->sock, data, count, &sent, tm_get(tm)); |
92 | if (err == IO_DONE) lua_pushnumber(L, sent); | 104 | if (err == IO_DONE) lua_pushnumber(L, sent); |
93 | else lua_pushnil(L); | 105 | else lua_pushnil(L); |
94 | error_push(L, err); | 106 | /* a 'closed' error on an unconnected means the target address was not |
107 | * accepted by the transport layer */ | ||
108 | io_pusherror(L, err == IO_CLOSED ? IO_REFUSED : err); | ||
95 | return 2; | 109 | return 2; |
96 | } | 110 | } |
97 | 111 | ||
@@ -118,7 +132,9 @@ static int meth_sendto(lua_State *L) | |||
118 | (SA *) &addr, sizeof(addr), tm_get(tm)); | 132 | (SA *) &addr, sizeof(addr), tm_get(tm)); |
119 | if (err == IO_DONE) lua_pushnumber(L, sent); | 133 | if (err == IO_DONE) lua_pushnumber(L, sent); |
120 | else lua_pushnil(L); | 134 | else lua_pushnil(L); |
121 | error_push(L, err == IO_CLOSED ? IO_REFUSED : err); | 135 | /* a 'closed' error on an unconnected means the target address was not |
136 | * accepted by the transport layer */ | ||
137 | io_pusherror(L, err == IO_CLOSED ? IO_REFUSED : err); | ||
122 | return 2; | 138 | return 2; |
123 | } | 139 | } |
124 | 140 | ||
@@ -137,7 +153,7 @@ static int meth_receive(lua_State *L) | |||
137 | err = sock_recv(&udp->sock, buffer, count, &got, tm_get(tm)); | 153 | err = sock_recv(&udp->sock, buffer, count, &got, tm_get(tm)); |
138 | if (err == IO_DONE) lua_pushlstring(L, buffer, got); | 154 | if (err == IO_DONE) lua_pushlstring(L, buffer, got); |
139 | else lua_pushnil(L); | 155 | else lua_pushnil(L); |
140 | error_push(L, err); | 156 | io_pusherror(L, err); |
141 | return 2; | 157 | return 2; |
142 | } | 158 | } |
143 | 159 | ||
@@ -164,7 +180,7 @@ static int meth_receivefrom(lua_State *L) | |||
164 | return 3; | 180 | return 3; |
165 | } else { | 181 | } else { |
166 | lua_pushnil(L); | 182 | lua_pushnil(L); |
167 | error_push(L, err); | 183 | io_pusherror(L, err); |
168 | return 2; | 184 | return 2; |
169 | } | 185 | } |
170 | } | 186 | } |
@@ -174,14 +190,14 @@ static int meth_receivefrom(lua_State *L) | |||
174 | \*-------------------------------------------------------------------------*/ | 190 | \*-------------------------------------------------------------------------*/ |
175 | static int meth_fd(lua_State *L) | 191 | static int meth_fd(lua_State *L) |
176 | { | 192 | { |
177 | p_udp udp = (p_udp) aux_checkclass(L, "udp{any}", 1); | 193 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
178 | lua_pushnumber(L, udp->sock); | 194 | lua_pushnumber(L, udp->sock); |
179 | return 1; | 195 | return 1; |
180 | } | 196 | } |
181 | 197 | ||
182 | static int meth_dirty(lua_State *L) | 198 | static int meth_dirty(lua_State *L) |
183 | { | 199 | { |
184 | p_udp udp = (p_udp) aux_checkclass(L, "udp{any}", 1); | 200 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
185 | (void) udp; | 201 | (void) udp; |
186 | lua_pushboolean(L, 0); | 202 | lua_pushboolean(L, 0); |
187 | return 1; | 203 | return 1; |
@@ -203,6 +219,37 @@ static int meth_getsockname(lua_State *L) | |||
203 | } | 219 | } |
204 | 220 | ||
205 | /*-------------------------------------------------------------------------*\ | 221 | /*-------------------------------------------------------------------------*\ |
222 | * Option handlers | ||
223 | \*-------------------------------------------------------------------------*/ | ||
224 | static int meth_setoption(lua_State *L) | ||
225 | { | ||
226 | return aux_meth_setoption(L, opt); | ||
227 | } | ||
228 | |||
229 | static int opt_boolean(lua_State *L, int level, int name) | ||
230 | { | ||
231 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | ||
232 | int val = aux_checkboolean(L, 2); | ||
233 | if (setsockopt(udp->sock, level, name, (char *) &val, sizeof(val)) < 0) { | ||
234 | lua_pushnil(L); | ||
235 | lua_pushstring(L, "setsockopt failed"); | ||
236 | return 2; | ||
237 | } | ||
238 | lua_pushnumber(L, 1); | ||
239 | return 1; | ||
240 | } | ||
241 | |||
242 | static int opt_dontroute(lua_State *L) | ||
243 | { | ||
244 | return opt_boolean(L, SOL_SOCKET, SO_DONTROUTE); | ||
245 | } | ||
246 | |||
247 | static int opt_broadcast(lua_State *L) | ||
248 | { | ||
249 | return opt_boolean(L, SOL_SOCKET, SO_BROADCAST); | ||
250 | } | ||
251 | |||
252 | /*-------------------------------------------------------------------------*\ | ||
206 | * Just call tm methods | 253 | * Just call tm methods |
207 | \*-------------------------------------------------------------------------*/ | 254 | \*-------------------------------------------------------------------------*/ |
208 | static int meth_timeout(lua_State *L) | 255 | static int meth_timeout(lua_State *L) |
@@ -1,6 +1,19 @@ | |||
1 | #ifndef UDP_H | 1 | #ifndef UDP_H |
2 | #define UDP_H | 2 | #define UDP_H |
3 | 3 | /*=========================================================================*\ | |
4 | * UDP object | ||
5 | * LuaSocket toolkit | ||
6 | * | ||
7 | * The udp.h module provides LuaSocket with support for UDP protocol | ||
8 | * (AF_INET, SOCK_DGRAM). | ||
9 | * | ||
10 | * Two classes are defined: connected and unconnected. UDP objects are | ||
11 | * originally unconnected. They can be "connected" to a given address | ||
12 | * with a call to the setpeername function. The same function can be used to | ||
13 | * break the connection. | ||
14 | * | ||
15 | * RCS ID: $Id$ | ||
16 | \*=========================================================================*/ | ||
4 | #include <lua.h> | 17 | #include <lua.h> |
5 | 18 | ||
6 | #include "timeout.h" | 19 | #include "timeout.h" |
@@ -16,4 +29,4 @@ typedef t_udp *p_udp; | |||
16 | 29 | ||
17 | void udp_open(lua_State *L); | 30 | void udp_open(lua_State *L); |
18 | 31 | ||
19 | #endif | 32 | #endif /* UDP_H */ |
diff --git a/src/url.lua b/src/url.lua index 06de9d3..65da57a 100644 --- a/src/url.lua +++ b/src/url.lua | |||
@@ -1,6 +1,6 @@ | |||
1 | ----------------------------------------------------------------------------- | 1 | ----------------------------------------------------------------------------- |
2 | -- URI parsing, composition and relative URL resolution | 2 | -- URI parsing, composition and relative URL resolution |
3 | -- LuaSocket 1.5 toolkit. | 3 | -- LuaSocket toolkit. |
4 | -- Author: Diego Nehab | 4 | -- Author: Diego Nehab |
5 | -- Conforming to: RFC 2396, LTN7 | 5 | -- Conforming to: RFC 2396, LTN7 |
6 | -- RCS ID: $Id$ | 6 | -- RCS ID: $Id$ |
diff --git a/src/usocket.c b/src/usocket.c index 062a0ff..cdd550c 100644 --- a/src/usocket.c +++ b/src/usocket.c | |||
@@ -1,49 +1,78 @@ | |||
1 | /*=========================================================================*\ | ||
2 | * Socket compatibilization module for Unix | ||
3 | * LuaSocket toolkit | ||
4 | * | ||
5 | * RCS ID: $Id$ | ||
6 | \*=========================================================================*/ | ||
1 | #include <string.h> | 7 | #include <string.h> |
2 | 8 | ||
3 | #include "socket.h" | 9 | #include "socket.h" |
4 | 10 | ||
11 | /*-------------------------------------------------------------------------*\ | ||
12 | * Initializes module | ||
13 | \*-------------------------------------------------------------------------*/ | ||
5 | int sock_open(void) | 14 | int sock_open(void) |
6 | { | 15 | { |
7 | /* instals a handler to ignore sigpipe. */ | 16 | /* instals a handler to ignore sigpipe or it will crash us */ |
8 | struct sigaction new; | 17 | struct sigaction ignore; |
9 | memset(&new, 0, sizeof(new)); | 18 | memset(&ignore, 0, sizeof(ignore)); |
10 | new.sa_handler = SIG_IGN; | 19 | ignore.sa_handler = SIG_IGN; |
11 | sigaction(SIGPIPE, &new, NULL); | 20 | sigaction(SIGPIPE, &ignore, NULL); |
12 | return 1; | 21 | return 1; |
13 | } | 22 | } |
14 | 23 | ||
24 | /*-------------------------------------------------------------------------*\ | ||
25 | * Close and inutilize socket | ||
26 | \*-------------------------------------------------------------------------*/ | ||
15 | void sock_destroy(p_sock ps) | 27 | void sock_destroy(p_sock ps) |
16 | { | 28 | { |
17 | close(*ps); | 29 | close(*ps); |
30 | *ps = SOCK_INVALID; | ||
18 | } | 31 | } |
19 | 32 | ||
33 | /*-------------------------------------------------------------------------*\ | ||
34 | * Creates and sets up a socket | ||
35 | \*-------------------------------------------------------------------------*/ | ||
20 | const char *sock_create(p_sock ps, int domain, int type, int protocol) | 36 | const char *sock_create(p_sock ps, int domain, int type, int protocol) |
21 | { | 37 | { |
38 | int val = 1; | ||
22 | t_sock sock = socket(domain, type, protocol); | 39 | t_sock sock = socket(domain, type, protocol); |
23 | if (sock == SOCK_INVALID) return sock_createstrerror(); | 40 | if (sock == SOCK_INVALID) return sock_createstrerror(); |
24 | *ps = sock; | 41 | *ps = sock; |
25 | sock_setnonblocking(ps); | 42 | sock_setnonblocking(ps); |
26 | sock_setreuseaddr(ps); | 43 | setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val)); |
27 | return NULL; | 44 | return NULL; |
28 | } | 45 | } |
29 | 46 | ||
47 | /*-------------------------------------------------------------------------*\ | ||
48 | * Connects or returns error message | ||
49 | \*-------------------------------------------------------------------------*/ | ||
30 | const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len) | 50 | const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len) |
31 | { | 51 | { |
32 | if (connect(*ps, addr, addr_len) < 0) return sock_connectstrerror(); | 52 | if (connect(*ps, addr, addr_len) < 0) return sock_connectstrerror(); |
33 | else return NULL; | 53 | else return NULL; |
34 | } | 54 | } |
35 | 55 | ||
56 | /*-------------------------------------------------------------------------*\ | ||
57 | * Binds or returns error message | ||
58 | \*-------------------------------------------------------------------------*/ | ||
36 | const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len) | 59 | const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len) |
37 | { | 60 | { |
38 | if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror(); | 61 | if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror(); |
39 | else return NULL; | 62 | else return NULL; |
40 | } | 63 | } |
41 | 64 | ||
65 | /*-------------------------------------------------------------------------*\ | ||
66 | * | ||
67 | \*-------------------------------------------------------------------------*/ | ||
42 | void sock_listen(p_sock ps, int backlog) | 68 | void sock_listen(p_sock ps, int backlog) |
43 | { | 69 | { |
44 | listen(*ps, backlog); | 70 | listen(*ps, backlog); |
45 | } | 71 | } |
46 | 72 | ||
73 | /*-------------------------------------------------------------------------*\ | ||
74 | * Accept with timeout | ||
75 | \*-------------------------------------------------------------------------*/ | ||
47 | int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, | 76 | int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, |
48 | int timeout) | 77 | int timeout) |
49 | { | 78 | { |
@@ -65,6 +94,9 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, | |||
65 | else return IO_DONE; | 94 | else return IO_DONE; |
66 | } | 95 | } |
67 | 96 | ||
97 | /*-------------------------------------------------------------------------*\ | ||
98 | * Send with timeout | ||
99 | \*-------------------------------------------------------------------------*/ | ||
68 | int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, | 100 | int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, |
69 | int timeout) | 101 | int timeout) |
70 | { | 102 | { |
@@ -99,6 +131,9 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, | |||
99 | } | 131 | } |
100 | } | 132 | } |
101 | 133 | ||
134 | /*-------------------------------------------------------------------------*\ | ||
135 | * Sendto with timeout | ||
136 | \*-------------------------------------------------------------------------*/ | ||
102 | int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, | 137 | int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, |
103 | SA *addr, socklen_t addr_len, int timeout) | 138 | SA *addr, socklen_t addr_len, int timeout) |
104 | { | 139 | { |
@@ -133,6 +168,9 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, | |||
133 | } | 168 | } |
134 | } | 169 | } |
135 | 170 | ||
171 | /*-------------------------------------------------------------------------*\ | ||
172 | * Receive with timeout | ||
173 | \*-------------------------------------------------------------------------*/ | ||
136 | int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) | 174 | int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) |
137 | { | 175 | { |
138 | t_sock sock = *ps; | 176 | t_sock sock = *ps; |
@@ -160,6 +198,9 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) | |||
160 | } | 198 | } |
161 | } | 199 | } |
162 | 200 | ||
201 | /*-------------------------------------------------------------------------*\ | ||
202 | * Recvfrom with timeout | ||
203 | \*-------------------------------------------------------------------------*/ | ||
163 | int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, | 204 | int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, |
164 | SA *addr, socklen_t *addr_len, int timeout) | 205 | SA *addr, socklen_t *addr_len, int timeout) |
165 | { | 206 | { |
@@ -188,6 +229,29 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, | |||
188 | } | 229 | } |
189 | } | 230 | } |
190 | 231 | ||
232 | /*-------------------------------------------------------------------------*\ | ||
233 | * Put socket into blocking mode | ||
234 | \*-------------------------------------------------------------------------*/ | ||
235 | void sock_setblocking(p_sock ps) | ||
236 | { | ||
237 | int flags = fcntl(*ps, F_GETFL, 0); | ||
238 | flags &= (~(O_NONBLOCK)); | ||
239 | fcntl(*ps, F_SETFL, flags); | ||
240 | } | ||
241 | |||
242 | /*-------------------------------------------------------------------------*\ | ||
243 | * Put socket into non-blocking mode | ||
244 | \*-------------------------------------------------------------------------*/ | ||
245 | void sock_setnonblocking(p_sock ps) | ||
246 | { | ||
247 | int flags = fcntl(*ps, F_GETFL, 0); | ||
248 | flags |= O_NONBLOCK; | ||
249 | fcntl(*ps, F_SETFL, flags); | ||
250 | } | ||
251 | |||
252 | /*-------------------------------------------------------------------------*\ | ||
253 | * Error translation functions | ||
254 | \*-------------------------------------------------------------------------*/ | ||
191 | const char *sock_hoststrerror(void) | 255 | const char *sock_hoststrerror(void) |
192 | { | 256 | { |
193 | switch (h_errno) { | 257 | switch (h_errno) { |
@@ -238,23 +302,3 @@ const char *sock_connectstrerror(void) | |||
238 | default: return "unknown error"; | 302 | default: return "unknown error"; |
239 | } | 303 | } |
240 | } | 304 | } |
241 | |||
242 | void sock_setreuseaddr(p_sock ps) | ||
243 | { | ||
244 | int val = 1; | ||
245 | setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); | ||
246 | } | ||
247 | |||
248 | void sock_setblocking(p_sock ps) | ||
249 | { | ||
250 | int flags = fcntl(*ps, F_GETFL, 0); | ||
251 | flags &= (~(O_NONBLOCK)); | ||
252 | fcntl(*ps, F_SETFL, flags); | ||
253 | } | ||
254 | |||
255 | void sock_setnonblocking(p_sock ps) | ||
256 | { | ||
257 | int flags = fcntl(*ps, F_GETFL, 0); | ||
258 | flags |= O_NONBLOCK; | ||
259 | fcntl(*ps, F_SETFL, flags); | ||
260 | } | ||
diff --git a/src/usocket.h b/src/usocket.h index 034ae74..85b7caa 100644 --- a/src/usocket.h +++ b/src/usocket.h | |||
@@ -1,10 +1,11 @@ | |||
1 | #ifndef USOCKET_H | ||
2 | #define USOCKET_H | ||
1 | /*=========================================================================*\ | 3 | /*=========================================================================*\ |
2 | * Socket compatibilization module for Unix | 4 | * Socket compatibilization module for Unix |
5 | * LuaSocket toolkit | ||
3 | * | 6 | * |
4 | * RCS ID: $Id$ | 7 | * RCS ID: $Id$ |
5 | \*=========================================================================*/ | 8 | \*=========================================================================*/ |
6 | #ifndef USOCKET_H | ||
7 | #define USOCKET_H | ||
8 | 9 | ||
9 | /*=========================================================================*\ | 10 | /*=========================================================================*\ |
10 | * BSD include files | 11 | * BSD include files |
@@ -30,9 +31,11 @@ | |||
30 | /* IP stuff*/ | 31 | /* IP stuff*/ |
31 | #include <netinet/in.h> | 32 | #include <netinet/in.h> |
32 | #include <arpa/inet.h> | 33 | #include <arpa/inet.h> |
34 | /* TCP options (nagle algorithm disable) */ | ||
35 | #include <netinet/tcp.h> | ||
33 | 36 | ||
34 | #ifdef __APPLE__ | 37 | #ifdef __APPLE__ |
35 | /* for some reason socklen_t is not defined in mac os x */ | 38 | /* for some reason socklen_t is not defined in Mac Os X */ |
36 | typedef int socklen_t; | 39 | typedef int socklen_t; |
37 | #endif | 40 | #endif |
38 | 41 | ||
diff --git a/src/wsocket.c b/src/wsocket.c index 56e65ec..2ce828e 100644 --- a/src/wsocket.c +++ b/src/wsocket.c | |||
@@ -1,14 +1,21 @@ | |||
1 | /*=========================================================================*\ | ||
2 | * Socket compatibilization module for Win32 | ||
3 | * LuaSocket toolkit | ||
4 | * | ||
5 | * RCS ID: $Id$ | ||
6 | \*=========================================================================*/ | ||
1 | #include <string.h> | 7 | #include <string.h> |
2 | 8 | ||
3 | #include "socket.h" | 9 | #include "socket.h" |
4 | 10 | ||
11 | /*-------------------------------------------------------------------------*\ | ||
12 | * Initializes module | ||
13 | \*-------------------------------------------------------------------------*/ | ||
5 | int sock_open(void) | 14 | int sock_open(void) |
6 | { | 15 | { |
7 | WORD wVersionRequested; | ||
8 | WSADATA wsaData; | 16 | WSADATA wsaData; |
9 | int err; | 17 | WORD wVersionRequested = MAKEWORD(2, 0); |
10 | wVersionRequested = MAKEWORD(2, 0); | 18 | int err = WSAStartup(wVersionRequested, &wsaData ); |
11 | err = WSAStartup(wVersionRequested, &wsaData ); | ||
12 | if (err != 0) return 0; | 19 | if (err != 0) return 0; |
13 | if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) { | 20 | if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) { |
14 | WSACleanup(); | 21 | WSACleanup(); |
@@ -17,38 +24,58 @@ int sock_open(void) | |||
17 | return 1; | 24 | return 1; |
18 | } | 25 | } |
19 | 26 | ||
27 | /*-------------------------------------------------------------------------*\ | ||
28 | * Close and inutilize socket | ||
29 | \*-------------------------------------------------------------------------*/ | ||
20 | void sock_destroy(p_sock ps) | 30 | void sock_destroy(p_sock ps) |
21 | { | 31 | { |
22 | closesocket(*ps); | 32 | closesocket(*ps); |
33 | *ps = SOCK_INVALID; | ||
23 | } | 34 | } |
24 | 35 | ||
36 | /*-------------------------------------------------------------------------*\ | ||
37 | * Creates and sets up a socket | ||
38 | \*-------------------------------------------------------------------------*/ | ||
25 | const char *sock_create(p_sock ps, int domain, int type, int protocol) | 39 | const char *sock_create(p_sock ps, int domain, int type, int protocol) |
26 | { | 40 | { |
41 | int val = 1; | ||
27 | t_sock sock = socket(domain, type, protocol); | 42 | t_sock sock = socket(domain, type, protocol); |
28 | if (sock == SOCK_INVALID) return sock_createstrerror(); | 43 | if (sock == SOCK_INVALID) return sock_createstrerror(); |
29 | *ps = sock; | 44 | *ps = sock; |
30 | sock_setnonblocking(ps); | 45 | sock_setnonblocking(ps); |
31 | sock_setreuseaddr(ps); | 46 | setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val)); |
32 | return NULL; | 47 | return NULL; |
33 | } | 48 | } |
34 | 49 | ||
50 | /*-------------------------------------------------------------------------*\ | ||
51 | * Connects or returns error message | ||
52 | \*-------------------------------------------------------------------------*/ | ||
35 | const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len) | 53 | const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len) |
36 | { | 54 | { |
37 | if (connect(*ps, addr, addr_len) < 0) return sock_connectstrerror(); | 55 | if (connect(*ps, addr, addr_len) < 0) return sock_connectstrerror(); |
38 | else return NULL; | 56 | else return NULL; |
39 | } | 57 | } |
40 | 58 | ||
59 | /*-------------------------------------------------------------------------*\ | ||
60 | * Binds or returns error message | ||
61 | \*-------------------------------------------------------------------------*/ | ||
41 | const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len) | 62 | const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len) |
42 | { | 63 | { |
43 | if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror(); | 64 | if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror(); |
44 | else return NULL; | 65 | else return NULL; |
45 | } | 66 | } |
46 | 67 | ||
68 | /*-------------------------------------------------------------------------*\ | ||
69 | * | ||
70 | \*-------------------------------------------------------------------------*/ | ||
47 | void sock_listen(p_sock ps, int backlog) | 71 | void sock_listen(p_sock ps, int backlog) |
48 | { | 72 | { |
49 | listen(*ps, backlog); | 73 | listen(*ps, backlog); |
50 | } | 74 | } |
51 | 75 | ||
76 | /*-------------------------------------------------------------------------*\ | ||
77 | * Accept with timeout | ||
78 | \*-------------------------------------------------------------------------*/ | ||
52 | int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, | 79 | int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, |
53 | int timeout) | 80 | int timeout) |
54 | { | 81 | { |
@@ -70,6 +97,9 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, | |||
70 | else return IO_DONE; | 97 | else return IO_DONE; |
71 | } | 98 | } |
72 | 99 | ||
100 | /*-------------------------------------------------------------------------*\ | ||
101 | * Send with timeout | ||
102 | \*-------------------------------------------------------------------------*/ | ||
73 | int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, | 103 | int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, |
74 | int timeout) | 104 | int timeout) |
75 | { | 105 | { |
@@ -104,6 +134,9 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, | |||
104 | } | 134 | } |
105 | } | 135 | } |
106 | 136 | ||
137 | /*-------------------------------------------------------------------------*\ | ||
138 | * Sendto with timeout | ||
139 | \*-------------------------------------------------------------------------*/ | ||
107 | int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, | 140 | int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, |
108 | SA *addr, socklen_t addr_len, int timeout) | 141 | SA *addr, socklen_t addr_len, int timeout) |
109 | { | 142 | { |
@@ -138,6 +171,9 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, | |||
138 | } | 171 | } |
139 | } | 172 | } |
140 | 173 | ||
174 | /*-------------------------------------------------------------------------*\ | ||
175 | * Receive with timeout | ||
176 | \*-------------------------------------------------------------------------*/ | ||
141 | int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) | 177 | int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) |
142 | { | 178 | { |
143 | t_sock sock = *ps; | 179 | t_sock sock = *ps; |
@@ -165,6 +201,9 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) | |||
165 | } | 201 | } |
166 | } | 202 | } |
167 | 203 | ||
204 | /*-------------------------------------------------------------------------*\ | ||
205 | * Recvfrom with timeout | ||
206 | \*-------------------------------------------------------------------------*/ | ||
168 | int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, | 207 | int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, |
169 | SA *addr, socklen_t *addr_len, int timeout) | 208 | SA *addr, socklen_t *addr_len, int timeout) |
170 | { | 209 | { |
@@ -193,6 +232,27 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, | |||
193 | } | 232 | } |
194 | } | 233 | } |
195 | 234 | ||
235 | /*-------------------------------------------------------------------------*\ | ||
236 | * Put socket into blocking mode | ||
237 | \*-------------------------------------------------------------------------*/ | ||
238 | void sock_setblocking(p_sock ps) | ||
239 | { | ||
240 | u_long argp = 0; | ||
241 | ioctlsocket(*ps, FIONBIO, &argp); | ||
242 | } | ||
243 | |||
244 | /*-------------------------------------------------------------------------*\ | ||
245 | * Put socket into non-blocking mode | ||
246 | \*-------------------------------------------------------------------------*/ | ||
247 | void sock_setnonblocking(p_sock ps) | ||
248 | { | ||
249 | u_long argp = 1; | ||
250 | ioctlsocket(*ps, FIONBIO, &argp); | ||
251 | } | ||
252 | |||
253 | /*-------------------------------------------------------------------------*\ | ||
254 | * Error translation functions | ||
255 | \*-------------------------------------------------------------------------*/ | ||
196 | const char *sock_hoststrerror(void) | 256 | const char *sock_hoststrerror(void) |
197 | { | 257 | { |
198 | switch (WSAGetLastError()) { | 258 | switch (WSAGetLastError()) { |
@@ -241,21 +301,3 @@ const char *sock_connectstrerror(void) | |||
241 | default: return "unknown error"; | 301 | default: return "unknown error"; |
242 | } | 302 | } |
243 | } | 303 | } |
244 | |||
245 | void sock_setreuseaddr(p_sock ps) | ||
246 | { | ||
247 | int val = 1; | ||
248 | setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); | ||
249 | } | ||
250 | |||
251 | void sock_setblocking(p_sock ps) | ||
252 | { | ||
253 | u_long argp = 0; | ||
254 | ioctlsocket(*ps, FIONBIO, &argp); | ||
255 | } | ||
256 | |||
257 | void sock_setnonblocking(p_sock ps) | ||
258 | { | ||
259 | u_long argp = 1; | ||
260 | ioctlsocket(*ps, FIONBIO, &argp); | ||
261 | } | ||
diff --git a/src/wsocket.h b/src/wsocket.h index ceecae7..d77841e 100644 --- a/src/wsocket.h +++ b/src/wsocket.h | |||
@@ -1,16 +1,16 @@ | |||
1 | #ifndef WSOCKET_H | ||
2 | #define WSOCKET_H | ||
1 | /*=========================================================================*\ | 3 | /*=========================================================================*\ |
2 | * Socket compatibilization module for Win32 | 4 | * Socket compatibilization module for Win32 |
5 | * LuaSocket toolkit | ||
3 | * | 6 | * |
4 | * RCS ID: $Id$ | 7 | * RCS ID: $Id$ |
5 | \*=========================================================================*/ | 8 | \*=========================================================================*/ |
6 | #ifndef WSOCKET_H | ||
7 | #define WSOCKET_H | ||
8 | 9 | ||
9 | /*=========================================================================*\ | 10 | /*=========================================================================*\ |
10 | * WinSock2 include files | 11 | * WinSock include files |
11 | \*=========================================================================*/ | 12 | \*=========================================================================*/ |
12 | #include <winsock2.h> | 13 | #include <winsock.h> |
13 | #include <winbase.h> | ||
14 | 14 | ||
15 | typedef int socklen_t; | 15 | typedef int socklen_t; |
16 | typedef int ssize_t; | 16 | typedef int ssize_t; |
diff --git a/test/testclnt.lua b/test/testclnt.lua index b2b4b18..e38c248 100644 --- a/test/testclnt.lua +++ b/test/testclnt.lua | |||
@@ -17,12 +17,14 @@ function warn(...) | |||
17 | io.write("WARNING: ", s, "\n") | 17 | io.write("WARNING: ", s, "\n") |
18 | end | 18 | end |
19 | 19 | ||
20 | pad = string.rep(" ", 8192) | ||
21 | |||
20 | function remote(...) | 22 | function remote(...) |
21 | local s = string.format(unpack(arg)) | 23 | local s = string.format(unpack(arg)) |
22 | s = string.gsub(s, "\n", ";") | 24 | s = string.gsub(s, "\n", ";") |
23 | s = string.gsub(s, "%s+", " ") | 25 | s = string.gsub(s, "%s+", " ") |
24 | s = string.gsub(s, "^%s*", "") | 26 | s = string.gsub(s, "^%s*", "") |
25 | control:send(s, "\n") | 27 | control:send(pad, s, "\n") |
26 | control:receive() | 28 | control:receive() |
27 | end | 29 | end |
28 | 30 | ||
@@ -82,16 +84,19 @@ function reconnect() | |||
82 | remote [[ | 84 | remote [[ |
83 | if data then data:close() data = nil end | 85 | if data then data:close() data = nil end |
84 | data = server:accept() | 86 | data = server:accept() |
87 | data:setoption("nodelay", true) | ||
85 | ]] | 88 | ]] |
86 | data, err = socket.connect(host, port) | 89 | data, err = socket.connect(host, port) |
87 | if not data then fail(err) | 90 | if not data then fail(err) |
88 | else pass("connected!") end | 91 | else pass("connected!") end |
92 | data:setoption("nodelay", true) | ||
89 | end | 93 | end |
90 | 94 | ||
91 | pass("attempting control connection...") | 95 | pass("attempting control connection...") |
92 | control, err = socket.connect(host, port) | 96 | control, err = socket.connect(host, port) |
93 | if err then fail(err) | 97 | if err then fail(err) |
94 | else pass("connected!") end | 98 | else pass("connected!") end |
99 | control:setoption("nodelay", true) | ||
95 | 100 | ||
96 | ------------------------------------------------------------------------ | 101 | ------------------------------------------------------------------------ |
97 | test("method registration") | 102 | test("method registration") |
@@ -157,16 +162,21 @@ remote "data:send(str); data:close()" | |||
157 | end | 162 | end |
158 | 163 | ||
159 | 164 | ||
160 | test_mixed(1) | 165 | --test_mixed(1) |
161 | test_mixed(17) | 166 | --test_mixed(17) |
162 | test_mixed(200) | 167 | --test_mixed(200) |
168 | --test_mixed(4091) | ||
169 | --test_mixed(80199) | ||
170 | --test_mixed(4091) | ||
171 | --test_mixed(200) | ||
172 | --test_mixed(17) | ||
173 | --test_mixed(1) | ||
174 | |||
175 | test_mixed(4091) | ||
176 | test_mixed(4091) | ||
177 | test_mixed(4091) | ||
163 | test_mixed(4091) | 178 | test_mixed(4091) |
164 | test_mixed(80199) | ||
165 | test_mixed(4091) | 179 | test_mixed(4091) |
166 | test_mixed(200) | ||
167 | test_mixed(17) | ||
168 | test_mixed(1) | ||
169 | |||
170 | ------------------------------------------------------------------------ | 180 | ------------------------------------------------------------------------ |
171 | test("character line") | 181 | test("character line") |
172 | reconnect() | 182 | reconnect() |
diff --git a/test/testsrvr.lua b/test/testsrvr.lua index 3c40840..39fe274 100644 --- a/test/testsrvr.lua +++ b/test/testsrvr.lua | |||
@@ -3,9 +3,11 @@ port = port or "8080" | |||
3 | 3 | ||
4 | server, error = socket.bind(host, port) | 4 | server, error = socket.bind(host, port) |
5 | if not server then print("server: " .. tostring(error)) os.exit() end | 5 | if not server then print("server: " .. tostring(error)) os.exit() end |
6 | ack = "\n" | ||
6 | while 1 do | 7 | while 1 do |
7 | print("server: waiting for client connection..."); | 8 | print("server: waiting for client connection..."); |
8 | control = server:accept() | 9 | control = server:accept() |
10 | control:setoption("nodelay", true) | ||
9 | while 1 do | 11 | while 1 do |
10 | command, error = control:receive() | 12 | command, error = control:receive() |
11 | if error then | 13 | if error then |
@@ -13,13 +15,12 @@ while 1 do | |||
13 | print("server: closing connection...") | 15 | print("server: closing connection...") |
14 | break | 16 | break |
15 | end | 17 | end |
16 | sent, error = control:send("\n") | 18 | sent, error = control:send(ack) |
17 | if error then | 19 | if error then |
18 | control:close() | 20 | control:close() |
19 | print("server: closing connection...") | 21 | print("server: closing connection...") |
20 | break | 22 | break |
21 | end | 23 | end |
22 | print(command); | ||
23 | (loadstring(command))() | 24 | (loadstring(command))() |
24 | end | 25 | end |
25 | end | 26 | end |