aboutsummaryrefslogtreecommitdiff
path: root/src/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tcp.c')
-rw-r--r--src/tcp.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/src/tcp.c b/src/tcp.c
index 01b07ee..4b3b0cc 100644
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -22,6 +22,7 @@
22\*=========================================================================*/ 22\*=========================================================================*/
23static int global_create(lua_State *L); 23static int global_create(lua_State *L);
24static int meth_connect(lua_State *L); 24static int meth_connect(lua_State *L);
25static int meth_listen(lua_State *L);
25static int meth_bind(lua_State *L); 26static int meth_bind(lua_State *L);
26static int meth_send(lua_State *L); 27static int meth_send(lua_State *L);
27static int meth_getsockname(lua_State *L); 28static int meth_getsockname(lua_State *L);
@@ -32,7 +33,8 @@ static int meth_accept(lua_State *L);
32static int meth_close(lua_State *L); 33static int meth_close(lua_State *L);
33static int meth_setoption(lua_State *L); 34static int meth_setoption(lua_State *L);
34static int meth_settimeout(lua_State *L); 35static int meth_settimeout(lua_State *L);
35static int meth_fd(lua_State *L); 36static int meth_getfd(lua_State *L);
37static int meth_setfd(lua_State *L);
36static int meth_dirty(lua_State *L); 38static int meth_dirty(lua_State *L);
37 39
38/* tcp object methods */ 40/* tcp object methods */
@@ -41,6 +43,7 @@ static luaL_reg tcp[] = {
41 {"send", meth_send}, 43 {"send", meth_send},
42 {"receive", meth_receive}, 44 {"receive", meth_receive},
43 {"bind", meth_bind}, 45 {"bind", meth_bind},
46 {"listen", meth_listen},
44 {"accept", meth_accept}, 47 {"accept", meth_accept},
45 {"setpeername", meth_connect}, 48 {"setpeername", meth_connect},
46 {"setsockname", meth_bind}, 49 {"setsockname", meth_bind},
@@ -51,7 +54,8 @@ static luaL_reg tcp[] = {
51 {"shutdown", meth_shutdown}, 54 {"shutdown", meth_shutdown},
52 {"setoption", meth_setoption}, 55 {"setoption", meth_setoption},
53 {"__gc", meth_close}, 56 {"__gc", meth_close},
54 {"fd", meth_fd}, 57 {"getfd", meth_getfd},
58 {"setfd", meth_setfd},
55 {"dirty", meth_dirty}, 59 {"dirty", meth_dirty},
56 {NULL, NULL} 60 {NULL, NULL}
57}; 61};
@@ -124,16 +128,24 @@ static int meth_setoption(lua_State *L)
124/*-------------------------------------------------------------------------*\ 128/*-------------------------------------------------------------------------*\
125* Select support methods 129* Select support methods
126\*-------------------------------------------------------------------------*/ 130\*-------------------------------------------------------------------------*/
127static int meth_fd(lua_State *L) 131static int meth_getfd(lua_State *L)
128{ 132{
129 p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client,server}", 1); 133 p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1);
130 lua_pushnumber(L, tcp->sock); 134 lua_pushnumber(L, tcp->sock);
131 return 1; 135 return 1;
132} 136}
133 137
138/* this is very dangerous, but can be handy for those that are brave enough */
139static int meth_setfd(lua_State *L)
140{
141 p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1);
142 tcp->sock = (t_sock) luaL_checknumber(L, 2);
143 return 0;
144}
145
134static int meth_dirty(lua_State *L) 146static int meth_dirty(lua_State *L)
135{ 147{
136 p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client,server}", 1); 148 p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1);
137 lua_pushboolean(L, !buf_isempty(&tcp->buf)); 149 lua_pushboolean(L, !buf_isempty(&tcp->buf));
138 return 1; 150 return 1;
139} 151}
@@ -147,9 +159,9 @@ static int meth_accept(lua_State *L)
147 p_tcp server = (p_tcp) aux_checkclass(L, "tcp{server}", 1); 159 p_tcp server = (p_tcp) aux_checkclass(L, "tcp{server}", 1);
148 p_tm tm = tm_markstart(&server->tm); 160 p_tm tm = tm_markstart(&server->tm);
149 t_sock sock; 161 t_sock sock;
150 int err = sock_accept(&server->sock, &sock, NULL, NULL, tm); 162 const char *err = sock_accept(&server->sock, &sock, NULL, NULL, tm);
151 /* if successful, push client socket */ 163 /* if successful, push client socket */
152 if (err == IO_DONE) { 164 if (!err) {
153 p_tcp clnt = lua_newuserdata(L, sizeof(t_tcp)); 165 p_tcp clnt = lua_newuserdata(L, sizeof(t_tcp));
154 aux_setclass(L, "tcp{client}", -1); 166 aux_setclass(L, "tcp{client}", -1);
155 /* initialize structure fields */ 167 /* initialize structure fields */
@@ -160,28 +172,25 @@ static int meth_accept(lua_State *L)
160 return 1; 172 return 1;
161 } else { 173 } else {
162 lua_pushnil(L); 174 lua_pushnil(L);
163 io_pusherror(L, err); 175 lua_pushstring(L, err);
164 return 2; 176 return 2;
165 } 177 }
166} 178}
167 179
168/*-------------------------------------------------------------------------*\ 180/*-------------------------------------------------------------------------*\
169* Turns a master object into a server object 181* Binds an object to an address
170\*-------------------------------------------------------------------------*/ 182\*-------------------------------------------------------------------------*/
171static int meth_bind(lua_State *L) 183static int meth_bind(lua_State *L)
172{ 184{
173 p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); 185 p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1);
174 const char *address = luaL_checkstring(L, 2); 186 const char *address = luaL_checkstring(L, 2);
175 unsigned short port = (unsigned short) luaL_checknumber(L, 3); 187 unsigned short port = (unsigned short) luaL_checknumber(L, 3);
176 int backlog = (int) luaL_optnumber(L, 4, 1); 188 const char *err = inet_trybind(&tcp->sock, address, port);
177 const char *err = inet_trybind(&tcp->sock, address, port, backlog);
178 if (err) { 189 if (err) {
179 lua_pushnil(L); 190 lua_pushnil(L);
180 lua_pushstring(L, err); 191 lua_pushstring(L, err);
181 return 2; 192 return 2;
182 } 193 }
183 /* turn master object into a server object if there was a listen */
184 if (backlog >= 0) aux_setclass(L, "tcp{server}", 1);
185 lua_pushnumber(L, 1); 194 lua_pushnumber(L, 1);
186 return 1; 195 return 1;
187} 196}
@@ -218,6 +227,25 @@ static int meth_close(lua_State *L)
218} 227}
219 228
220/*-------------------------------------------------------------------------*\ 229/*-------------------------------------------------------------------------*\
230* Puts the sockt in listen mode
231\*-------------------------------------------------------------------------*/
232static int meth_listen(lua_State *L)
233{
234 p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1);
235 int backlog = (int) luaL_checknumber(L, 2);
236 const char *err = sock_listen(&tcp->sock, backlog);
237 if (err) {
238 lua_pushnil(L);
239 lua_pushstring(L, err);
240 return 2;
241 }
242 /* turn master object into a server object */
243 aux_setclass(L, "tcp{server}", 1);
244 lua_pushnumber(L, 1);
245 return 1;
246}
247
248/*-------------------------------------------------------------------------*\
221* Shuts the connection down partially 249* Shuts the connection down partially
222\*-------------------------------------------------------------------------*/ 250\*-------------------------------------------------------------------------*/
223static int meth_shutdown(lua_State *L) 251static int meth_shutdown(lua_State *L)