aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2000-12-27 19:19:22 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2000-12-27 19:19:22 +0000
commitdf9a7e548f83b0694d7e4096e004858a43ab8a28 (patch)
tree7d15239a131af14f0ff43b05bb74c3a5998f3cc7 /src
parentd455d1707fbdd03592f78a5c5476e90822221359 (diff)
downloadluasocket-df9a7e548f83b0694d7e4096e004858a43ab8a28.tar.gz
luasocket-df9a7e548f83b0694d7e4096e004858a43ab8a28.tar.bz2
luasocket-df9a7e548f83b0694d7e4096e004858a43ab8a28.zip
Added new receive pattern "*a"
Added new bind pattern "*" that binds to INADDR_ANY bind now also returns the ip and port bound to.
Diffstat (limited to 'src')
-rw-r--r--src/luasocket.c588
1 files changed, 386 insertions, 202 deletions
diff --git a/src/luasocket.c b/src/luasocket.c
index 027afa3..ab44490 100644
--- a/src/luasocket.c
+++ b/src/luasocket.c
@@ -3,7 +3,7 @@
3* Diego Nehab 3* Diego Nehab
4* 26/11/1999 4* 26/11/1999
5* 5*
6* Module: LSOCK.C 6* Module: LUASOCKET.C
7* 7*
8* This module is part of an effort to make the most important features 8* This module is part of an effort to make the most important features
9* of the TCP/IP protocol available for Lua scripts. 9* of the TCP/IP protocol available for Lua scripts.
@@ -29,13 +29,11 @@
29 29
30#include <assert.h> 30#include <assert.h>
31 31
32#define LUA_REENTRANT
33
34#include <lua.h> 32#include <lua.h>
35#include <lauxlib.h> 33#include <lauxlib.h>
36#include <lualib.h> 34#include <lualib.h>
37 35
38#include "lsock.h" 36#include "luasocket.h"
39 37
40/*=========================================================================*\ 38/*=========================================================================*\
41* WinSock2 include files 39* WinSock2 include files
@@ -108,22 +106,21 @@
108* function connect, and implementing the methods send, receive, timeout 106* function connect, and implementing the methods send, receive, timeout
109* and close. A server socket is an object created by the function bind, 107* and close. A server socket is an object created by the function bind,
110* and implementing the methods listen, accept and close. Lua tag values 108* and implementing the methods listen, accept and close. Lua tag values
111* for these objects are created in the lua_socklibopen function, and 109* for these objects are created in the lua_socketlibopen function, and
112* passed as closure values (first argumnents to every library function, 110* passed as closure values (first argumnents to every library function,
113# because we can't have any global variables. 111# because we can't have any global variables.
114\*-------------------------------------------------------------------------*/ 112\*-------------------------------------------------------------------------*/
115#define CLIENT_TAG 1 113#define CLIENT_TAG -2
116#define SERVER_TAG 2 114#define SERVER_TAG -1
117#define FIRST_PAR 3
118 115
119/*-------------------------------------------------------------------------*\ 116/*-------------------------------------------------------------------------*\
120* Both socket types are stored in the same structure to simplify 117* Both socket types are stored in the same structure to simplify
121* implementation. The tag value used is different, though. The timeout 118* implementation. The tag value used is different, though. The timeout
122* fields are not used for the server socket object. 119* fields are not used for the server socket object.
123* There are two timeout values. The block timeout specifies the maximum 120* There are two timeout values. The block timeout specifies the maximum
124* time the any IO operation performed by luasock can be blocked waiting 121* time the any IO operation performed by luasocket can be blocked waiting
125* for completion. The return timeout specifies the maximum time a Lua script 122* for completion. The return timeout specifies the maximum time a Lua script
126* can be blocked waiting for an luasock IO operation to complete. 123* can be blocked waiting for an luasocket IO operation to complete.
127\*-------------------------------------------------------------------------*/ 124\*-------------------------------------------------------------------------*/
128typedef struct t_sock { 125typedef struct t_sock {
129 SOCKET sock; /* operating system socket object */ 126 SOCKET sock; /* operating system socket object */
@@ -136,9 +133,6 @@ typedef t_sock *p_sock;
136/*-------------------------------------------------------------------------*\ 133/*-------------------------------------------------------------------------*\
137* Macros and internal declarations 134* Macros and internal declarations
138\*-------------------------------------------------------------------------*/ 135\*-------------------------------------------------------------------------*/
139/* internal function prototypes */
140#include "sock.h"
141
142/* return time since marked start in ms */ 136/* return time since marked start in ms */
143#define time_since(start) (get_time()-start) 137#define time_since(start) (get_time()-start)
144 138
@@ -151,23 +145,84 @@ typedef t_sock *p_sock;
151#endif 145#endif
152 146
153/*=========================================================================*\ 147/*=========================================================================*\
148* Internal function prototypes
149\*=========================================================================*/
150/* luasocket API functions */
151static int net_connect(lua_State *L);
152static int net_bind(lua_State *L);
153static int net_listen(lua_State *L);
154static int net_accept(lua_State *L);
155static int net_send(lua_State *L);
156static int net_receive(lua_State *L);
157static int net_timeout(lua_State *L);
158static int net_close(lua_State *L);
159
160/* fallbacks */
161static int server_gettable(lua_State *L);
162static int client_gettable(lua_State *L);
163static int sock_gc(lua_State *L);
164
165/* argument checking routines */
166static p_sock check_client(lua_State *L, int numArg, int client_tag);
167static p_sock check_server(lua_State *L, int numArg, int server_tag);
168static p_sock check_sock(lua_State *L, int numArg, int server_tag,
169 int client_tag);
170static void pop_tags(lua_State *L, int *client_tag, int *server_tag);
171static void push_tags(lua_State *L, int client_tag, int server_tag);
172
173/* result handling routines */
174static char *host_strerror(void);
175static char *bind_strerror(void);
176static char *sock_strerror(void);
177static char *connect_strerror(void);
178
179static void push_error(lua_State *L, int err);
180static void push_client(lua_State *L, p_sock sock, int client_tag);
181static void push_server(lua_State *L, p_sock sock, int server_tag);
182
183/* plataform specific functions */
184static int get_time(void);
185static void set_blocking(p_sock sock);
186static void set_nonblocking(p_sock sock);
187
188/* auxiliary functions */
189static p_sock create_sock(void);
190static p_sock create_tcpsock(void);
191static int fill_sockaddr(struct sockaddr_in *server, const char *hostname,
192 unsigned short port);
193static int get_timeout(p_sock sock, int elapsed);
194static int read_or_timeout(p_sock sock, int elapsed);
195static int write_or_timeout(p_sock sock, int elapsed);
196static int send_raw(p_sock sock, const char *data, int wanted,
197 int start, int *err, int *end);
198static void receive_raw(lua_State *L, p_sock sock, int wanted,
199 int start, int *err, int *end);
200static void receive_dosline(lua_State *L, p_sock sock, int start,
201 int *err, int *end);
202static void receive_unixline(lua_State *L, p_sock sock, int start,
203 int *err, int *end);
204static void receive_all(lua_State *L, p_sock sock, int start,
205 int *err, int *end);
206
207/*=========================================================================*\
154* Test support functions 208* Test support functions
155\*=========================================================================*/ 209\*=========================================================================*/
156#ifdef _DEBUG 210#ifdef _DEBUG
157/*-------------------------------------------------------------------------*\ 211/*-------------------------------------------------------------------------*\
158* Returns the time the system has been up, in secconds. 212* Returns the time the system has been up, in secconds.
159\*-------------------------------------------------------------------------*/ 213\*-------------------------------------------------------------------------*/
160static void net_time(lua_State *L); 214static int net_time(lua_State *L);
161static void net_time(lua_State *L) 215static int net_time(lua_State *L)
162{ 216{
163 lua_pushnumber(L, get_time()/1000.0); 217 lua_pushnumber(L, get_time()/1000.0);
218 return 1;
164} 219}
165 220
166/*-------------------------------------------------------------------------*\ 221/*-------------------------------------------------------------------------*\
167* Causes a Lua script to sleep for the specified number of secconds 222* Causes a Lua script to sleep for the specified number of secconds
168\*-------------------------------------------------------------------------*/ 223\*-------------------------------------------------------------------------*/
169static void net_sleep(lua_State *L); 224static int net_sleep(lua_State *L);
170static void net_sleep(lua_State *L) 225static int net_sleep(lua_State *L)
171{ 226{
172 int sec = (int) luaL_check_number(L, 1); 227 int sec = (int) luaL_check_number(L, 1);
173#ifdef WIN32 228#ifdef WIN32
@@ -175,6 +230,7 @@ static void net_sleep(lua_State *L)
175#else 230#else
176 sleep(sec); 231 sleep(sec);
177#endif 232#endif
233 return 0;
178} 234}
179 235
180#endif 236#endif
@@ -194,15 +250,19 @@ static void net_sleep(lua_State *L)
194* On success: client socket 250* On success: client socket
195* On error: nil, followed by an error message 251* On error: nil, followed by an error message
196\*-------------------------------------------------------------------------*/ 252\*-------------------------------------------------------------------------*/
197static void net_connect(lua_State *L) 253static int net_connect(lua_State *L)
198{ 254{
199 const char *hostname = luaL_check_string(L, FIRST_PAR); 255 const char *hostname = luaL_check_string(L, 1);
200 unsigned short port = (unsigned short) luaL_check_number(L, FIRST_PAR+1); 256 unsigned short port = (unsigned short) luaL_check_number(L, 2);
257 int client_tag, server_tag;
201 struct sockaddr_in server; 258 struct sockaddr_in server;
202 p_sock sock = create_tcpsock(); 259 p_sock sock;
260 pop_tags(L, &client_tag, &server_tag);
261 sock = create_tcpsock();
203 if (!sock) { 262 if (!sock) {
204 lua_pushnil(L); 263 lua_pushnil(L);
205 lua_pushstring(L, sock_strerror()); 264 lua_pushstring(L, sock_strerror());
265 return 2;
206 } 266 }
207 /* fills the sockaddr structure with the information needed to 267 /* fills the sockaddr structure with the information needed to
208 ** connect our socket with the remote host */ 268 ** connect our socket with the remote host */
@@ -210,17 +270,18 @@ static void net_connect(lua_State *L)
210 free(sock); 270 free(sock);
211 lua_pushnil(L); 271 lua_pushnil(L);
212 lua_pushstring(L, host_strerror()); 272 lua_pushstring(L, host_strerror());
213 return; 273 return 2;
214 } 274 }
215 if (connect(sock->sock,(struct sockaddr *)&server,sizeof(server)) < 0) { 275 if (connect(sock->sock,(struct sockaddr *)&server,sizeof(server)) < 0) {
216 /* no connection? we close the socket to free the descriptor */ 276 /* no connection? we close the socket to free the descriptor */
217 closesocket(sock->sock); 277 closesocket(sock->sock);
218 lua_pushnil(L); 278 lua_pushnil(L);
219 lua_pushstring(L, connect_strerror()); 279 lua_pushstring(L, connect_strerror());
220 return; 280 return 2;
221 } 281 }
222 push_client(L, sock); 282 push_client(L, sock, client_tag);
223 /* no need to push second return value, since it would be nil anyways */ 283 lua_pushnil(L);
284 return 2;
224} 285}
225 286
226/*-------------------------------------------------------------------------*\ 287/*-------------------------------------------------------------------------*\
@@ -232,14 +293,21 @@ static void net_connect(lua_State *L)
232* On success: nil 293* On success: nil
233* On error: an error message 294* On error: an error message
234\*-------------------------------------------------------------------------*/ 295\*-------------------------------------------------------------------------*/
235static void net_listen(lua_State *L) 296static int net_listen(lua_State *L)
236{ 297{
237 p_sock sock = check_server(L, FIRST_PAR); 298 p_sock sock;
238 unsigned int backlog = (unsigned int) luaL_check_number(L, FIRST_PAR+1); 299 int client_tag, server_tag;
239 300 unsigned int backlog;
240 if (listen(sock->sock, backlog) < 0) 301 pop_tags(L, &client_tag, &server_tag);
302 sock = check_server(L, 1, server_tag);
303 backlog = (unsigned int) luaL_check_number(L, 2);
304 if (listen(sock->sock, backlog) < 0) {
241 lua_pushstring(L, "listen error"); 305 lua_pushstring(L, "listen error");
242 /* no need to push return value, since it would be nil anyways */ 306 return 1;
307 } else {
308 lua_pushnil(L);
309 return 1;
310 }
243} 311}
244 312
245/*-------------------------------------------------------------------------*\ 313/*-------------------------------------------------------------------------*\
@@ -251,13 +319,16 @@ static void net_listen(lua_State *L)
251* On success: client socket attempting connection 319* On success: client socket attempting connection
252* On error: nil followed by an error message 320* On error: nil followed by an error message
253\*-------------------------------------------------------------------------*/ 321\*-------------------------------------------------------------------------*/
254static void net_accept(lua_State *L) 322static int net_accept(lua_State *L)
255{ 323{
256 struct sockaddr_in client_addr; 324 struct sockaddr_in client_addr;
257 p_sock server = check_server(L, FIRST_PAR); 325 int client_tag, server_tag;
326 p_sock server;
258 int client_sock = -1; 327 int client_sock = -1;
259 unsigned int client_len = sizeof(client_addr); 328 unsigned int client_len = sizeof(client_addr);
260 p_sock client; 329 p_sock client;
330 pop_tags(L, &client_tag, &server_tag);
331 server = check_server(L, 1, server_tag);
261 /* waits for a connection */ 332 /* waits for a connection */
262 client_sock = accept(server->sock, (struct sockaddr *) &client_addr, 333 client_sock = accept(server->sock, (struct sockaddr *) &client_addr,
263 &client_len); 334 &client_len);
@@ -267,10 +338,13 @@ static void net_accept(lua_State *L)
267 if (!client) { 338 if (!client) {
268 lua_pushnil(L); 339 lua_pushnil(L);
269 lua_pushstring(L, "out of memory"); 340 lua_pushstring(L, "out of memory");
270 return; 341 return 2;
342 } else {
343 client->sock = client_sock;
344 push_client(L, client, client_tag);
345 lua_pushnil(L);
346 return 2;
271 } 347 }
272 client->sock = client_sock;
273 push_client(L, client);
274} 348}
275 349
276/*-------------------------------------------------------------------------*\ 350/*-------------------------------------------------------------------------*\
@@ -281,42 +355,56 @@ static void net_accept(lua_State *L)
281* backlog: optional parameter specifying the number of connections 355* backlog: optional parameter specifying the number of connections
282* to keep waiting before refuse a connection. the default value is 1. 356* to keep waiting before refuse a connection. the default value is 1.
283* Returns 357* Returns
284* On success: server socket bound to address 358* On success: server socket bound to address, the ip address and port bound
285* On error: nil, followed by an error message 359* On error: nil, followed by an error message
286\*-------------------------------------------------------------------------*/ 360\*-------------------------------------------------------------------------*/
287static void net_bind(lua_State *L) 361static int net_bind(lua_State *L)
288{ 362{
289 const char *hostname = luaL_check_string(L, FIRST_PAR); 363 const char *hostname = luaL_check_string(L, 1);
290 unsigned short port = (unsigned short) luaL_check_number(L, FIRST_PAR+1); 364 unsigned short port = (unsigned short) luaL_check_number(L, 2);
291 unsigned int backlog = (unsigned int) luaL_opt_number(L, FIRST_PAR+2, 1.0); 365 unsigned int backlog = (unsigned int) luaL_opt_number(L, 3, 1.0);
292 struct sockaddr_in server; 366 struct sockaddr_in server;
367 int server_size = sizeof(server);
368 int client_tag, server_tag;
293 p_sock sock = create_tcpsock(); 369 p_sock sock = create_tcpsock();
370 pop_tags(L, &client_tag, &server_tag);
294 if (!sock) { 371 if (!sock) {
295 lua_pushnil(L); 372 lua_pushnil(L);
296 lua_pushstring(L, sock_strerror()); 373 lua_pushstring(L, sock_strerror());
374 return 2;
297 } 375 }
298 /* fills the sockaddr structure with the information needed to 376 /* fills the sockaddr structure with the information needed to
299 ** connect our socket with local address */ 377 ** connect our socket with local address */
300 if (!fill_sockaddr(&server, hostname, port)) { 378 else if (!fill_sockaddr(&server, hostname, port)) {
301 free(sock); 379 free(sock);
302 lua_pushnil(L); 380 lua_pushnil(L);
303 lua_pushstring(L, host_strerror()); 381 lua_pushstring(L, host_strerror());
304 return; 382 return 2;
305 } 383 }
306 if (bind(sock->sock,(struct sockaddr *)&server,sizeof(server)) < 0) { 384 else if (bind(sock->sock,(struct sockaddr *)&server, server_size) < 0) {
307 lua_pushnil(L); 385 lua_pushnil(L);
308 lua_pushstring(L, bind_strerror()); 386 lua_pushstring(L, bind_strerror());
309 return; 387 return 2;
310 } 388 }
311 /* define the connection waiting queue length */ 389 /* define the connection waiting queue length */
312 if (listen(sock->sock, backlog) < 0) { 390 else if (listen(sock->sock, backlog) < 0) {
313 lua_pushnil(L); 391 lua_pushnil(L);
314 lua_pushstring(L, "listen error"); 392 lua_pushstring(L, "listen error");
315 return; 393 return 2;
316 } 394 }
317 /* pass the created socket to Lua, as a server socket */ 395 /* pass the created socket to Lua, as a server socket */
318 push_server(L, sock); 396 else {
319 /* no need to push return value, since it would be nil anyways */ 397 /* pass server */
398 push_server(L, sock, server_tag);
399 /* get used address and port */
400 getsockname(sock->sock, (struct sockaddr *)&server, &server_size);
401 /* pass ip number */
402 lua_pushstring(L, inet_ntoa(server.sin_addr));
403 /* pass port number */
404 lua_pushnumber(L, ntohs(server.sin_port));
405 lua_pushnil(L);
406 return 4;
407 }
320} 408}
321 409
322/*-------------------------------------------------------------------------*\ 410/*-------------------------------------------------------------------------*\
@@ -331,11 +419,16 @@ static void net_bind(lua_State *L)
331* Returns 419* Returns
332* no return value 420* no return value
333\*-------------------------------------------------------------------------*/ 421\*-------------------------------------------------------------------------*/
334static void net_timeout(lua_State *L) 422static int net_timeout(lua_State *L)
335{ 423{
336 p_sock sock = check_client(L, FIRST_PAR); 424 int client_tag, server_tag;
337 int ms = (int) (luaL_check_number(L, FIRST_PAR+1)*1000.0); 425 p_sock sock;
338 const char *mode = luaL_opt_string(L, FIRST_PAR+2, "b"); 426 int ms;
427 const char *mode;
428 pop_tags(L, &client_tag, &server_tag);
429 sock = check_client(L, 1, client_tag);
430 ms = (int) (luaL_check_number(L, 2)*1000.0);
431 mode = luaL_opt_string(L, 3, "b");
339 switch (*mode) { 432 switch (*mode) {
340 case 'b': 433 case 'b':
341 sock->b = ms; 434 sock->b = ms;
@@ -344,9 +437,10 @@ static void net_timeout(lua_State *L)
344 sock->r = ms; 437 sock->r = ms;
345 break; 438 break;
346 default: 439 default:
347 luaL_arg_check(L, 0, FIRST_PAR+2, "invalid timeout mode"); 440 luaL_arg_check(L, 0, 3, "invalid timeout mode");
348 break; 441 break;
349 } 442 }
443 return 0;
350} 444}
351 445
352/*-------------------------------------------------------------------------*\ 446/*-------------------------------------------------------------------------*\
@@ -358,33 +452,44 @@ static void net_timeout(lua_State *L)
358* Returns 452* Returns
359* On success: nil, followed by the total number of bytes sent 453* On success: nil, followed by the total number of bytes sent
360* On error: NET_TIMEOUT if the connection timedout, or NET_CLOSED if 454* On error: NET_TIMEOUT if the connection timedout, or NET_CLOSED if
361* the connection has been closed 455* the connection has been closed, followed by the total number of
456* bytes sent
362\*-------------------------------------------------------------------------*/ 457\*-------------------------------------------------------------------------*/
363static void net_send(lua_State *L) 458static int net_send(lua_State *L)
364{ 459{
365 p_sock sock = check_client(L, FIRST_PAR); 460 p_sock sock;
366 const char *data; 461 const char *data;
367 long size; 462 size_t size;
368 int start = get_time(); 463 int start = get_time();
369 long total = 0; 464 long total = 0;
370 int arg = FIRST_PAR+1; 465 int arg;
371 int err = NET_DONE; 466 int err = NET_DONE;
372 int end; 467 int end;
468 int top;
469 int client_tag, server_tag;
470 pop_tags(L, &client_tag, &server_tag);
471 top = lua_gettop(L);
472 sock = check_client(L, 1, client_tag);
373#ifdef _DEBUG_BLOCK 473#ifdef _DEBUG_BLOCK
374printf("luasock: send start\n"); 474printf("luasocket: send start\n");
375#endif 475#endif
376 while ((data = luaL_opt_lstr(L, arg++, NULL, &size)) && err == NET_DONE) 476 for (arg = 2; arg <= top; arg++) {
477 data = luaL_opt_lstr(L, arg, NULL, &size);
478 if (!data || err != NET_DONE)
479 break;
377 total += send_raw(sock, data, size, start, &err, &end); 480 total += send_raw(sock, data, size, start, &err, &end);
481 }
378 push_error(L, err); 482 push_error(L, err);
379 lua_pushnumber(L, (double) total); 483 lua_pushnumber(L, (double) total);
380#ifdef _DEBUG_BLOCK 484#ifdef _DEBUG_BLOCK
381printf("luasock: send end\n"); 485printf("luasocket: send end\n");
382#endif 486#endif
383#ifdef _DEBUG 487#ifdef _DEBUG
384/* pass the time elapsed during function execution to Lua, so that 488/* pass the time elapsed during function execution to Lua, so that
385** the test script can make sure we respected the timeouts */ 489** the test script can make sure we respected the timeouts */
386lua_pushnumber(L, (end-start)/1000.0); 490lua_pushnumber(L, (end-start)/1000.0);
387#endif 491#endif
492 return lua_gettop(L) - top;
388} 493}
389 494
390/*-------------------------------------------------------------------------*\ 495/*-------------------------------------------------------------------------*\
@@ -399,57 +504,73 @@ lua_pushnumber(L, (end-start)/1000.0);
399* number: reads 'number' characters from the socket 504* number: reads 'number' characters from the socket
400* Returns 505* Returns
401* On success: one string for each pattern 506* On success: one string for each pattern
402* On error: all strings for which there was no error, followed by on 507* On error: all strings for which there was no error, followed by one
403* nil value for each failed string, followed by an error code 508* nil value for each failed string, followed by an error code
404\*-------------------------------------------------------------------------*/ 509\*-------------------------------------------------------------------------*/
405static void net_receive(lua_State *L) 510static int net_receive(lua_State *L)
406{ 511{
407 static const char *const modenames[] = {"*l", "*lu", NULL}; 512 static const char *const modenames[] = {"*l", "*lu", "*a", NULL};
408 p_sock sock = check_client(L, FIRST_PAR); 513 int err = NET_DONE, arg = 2;
409 int err = NET_DONE, arg = FIRST_PAR+1, got = 0;
410 char *data = NULL;
411 int start = get_time(); 514 int start = get_time();
412 const char *mode = luaL_opt_string(L, arg++, "*l");
413 int end; 515 int end;
516 int client_tag, server_tag;
517 int top;
518 p_sock sock;
519 const char *mode;
520 pop_tags(L, &client_tag, &server_tag);
521 sock = check_client(L, 1, client_tag);
414#ifdef _DEBUG_BLOCK 522#ifdef _DEBUG_BLOCK
415printf("luasock: receive start\n"); 523printf("luasocket: receive start\n");
416#endif 524#endif
417 do { 525 /* push default pattern */
526 top = lua_gettop(L);
527 if (top < 2) {
528 lua_pushstring(L, "*l");
529 top++;
530 }
531 for (arg = 2; arg <= top; arg++) {
418 /* if one pattern failed, we just skip all other patterns */ 532 /* if one pattern failed, we just skip all other patterns */
419 if (err != NET_DONE) { 533 if (err != NET_DONE) {
420 lua_pushnil(L); 534 lua_pushnil(L);
421 continue; 535 continue;
422 } 536 }
423 /* get next pattern */ 537 if (lua_isnumber(L, arg)) {
424 switch (luaL_findstring(mode, modenames)) { 538 long size = (long) lua_tonumber(L, arg);
425 /* DOS line mode */ 539 receive_raw(L, sock, size, start, &err, &end);
426 case 0: 540 } else {
427 got = receive_dosline(L, sock, &data, start, &err, &end); 541 mode = luaL_opt_string(L, arg, NULL);
428 break; 542 /* get next pattern */
429 /* Unix line mode */ 543 switch (luaL_findstring(mode, modenames)) {
430 case 2: 544 /* DOS line mode */
431 got = receive_unixline(L, sock, &data, start, &err, &end); 545 case 0:
432 break; 546 receive_dosline(L, sock, start, &err, &end);
433 /* else it must be a number, raw mode */ 547 break;
434 default: { 548 /* Unix line mode */
435 long size = (long) luaL_check_number(L, arg-1); 549 case 1:
436 got = receive_raw(L, sock, size, &data, start, &err, &end); 550 receive_unixline(L, sock, start, &err, &end);
437 break; 551 break;
552 /* 'Til closed mode */
553 case 2:
554 receive_all(L, sock, start, &err, &end);
555 break;
556 /* else it must be a number, raw mode */
557 default:
558 luaL_arg_check(L, 0, arg, "invalid receive pattern");
559 break;
438 } 560 }
439 } 561 }
440 /* pass result */ 562 }
441 lua_pushlstring(L, data, got);
442 } while ((mode = luaL_opt_string(L, arg++, NULL)));
443 /* last return is an error code */ 563 /* last return is an error code */
444 push_error(L, err); 564 push_error(L, err);
445#ifdef _DEBUG_BLOCK 565#ifdef _DEBUG_BLOCK
446printf("luasock: receive end\n"); 566printf("luasocket: receive end\n");
447#endif 567#endif
448#ifdef _DEBUG 568#ifdef _DEBUG
449/* pass the time elapsed during function execution to Lua, so that 569/* pass the time elapsed during function execution to Lua, so that
450** the test script can make sure we respected the timeouts */ 570** the test script can make sure we respected the timeouts */
451lua_pushnumber(L, (end-start)/1000.0); 571lua_pushnumber(L, (end-start)/1000.0);
452#endif 572#endif
573 return lua_gettop(L) - top;
453} 574}
454 575
455/*-------------------------------------------------------------------------*\ 576/*-------------------------------------------------------------------------*\
@@ -457,13 +578,17 @@ lua_pushnumber(L, (end-start)/1000.0);
457* Input 578* Input
458* sock: socket to be closed 579* sock: socket to be closed
459\*-------------------------------------------------------------------------*/ 580\*-------------------------------------------------------------------------*/
460static void net_close(lua_State *L) 581static int net_close(lua_State *L)
461{ 582{
462 p_sock sock = check_sock(L, FIRST_PAR); 583 int client_tag, server_tag;
584 p_sock sock;
585 pop_tags(L, &client_tag, &server_tag);
586 sock = check_sock(L, 1, client_tag, server_tag);
463 closesocket(sock->sock); 587 closesocket(sock->sock);
464 /* set value to -1 so that we can later detect the use of a 588 /* set value to -1 so that we can later detect the use of a
465 ** closed socket */ 589 ** closed socket */
466 sock->sock = -1; 590 sock->sock = -1;
591 return 0;
467} 592}
468 593
469/*-------------------------------------------------------------------------*\ 594/*-------------------------------------------------------------------------*\
@@ -471,36 +596,35 @@ static void net_close(lua_State *L)
471* alternative interface client:receive, client:send etc for the client 596* alternative interface client:receive, client:send etc for the client
472* socket methods. 597* socket methods.
473\*-------------------------------------------------------------------------*/ 598\*-------------------------------------------------------------------------*/
474static void client_gettable(lua_State *L) 599static int client_gettable(lua_State *L)
475{ 600{
476 static const char *const net_api[] = {"receive","send","timeout","close", 601 static const char *const net_api[] = {"receive","send","timeout","close",
477 "connect", NULL}; 602 "connect", NULL};
478 const char *idx = luaL_check_string(L, FIRST_PAR+1); 603 const char *idx = luaL_check_string(L, 2);
604 int server_tag, client_tag;
605 pop_tags(L, &client_tag, &server_tag);
479 switch (luaL_findstring(idx, net_api)) { 606 switch (luaL_findstring(idx, net_api)) {
480 case 0: 607 case 0:
481 lua_pushnumber(L, get_tag(L, CLIENT_TAG)); 608 push_tags(L, client_tag, server_tag);
482 lua_pushnumber(L, get_tag(L, SERVER_TAG));
483 lua_pushcclosure(L, net_receive, 2); 609 lua_pushcclosure(L, net_receive, 2);
484 break; 610 break;
485 case 1: 611 case 1:
486 lua_pushnumber(L, get_tag(L, CLIENT_TAG)); 612 push_tags(L, client_tag, server_tag);
487 lua_pushnumber(L, get_tag(L, SERVER_TAG));
488 lua_pushcclosure(L, net_send, 2); 613 lua_pushcclosure(L, net_send, 2);
489 break; 614 break;
490 case 2: 615 case 2:
491 lua_pushnumber(L, get_tag(L, CLIENT_TAG)); 616 push_tags(L, client_tag, server_tag);
492 lua_pushnumber(L, get_tag(L, SERVER_TAG));
493 lua_pushcclosure(L, net_timeout, 2); 617 lua_pushcclosure(L, net_timeout, 2);
494 break; 618 break;
495 case 3: 619 case 3:
496 lua_pushnumber(L, get_tag(L, CLIENT_TAG)); 620 push_tags(L, client_tag, server_tag);
497 lua_pushnumber(L, get_tag(L, SERVER_TAG));
498 lua_pushcclosure(L, net_close, 2); 621 lua_pushcclosure(L, net_close, 2);
499 break; 622 break;
500 default: 623 default:
501 lua_pushnil(L); 624 lua_pushnil(L);
502 break; 625 break;
503 } 626 }
627 return 1;
504} 628}
505 629
506/*-------------------------------------------------------------------------*\ 630/*-------------------------------------------------------------------------*\
@@ -508,30 +632,30 @@ static void client_gettable(lua_State *L)
508* alternative interface server:listen, server:accept etc for the server 632* alternative interface server:listen, server:accept etc for the server
509* socket methods. 633* socket methods.
510\*-------------------------------------------------------------------------*/ 634\*-------------------------------------------------------------------------*/
511static void server_gettable(lua_State *L) 635static int server_gettable(lua_State *L)
512{ 636{
513 static const char *const net_api[] = {"listen","accept","close", NULL}; 637 static const char *const net_api[] = {"listen","accept","close", NULL};
514 const char *idx = luaL_check_string(L, FIRST_PAR+1); 638 const char *idx = luaL_check_string(L, 2);
639 int server_tag, client_tag;
640 pop_tags(L, &client_tag, &server_tag);
515 switch (luaL_findstring(idx, net_api)) { 641 switch (luaL_findstring(idx, net_api)) {
516 case 0: 642 case 0:
517 lua_pushnumber(L, get_tag(L, CLIENT_TAG)); 643 push_tags(L, client_tag, server_tag);
518 lua_pushnumber(L, get_tag(L, SERVER_TAG));
519 lua_pushcclosure(L, net_listen, 2); 644 lua_pushcclosure(L, net_listen, 2);
520 break; 645 break;
521 case 1: 646 case 1:
522 lua_pushnumber(L, get_tag(L, CLIENT_TAG)); 647 push_tags(L, client_tag, server_tag);
523 lua_pushnumber(L, get_tag(L, SERVER_TAG));
524 lua_pushcclosure(L, net_accept, 2); 648 lua_pushcclosure(L, net_accept, 2);
525 break; 649 break;
526 case 2: 650 case 2:
527 lua_pushnumber(L, get_tag(L, CLIENT_TAG)); 651 push_tags(L, client_tag, server_tag);
528 lua_pushnumber(L, get_tag(L, SERVER_TAG));
529 lua_pushcclosure(L, net_close, 2); 652 lua_pushcclosure(L, net_close, 2);
530 break; 653 break;
531 default: 654 default:
532 lua_pushnil(L); 655 lua_pushnil(L);
533 break; 656 break;
534 } 657 }
658 return 1;
535} 659}
536 660
537/*-------------------------------------------------------------------------*\ 661/*-------------------------------------------------------------------------*\
@@ -539,12 +663,16 @@ static void server_gettable(lua_State *L)
539* makes sure that all collected sockets are closed and that the memory 663* makes sure that all collected sockets are closed and that the memory
540* used by the C structure t_sock is properly released. 664* used by the C structure t_sock is properly released.
541\*-------------------------------------------------------------------------*/ 665\*-------------------------------------------------------------------------*/
542static void sock_gc(lua_State *L) 666static int sock_gc(lua_State *L)
543{ 667{
544 p_sock sock = check_sock(L, FIRST_PAR); 668 int server_tag, client_tag;
669 p_sock sock;
670 pop_tags(L, &client_tag, &server_tag);
671 sock = check_sock(L, 1, client_tag, server_tag);
545 if (sock->sock >= 0) 672 if (sock->sock >= 0)
546 closesocket(sock->sock); 673 closesocket(sock->sock);
547 free(sock); 674 free(sock);
675 return 1;
548} 676}
549 677
550/*=========================================================================*\ 678/*=========================================================================*\
@@ -637,19 +765,24 @@ static int fill_sockaddr(struct sockaddr_in *address, const char *hostname,
637{ 765{
638 struct hostent *host = NULL; 766 struct hostent *host = NULL;
639 unsigned long addr = inet_addr(hostname); 767 unsigned long addr = inet_addr(hostname);
640 /* BSD says we could have used gethostbyname even if the hostname is
641 ** in ip address form, but WinSock2 says we can't. Therefore we
642 ** choose a method that works on both plataforms */
643 if (addr == INADDR_NONE)
644 host = gethostbyname(hostname);
645 else
646 host = gethostbyaddr((char * ) &addr, sizeof(unsigned long), AF_INET);
647 if (!host)
648 return 0;
649 memset(address, 0, sizeof(struct sockaddr_in)); 768 memset(address, 0, sizeof(struct sockaddr_in));
769 if (strcmp(hostname, "*")) {
770 /* BSD says we could have used gethostbyname even if the hostname is
771 ** in ip address form, but WinSock2 says we can't. Therefore we
772 ** choose a method that works on both plataforms */
773 if (addr == INADDR_NONE)
774 host = gethostbyname(hostname);
775 else
776 host = gethostbyaddr((char * ) &addr, sizeof(unsigned long),
777 AF_INET);
778 if (!host)
779 return 0;
780 memcpy(&(address->sin_addr), host->h_addr, (unsigned) host->h_length);
781 } else {
782 address->sin_addr.s_addr = htonl(INADDR_ANY);
783 }
650 address->sin_family = AF_INET; 784 address->sin_family = AF_INET;
651 address->sin_port = htons(port); 785 address->sin_port = htons(port);
652 memcpy(&(address->sin_addr), host->h_addr, (unsigned) host->h_length);
653 return 1; 786 return 1;
654} 787}
655 788
@@ -776,7 +909,7 @@ static int send_raw(p_sock sock, const char *data, int wanted,
776#ifdef _DEBUG 909#ifdef _DEBUG
777/* the lua_pushlstring function can take a long time to pass a large block 910/* the lua_pushlstring function can take a long time to pass a large block
778** to Lua, therefore, we mark the time before passing the result. 911** to Lua, therefore, we mark the time before passing the result.
779** also, the call to write of read might take longer then the time we had 912** also, the call to write or read might take longer then the time we had
780** left, so that the end of the operation is marked before the last call 913** left, so that the end of the operation is marked before the last call
781** to the OS */ 914** to the OS */
782*end = get_time(); 915*end = get_time();
@@ -795,7 +928,7 @@ static int send_raw(p_sock sock, const char *data, int wanted,
795 return total; 928 return total;
796 } 929 }
797#ifdef _DEBUG_BLOCK 930#ifdef _DEBUG_BLOCK
798printf("luasock: sent %d bytes, %dms elapsed\n", put, time_since(start)); 931printf("luasocket: sent %d bytes, %dms elapsed\n", put, time_since(start));
799#endif 932#endif
800 wanted -= put; 933 wanted -= put;
801 data += put; 934 data += put;
@@ -813,46 +946,84 @@ printf("luasock: sent %d bytes, %dms elapsed\n", put, time_since(start));
813* wanted: number of bytes to be read 946* wanted: number of bytes to be read
814* start: time the operation started, in ms 947* start: time the operation started, in ms
815* Output 948* Output
816* data: pointer to an internal buffer containing the data read
817* err: operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED 949* err: operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED
818* Returns 950* Returns
819* Number of bytes read 951* Number of bytes read
820\*-------------------------------------------------------------------------*/ 952\*-------------------------------------------------------------------------*/
821static int receive_raw(lua_State *L, p_sock sock, int wanted, char **data, 953#define MIN(x,y) ((x)<(y)?(x):(y))
822 int start, int *err, int *end) 954static void receive_raw(lua_State *L, p_sock sock, int wanted, int start,
955 int *err, int *end)
823{ 956{
824 int got = 0; 957 int got = 0;
825 char *buffer = NULL; 958 char *buffer = NULL;
959 luaL_Buffer b;
826 *end = start; 960 *end = start;
827 luaL_resetbuffer(L); 961 luaL_buffinit(L, &b);
828 while (wanted > 0) { 962 while (wanted > 0) {
829 buffer = luaL_openspace(L, wanted);
830 if(!read_or_timeout(sock, time_since(start))) { 963 if(!read_or_timeout(sock, time_since(start))) {
831#ifdef _DEBUG 964#ifdef _DEBUG
832*end = get_time(); 965*end = get_time();
833#endif 966#endif
834 *data = luaL_buffer(L);
835 *err = NET_TIMEOUT; 967 *err = NET_TIMEOUT;
836 return luaL_getsize(L); 968 luaL_pushresult(&b);
969 return;
837 } 970 }
838#ifdef _DEBUG 971#ifdef _DEBUG
839*end = get_time(); 972*end = get_time();
840#endif 973#endif
841 got = recv(sock->sock, buffer, wanted, 0); 974 buffer = luaL_prepbuffer(&b);
975 got = recv(sock->sock, buffer, MIN(wanted, LUAL_BUFFERSIZE), 0);
842#ifdef _DEBUG_BLOCK 976#ifdef _DEBUG_BLOCK
843printf("luasock: wanted %d, got %d, %dms elapsed\n", wanted, got, time_since(start)); 977printf("luasocket: wanted %d, got %d, %dms elapsed\n", wanted, got, time_since(start));
844#endif 978#endif
845 if (got <= 0) { 979 if (got <= 0) {
846 *data = luaL_buffer(L);
847 *err = NET_CLOSED; 980 *err = NET_CLOSED;
848 return luaL_getsize(L); 981 luaL_pushresult(&b);
982 return;
849 } 983 }
850 wanted -= got; 984 wanted -= got;
851 luaL_addsize(L,got); 985 luaL_addsize(&b, got);
852 } 986 }
853 *data = luaL_buffer(L);
854 *err = NET_DONE; 987 *err = NET_DONE;
855 return luaL_getsize(L); 988 luaL_pushresult(&b);
989}
990
991/*-------------------------------------------------------------------------*\
992* Reads everything until the connection is closed
993* Input
994* sock: socket structure being used in operation
995* start: time the operation started, in ms
996* Output
997* err: operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED
998* Result
999* a string is pushed into the Lua stack with the line just read
1000\*-------------------------------------------------------------------------*/
1001static void receive_all(lua_State *L, p_sock sock, int start,
1002 int *err, int *end)
1003{
1004 int got;
1005 char *buffer;
1006 luaL_Buffer b;
1007 *end = start;
1008 luaL_buffinit(L, &b);
1009 for ( ;; ) {
1010 buffer = luaL_prepbuffer(&b);
1011 if (read_or_timeout(sock, time_since(start))) {
1012#ifdef _DEBUG
1013*end = get_time();
1014#endif
1015 got = recv(sock->sock, buffer, LUAL_BUFFERSIZE, 0);
1016 if (got <= 0) {
1017 *err = NET_DONE;
1018 break;
1019 }
1020 luaL_addsize(&b, got);
1021 } else {
1022 *err = NET_TIMEOUT;
1023 break;
1024 }
1025 }
1026 luaL_pushresult(&b);
856} 1027}
857 1028
858/*-------------------------------------------------------------------------*\ 1029/*-------------------------------------------------------------------------*\
@@ -866,17 +1037,18 @@ printf("luasock: wanted %d, got %d, %dms elapsed\n", wanted, got, time_since(sta
866* Output 1037* Output
867* data: pointer to an internal buffer containing the data read 1038* data: pointer to an internal buffer containing the data read
868* err: operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED 1039* err: operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED
869* Returns 1040* Result
870* Number of bytes read 1041* a string is pushed into the Lua stack with the line just read
871\*-------------------------------------------------------------------------*/ 1042\*-------------------------------------------------------------------------*/
872static long receive_dosline(lua_State *L, p_sock sock, char **data, 1043static void receive_dosline(lua_State *L, p_sock sock, int start,
873 int start, int *err, int *end) 1044 int *err, int *end)
874{ 1045{
875 char c = ' '; 1046 char c = ' ';
876 long got = 0; 1047 long got = 0;
1048 luaL_Buffer b;
877 *end = start; 1049 *end = start;
878 luaL_resetbuffer(L); 1050 luaL_buffinit(L, &b);
879 while (c != '\n') { 1051 for ( ;; ) {
880 if (read_or_timeout(sock, time_since(start))) { 1052 if (read_or_timeout(sock, time_since(start))) {
881#ifdef _DEBUG 1053#ifdef _DEBUG
882*end = get_time(); 1054*end = get_time();
@@ -884,21 +1056,20 @@ static long receive_dosline(lua_State *L, p_sock sock, char **data,
884 got = recv(sock->sock, &c, 1, 0); 1056 got = recv(sock->sock, &c, 1, 0);
885 if (got <= 0) { 1057 if (got <= 0) {
886 *err = NET_CLOSED; 1058 *err = NET_CLOSED;
887 *data = luaL_buffer(L); 1059 break;
888 return luaL_getsize(L); 1060 }
1061 if (c != '\n') {
1062 if (c != '\r') luaL_putchar(&b, c);
1063 } else {
1064 *err = NET_DONE;
1065 break;
889 } 1066 }
890 luaL_addchar(L, c);
891 } else { 1067 } else {
892 *err = NET_TIMEOUT; 1068 *err = NET_TIMEOUT;
893 *data = luaL_buffer(L); 1069 break;
894 return luaL_getsize(L);
895 } 1070 }
896 } 1071 }
897 *err = NET_DONE; 1072 luaL_pushresult(&b);
898 *data = luaL_buffer(L);
899 got = luaL_getsize(L);
900 if ((*data)[got-2] == '\r') return got-2;
901 else return got-1;
902} 1073}
903 1074
904/*-------------------------------------------------------------------------*\ 1075/*-------------------------------------------------------------------------*\
@@ -915,43 +1086,50 @@ static long receive_dosline(lua_State *L, p_sock sock, char **data,
915* Returns 1086* Returns
916* Number of bytes read 1087* Number of bytes read
917\*-------------------------------------------------------------------------*/ 1088\*-------------------------------------------------------------------------*/
918static long receive_unixline(lua_State *L, p_sock sock, char **data, 1089static void receive_unixline(lua_State *L, p_sock sock, int start,
919 int start, int *err, int *end) 1090 int *err, int *end)
920{ 1091{
921 char c = ' '; 1092 char c = ' ';
1093 long got = 0;
1094 long size = 0;
1095 luaL_Buffer b;
922 *end = start; 1096 *end = start;
923 luaL_resetbuffer(L); 1097 luaL_buffinit(L, &b);
924 while (c != '\n') { 1098 for ( ;; ) {
925 if (read_or_timeout(sock, time_since(start))) { 1099 if (read_or_timeout(sock, time_since(start))) {
926#ifdef _DEBUG 1100#ifdef _DEBUG
927*end = get_time(); 1101*end = get_time();
928#endif 1102#endif
929 if (recv(sock->sock, &c, 1, 0) <= 0) { 1103 got = recv(sock->sock, &c, 1, 0);
1104 if (got <= 0) {
930 *err = NET_CLOSED; 1105 *err = NET_CLOSED;
931 *data = luaL_buffer(L); 1106 break;
932 return luaL_getsize(L); 1107 }
1108 if (c != '\n') {
1109 luaL_putchar(&b, c);
1110 size++;
1111 } else {
1112 *err = NET_DONE;
1113 break;
933 } 1114 }
934 luaL_addchar(L, c);
935 } else { 1115 } else {
936 *err = NET_TIMEOUT; 1116 *err = NET_TIMEOUT;
937 *data = luaL_buffer(L); 1117 break;
938 return luaL_getsize(L);
939 } 1118 }
940 } 1119 }
941 *err = NET_DONE; 1120 luaL_pushresult(&b);
942 *data = luaL_buffer(L);
943 return luaL_getsize(L) - 1;
944} 1121}
945 1122
946/*-------------------------------------------------------------------------*\ 1123/*-------------------------------------------------------------------------*\
947* Gets a tag from a closure parameter 1124* Pops tags from closures
948* Input 1125* Input
949* L: lua environment 1126* L: lua environment
950* par: parameter number
951\*-------------------------------------------------------------------------*/ 1127\*-------------------------------------------------------------------------*/
952static int get_tag(lua_State *L, int par) 1128static void pop_tags(lua_State *L, int *client_tag, int *server_tag)
953{ 1129{
954 return (int) lua_getnumber(L, lua_getparam(L, par)); 1130 *client_tag = (int) lua_tonumber(L, CLIENT_TAG);
1131 *server_tag = (int) lua_tonumber(L, SERVER_TAG);
1132 lua_pop(L, 2);
955} 1133}
956 1134
957/*-------------------------------------------------------------------------*\ 1135/*-------------------------------------------------------------------------*\
@@ -975,6 +1153,17 @@ static void push_error(lua_State *L, int err)
975} 1153}
976 1154
977/*-------------------------------------------------------------------------*\ 1155/*-------------------------------------------------------------------------*\
1156* Passes socket tags to lua in correct order
1157* Input:
1158* client_tag, server_tag
1159\*-------------------------------------------------------------------------*/
1160static void push_tags(lua_State *L, int client_tag, int server_tag)
1161{
1162 lua_pushnumber(L, client_tag);
1163 lua_pushnumber(L, server_tag);
1164}
1165
1166/*-------------------------------------------------------------------------*\
978* Passes a client socket to Lua. 1167* Passes a client socket to Lua.
979* Must be called from a closure receiving the socket tags as its 1168* Must be called from a closure receiving the socket tags as its
980* parameters. 1169* parameters.
@@ -982,9 +1171,9 @@ static void push_error(lua_State *L, int err)
982* L: lua environment 1171* L: lua environment
983* sock: pointer to socket structure to be used 1172* sock: pointer to socket structure to be used
984\*-------------------------------------------------------------------------*/ 1173\*-------------------------------------------------------------------------*/
985static void push_client(lua_State *L, p_sock sock) 1174static void push_client(lua_State *L, p_sock sock, int client_tag)
986{ 1175{
987 lua_pushusertag(L, (void *) sock, get_tag(L, CLIENT_TAG)); 1176 lua_pushusertag(L, (void *) sock, client_tag);
988} 1177}
989 1178
990/*-------------------------------------------------------------------------*\ 1179/*-------------------------------------------------------------------------*\
@@ -995,9 +1184,9 @@ static void push_client(lua_State *L, p_sock sock)
995* L: lua environment 1184* L: lua environment
996* sock: pointer to socket structure to be used 1185* sock: pointer to socket structure to be used
997\*-------------------------------------------------------------------------*/ 1186\*-------------------------------------------------------------------------*/
998static void push_server(lua_State *L, p_sock sock) 1187static void push_server(lua_State *L, p_sock sock, int server_tag)
999{ 1188{
1000 lua_pushusertag(L, (void *) sock, get_tag(L, SERVER_TAG)); 1189 lua_pushusertag(L, (void *) sock, server_tag);
1001} 1190}
1002 1191
1003/*=========================================================================*\ 1192/*=========================================================================*\
@@ -1233,7 +1422,7 @@ static char *connect_strerror(void)
1233* Initializes the library interface with Lua and the socket library. 1422* Initializes the library interface with Lua and the socket library.
1234* Defines the symbols exported to Lua. 1423* Defines the symbols exported to Lua.
1235\*-------------------------------------------------------------------------*/ 1424\*-------------------------------------------------------------------------*/
1236void lua_socklibopen(lua_State *L) 1425void lua_socketlibopen(lua_State *L)
1237{ 1426{
1238 int client_tag, server_tag; 1427 int client_tag, server_tag;
1239 static struct luaL_reg funcs[] = { 1428 static struct luaL_reg funcs[] = {
@@ -1256,29 +1445,24 @@ void lua_socklibopen(lua_State *L)
1256 server_tag = lua_newtag(L); 1445 server_tag = lua_newtag(L);
1257 /* Lua exported functions */ 1446 /* Lua exported functions */
1258 for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) { 1447 for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) {
1259 lua_pushnumber(L, client_tag); 1448 push_tags(L, client_tag, server_tag);
1260 lua_pushnumber(L, server_tag); 1449 lua_pushcclosure(L, funcs[i].func, 2);
1261 lua_pushcclosure(L, funcs[i].func, 2 ); 1450 lua_setglobal(L, funcs[i].name);
1262 lua_setglobal(L, funcs[i].name );
1263 } 1451 }
1264 /* fallbacks */ 1452 /* fallbacks */
1265 lua_pushnumber(L, client_tag); 1453 push_tags(L, client_tag, server_tag);
1266 lua_pushnumber(L, server_tag);
1267 lua_pushcclosure(L, client_gettable, 2); 1454 lua_pushcclosure(L, client_gettable, 2);
1268 lua_settagmethod(L, client_tag, "gettable"); 1455 lua_settagmethod(L, client_tag, "gettable");
1269 1456
1270 lua_pushnumber(L, client_tag); 1457 push_tags(L, client_tag, server_tag);
1271 lua_pushnumber(L, server_tag);
1272 lua_pushcclosure(L, server_gettable, 2); 1458 lua_pushcclosure(L, server_gettable, 2);
1273 lua_settagmethod(L, server_tag, "gettable"); 1459 lua_settagmethod(L, server_tag, "gettable");
1274 1460
1275 lua_pushnumber(L, client_tag); 1461 push_tags(L, client_tag, server_tag);
1276 lua_pushnumber(L, server_tag);
1277 lua_pushcclosure(L, sock_gc, 2); 1462 lua_pushcclosure(L, sock_gc, 2);
1278 lua_settagmethod(L, client_tag, "gc"); 1463 lua_settagmethod(L, client_tag, "gc");
1279 1464
1280 lua_pushnumber(L, client_tag); 1465 push_tags(L, client_tag, server_tag);
1281 lua_pushnumber(L, server_tag);
1282 lua_pushcclosure(L, sock_gc, 2); 1466 lua_pushcclosure(L, sock_gc, 2);
1283 lua_settagmethod(L, server_tag, "gc"); 1467 lua_settagmethod(L, server_tag, "gc");
1284 1468
@@ -1308,13 +1492,12 @@ lua_pushcfunction(L, net_time); lua_setglobal(L, "time");
1308* Returns 1492* Returns
1309* pointer to client socket, or doesn't return in case of error 1493* pointer to client socket, or doesn't return in case of error
1310\*-------------------------------------------------------------------------*/ 1494\*-------------------------------------------------------------------------*/
1311static p_sock check_client(lua_State *L, int numArg) 1495static p_sock check_client(lua_State *L, int numArg, int client_tag)
1312{ 1496{
1313 p_sock sock; 1497 p_sock sock;
1314 lua_Object o = lua_getparam(L, numArg); 1498 luaL_arg_check(L, lua_tag(L, numArg) == client_tag,
1315 luaL_arg_check(L, lua_tag(L, o) == get_tag(L, CLIENT_TAG),
1316 numArg, "client socket expected"); 1499 numArg, "client socket expected");
1317 sock = (p_sock) lua_getuserdata(L, o); 1500 sock = (p_sock) lua_touserdata(L, numArg);
1318 if (sock->sock < 0) 1501 if (sock->sock < 0)
1319 lua_error(L, "operation on closed socket"); 1502 lua_error(L, "operation on closed socket");
1320 return sock; 1503 return sock;
@@ -1328,13 +1511,12 @@ static p_sock check_client(lua_State *L, int numArg)
1328* Returns 1511* Returns
1329* pointer to server socket, or doesn't return in case of error 1512* pointer to server socket, or doesn't return in case of error
1330\*-------------------------------------------------------------------------*/ 1513\*-------------------------------------------------------------------------*/
1331static p_sock check_server(lua_State *L, int numArg) 1514static p_sock check_server(lua_State *L, int numArg, int server_tag)
1332{ 1515{
1333 p_sock sock; 1516 p_sock sock;
1334 lua_Object o = lua_getparam(L, numArg); 1517 luaL_arg_check(L, lua_tag(L, numArg) == server_tag,
1335 luaL_arg_check(L, lua_tag(L, o) == get_tag(L, SERVER_TAG),
1336 numArg, "server socket expected"); 1518 numArg, "server socket expected");
1337 sock = (p_sock) lua_getuserdata(L, o); 1519 sock = (p_sock) lua_touserdata(L, numArg);
1338 if (sock->sock < 0) 1520 if (sock->sock < 0)
1339 lua_error(L, "operation on closed socket"); 1521 lua_error(L, "operation on closed socket");
1340 return sock; 1522 return sock;
@@ -1348,10 +1530,12 @@ static p_sock check_server(lua_State *L, int numArg)
1348* Returns 1530* Returns
1349* pointer to socket, or doesn't return in case of error 1531* pointer to socket, or doesn't return in case of error
1350\*-------------------------------------------------------------------------*/ 1532\*-------------------------------------------------------------------------*/
1351static p_sock check_sock(lua_State *L, int numArg) 1533static p_sock check_sock(lua_State *L, int numArg, int client_tag,
1534 int server_tag)
1352{ 1535{
1353 lua_Object o = lua_getparam(L, numArg); 1536 p_sock sock;
1354 luaL_arg_check(L, (lua_tag(L, o) == get_tag(L, CLIENT_TAG)) || 1537 luaL_arg_check(L, (lua_tag(L, numArg) == client_tag) ||
1355 (lua_tag(L, o) == get_tag(L, SERVER_TAG)), numArg, "socket expected"); 1538 (lua_tag(L, numArg) == server_tag), numArg, "socket expected");
1356 return lua_getuserdata(L, o); 1539 sock = lua_touserdata(L, numArg);
1540 return sock;
1357} 1541}