aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2003-06-26 18:47:49 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2003-06-26 18:47:49 +0000
commit71f6bb60bf2b7457091c7106190f92ab7e51f7c6 (patch)
tree8ad3668667bd3da3c34f7ff7ae0a9a7a4daa4679 /src
parentf330540576031528f0daac231c61d4dd06e8ba1e (diff)
downloadluasocket-71f6bb60bf2b7457091c7106190f92ab7e51f7c6.tar.gz
luasocket-71f6bb60bf2b7457091c7106190f92ab7e51f7c6.tar.bz2
luasocket-71f6bb60bf2b7457091c7106190f92ab7e51f7c6.zip
Finished implementation of LuaSocket 2.0 alpha on Linux.
Some testing still needed.
Diffstat (limited to 'src')
-rw-r--r--src/auxiliar.c181
-rw-r--r--src/auxiliar.h48
-rw-r--r--src/buffer.c33
-rw-r--r--src/buffer.h27
-rw-r--r--src/ftp.lua2
-rw-r--r--src/http.lua2
-rw-r--r--src/inet.c43
-rw-r--r--src/inet.h23
-rw-r--r--src/io.c40
-rw-r--r--src/io.h29
-rw-r--r--src/luasocket.c20
-rw-r--r--src/luasocket.h10
-rw-r--r--src/select.c52
-rw-r--r--src/select.h14
-rw-r--r--src/smtp.lua2
-rw-r--r--src/socket.h15
-rw-r--r--src/tcp.c85
-rw-r--r--src/tcp.h19
-rw-r--r--src/timeout.c4
-rw-r--r--src/timeout.h8
-rw-r--r--src/udp.c61
-rw-r--r--src/udp.h17
-rw-r--r--src/url.lua2
-rw-r--r--src/usocket.c96
-rw-r--r--src/usocket.h9
-rw-r--r--src/wsocket.c88
-rw-r--r--src/wsocket.h10
27 files changed, 644 insertions, 296 deletions
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\*-------------------------------------------------------------------------*/
16void aux_newclass(lua_State *L, const char *name, luaL_reg *func) 18void 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\*-------------------------------------------------------------------------*/
36void aux_add2group(lua_State *L, const char *name, const char *group) 38void 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\*-------------------------------------------------------------------------*/
61void 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\*-------------------------------------------------------------------------*/
73int 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\*-------------------------------------------------------------------------*/
53void *aux_checkclass(lua_State *L, const char *name, int objidx) 83int 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\*-------------------------------------------------------------------------*/
104void *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\*-------------------------------------------------------------------------*/
67void *aux_checkgroup(lua_State *L, const char *group, int objidx) 119void *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\*-------------------------------------------------------------------------*/
81void aux_setclass(lua_State *L, const char *name, int objidx) 133void 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\*-------------------------------------------------------------------------*/
95void *aux_getgroupudata(lua_State *L, const char *group, int objidx) 144void *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\*-------------------------------------------------------------------------*/
124void *aux_getclassudata(lua_State *L, const char *group, int objidx) 163void *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
12void aux_newclass(lua_State *L, const char *name, luaL_reg *func);
13void aux_add2group(lua_State *L, const char *name, const char *group);
14void *aux_checkclass(lua_State *L, const char *name, int objidx);
15void *aux_checkgroup(lua_State *L, const char *group, int objidx);
16void *aux_getclassudata(lua_State *L, const char *group, int objidx);
17void *aux_getgroupudata(lua_State *L, const char *group, int objidx);
18void 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 43void aux_open(lua_State *L);
44void aux_newclass(lua_State *L, const char *classname, luaL_reg *func);
45void aux_add2group(lua_State *L, const char *classname, const char *group);
46void aux_setclass(lua_State *L, const char *classname, int objidx);
47void *aux_checkclass(lua_State *L, const char *classname, int objidx);
48void *aux_checkgroup(lua_State *L, const char *groupname, int objidx);
49void *aux_getclassudata(lua_State *L, const char *groupname, int objidx);
50void *aux_getgroupudata(lua_State *L, const char *groupname, int objidx);
51int aux_meth_setoption(lua_State *L, luaL_reg *opt);
52int 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\*-------------------------------------------------------------------------*/
47int buf_meth_send(lua_State *L, p_buf buf) 47int 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\*-------------------------------------------------------------------------*/
73int buf_meth_receive(lua_State *L, p_buf buf) 73int 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\*-------------------------------------------------------------------------*/
132static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent) 132static
133int 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\*-------------------------------------------------------------------------*/
150static 151static
151int recvraw(lua_State *L, p_buf buf, size_t wanted) 152int 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\*-------------------------------------------------------------------------*/
172static 173static
173int recvall(lua_State *L, p_buf buf) 174int 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\*-------------------------------------------------------------------------*/
192static 193static
193int recvline(lua_State *L, p_buf buf) 194int 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\*-------------------------------------------------------------------------*/
220static 222static
221void buf_skip(p_buf buf, size_t count) 223void 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\*-------------------------------------------------------------------------*/
232static 234static
233int buf_get(p_buf buf, const char **data, size_t *count) 235int 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\*-------------------------------------------------------------------------*/
19typedef struct t_buf_ { 29typedef 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;
25typedef t_buf *p_buf; 35typedef t_buf *p_buf;
26 36
27/*-------------------------------------------------------------------------*\
28* Exported functions
29\*-------------------------------------------------------------------------*/
30void buf_open(lua_State *L); 37void buf_open(lua_State *L);
31void buf_init(p_buf buf, p_io io, p_tm tm); 38void buf_init(p_buf buf, p_io io, p_tm tm);
32int buf_meth_send(lua_State *L, p_buf buf); 39int 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$
diff --git a/src/inet.c b/src/inet.c
index b7f3ae5..312a45b 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -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\*=========================================================================*/
17static int inet_global_toip(lua_State *L); 19static int inet_global_toip(lua_State *L);
18static int inet_global_tohostname(lua_State *L); 20static int inet_global_tohostname(lua_State *L);
19
20static void inet_pushresolved(lua_State *L, struct hostent *hp); 21static void inet_pushresolved(lua_State *L, struct hostent *hp);
21 22
22static luaL_reg func[] = { 23static 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\*-------------------------------------------------------------------------*/
52static int inet_global_toip(lua_State *L) 48static 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\*-------------------------------------------------------------------------*/
81static int inet_global_tohostname(lua_State *L) 72static 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\*-------------------------------------------------------------------------*/
111int inet_meth_getpeername(lua_State *L, p_sock ps) 97int 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\*-------------------------------------------------------------------------*/
132int inet_meth_getsockname(lua_State *L, p_sock ps) 113int 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\*-------------------------------------------------------------------------*/
153static void inet_pushresolved(lua_State *L, struct hostent *hp) 132static 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\*-------------------------------------------------------------------------*/
195const char *inet_tryconnect(p_sock ps, const char *address, 168const 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\*-------------------------------------------------------------------------*/
234const char *inet_trybind(p_sock ps, const char *address, unsigned short port, 201const 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\*-------------------------------------------------------------------------*/
272const char *inet_trycreate(p_sock ps, int type) 235const 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
diff --git a/src/inet.h b/src/inet.h
index 60be9e4..244a310 100644
--- a/src/inet.h
+++ b/src/inet.h
@@ -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\*-------------------------------------------------------------------------*/
15void inet_open(lua_State *L); 22void inet_open(lua_State *L);
16
17const char *inet_tryconnect(p_sock ps, const char *address, 23const char *inet_tryconnect(p_sock ps, const char *address,
18 unsigned short port); 24 unsigned short port);
19const char *inet_trybind(p_sock ps, const char *address, 25const char *inet_trybind(p_sock ps, const char *address,
20 unsigned short port, int backlog); 26 unsigned short port, int backlog);
21const char *inet_trycreate(p_sock ps, int type); 27const char *inet_trycreate(p_sock ps, int type);
22
23int inet_meth_getpeername(lua_State *L, p_sock ps); 28int inet_meth_getpeername(lua_State *L, p_sock ps);
24int inet_meth_getsockname(lua_State *L, p_sock ps); 29int 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);
27int inet_aton(const char *cp, struct in_addr *inp); 32int inet_aton(const char *cp, struct in_addr *inp);
28#endif 33#endif
29 34
30#endif /* INET_H_ */ 35#endif /* INET_H */
diff --git a/src/io.c b/src/io.c
index 902124a..2d62147 100644
--- a/src/io.c
+++ b/src/io.c
@@ -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\*-------------------------------------------------------------------------*/
3void io_init(p_io io, p_send send, p_recv recv, void *ctx) 15void 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\*-------------------------------------------------------------------------*/
25void 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
diff --git a/src/io.h b/src/io.h
index 30d445b..f56094a 100644
--- a/src/io.h
+++ b/src/io.h
@@ -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 */
7enum { 21enum {
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;
40typedef t_io *p_io; 54typedef t_io *p_io;
41 55
56void io_pusherror(lua_State *L, int code);
42void io_init(p_io io, p_send send, p_recv recv, void *ctx); 57void 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\*-------------------------------------------------------------------------*/
41LUASOCKET_API int luaopen_socketlib(lua_State *L) 43LUASOCKET_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\*-------------------------------------------------------------------------*/
31LUASOCKET_API int luaopen_socketlib(lua_State *L); 33LUASOCKET_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\*=========================================================================*/
15static int meth_set(lua_State *L); 20static int meth_set(lua_State *L);
16static int meth_isset(lua_State *L); 21static int meth_isset(lua_State *L);
17static int c_select(lua_State *L); 22static 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\*-------------------------------------------------------------------------*/
34void select_open(lua_State *L) 45void 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
79static 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
93static int meth_set(lua_State *L) 96static 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\*=========================================================================*/
116static 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
110static void check_obj_tab(lua_State *L, int tabidx) 130static 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
8void select_open(lua_State *L); 18void 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,
32const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len); 37const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len);
33const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len); 38const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len);
34void sock_listen(p_sock ps, int backlog); 39void sock_listen(p_sock ps, int backlog);
35
36int sock_send(p_sock ps, const char *data, size_t count, 40int sock_send(p_sock ps, const char *data, size_t count,
37 size_t *sent, int timeout); 41 size_t *sent, int timeout);
38int sock_recv(p_sock ps, char *data, size_t count, 42int 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);
42int sock_recvfrom(p_sock ps, char *data, size_t count, 46int 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
45void sock_setnonblocking(p_sock ps); 48void sock_setnonblocking(p_sock ps);
46void sock_setblocking(p_sock ps); 49void sock_setblocking(p_sock ps);
47void sock_setreuseaddr(p_sock ps);
48
49const char *sock_hoststrerror(void); 50const char *sock_hoststrerror(void);
50const char *sock_createstrerror(void); 51const char *sock_createstrerror(void);
51const char *sock_bindstrerror(void); 52const char *sock_bindstrerror(void);
diff --git a/src/tcp.c b/src/tcp.c
index dc7683d..28f38f5 100644
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -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);
28static int meth_receive(lua_State *L); 28static int meth_receive(lua_State *L);
29static int meth_accept(lua_State *L); 29static int meth_accept(lua_State *L);
30static int meth_close(lua_State *L); 30static int meth_close(lua_State *L);
31static int meth_setoption(lua_State *L);
31static int meth_timeout(lua_State *L); 32static int meth_timeout(lua_State *L);
32static int meth_fd(lua_State *L); 33static int meth_fd(lua_State *L);
33static int meth_dirty(lua_State *L); 34static int meth_dirty(lua_State *L);
35static int opt_nodelay(lua_State *L);
36static int opt_keepalive(lua_State *L);
37static int opt_linger(lua_State *L);
34 38
35/* tcp object methods */ 39/* tcp object methods */
36static luaL_reg tcp[] = { 40static 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 */
60static 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 */
54static luaL_reg func[] = { 68static 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\*-------------------------------------------------------------------------*/
117static int meth_setoption(lua_State *L)
118{
119 return aux_meth_setoption(L, opt);
120}
121
122static 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 */
136static 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
147static int opt_keepalive(lua_State *L)
148{
149 return opt_boolean(L, SOL_SOCKET, SO_KEEPALIVE);
150}
151
152int 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\*-------------------------------------------------------------------------*/
102static int meth_fd(lua_State *L) 179static 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
109static int meth_dirty(lua_State *L) 186static 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;
diff --git a/src/tcp.h b/src/tcp.h
index f4319f3..82b88a9 100644
--- a/src/tcp.h
+++ b/src/tcp.h
@@ -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
18void tcp_open(lua_State *L); 33void 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);
28int tm_gettime(void); 28int tm_gettime(void);
29int tm_meth_timeout(lua_State *L, p_tm tm); 29int tm_meth_timeout(lua_State *L, p_tm tm);
30 30
31#endif 31#endif /* TM_H */
diff --git a/src/udp.c b/src/udp.c
index 79831e7..b772b2e 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -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);
29static int meth_setsockname(lua_State *L); 29static int meth_setsockname(lua_State *L);
30static int meth_setpeername(lua_State *L); 30static int meth_setpeername(lua_State *L);
31static int meth_close(lua_State *L); 31static int meth_close(lua_State *L);
32static int meth_setoption(lua_State *L);
32static int meth_timeout(lua_State *L); 33static int meth_timeout(lua_State *L);
33static int meth_fd(lua_State *L); 34static int meth_fd(lua_State *L);
34static int meth_dirty(lua_State *L); 35static int meth_dirty(lua_State *L);
36static int opt_dontroute(lua_State *L);
37static int opt_broadcast(lua_State *L);
35 38
36/* udp object methods */ 39/* udp object methods */
37static luaL_reg udp[] = { 40static 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 */
59static 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 */
54static luaL_reg func[] = { 66static 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\*-------------------------------------------------------------------------*/
175static int meth_fd(lua_State *L) 191static 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
182static int meth_dirty(lua_State *L) 198static 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\*-------------------------------------------------------------------------*/
224static int meth_setoption(lua_State *L)
225{
226 return aux_meth_setoption(L, opt);
227}
228
229static 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
242static int opt_dontroute(lua_State *L)
243{
244 return opt_boolean(L, SOL_SOCKET, SO_DONTROUTE);
245}
246
247static 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\*-------------------------------------------------------------------------*/
208static int meth_timeout(lua_State *L) 255static int meth_timeout(lua_State *L)
diff --git a/src/udp.h b/src/udp.h
index a6f17e2..699e31a 100644
--- a/src/udp.h
+++ b/src/udp.h
@@ -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
17void udp_open(lua_State *L); 30void 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\*-------------------------------------------------------------------------*/
5int sock_open(void) 14int 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\*-------------------------------------------------------------------------*/
15void sock_destroy(p_sock ps) 27void 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\*-------------------------------------------------------------------------*/
20const char *sock_create(p_sock ps, int domain, int type, int protocol) 36const 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\*-------------------------------------------------------------------------*/
30const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len) 50const 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\*-------------------------------------------------------------------------*/
36const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len) 59const 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\*-------------------------------------------------------------------------*/
42void sock_listen(p_sock ps, int backlog) 68void 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\*-------------------------------------------------------------------------*/
47int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, 76int 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\*-------------------------------------------------------------------------*/
68int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, 100int 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\*-------------------------------------------------------------------------*/
102int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, 137int 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\*-------------------------------------------------------------------------*/
136int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) 174int 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\*-------------------------------------------------------------------------*/
163int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, 204int 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\*-------------------------------------------------------------------------*/
235void 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\*-------------------------------------------------------------------------*/
245void 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\*-------------------------------------------------------------------------*/
191const char *sock_hoststrerror(void) 255const 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
242void sock_setreuseaddr(p_sock ps)
243{
244 int val = 1;
245 setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
246}
247
248void 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
255void 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 */
36typedef int socklen_t; 39typedef 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\*-------------------------------------------------------------------------*/
5int sock_open(void) 14int 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\*-------------------------------------------------------------------------*/
20void sock_destroy(p_sock ps) 30void 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\*-------------------------------------------------------------------------*/
25const char *sock_create(p_sock ps, int domain, int type, int protocol) 39const 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\*-------------------------------------------------------------------------*/
35const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len) 53const 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\*-------------------------------------------------------------------------*/
41const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len) 62const 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\*-------------------------------------------------------------------------*/
47void sock_listen(p_sock ps, int backlog) 71void 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\*-------------------------------------------------------------------------*/
52int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, 79int 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\*-------------------------------------------------------------------------*/
73int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, 103int 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\*-------------------------------------------------------------------------*/
107int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, 140int 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\*-------------------------------------------------------------------------*/
141int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) 177int 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\*-------------------------------------------------------------------------*/
168int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, 207int 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\*-------------------------------------------------------------------------*/
238void 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\*-------------------------------------------------------------------------*/
247void sock_setnonblocking(p_sock ps)
248{
249 u_long argp = 1;
250 ioctlsocket(*ps, FIONBIO, &argp);
251}
252
253/*-------------------------------------------------------------------------*\
254* Error translation functions
255\*-------------------------------------------------------------------------*/
196const char *sock_hoststrerror(void) 256const 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
245void sock_setreuseaddr(p_sock ps)
246{
247 int val = 1;
248 setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
249}
250
251void sock_setblocking(p_sock ps)
252{
253 u_long argp = 0;
254 ioctlsocket(*ps, FIONBIO, &argp);
255}
256
257void 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
15typedef int socklen_t; 15typedef int socklen_t;
16typedef int ssize_t; 16typedef int ssize_t;