diff options
Diffstat (limited to 'src/tcp.c')
-rw-r--r-- | src/tcp.c | 38 |
1 files changed, 35 insertions, 3 deletions
@@ -25,6 +25,7 @@ static int meth_bind(lua_State *L); | |||
25 | static int meth_send(lua_State *L); | 25 | static int meth_send(lua_State *L); |
26 | static int meth_getsockname(lua_State *L); | 26 | static int meth_getsockname(lua_State *L); |
27 | static int meth_getpeername(lua_State *L); | 27 | static int meth_getpeername(lua_State *L); |
28 | static int meth_shutdown(lua_State *L); | ||
28 | static int meth_receive(lua_State *L); | 29 | static int meth_receive(lua_State *L); |
29 | static int meth_accept(lua_State *L); | 30 | static int meth_accept(lua_State *L); |
30 | static int meth_close(lua_State *L); | 31 | static int meth_close(lua_State *L); |
@@ -49,6 +50,7 @@ static luaL_reg tcp[] = { | |||
49 | {"getsockname", meth_getsockname}, | 50 | {"getsockname", meth_getsockname}, |
50 | {"settimeout", meth_settimeout}, | 51 | {"settimeout", meth_settimeout}, |
51 | {"close", meth_close}, | 52 | {"close", meth_close}, |
53 | {"shutdown", meth_shutdown}, | ||
52 | {"setoption", meth_setoption}, | 54 | {"setoption", meth_setoption}, |
53 | {"__gc", meth_close}, | 55 | {"__gc", meth_close}, |
54 | {"fd", meth_fd}, | 56 | {"fd", meth_fd}, |
@@ -201,12 +203,12 @@ static int meth_accept(lua_State *L) | |||
201 | int err = IO_ERROR; | 203 | int err = IO_ERROR; |
202 | p_tcp server = (p_tcp) aux_checkclass(L, "tcp{server}", 1); | 204 | p_tcp server = (p_tcp) aux_checkclass(L, "tcp{server}", 1); |
203 | p_tm tm = &server->tm; | 205 | p_tm tm = &server->tm; |
204 | p_tcp client = lua_newuserdata(L, sizeof(t_tcp)); | 206 | p_tcp client; |
205 | aux_setclass(L, "tcp{client}", -1); | 207 | t_sock sock; |
206 | tm_markstart(tm); | 208 | tm_markstart(tm); |
207 | /* loop until connection accepted or timeout happens */ | 209 | /* loop until connection accepted or timeout happens */ |
208 | while (err != IO_DONE) { | 210 | while (err != IO_DONE) { |
209 | err = sock_accept(&server->sock, &client->sock, | 211 | err = sock_accept(&server->sock, &sock, |
210 | (SA *) &addr, &addr_len, tm_getfailure(tm)); | 212 | (SA *) &addr, &addr_len, tm_getfailure(tm)); |
211 | if (err == IO_CLOSED || (err == IO_TIMEOUT && !tm_getfailure(tm))) { | 213 | if (err == IO_CLOSED || (err == IO_TIMEOUT && !tm_getfailure(tm))) { |
212 | lua_pushnil(L); | 214 | lua_pushnil(L); |
@@ -214,6 +216,9 @@ static int meth_accept(lua_State *L) | |||
214 | return 2; | 216 | return 2; |
215 | } | 217 | } |
216 | } | 218 | } |
219 | client = lua_newuserdata(L, sizeof(t_tcp)); | ||
220 | aux_setclass(L, "tcp{client}", -1); | ||
221 | client->sock = sock; | ||
217 | /* initialize remaining structure fields */ | 222 | /* initialize remaining structure fields */ |
218 | io_init(&client->io, (p_send) sock_send, (p_recv) sock_recv, &client->sock); | 223 | io_init(&client->io, (p_send) sock_send, (p_recv) sock_recv, &client->sock); |
219 | tm_init(&client->tm, -1, -1); | 224 | tm_init(&client->tm, -1, -1); |
@@ -273,6 +278,33 @@ static int meth_close(lua_State *L) | |||
273 | } | 278 | } |
274 | 279 | ||
275 | /*-------------------------------------------------------------------------*\ | 280 | /*-------------------------------------------------------------------------*\ |
281 | * Shuts the connection down | ||
282 | \*-------------------------------------------------------------------------*/ | ||
283 | static int meth_shutdown(lua_State *L) | ||
284 | { | ||
285 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); | ||
286 | const char *how = luaL_optstring(L, 2, "both"); | ||
287 | switch (how[0]) { | ||
288 | case 'b': | ||
289 | if (strcmp(how, "both")) goto error; | ||
290 | sock_shutdown(&tcp->sock, 2); | ||
291 | break; | ||
292 | case 's': | ||
293 | if (strcmp(how, "send")) goto error; | ||
294 | sock_shutdown(&tcp->sock, 1); | ||
295 | break; | ||
296 | case 'r': | ||
297 | if (strcmp(how, "receive")) goto error; | ||
298 | sock_shutdown(&tcp->sock, 0); | ||
299 | break; | ||
300 | } | ||
301 | return 0; | ||
302 | error: | ||
303 | luaL_argerror(L, 2, "invalid shutdown method"); | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | /*-------------------------------------------------------------------------*\ | ||
276 | * Just call inet methods | 308 | * Just call inet methods |
277 | \*-------------------------------------------------------------------------*/ | 309 | \*-------------------------------------------------------------------------*/ |
278 | static int meth_getpeername(lua_State *L) | 310 | static int meth_getpeername(lua_State *L) |