aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2001-01-15 04:16:35 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2001-01-15 04:16:35 +0000
commit84baa83864b4832844151aef694465ddf96c28f3 (patch)
tree6d9f528b6f1b90b6660467cca329b6dc6ebff299 /src
parentb40d2ba005034c36c6b7f4439e6d6df1ef08d5e4 (diff)
downloadluasocket-84baa83864b4832844151aef694465ddf96c28f3.tar.gz
luasocket-84baa83864b4832844151aef694465ddf96c28f3.tar.bz2
luasocket-84baa83864b4832844151aef694465ddf96c28f3.zip
The actuall bind to the Lua language has been rewritten with
generalized use of closure values. Sockets are now real tables, where each method receives a p_sock structure as a closure. Global version of methods are now optional, and call the table versions. Included the toip function that converts from host name to ip address. new implementation of '*a' was broken as has been fixed. The windows code has been tested and is working.
Diffstat (limited to 'src')
-rw-r--r--src/luasocket.c899
1 files changed, 442 insertions, 457 deletions
diff --git a/src/luasocket.c b/src/luasocket.c
index 4f03ad2..e6f423c 100644
--- a/src/luasocket.c
+++ b/src/luasocket.c
@@ -104,17 +104,10 @@
104#define TM_SEND 2 104#define TM_SEND 2
105 105
106/*-------------------------------------------------------------------------*\ 106/*-------------------------------------------------------------------------*\
107* As far as a Lua script is concerned, there are two kind of objects 107* Each socket is represented by a table with the supported methods and
108* representing a socket. A client socket is an object created by the 108* the p_sock structure as fields.
109* function connect, and implementing the methods send, receive, timeout
110* and close. A server socket is an object created by the function bind,
111* and implementing the methods listen, accept and close. Lua tag values
112* for these objects are created in the lua_socketlibopen function, and
113* passed as closure values (last argumnents to every library function)
114# because we can't have any global variables.
115\*-------------------------------------------------------------------------*/ 109\*-------------------------------------------------------------------------*/
116#define CLIENT_TAG -2 110#define P_SOCK "(p_sock)sock"
117#define SERVER_TAG -1
118 111
119/*-------------------------------------------------------------------------*\ 112/*-------------------------------------------------------------------------*\
120* Both socket types are stored in the same structure to simplify 113* Both socket types are stored in the same structure to simplify
@@ -126,20 +119,28 @@ typedef struct t_sock {
126 SOCKET sock; 119 SOCKET sock;
127 /* start time of the current operation */ 120 /* start time of the current operation */
128 int tm_start; 121 int tm_start;
129#ifdef _DEBUG
130 /* end time of current operation, for debug purposes */
131 int tm_end;
132#endif
133 /* return and blocking timeout values (-1 if no limit) */ 122 /* return and blocking timeout values (-1 if no limit) */
134 int tm_return, tm_block; 123 int tm_return, tm_block;
135 /* buffered I/O storage */ 124 /* buffered I/O storage */
136 unsigned char bf_buffer[LUASOCKET_BUFFERSIZE]; 125 unsigned char bf_buffer[LUASOCKET_BUFFERSIZE];
137 /* first and last red bytes not yet passed to application */ 126 /* first and last red bytes not yet passed to application */
138 int bf_first, bf_last; 127 int bf_first, bf_last;
128#ifdef _DEBUG
129 /* end time of current operation, for debug purposes */
130 int tm_end;
131#endif
139} t_sock; 132} t_sock;
140typedef t_sock *p_sock; 133typedef t_sock *p_sock;
141 134
142/*-------------------------------------------------------------------------*\ 135/*-------------------------------------------------------------------------*\
136* Tags passed as closure values to global LuaSocket API functions
137\*-------------------------------------------------------------------------*/
138typedef struct t_tags {
139 int client, server, table;
140} t_tags;
141typedef t_tags *p_tags;
142
143/*-------------------------------------------------------------------------*\
143* Macros and internal declarations 144* Macros and internal declarations
144\*-------------------------------------------------------------------------*/ 145\*-------------------------------------------------------------------------*/
145/* min and max macros */ 146/* min and max macros */
@@ -154,14 +155,24 @@ typedef t_sock *p_sock;
154* Internal function prototypes 155* Internal function prototypes
155\*=========================================================================*/ 156\*=========================================================================*/
156/* luasocket API functions */ 157/* luasocket API functions */
157static int net_connect(lua_State *L); 158static int global_connect(lua_State *L);
158static int net_bind(lua_State *L); 159static int global_bind(lua_State *L);
159static int net_listen(lua_State *L); 160static int table_listen(lua_State *L);
160static int net_accept(lua_State *L); 161static int table_accept(lua_State *L);
161static int net_send(lua_State *L); 162static int table_send(lua_State *L);
162static int net_receive(lua_State *L); 163static int table_receive(lua_State *L);
163static int net_timeout(lua_State *L); 164static int table_timeout(lua_State *L);
164static int net_close(lua_State *L); 165static int table_close(lua_State *L);
166#ifndef LUASOCKET_NOGLOBALS
167static int global_listen(lua_State *L);
168static int global_accept(lua_State *L);
169static int global_send(lua_State *L);
170static int global_receive(lua_State *L);
171static int global_timeout(lua_State *L);
172static int global_close(lua_State *L);
173static p_sock get_selfclientsock(lua_State *L, p_tags tags);
174static p_sock get_selfserversock(lua_State *L, p_tags tags);
175#endif
165 176
166/* buffered I/O management */ 177/* buffered I/O management */
167static const unsigned char *bf_receive(p_sock sock, int *length); 178static const unsigned char *bf_receive(p_sock sock, int *length);
@@ -181,18 +192,14 @@ static int receive_dosline(lua_State *L, p_sock sock);
181static int receive_unixline(lua_State *L, p_sock sock); 192static int receive_unixline(lua_State *L, p_sock sock);
182static int receive_all(lua_State *L, p_sock sock); 193static int receive_all(lua_State *L, p_sock sock);
183 194
184/* fallbacks */ 195/* parameter manipulation functions */
185static int server_gettable(lua_State *L); 196static p_tags pop_tags(lua_State *L);
186static int client_gettable(lua_State *L); 197static p_sock pop_sock(lua_State *L);
187static int sock_gc(lua_State *L); 198static p_sock get_selfsock(lua_State *L, p_tags tags);
188 199static int gc_sock(lua_State *L);
189/* argument checking routines */ 200static p_sock push_servertable(lua_State *L, p_tags tags);
190static p_sock check_client(lua_State *L, int numArg, int client_tag); 201static p_sock push_clienttable(lua_State *L, p_tags tags);
191static p_sock check_server(lua_State *L, int numArg, int server_tag); 202static void push_error(lua_State *L, int err);
192static p_sock check_sock(lua_State *L, int numArg, int server_tag,
193 int client_tag);
194static void pop_tags(lua_State *L, int *client_tag, int *server_tag);
195static void push_tags(lua_State *L, int client_tag, int server_tag);
196 203
197/* error code translations functions */ 204/* error code translations functions */
198static char *host_strerror(void); 205static char *host_strerror(void);
@@ -200,20 +207,17 @@ static char *bind_strerror(void);
200static char *sock_strerror(void); 207static char *sock_strerror(void);
201static char *connect_strerror(void); 208static char *connect_strerror(void);
202 209
203static void push_error(lua_State *L, int err); 210/* auxiliary functions */
204static void push_client(lua_State *L, p_sock sock, int client_tag);
205static void push_server(lua_State *L, p_sock sock, int server_tag);
206
207/* plataform specific functions */
208static void set_blocking(p_sock sock); 211static void set_blocking(p_sock sock);
209static void set_nonblocking(p_sock sock); 212static void set_nonblocking(p_sock sock);
210 213static int create_tcpsocket(p_sock sock);
211/* auxiliary functions */
212static p_sock create_sock(void);
213static p_sock create_tcpsock(void);
214static int fill_sockaddr(struct sockaddr_in *server, const char *hostname, 214static int fill_sockaddr(struct sockaddr_in *server, const char *hostname,
215 unsigned short port); 215 unsigned short port);
216 216
217#ifdef WIN32
218static int winsock_open(void);
219#endif
220
217/*=========================================================================*\ 221/*=========================================================================*\
218* Test support functions 222* Test support functions
219\*=========================================================================*/ 223\*=========================================================================*/
@@ -221,8 +225,8 @@ static int fill_sockaddr(struct sockaddr_in *server, const char *hostname,
221/*-------------------------------------------------------------------------*\ 225/*-------------------------------------------------------------------------*\
222* Returns the time the system has been up, in secconds. 226* Returns the time the system has been up, in secconds.
223\*-------------------------------------------------------------------------*/ 227\*-------------------------------------------------------------------------*/
224static int net_time(lua_State *L); 228static int global_time(lua_State *L);
225static int net_time(lua_State *L) 229static int global_time(lua_State *L)
226{ 230{
227 lua_pushnumber(L, tm_gettime()/1000.0); 231 lua_pushnumber(L, tm_gettime()/1000.0);
228 return 1; 232 return 1;
@@ -231,8 +235,8 @@ static int net_time(lua_State *L)
231/*-------------------------------------------------------------------------*\ 235/*-------------------------------------------------------------------------*\
232* Causes a Lua script to sleep for the specified number of secconds 236* Causes a Lua script to sleep for the specified number of secconds
233\*-------------------------------------------------------------------------*/ 237\*-------------------------------------------------------------------------*/
234static int net_sleep(lua_State *L); 238static int global_sleep(lua_State *L);
235static int net_sleep(lua_State *L) 239static int global_sleep(lua_State *L)
236{ 240{
237 int sec = (int) luaL_check_number(L, 1); 241 int sec = (int) luaL_check_number(L, 1);
238#ifdef WIN32 242#ifdef WIN32
@@ -253,65 +257,87 @@ static int net_sleep(lua_State *L)
253* Creates a client socket and returns it to the Lua script. The timeout 257* Creates a client socket and returns it to the Lua script. The timeout
254* values are initialized as -1 so that the socket will block at any 258* values are initialized as -1 so that the socket will block at any
255* IO operation. 259* IO operation.
256* Input 260* Lua Input
257* host: host name or ip address to connect to 261* host: host name or ip address to connect to
258* port: port number on host 262* port: port number on host
259* Returns 263* Lua Returns
260* On success: client socket 264* On success: client socket
261* On error: nil, followed by an error message 265* On error: nil, followed by an error message
262\*-------------------------------------------------------------------------*/ 266\*-------------------------------------------------------------------------*/
263static int net_connect(lua_State *L) 267static int global_connect(lua_State *L)
264{ 268{
269 p_tags tags = pop_tags(L);
265 const char *hostname = luaL_check_string(L, 1); 270 const char *hostname = luaL_check_string(L, 1);
266 unsigned short port = (unsigned short) luaL_check_number(L, 2); 271 unsigned short port = (unsigned short) luaL_check_number(L, 2);
267 int client_tag, server_tag;
268 struct sockaddr_in server; 272 struct sockaddr_in server;
269 p_sock sock; 273 p_sock sock = push_clienttable(L, tags);
270 pop_tags(L, &client_tag, &server_tag);
271 sock = create_tcpsock();
272 if (!sock) { 274 if (!sock) {
273 lua_pushnil(L); 275 lua_pushnil(L);
276 lua_pushstring(L, "out of memory");
277 return 2;
278 }
279 if (!create_tcpsocket(sock)) {
280 lua_pushnil(L);
274 lua_pushstring(L, sock_strerror()); 281 lua_pushstring(L, sock_strerror());
275 return 2; 282 return 2;
276 } 283 }
277 /* fills the sockaddr structure with the information needed to 284 /* fills the sockaddr structure with the information needed to
278 ** connect our socket with the remote host */ 285 ** connect our socket with the remote host */
279 if (!fill_sockaddr(&server, hostname, port)) { 286 if (!fill_sockaddr(&server, hostname, port)) {
280 free(sock);
281 lua_pushnil(L); 287 lua_pushnil(L);
282 lua_pushstring(L, host_strerror()); 288 lua_pushstring(L, host_strerror());
283 return 2; 289 return 2;
284 } 290 }
285 if (connect(sock->sock,(struct sockaddr *)&server,sizeof(server)) < 0) { 291 if (connect(sock->sock, (struct sockaddr *)&server, sizeof(server)) < 0) {
286 /* no connection? we close the socket to free the descriptor */ 292 /* no connection? we close the socket to free the descriptor */
287 closesocket(sock->sock); 293 closesocket(sock->sock);
288 lua_pushnil(L); 294 lua_pushnil(L);
289 lua_pushstring(L, connect_strerror()); 295 lua_pushstring(L, connect_strerror());
290 return 2; 296 return 2;
291 } 297 }
298 /* all operations on client sockets are non-blocking */
292 set_nonblocking(sock); 299 set_nonblocking(sock);
293 push_client(L, sock, client_tag);
294 lua_pushnil(L); 300 lua_pushnil(L);
295 return 2; 301 return 2;
296} 302}
297 303
298/*-------------------------------------------------------------------------*\ 304/*-------------------------------------------------------------------------*\
305* Converts from ip number to host name
306* Lua Input
307* ip: ip number
308* Lua Returns
309* On success: domain name
310* On error: nil, followed by an error message
311\*-------------------------------------------------------------------------*/
312static int global_toip(lua_State *L)
313{
314 struct hostent *host;
315 struct in_addr addr;
316 pop_tags(L);
317 host = gethostbyname(luaL_check_string(L, 1));
318 if (!host) {
319 lua_pushnil(L);
320 lua_pushstring(L, host_strerror());
321 return 2;
322 }
323 memcpy(&addr, host->h_addr, (unsigned) host->h_length);
324 lua_pushstring(L, inet_ntoa(addr));
325 return 1;
326}
327
328/*-------------------------------------------------------------------------*\
299* Specifies the number of connections that can be queued on a server 329* Specifies the number of connections that can be queued on a server
300* socket. 330* socket.
301* Input 331* Lua Input
302* sock: server socket created by the bind function 332* sock: server socket created by the bind function
303* Returns 333* Lua Returns
304* On success: nil 334* On success: nil
305* On error: an error message 335* On error: an error message
306\*-------------------------------------------------------------------------*/ 336\*-------------------------------------------------------------------------*/
307static int net_listen(lua_State *L) 337static int table_listen(lua_State *L)
308{ 338{
309 p_sock sock; 339 p_sock sock = pop_sock(L);
310 int client_tag, server_tag; 340 unsigned int backlog = (unsigned int) luaL_check_number(L, 2);
311 unsigned int backlog;
312 pop_tags(L, &client_tag, &server_tag);
313 sock = check_server(L, 1, server_tag);
314 backlog = (unsigned int) luaL_check_number(L, 2);
315 if (listen(sock->sock, backlog) < 0) { 341 if (listen(sock->sock, backlog) < 0) {
316 lua_pushstring(L, "listen error"); 342 lua_pushstring(L, "listen error");
317 return 1; 343 return 1;
@@ -324,39 +350,25 @@ static int net_listen(lua_State *L)
324/*-------------------------------------------------------------------------*\ 350/*-------------------------------------------------------------------------*\
325* Returns a client socket attempting to connect to a server socket. 351* Returns a client socket attempting to connect to a server socket.
326* The function blocks until a client shows up. 352* The function blocks until a client shows up.
327* Input 353* Lua Input
328* sock: server socket created by the bind function 354* sock: server socket created by the bind function
329* Returns 355* Lua Returns
330* On success: client socket attempting connection 356* On success: client socket attempting connection
331* On error: nil followed by an error message 357* On error: nil followed by an error message
332\*-------------------------------------------------------------------------*/ 358\*-------------------------------------------------------------------------*/
333static int net_accept(lua_State *L) 359static int table_accept(lua_State *L)
334{ 360{
335 struct sockaddr_in client_addr; 361 struct sockaddr_in client_addr;
336 int client_tag, server_tag;
337 p_sock server;
338 int client_sock = -1;
339 size_t client_len = sizeof(client_addr); 362 size_t client_len = sizeof(client_addr);
340 p_sock client; 363 p_sock server = pop_sock(L);
341 pop_tags(L, &client_tag, &server_tag); 364 p_tags tags = pop_tags(L);
342 server = check_server(L, 1, server_tag); 365 p_sock client = push_clienttable(L, tags);
343 /* waits for a connection */ 366 SOCKET accepted = accept(server->sock, (struct sockaddr *) &client_addr,
344 client_sock = accept(server->sock, (struct sockaddr *) &client_addr,
345 &client_len); 367 &client_len);
346 /* we create and return a client socket object, passing the received 368 client->sock = accepted;
347 ** socket to Lua, as a client socket */ 369 set_nonblocking(client);
348 client = create_sock(); 370 lua_pushnil(L);
349 if (!client) { 371 return 2;
350 lua_pushnil(L);
351 lua_pushstring(L, "out of memory");
352 return 2;
353 } else {
354 client->sock = client_sock;
355 set_nonblocking(client);
356 push_client(L, client, client_tag);
357 lua_pushnil(L);
358 return 2;
359 }
360} 372}
361 373
362/*-------------------------------------------------------------------------*\ 374/*-------------------------------------------------------------------------*\
@@ -370,16 +382,15 @@ static int net_accept(lua_State *L)
370* On success: server socket bound to address, the ip address and port bound 382* On success: server socket bound to address, the ip address and port bound
371* On error: nil, followed by an error message 383* On error: nil, followed by an error message
372\*-------------------------------------------------------------------------*/ 384\*-------------------------------------------------------------------------*/
373static int net_bind(lua_State *L) 385static int global_bind(lua_State *L)
374{ 386{
387 p_tags tags = pop_tags(L);
375 const char *hostname = luaL_check_string(L, 1); 388 const char *hostname = luaL_check_string(L, 1);
376 unsigned short port = (unsigned short) luaL_check_number(L, 2); 389 unsigned short port = (unsigned short) luaL_check_number(L, 2);
377 unsigned int backlog = (unsigned int) luaL_opt_number(L, 3, 1.0); 390 unsigned int backlog = (unsigned int) luaL_opt_number(L, 3, 1.0);
378 struct sockaddr_in server; 391 struct sockaddr_in server;
379 size_t server_size = sizeof(server); 392 size_t server_size = sizeof(server);
380 int client_tag, server_tag; 393 p_sock sock = push_servertable(L, tags);
381 p_sock sock = create_tcpsock();
382 pop_tags(L, &client_tag, &server_tag);
383 if (!sock) { 394 if (!sock) {
384 lua_pushnil(L); 395 lua_pushnil(L);
385 lua_pushstring(L, sock_strerror()); 396 lua_pushstring(L, sock_strerror());
@@ -406,8 +417,6 @@ static int net_bind(lua_State *L)
406 } 417 }
407 /* pass the created socket to Lua, as a server socket */ 418 /* pass the created socket to Lua, as a server socket */
408 else { 419 else {
409 /* pass server */
410 push_server(L, sock, server_tag);
411 /* get used address and port */ 420 /* get used address and port */
412 getsockname(sock->sock, (struct sockaddr *)&server, &server_size); 421 getsockname(sock->sock, (struct sockaddr *)&server, &server_size);
413 /* pass ip number */ 422 /* pass ip number */
@@ -421,26 +430,19 @@ static int net_bind(lua_State *L)
421 430
422/*-------------------------------------------------------------------------*\ 431/*-------------------------------------------------------------------------*\
423* Sets timeout values for IO operations on a client socket 432* Sets timeout values for IO operations on a client socket
424* Input 433* Lua Input
425* sock: client socket created by the connect function 434* sock: client socket created by the connect function
426* time: time out value in seconds 435* time: time out value in seconds
427* mode: optional timeout mode. "block" specifies the upper bound on 436* mode: optional timeout mode. "block" specifies the upper bound on
428* the time any IO operation on sock can cause the program to block. 437* the time any IO operation on sock can cause the program to block.
429* "return" specifies the upper bound on the time elapsed before the 438* "return" specifies the upper bound on the time elapsed before the
430* function returns control to the script. "block" is the default. 439* function returns control to the script. "block" is the default.
431* Returns
432* no return value
433\*-------------------------------------------------------------------------*/ 440\*-------------------------------------------------------------------------*/
434static int net_timeout(lua_State *L) 441static int table_timeout(lua_State *L)
435{ 442{
436 int client_tag, server_tag; 443 p_sock sock = pop_sock(L);
437 p_sock sock; 444 int ms = (int) (luaL_check_number(L, 2)*1000.0);
438 int ms; 445 const char *mode = luaL_opt_string(L, 3, "b");
439 const char *mode;
440 pop_tags(L, &client_tag, &server_tag);
441 sock = check_client(L, 1, client_tag);
442 ms = (int) (luaL_check_number(L, 2)*1000.0);
443 mode = luaL_opt_string(L, 3, "b");
444 switch (*mode) { 446 switch (*mode) {
445 case 'b': 447 case 'b':
446 sock->tm_block = ms; 448 sock->tm_block = ms;
@@ -457,34 +459,30 @@ static int net_timeout(lua_State *L)
457 459
458/*-------------------------------------------------------------------------*\ 460/*-------------------------------------------------------------------------*\
459* Send data through a socket 461* Send data through a socket
460* Input: sock, a_1 [, a_2, a_3 ... a_n] 462* Lua Input: sock, a_1 [, a_2, a_3 ... a_n]
461* sock: client socket created by the connect function 463* sock: client socket created by the connect function
462* a_i: strings to be sent. The strings will be sent on the order they 464* a_i: strings to be sent. The strings will be sent on the order they
463* appear as parameters 465* appear as parameters
464* Returns 466* Lua Returns
465* On success: nil, followed by the total number of bytes sent 467* On success: nil, followed by the total number of bytes sent
466* On error: NET_TIMEOUT if the connection timedout, or NET_CLOSED if 468* On error: NET_TIMEOUT if the connection timedout, or NET_CLOSED if
467* the connection has been closed, followed by the total number of 469* the connection has been closed, followed by the total number of
468* bytes sent 470* bytes sent
469\*-------------------------------------------------------------------------*/ 471\*-------------------------------------------------------------------------*/
470static int net_send(lua_State *L) 472static int table_send(lua_State *L)
471{ 473{
472 p_sock sock;
473 const char *data;
474 int wanted;
475 long total = 0;
476 int arg; 474 int arg;
475 p_sock sock = pop_sock(L);
476 int top = lua_gettop(L);
477 int total = 0;
477 int err = NET_DONE; 478 int err = NET_DONE;
478 int top;
479 int client_tag, server_tag;
480 pop_tags(L, &client_tag, &server_tag);
481 top = lua_gettop(L);
482 sock = check_client(L, 1, client_tag);
483 tm_markstart(sock); 479 tm_markstart(sock);
484 for (arg = 2; arg <= top; arg++) { 480 for (arg = 2; arg <= top; arg++) { /* skip self table */
485 data = luaL_opt_lstr(L, arg, NULL, &wanted); 481 int sent, wanted;
482 const char *data = luaL_opt_lstr(L, arg, NULL, &wanted);
486 if (!data || err != NET_DONE) break; 483 if (!data || err != NET_DONE) break;
487 total += send_raw(sock, data, wanted, &err); 484 err = send_raw(sock, data, wanted, &sent);
485 total += sent;
488 } 486 }
489 push_error(L, err); 487 push_error(L, err);
490 lua_pushnumber(L, (double) total); 488 lua_pushnumber(L, (double) total);
@@ -497,7 +495,7 @@ static int net_send(lua_State *L)
497 495
498/*-------------------------------------------------------------------------*\ 496/*-------------------------------------------------------------------------*\
499* Receive data from a socket 497* Receive data from a socket
500* Input: sock [pat_1, pat_2 ... pat_n] 498* Lua Input: sock [pat_1, pat_2 ... pat_n]
501* sock: client socket created by the connect function 499* sock: client socket created by the connect function
502* pat_i: may be one of the following 500* pat_i: may be one of the following
503* "*l": reads a text line, defined as a string of caracters terminates 501* "*l": reads a text line, defined as a string of caracters terminates
@@ -506,24 +504,21 @@ static int net_send(lua_State *L)
506* "*lu": reads a text line, terminanted by a CR character only. (Unix mode) 504* "*lu": reads a text line, terminanted by a CR character only. (Unix mode)
507* "*a": reads until connection closed 505* "*a": reads until connection closed
508* number: reads 'number' characters from the socket 506* number: reads 'number' characters from the socket
509* Returns 507* Lua Returns
510* On success: one string for each pattern 508* On success: one string for each pattern
511* On error: all strings for which there was no error, followed by one 509* On error: all strings for which there was no error, followed by one
512* nil value for the remaining strings, followed by an error code 510* nil value for the remaining strings, followed by an error code
513\*-------------------------------------------------------------------------*/ 511\*-------------------------------------------------------------------------*/
514static int net_receive(lua_State *L) 512static int table_receive(lua_State *L)
515{ 513{
516 static const char *const modenames[] = {"*l", "*lu", "*a", NULL}; 514 static const char *const modenames[] = {"*l", "*lu", "*a", NULL};
517 int err = NET_DONE, arg = 2;
518 const char *mode; 515 const char *mode;
519 int client_tag, server_tag; 516 int err = NET_DONE;
520 int top; 517 int arg;
521 p_sock sock; 518 p_sock sock = pop_sock(L);
522 pop_tags(L, &client_tag, &server_tag); 519 int top = lua_gettop(L);
523 sock = check_client(L, 1, client_tag);
524 tm_markstart(sock); 520 tm_markstart(sock);
525 /* push default pattern */ 521 /* push default pattern if need be */
526 top = lua_gettop(L);
527 if (top < 2) { 522 if (top < 2) {
528 lua_pushstring(L, "*l"); 523 lua_pushstring(L, "*l");
529 top++; 524 top++;
@@ -536,7 +531,7 @@ static int net_receive(lua_State *L)
536 continue; 531 continue;
537 } 532 }
538 if (lua_isnumber(L, arg)) { 533 if (lua_isnumber(L, arg)) {
539 long size = (long) lua_tonumber(L, arg); 534 int size = (int) lua_tonumber(L, arg);
540 err = receive_raw(L, sock, size); 535 err = receive_raw(L, sock, size);
541 } else { 536 } else {
542 mode = luaL_opt_string(L, arg, NULL); 537 mode = luaL_opt_string(L, arg, NULL);
@@ -572,104 +567,30 @@ static int net_receive(lua_State *L)
572 567
573/*-------------------------------------------------------------------------*\ 568/*-------------------------------------------------------------------------*\
574* Closes a socket. 569* Closes a socket.
575* Input 570* Lua Input
576* sock: socket to be closed 571* sock: socket to be closed
577\*-------------------------------------------------------------------------*/ 572\*-------------------------------------------------------------------------*/
578static int net_close(lua_State *L) 573static int table_close(lua_State *L)
579{ 574{
580 int client_tag, server_tag; 575 /* close socket and set value to -1 so that pop_socket can later
581 p_sock sock; 576 ** detect the use of a closed socket */
582 pop_tags(L, &client_tag, &server_tag); 577 p_sock sock = pop_sock(L);
583 sock = check_sock(L, 1, client_tag, server_tag);
584 closesocket(sock->sock); 578 closesocket(sock->sock);
585 /* set value to -1 so that we can later detect the use of a
586 ** closed socket */
587 sock->sock = -1; 579 sock->sock = -1;
588 return 0; 580 return 0;
589} 581}
590 582
591/*-------------------------------------------------------------------------*\ 583/*-------------------------------------------------------------------------*\
592* Gettable fallback for the client socket. This function provides the
593* alternative interface client:receive, client:send etc for the client
594* socket methods.
595\*-------------------------------------------------------------------------*/
596static int client_gettable(lua_State *L)
597{
598 static const char *const net_api[] =
599 {"receive","send","timeout","close", "connect", NULL};
600 const char *idx = luaL_check_string(L, 2);
601 int server_tag, client_tag;
602 pop_tags(L, &client_tag, &server_tag);
603 switch (luaL_findstring(idx, net_api)) {
604 case 0:
605 push_tags(L, client_tag, server_tag);
606 lua_pushcclosure(L, net_receive, 2);
607 break;
608 case 1:
609 push_tags(L, client_tag, server_tag);
610 lua_pushcclosure(L, net_send, 2);
611 break;
612 case 2:
613 push_tags(L, client_tag, server_tag);
614 lua_pushcclosure(L, net_timeout, 2);
615 break;
616 case 3:
617 push_tags(L, client_tag, server_tag);
618 lua_pushcclosure(L, net_close, 2);
619 break;
620 default:
621 lua_pushnil(L);
622 break;
623 }
624 return 1;
625}
626
627/*-------------------------------------------------------------------------*\
628* Gettable fallback for the server socket. This function provides the
629* alternative interface server:listen, server:accept etc for the server
630* socket methods.
631\*-------------------------------------------------------------------------*/
632static int server_gettable(lua_State *L)
633{
634 static const char *const net_api[] = {"listen","accept","close", NULL};
635 const char *idx = luaL_check_string(L, 2);
636 int server_tag, client_tag;
637 pop_tags(L, &client_tag, &server_tag);
638 switch (luaL_findstring(idx, net_api)) {
639 case 0:
640 push_tags(L, client_tag, server_tag);
641 lua_pushcclosure(L, net_listen, 2);
642 break;
643 case 1:
644 push_tags(L, client_tag, server_tag);
645 lua_pushcclosure(L, net_accept, 2);
646 break;
647 case 2:
648 push_tags(L, client_tag, server_tag);
649 lua_pushcclosure(L, net_close, 2);
650 break;
651 default:
652 lua_pushnil(L);
653 break;
654 }
655 return 1;
656}
657
658/*-------------------------------------------------------------------------*\
659* Garbage collection fallback for the socket objects. This function 584* Garbage collection fallback for the socket objects. This function
660* makes sure that all collected sockets are closed and that the memory 585* makes sure that all collected sockets are closed.
661* used by the C structure t_sock is properly released.
662\*-------------------------------------------------------------------------*/ 586\*-------------------------------------------------------------------------*/
663static int sock_gc(lua_State *L) 587static int gc_sock(lua_State *L)
664{ 588{
665 int server_tag, client_tag; 589 p_tags tags = pop_tags(L);
666 p_sock sock; 590 p_sock sock = get_selfsock(L, tags);
667 pop_tags(L, &client_tag, &server_tag); 591 /* sock might have been closed */
668 sock = check_sock(L, 1, client_tag, server_tag); 592 if (sock->sock >= 0) closesocket(sock->sock);
669 if (sock->sock >= 0) 593 return 0;
670 closesocket(sock->sock);
671 free(sock);
672 return 1;
673} 594}
674 595
675/*=========================================================================*\ 596/*=========================================================================*\
@@ -692,34 +613,16 @@ static void handle_sigpipe(void)
692#endif 613#endif
693 614
694/*-------------------------------------------------------------------------*\ 615/*-------------------------------------------------------------------------*\
695* Creates a t_sock structure with default values.
696\*-------------------------------------------------------------------------*/
697static p_sock create_sock(void)
698{
699 p_sock sock = (p_sock) malloc(sizeof(t_sock));
700 if (!sock) return NULL;
701 sock->sock = -1;
702 sock->tm_block = -1;
703 sock->tm_return = -1;
704 sock->bf_first = sock->bf_last = 0;
705 return sock;
706}
707
708/*-------------------------------------------------------------------------*\
709* Creates a TCP/IP socket. 616* Creates a TCP/IP socket.
617* Input
618* sock: structure to receive new socket
710* Returns 619* Returns
711* A pointer to a t_sock structure or NULL in case of error 620* 1 if successfull, 0 in case or error
712\*-------------------------------------------------------------------------*/ 621\*-------------------------------------------------------------------------*/
713static p_sock create_tcpsock(void) 622static int create_tcpsocket(p_sock sock)
714{ 623{
715 p_sock sock = create_sock();
716 if (!sock)
717 return NULL;
718 sock->sock = socket(AF_INET, SOCK_STREAM, 0); 624 sock->sock = socket(AF_INET, SOCK_STREAM, 0);
719 if (sock->sock < 0) { 625 if (sock->sock < 0) return 0;
720 free(sock);
721 sock = NULL;
722 }
723#ifdef _DEBUG 626#ifdef _DEBUG
724/* this allow us to re-bind onto an address even if there is still 627/* this allow us to re-bind onto an address even if there is still
725** a TIME_WAIT condition. debugging is much more confortable, because 628** a TIME_WAIT condition. debugging is much more confortable, because
@@ -733,7 +636,7 @@ static p_sock create_tcpsock(void)
733 sizeof(val)); 636 sizeof(val));
734} 637}
735#endif 638#endif
736 return sock; 639 return 1;
737} 640}
738 641
739/*-------------------------------------------------------------------------*\ 642/*-------------------------------------------------------------------------*\
@@ -756,10 +659,8 @@ static int fill_sockaddr(struct sockaddr_in *address, const char *hostname,
756 /* BSD says we could have used gethostbyname even if the hostname is 659 /* BSD says we could have used gethostbyname even if the hostname is
757 ** in ip address form, but WinSock2 says we can't. Therefore we 660 ** in ip address form, but WinSock2 says we can't. Therefore we
758 ** choose a method that works on both plataforms */ 661 ** choose a method that works on both plataforms */
759 if (addr == INADDR_NONE) 662 if (addr == INADDR_NONE) host = gethostbyname(hostname);
760 host = gethostbyname(hostname); 663 else host = gethostbyaddr((char * ) &addr, sizeof(unsigned long),
761 else
762 host = gethostbyaddr((char * ) &addr, sizeof(unsigned long),
763 AF_INET); 664 AF_INET);
764 if (!host) 665 if (!host)
765 return 0; 666 return 0;
@@ -773,6 +674,87 @@ static int fill_sockaddr(struct sockaddr_in *address, const char *hostname,
773} 674}
774 675
775/*-------------------------------------------------------------------------*\ 676/*-------------------------------------------------------------------------*\
677* Creates a t_sock structure with default values for a client sock.
678* Pushes the Lua table with sock fields and appropriate methods
679* Input
680* tags: tags structure
681* Returns
682* pointer to allocated t_sock structure, NULL in case of error
683\*-------------------------------------------------------------------------*/
684static p_sock push_clienttable(lua_State *L, p_tags tags)
685{
686 static struct luaL_reg funcs[] = {
687 {"send", table_send},
688 {"receive", table_receive},
689 {"close", table_close},
690 {"timeout", table_timeout},
691 };
692 int i;
693 p_sock sock;
694 lua_newtable(L); lua_settag(L, tags->table);
695 lua_pushstring(L, P_SOCK);
696 sock = (p_sock) lua_newuserdata(L, sizeof(t_sock));
697 if (!sock) lua_error(L, "out of memory");
698 lua_settag(L, tags->client);
699 lua_settable(L, -3);
700 sock->sock = -1;
701 sock->tm_block = -1;
702 sock->tm_return = -1;
703 sock->bf_first = sock->bf_last = 0;
704 for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) {
705 lua_pushstring(L, funcs[i].name);
706 lua_pushusertag(L, sock, tags->client);
707 lua_pushcclosure(L, funcs[i].func, 1);
708 lua_settable(L, -3);
709 }
710 return sock;
711}
712
713/*-------------------------------------------------------------------------*\
714* Creates a t_sock structure with default values for a server sock.
715* Pushes the Lua table with sock fields and appropriate methods
716* Input
717* tags: tags structure
718* Returns
719* pointer to allocated t_sock structure, NULL in case of error
720\*-------------------------------------------------------------------------*/
721static p_sock push_servertable(lua_State *L, p_tags tags)
722{
723 static struct luaL_reg funcs[] = {
724 {"listen", table_listen},
725 {"close", table_close},
726 };
727 int i;
728 p_sock sock;
729 lua_newtable(L); lua_settag(L, tags->table);
730 lua_pushstring(L, P_SOCK);
731 sock = (p_sock) lua_newuserdata(L, sizeof(t_sock));
732 if (!sock) lua_error(L, "out of memory");
733 lua_settag(L, tags->server);
734 lua_settable(L, -3);
735 if (!create_tcpsocket(sock)) return NULL;
736 sock->tm_block = -1;
737 sock->tm_return = -1;
738 sock->bf_first = sock->bf_last = 0;
739 for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) {
740 lua_pushstring(L, funcs[i].name);
741 lua_pushusertag(L, sock, tags->client);
742 lua_pushcclosure(L, funcs[i].func, 1);
743 lua_settable(L, -3);
744 }
745 /* the accept method is different, it needs the tags closure too */
746 lua_pushstring(L, "accept");
747 lua_pushuserdata(L, tags);
748 lua_pushusertag(L, sock, tags->client);
749 lua_pushcclosure(L, table_accept, 2);
750 lua_settable(L, -3);
751 return sock;
752}
753
754/*=========================================================================*\
755* Timeout management functions
756\*=========================================================================*/
757/*-------------------------------------------------------------------------*\
776* Determines how much time we have left for the current io operation 758* Determines how much time we have left for the current io operation
777* an IO write operation. 759* an IO write operation.
778* Input 760* Input
@@ -827,7 +809,7 @@ static int tm_timedout(p_sock sock, int mode)
827 /* see if we can read or write or if we timedout */ 809 /* see if we can read or write or if we timedout */
828 ret = select(sock->sock+1, preadfds, pwritefds, NULL, ptm); 810 ret = select(sock->sock+1, preadfds, pwritefds, NULL, ptm);
829#ifdef _DEBUG 811#ifdef _DEBUG
830 /* store end time for this operation before calling select */ 812 /* store end time for this operation next call to OS */
831 sock->tm_end = tm_gettime(); 813 sock->tm_end = tm_gettime();
832#endif 814#endif
833 return ret <= 0; 815 return ret <= 0;
@@ -847,6 +829,24 @@ static void tm_markstart(p_sock sock)
847} 829}
848 830
849/*-------------------------------------------------------------------------*\ 831/*-------------------------------------------------------------------------*\
832* Gets time in ms, relative to system startup.
833* Returns
834* time in ms.
835\*-------------------------------------------------------------------------*/
836static int tm_gettime(void)
837{
838#ifdef _WIN32
839 return GetTickCount();
840#else
841 struct tms t;
842 return (times(&t)*1000)/CLK_TCK;
843#endif
844}
845
846/*=========================================================================*\
847* Buffered I/O management functions
848\*=========================================================================*/
849/*-------------------------------------------------------------------------*\
850* Determines of there is any data in the read buffer 850* Determines of there is any data in the read buffer
851* Input 851* Input
852* sock: socket structure being used in operation 852* sock: socket structure being used in operation
@@ -892,21 +892,9 @@ static const unsigned char *bf_receive(p_sock sock, int *length)
892 return sock->bf_buffer + sock->bf_first; 892 return sock->bf_buffer + sock->bf_first;
893} 893}
894 894
895/*-------------------------------------------------------------------------*\ 895/*=========================================================================*\
896* Gets time in ms, relative to system startup. 896* These are the function that are called for each I/O pattern
897* Returns 897\*=========================================================================*/
898* time in ms.
899\*-------------------------------------------------------------------------*/
900static int tm_gettime(void)
901{
902#ifdef _WIN32
903 return GetTickCount();
904#else
905 struct tms t;
906 return (times(&t)*1000)/CLK_TCK;
907#endif
908}
909
910/*-------------------------------------------------------------------------*\ 898/*-------------------------------------------------------------------------*\
911* Sends a raw block of data through a socket. The operations are all 899* Sends a raw block of data through a socket. The operations are all
912* non-blocking and the function respects the timeout values in sock. 900* non-blocking and the function respects the timeout values in sock.
@@ -915,29 +903,32 @@ static int tm_gettime(void)
915* data: buffer to be sent 903* data: buffer to be sent
916* wanted: number of bytes in buffer 904* wanted: number of bytes in buffer
917* Output 905* Output
918* err: operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED 906* total: Number of bytes written
919* Returns 907* Returns
920* Number of bytes written 908* operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED
921\*-------------------------------------------------------------------------*/ 909\*-------------------------------------------------------------------------*/
922static int send_raw(p_sock sock, const char *data, int wanted, int *err) 910static int send_raw(p_sock sock, const char *data, int wanted, int *total)
923{ 911{
924 int put = 0, total = 0; 912 int put = 0;
913 *total = 0;
925 while (wanted > 0) { 914 while (wanted > 0) {
926 if (tm_timedout(sock, TM_SEND)) { 915 if (tm_timedout(sock, TM_SEND)) return NET_TIMEOUT;
927 *err = NET_TIMEOUT;
928 return total;
929 }
930 put = send(sock->sock, data, wanted, 0); 916 put = send(sock->sock, data, wanted, 0);
931 if (put <= 0) { 917 if (put <= 0) {
932 *err = NET_CLOSED; 918#ifdef WIN32
933 return total; 919 /* a bug in WinSock forces us to do a busy wait until we manage
920 ** to write, because select returns immediately even though it
921 ** should have blocked us */
922 if (WSAGetLastError() == WSAEWOULDBLOCK)
923 continue;
924#endif
925 return NET_CLOSED;
934 } 926 }
935 wanted -= put; 927 wanted -= put;
936 data += put; 928 data += put;
937 total += put; 929 *total += put;
938 } 930 }
939 *err = NET_DONE; 931 return NET_DONE;
940 return total;
941} 932}
942 933
943/*-------------------------------------------------------------------------*\ 934/*-------------------------------------------------------------------------*\
@@ -989,16 +980,16 @@ static int receive_all(lua_State *L, p_sock sock)
989 luaL_buffinit(L, &b); 980 luaL_buffinit(L, &b);
990 for ( ;; ) { 981 for ( ;; ) {
991 if (bf_isempty(sock) && tm_timedout(sock, TM_RECEIVE)) { 982 if (bf_isempty(sock) && tm_timedout(sock, TM_RECEIVE)) {
992 buffer = bf_receive(sock, &got);
993 if (got <= 0) {
994 luaL_pushresult(&b);
995 return NET_DONE;
996 }
997 luaL_addlstring(&b, buffer, got);
998 } else {
999 luaL_pushresult(&b); 983 luaL_pushresult(&b);
1000 return NET_TIMEOUT; 984 return NET_TIMEOUT;
985 }
986 buffer = bf_receive(sock, &got);
987 if (got <= 0) {
988 luaL_pushresult(&b);
989 return NET_DONE;
1001 } 990 }
991 luaL_addlstring(&b, buffer, got);
992 bf_skip(sock, got);
1002 } 993 }
1003} 994}
1004 995
@@ -1088,18 +1079,125 @@ static int receive_unixline(lua_State *L, p_sock sock)
1088 } 1079 }
1089} 1080}
1090 1081
1082/*=========================================================================*\
1083* Module exported functions
1084\*=========================================================================*/
1091/*-------------------------------------------------------------------------*\ 1085/*-------------------------------------------------------------------------*\
1092* Pops tags from closures 1086* Initializes the library interface with Lua and the socket library.
1093* Input 1087* Defines the symbols exported to Lua.
1094* L: lua environment
1095\*-------------------------------------------------------------------------*/ 1088\*-------------------------------------------------------------------------*/
1096static void pop_tags(lua_State *L, int *client_tag, int *server_tag) 1089void lua_socketlibopen(lua_State *L)
1097{ 1090{
1098 *client_tag = (int) lua_tonumber(L, CLIENT_TAG); 1091 static struct luaL_reg funcs[] = {
1099 *server_tag = (int) lua_tonumber(L, SERVER_TAG); 1092 {"connect", global_connect},
1100 lua_pop(L, 2); 1093 {"bind", global_bind},
1094 {"toip", global_toip},
1095 };
1096 int i;
1097 /* declare new Lua tags for used userdata values */
1098 p_tags tags = (p_tags) lua_newuserdata(L, sizeof(t_tags));
1099 if (!tags) lua_error(L, "out of memory");
1100 tags->client = lua_newtag(L);
1101 tags->server = lua_newtag(L);
1102 tags->table = lua_newtag(L);
1103 /* global functions exported */
1104 for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) {
1105 lua_pushuserdata(L, tags);
1106 lua_pushcclosure(L, funcs[i].func, 1);
1107 lua_setglobal(L, funcs[i].name);
1108 }
1109 /* socket garbage collection */
1110 lua_pushuserdata(L, tags);
1111 lua_pushcclosure(L, gc_sock, 1);
1112 lua_settagmethod(L, tags->table, "gc");
1113
1114#ifndef LUASOCKET_NOGLOBALS
1115 /* global version of socket table functions */
1116{ static struct luaL_reg opt_funcs[] = {
1117 {"send", global_send},
1118 {"receive", global_receive},
1119 {"accept", global_accept},
1120 {"close", global_close},
1121 {"timeout", global_timeout},
1122 {"listen", global_listen},
1123 };
1124 for (i = 0; i < sizeof(opt_funcs)/sizeof(opt_funcs[0]); i++) {
1125 lua_pushuserdata(L, tags);
1126 lua_pushcclosure(L, opt_funcs[i].func, 1);
1127 lua_setglobal(L, opt_funcs[i].name);
1128 }
1129}
1130#endif
1131#ifdef WIN32
1132 /* WinSock needs special initialization */
1133 winsock_open();
1134#else
1135 /* avoid getting killed by a SIGPIPE signal thrown by send */
1136 handle_sigpipe();
1137#endif
1138#ifdef _DEBUG
1139 /* test support functions */
1140 lua_pushcfunction(L, global_sleep); lua_setglobal(L, "sleep");
1141 lua_pushcfunction(L, global_time); lua_setglobal(L, "time");
1142#endif
1143 /* avoid stupid compiler warnings */
1144 (void) set_blocking;
1145}
1146
1147/*=========================================================================*\
1148* Optional global version of socket table methods
1149\*=========================================================================*/
1150#ifndef LUASOCKET_NOGLOBALS
1151int global_accept(lua_State *L)
1152{
1153 p_tags tags = pop_tags(L);
1154 p_sock sock = get_selfserversock(L, tags);
1155 lua_pushuserdata(L, tags);
1156 lua_pushusertag(L, sock, tags->server);
1157 return table_accept(L);
1101} 1158}
1102 1159
1160int global_listen(lua_State *L)
1161{
1162 p_tags tags = pop_tags(L);
1163 p_sock sock = get_selfserversock(L, tags);
1164 lua_pushusertag(L, sock, tags->server);
1165 return table_listen(L);
1166}
1167
1168int global_send(lua_State *L)
1169{
1170 p_tags tags = pop_tags(L);
1171 p_sock sock = get_selfclientsock(L, tags);
1172 lua_pushusertag(L, sock, tags->client);
1173 return table_send(L);
1174}
1175
1176int global_receive(lua_State *L)
1177{
1178 p_tags tags = pop_tags(L);
1179 p_sock sock = get_selfclientsock(L, tags);
1180 lua_pushusertag(L, sock, tags->client);
1181 return table_receive(L);
1182}
1183
1184int global_timeout(lua_State *L)
1185{
1186 p_tags tags = pop_tags(L);
1187 p_sock sock = get_selfclientsock(L, tags);
1188 lua_pushusertag(L, sock, tags->client);
1189 return table_timeout(L);
1190}
1191
1192int global_close(lua_State *L)
1193{
1194 return gc_sock(L);
1195}
1196#endif
1197
1198/*=========================================================================*\
1199* Parameter manipulation functions
1200\*=========================================================================*/
1103/*-------------------------------------------------------------------------*\ 1201/*-------------------------------------------------------------------------*\
1104* Passes an error code to Lua. The NET_DONE error is translated to nil. 1202* Passes an error code to Lua. The NET_DONE error is translated to nil.
1105* Input 1203* Input
@@ -1120,43 +1218,63 @@ static void push_error(lua_State *L, int err)
1120 } 1218 }
1121} 1219}
1122 1220
1123/*-------------------------------------------------------------------------*\ 1221static p_tags pop_tags(lua_State *L)
1124* Passes socket tags to lua in correct order
1125* Input:
1126* client_tag, server_tag
1127\*-------------------------------------------------------------------------*/
1128static void push_tags(lua_State *L, int client_tag, int server_tag)
1129{ 1222{
1130 lua_pushnumber(L, client_tag); 1223 p_tags tags = (p_tags) lua_touserdata(L, -1);
1131 lua_pushnumber(L, server_tag); 1224 if (!tags) lua_error(L, "invalid closure! (probably misuse of library)");
1225 lua_pop(L, 1);
1226 return tags;
1132} 1227}
1133 1228
1134/*-------------------------------------------------------------------------*\ 1229static p_sock pop_sock(lua_State *L)
1135* Passes a client socket to Lua.
1136* Must be called from a closure receiving the socket tags as its
1137* parameters.
1138* Input
1139* L: lua environment
1140* sock: pointer to socket structure to be used
1141\*-------------------------------------------------------------------------*/
1142static void push_client(lua_State *L, p_sock sock, int client_tag)
1143{ 1230{
1144 lua_pushusertag(L, (void *) sock, client_tag); 1231 p_sock sock = (p_sock) lua_touserdata(L, -1);
1232 if (!sock) lua_error(L, "invalid socket object");
1233 if (sock->sock < 0) lua_error(L, "operation on closed socket");
1234 lua_pop(L, 1);
1235 return sock;
1145} 1236}
1146 1237
1147/*-------------------------------------------------------------------------*\ 1238static p_sock get_selfsock(lua_State *L, p_tags tags)
1148* Passes a server socket to Lua.
1149* Must be called from a closure receiving the socket tags as its
1150* parameters.
1151* Input
1152* L: lua environment
1153* sock: pointer to socket structure to be used
1154\*-------------------------------------------------------------------------*/
1155static void push_server(lua_State *L, p_sock sock, int server_tag)
1156{ 1239{
1157 lua_pushusertag(L, (void *) sock, server_tag); 1240 p_sock sock;
1241 if (lua_tag(L, 1) != tags->table) lua_error(L, "invalid socket object");
1242 lua_pushstring(L, P_SOCK);
1243 lua_gettable(L, 1);
1244 sock = lua_touserdata(L, -1);
1245 if (!sock) lua_error(L, "invalid socket object");
1246 lua_pop(L, 1);
1247 return sock;
1158} 1248}
1159 1249
1250#ifndef LUASOCKET_NOGLOBALS
1251static p_sock get_selfclientsock(lua_State *L, p_tags tags)
1252{
1253 p_sock sock;
1254 if (lua_tag(L, 1) != tags->table) lua_error(L, "invalid socket object");
1255 lua_pushstring(L, P_SOCK);
1256 lua_gettable(L, 1);
1257 sock = lua_touserdata(L, -1);
1258 if (!sock || lua_tag(L, -1) != tags->client)
1259 lua_error(L, "client socket expected");
1260 lua_pop(L, 1);
1261 return sock;
1262}
1263
1264static p_sock get_selfserversock(lua_State *L, p_tags tags)
1265{
1266 p_sock sock;
1267 if (lua_tag(L, 1) != tags->table) lua_error(L, "invalid socket object");
1268 lua_pushstring(L, P_SOCK);
1269 lua_gettable(L, 1);
1270 sock = lua_touserdata(L, -1);
1271 if (!sock || lua_tag(L, -1) != tags->server)
1272 lua_error(L, "server socket expected");
1273 lua_pop(L, 1);
1274 return sock;
1275}
1276#endif
1277
1160/*=========================================================================*\ 1278/*=========================================================================*\
1161* WinSock2 specific functions. 1279* WinSock2 specific functions.
1162\*=========================================================================*/ 1280\*=========================================================================*/
@@ -1166,7 +1284,7 @@ static void push_server(lua_State *L, p_sock sock, int server_tag)
1166* Returns 1284* Returns
1167* 1 in case of success. 0 in case of error. 1285* 1 in case of success. 0 in case of error.
1168\*-------------------------------------------------------------------------*/ 1286\*-------------------------------------------------------------------------*/
1169static int wsock_open(void) 1287static int winsock_open(void)
1170{ 1288{
1171 WORD wVersionRequested;WSADATA wsaData;int err; 1289 WORD wVersionRequested;WSADATA wsaData;int err;
1172 wVersionRequested = MAKEWORD( 2, 0 ); 1290 wVersionRequested = MAKEWORD( 2, 0 );
@@ -1181,7 +1299,6 @@ static int wsock_open(void)
1181 } 1299 }
1182 return 1; 1300 return 1;
1183} 1301}
1184
1185 1302
1186/*-------------------------------------------------------------------------*\ 1303/*-------------------------------------------------------------------------*\
1187* Put socket into blocking mode. 1304* Put socket into blocking mode.
@@ -1189,10 +1306,7 @@ static int wsock_open(void)
1189static void set_blocking(p_sock sock) 1306static void set_blocking(p_sock sock)
1190{ 1307{
1191 u_long argp = 0; 1308 u_long argp = 0;
1192 if (!sock->blocking) { 1309 ioctlsocket(sock->sock, FIONBIO, &argp);
1193 ioctlsocket(sock->sock, FIONBIO, &argp);
1194 sock->blocking = 1;
1195 }
1196} 1310}
1197 1311
1198/*-------------------------------------------------------------------------*\ 1312/*-------------------------------------------------------------------------*\
@@ -1201,10 +1315,7 @@ static void set_blocking(p_sock sock)
1201static void set_nonblocking(p_sock sock) 1315static void set_nonblocking(p_sock sock)
1202{ 1316{
1203 u_long argp = 1; 1317 u_long argp = 1;
1204 if (sock->blocking) { 1318 ioctlsocket(sock->sock, FIONBIO, &argp);
1205 ioctlsocket(sock->sock, FIONBIO, &argp);
1206 sock->blocking = 0;
1207 }
1208} 1319}
1209 1320
1210/*-------------------------------------------------------------------------*\ 1321/*-------------------------------------------------------------------------*\
@@ -1354,130 +1465,4 @@ static char *connect_strerror(void)
1354 default: return "unknown error"; 1465 default: return "unknown error";
1355 } 1466 }
1356} 1467}
1357
1358#endif
1359
1360/*=========================================================================*\
1361* Module exported functions
1362\*=========================================================================*/
1363/*-------------------------------------------------------------------------*\
1364* Initializes the library interface with Lua and the socket library.
1365* Defines the symbols exported to Lua.
1366\*-------------------------------------------------------------------------*/
1367void lua_socketlibopen(lua_State *L)
1368{
1369 int client_tag, server_tag;
1370 static struct luaL_reg funcs[] = {
1371 {"connect", net_connect},
1372 {"bind", net_bind},
1373 {"listen", net_listen},
1374 {"accept", net_accept},
1375 {"close", net_close},
1376 {"send", net_send},
1377 {"receive", net_receive},
1378 {"timeout", net_timeout}
1379 };
1380 int i;
1381
1382#ifdef WIN32
1383 wsock_open();
1384#endif
1385 /* declare new Lua tags for used userdata values */
1386 client_tag = lua_newtag(L);
1387 server_tag = lua_newtag(L);
1388 /* Lua exported functions */
1389 for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) {
1390 push_tags(L, client_tag, server_tag);
1391 lua_pushcclosure(L, funcs[i].func, 2);
1392 lua_setglobal(L, funcs[i].name);
1393 }
1394 /* fallbacks */
1395 push_tags(L, client_tag, server_tag);
1396 lua_pushcclosure(L, client_gettable, 2);
1397 lua_settagmethod(L, client_tag, "gettable");
1398
1399 push_tags(L, client_tag, server_tag);
1400 lua_pushcclosure(L, server_gettable, 2);
1401 lua_settagmethod(L, server_tag, "gettable");
1402
1403 push_tags(L, client_tag, server_tag);
1404 lua_pushcclosure(L, sock_gc, 2);
1405 lua_settagmethod(L, client_tag, "gc");
1406
1407 push_tags(L, client_tag, server_tag);
1408 lua_pushcclosure(L, sock_gc, 2);
1409 lua_settagmethod(L, server_tag, "gc");
1410
1411 /* avoid stupid compiler warnings */
1412 (void) set_blocking;
1413
1414#ifndef WIN32
1415 /* avoid getting killed by a SIGPIPE signal */
1416 handle_sigpipe();
1417#endif
1418
1419#ifdef _DEBUG
1420/* test support functions */
1421lua_pushcfunction(L, net_sleep); lua_setglobal(L, "sleep");
1422lua_pushcfunction(L, net_time); lua_setglobal(L, "time");
1423#endif 1468#endif
1424}
1425
1426/*=========================================================================*\
1427* Lua2c and c2lua stack auxiliary functions
1428\*=========================================================================*/
1429/*-------------------------------------------------------------------------*\
1430* Checks if argument is a client socket, printing an error message in
1431* case of error
1432* Input
1433* numArg: argument position in lua2c stack
1434* Returns
1435* pointer to client socket, or doesn't return in case of error
1436\*-------------------------------------------------------------------------*/
1437static p_sock check_client(lua_State *L, int numArg, int client_tag)
1438{
1439 p_sock sock;
1440 luaL_arg_check(L, lua_tag(L, numArg) == client_tag,
1441 numArg, "client socket expected");
1442 sock = (p_sock) lua_touserdata(L, numArg);
1443 if (sock->sock < 0)
1444 lua_error(L, "operation on closed socket");
1445 return sock;
1446}
1447
1448/*-------------------------------------------------------------------------*\
1449* Checks if argument is a server socket, printing an error message in
1450* case of error
1451* Input
1452* numArg: argument position in lua2c stack
1453* Returns
1454* pointer to server socket, or doesn't return in case of error
1455\*-------------------------------------------------------------------------*/
1456static p_sock check_server(lua_State *L, int numArg, int server_tag)
1457{
1458 p_sock sock;
1459 luaL_arg_check(L, lua_tag(L, numArg) == server_tag,
1460 numArg, "server socket expected");
1461 sock = (p_sock) lua_touserdata(L, numArg);
1462 if (sock->sock < 0)
1463 lua_error(L, "operation on closed socket");
1464 return sock;
1465}
1466
1467/*-------------------------------------------------------------------------*\
1468* Checks if argument is a socket, printing an error message in
1469* case of error
1470* Input
1471* numArg: argument position in lua2c stack
1472* Returns
1473* pointer to socket, or doesn't return in case of error
1474\*-------------------------------------------------------------------------*/
1475static p_sock check_sock(lua_State *L, int numArg, int client_tag,
1476 int server_tag)
1477{
1478 p_sock sock;
1479 luaL_arg_check(L, (lua_tag(L, numArg) == client_tag) ||
1480 (lua_tag(L, numArg) == server_tag), numArg, "socket expected");
1481 sock = lua_touserdata(L, numArg);
1482 return sock;
1483}