diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/luasocket.c | 530 |
1 files changed, 201 insertions, 329 deletions
diff --git a/src/luasocket.c b/src/luasocket.c index 644edd6..c4f51bd 100644 --- a/src/luasocket.c +++ b/src/luasocket.c | |||
| @@ -66,13 +66,14 @@ | |||
| 66 | * Datatype compatibilization and some simple changes | 66 | * Datatype compatibilization and some simple changes |
| 67 | \*=========================================================================*/ | 67 | \*=========================================================================*/ |
| 68 | #ifndef WIN32 | 68 | #ifndef WIN32 |
| 69 | #define closesocket close /* WinSock2 has a closesock function instead | 69 | /* WinSock2 has a closesock function instead of the regular close */ |
| 70 | ** of using the regular close function */ | 70 | #define closesocket close |
| 71 | #define SOCKET int /* it defines a SOCKET type instead of | 71 | /* it defines a SOCKET type instead of using an integer file descriptor */ |
| 72 | ** using an integer file descriptor */ | 72 | #define SOCKET int |
| 73 | #define INVALID_SOCKET (-1) /* and uses the this macro to represent and | 73 | /* and uses the this macro to represent and invalid socket */ |
| 74 | ** invalid socket */ | 74 | #define INVALID_SOCKET (-1) |
| 75 | #ifndef CLK_TCK /* SunOS, does not define CLK_TCK */ | 75 | /* SunOS, does not define CLK_TCK */ |
| 76 | #ifndef CLK_TCK | ||
| 76 | #define CLK_TCK 60 | 77 | #define CLK_TCK 60 |
| 77 | #endif | 78 | #endif |
| 78 | #endif | 79 | #endif |
| @@ -103,11 +104,6 @@ | |||
| 103 | #define P_SOCK "(p_sock)sock" | 104 | #define P_SOCK "(p_sock)sock" |
| 104 | 105 | ||
| 105 | /*-------------------------------------------------------------------------*\ | 106 | /*-------------------------------------------------------------------------*\ |
| 106 | * The maximum message size handled (576 bytes should be enough...) | ||
| 107 | \*-------------------------------------------------------------------------*/ | ||
| 108 | #define UDPMAX 4096 | ||
| 109 | |||
| 110 | /*-------------------------------------------------------------------------*\ | ||
| 111 | * Both socket types are stored in the same structure to simplify | 107 | * Both socket types are stored in the same structure to simplify |
| 112 | * implementation. The tag value used is different, though. | 108 | * implementation. The tag value used is different, though. |
| 113 | * The buffer parameters are not used by server and UDP sockets. | 109 | * The buffer parameters are not used by server and UDP sockets. |
| @@ -120,7 +116,7 @@ typedef struct t_sock { | |||
| 120 | /* return and blocking timeout values (-1 if no limit) */ | 116 | /* return and blocking timeout values (-1 if no limit) */ |
| 121 | int tm_return, tm_block; | 117 | int tm_return, tm_block; |
| 122 | /* buffered I/O storage */ | 118 | /* buffered I/O storage */ |
| 123 | unsigned char bf_buffer[LUASOCKET_BUFFERSIZE]; | 119 | unsigned char bf_buffer[LUASOCKET_TCPBUFFERSIZE]; |
| 124 | /* first and last red bytes not yet passed to application */ | 120 | /* first and last red bytes not yet passed to application */ |
| 125 | int bf_first, bf_last; | 121 | int bf_first, bf_last; |
| 126 | /* is this udp socket in "connected" state? */ | 122 | /* is this udp socket in "connected" state? */ |
| @@ -144,11 +140,11 @@ typedef t_tags *p_tags; | |||
| 144 | * Macros and internal declarations | 140 | * Macros and internal declarations |
| 145 | \*-------------------------------------------------------------------------*/ | 141 | \*-------------------------------------------------------------------------*/ |
| 146 | /* min and max macros */ | 142 | /* min and max macros */ |
| 147 | #ifndef min | 143 | #ifndef MIN |
| 148 | #define min(x, y) ((x) < (y) ? x : y) | 144 | #define MIN(x, y) ((x) < (y) ? x : y) |
| 149 | #endif | 145 | #endif |
| 150 | #ifndef max | 146 | #ifndef MAX |
| 151 | #define max(x, y) ((x) > (y) ? x : y) | 147 | #define MAX(x, y) ((x) > (y) ? x : y) |
| 152 | #endif | 148 | #endif |
| 153 | 149 | ||
| 154 | /* we are lazy.. */ | 150 | /* we are lazy.. */ |
| @@ -160,9 +156,10 @@ typedef struct sockaddr SA; | |||
| 160 | /* luasocket global API functions */ | 156 | /* luasocket global API functions */ |
| 161 | static int global_tcpconnect(lua_State *L); | 157 | static int global_tcpconnect(lua_State *L); |
| 162 | static int global_tcpbind(lua_State *L); | 158 | static int global_tcpbind(lua_State *L); |
| 163 | static int global_udpsocket(lua_State *L); | 159 | static int global_select(lua_State *L); |
| 164 | static int global_toip(lua_State *L); | 160 | static int global_toip(lua_State *L); |
| 165 | static int global_tohostname(lua_State *L); | 161 | static int global_tohostname(lua_State *L); |
| 162 | static int global_udpsocket(lua_State *L); | ||
| 166 | 163 | ||
| 167 | /* luasocket table method API functions */ | 164 | /* luasocket table method API functions */ |
| 168 | static int table_tcpaccept(lua_State *L); | 165 | static int table_tcpaccept(lua_State *L); |
| @@ -173,26 +170,9 @@ static int table_udpreceivefrom(lua_State *L); | |||
| 173 | static int table_udpsetpeername(lua_State *L); | 170 | static int table_udpsetpeername(lua_State *L); |
| 174 | static int table_timeout(lua_State *L); | 171 | static int table_timeout(lua_State *L); |
| 175 | static int table_close(lua_State *L); | 172 | static int table_close(lua_State *L); |
| 176 | static int table_poll(lua_State *L); | ||
| 177 | static int table_getpeername(lua_State *L); | 173 | static int table_getpeername(lua_State *L); |
| 178 | static int table_getsockname(lua_State *L); | 174 | static int table_getsockname(lua_State *L); |
| 179 | 175 | ||
| 180 | /* luasocket optional global API functions */ | ||
| 181 | #ifndef LUASOCKET_NOGLOBALS | ||
| 182 | static int global_tcpaccept(lua_State *L); | ||
| 183 | static int global_udpsendto(lua_State *L); | ||
| 184 | static int global_udpreceivefrom(lua_State *L); | ||
| 185 | static int global_udpsetpeername(lua_State *L); | ||
| 186 | static int global_udpsetsockname(lua_State *L); | ||
| 187 | static int global_getsockname(lua_State *L); | ||
| 188 | static int global_getpeername(lua_State *L); | ||
| 189 | static int global_send(lua_State *L); | ||
| 190 | static int global_receive(lua_State *L); | ||
| 191 | static int global_timeout(lua_State *L); | ||
| 192 | static int global_close(lua_State *L); | ||
| 193 | static int global_poll(lua_State *L); | ||
| 194 | #endif | ||
| 195 | |||
| 196 | /* buffered I/O management */ | 176 | /* buffered I/O management */ |
| 197 | static const unsigned char *bf_receive(p_sock sock, int *length); | 177 | static const unsigned char *bf_receive(p_sock sock, int *length); |
| 198 | static void bf_skip(p_sock sock, int length); | 178 | static void bf_skip(p_sock sock, int length); |
| @@ -214,6 +194,7 @@ static int receive_all(lua_State *L, p_sock sock); | |||
| 214 | /* parameter manipulation functions */ | 194 | /* parameter manipulation functions */ |
| 215 | static p_tags pop_tags(lua_State *L); | 195 | static p_tags pop_tags(lua_State *L); |
| 216 | static p_sock pop_sock(lua_State *L); | 196 | static p_sock pop_sock(lua_State *L); |
| 197 | static p_sock get_sock(lua_State *L, int s, p_tags tags, int *tag); | ||
| 217 | static p_sock get_selfsock(lua_State *L, p_tags tags, int *tag); | 198 | static p_sock get_selfsock(lua_State *L, p_tags tags, int *tag); |
| 218 | static p_sock push_servertable(lua_State *L, p_tags tags); | 199 | static p_sock push_servertable(lua_State *L, p_tags tags); |
| 219 | static p_sock push_clienttable(lua_State *L, p_tags tags); | 200 | static p_sock push_clienttable(lua_State *L, p_tags tags); |
| @@ -249,11 +230,6 @@ static int winsock_open(void); | |||
| 249 | static int inet_aton(const char *cp, struct in_addr *inp); | 230 | static int inet_aton(const char *cp, struct in_addr *inp); |
| 250 | #endif | 231 | #endif |
| 251 | 232 | ||
| 252 | #ifndef LUASOCKET_NOGLOBALS | ||
| 253 | static p_sock get_selfserversock(lua_State *L, p_tags tags); | ||
| 254 | static p_sock get_selfudpsock(lua_State *L, p_tags tags); | ||
| 255 | #endif | ||
| 256 | |||
| 257 | /* tag methods */ | 233 | /* tag methods */ |
| 258 | static int gc_table(lua_State *L); | 234 | static int gc_table(lua_State *L); |
| 259 | 235 | ||
| @@ -359,22 +335,22 @@ static int table_tcpaccept(lua_State *L) | |||
| 359 | p_tags tags = pop_tags(L); | 335 | p_tags tags = pop_tags(L); |
| 360 | p_sock client = push_clienttable(L, tags); | 336 | p_sock client = push_clienttable(L, tags); |
| 361 | tm_markstart(server); | 337 | tm_markstart(server); |
| 362 | if (tm_gettimeleft(server) >= 0) { | 338 | if (tm_gettimeleft(server) >= 0) { |
| 363 | set_nonblocking(server); | 339 | set_nonblocking(server); |
| 364 | do { | 340 | do { |
| 365 | if (tm_timedout(server, TM_RECEIVE)) { | 341 | if (tm_timedout(server, TM_RECEIVE)) { |
| 366 | lua_pushnil(L); | 342 | lua_pushnil(L); |
| 367 | push_error(L, NET_TIMEOUT); | 343 | push_error(L, NET_TIMEOUT); |
| 368 | return 2; | 344 | return 2; |
| 369 | } | 345 | } |
| 370 | client->sock = accept(server->sock, (SA *) &client_addr, | 346 | client->sock = accept(server->sock, (SA *) &client_addr, |
| 371 | &client_len); | 347 | &client_len); |
| 372 | } while (client->sock == INVALID_SOCKET); | 348 | } while (client->sock == INVALID_SOCKET); |
| 373 | 349 | ||
| 374 | } else { | 350 | } else { |
| 375 | set_blocking(server); | 351 | set_blocking(server); |
| 376 | client->sock = accept(server->sock, (SA *) &client_addr, &client_len); | 352 | client->sock = accept(server->sock, (SA *) &client_addr, &client_len); |
| 377 | } | 353 | } |
| 378 | set_nonblocking(client); | 354 | set_nonblocking(client); |
| 379 | return 1; | 355 | return 1; |
| 380 | } | 356 | } |
| @@ -561,6 +537,118 @@ static int table_udpsendto(lua_State *L) | |||
| 561 | } | 537 | } |
| 562 | 538 | ||
| 563 | /*-------------------------------------------------------------------------*\ | 539 | /*-------------------------------------------------------------------------*\ |
| 540 | * Waits for a set of sockets until a condition is met or timeout. | ||
| 541 | * Lua Input: {input}, {output} [, timeout] | ||
| 542 | * {input}: table of sockets to be tested for input | ||
| 543 | * {output}: table of sockets to be tested for output | ||
| 544 | * timeout: maximum amount of time to wait for condition, in seconds | ||
| 545 | * Lua Returns: {input}, {output}, err | ||
| 546 | * {input}: table with sockets ready for input | ||
| 547 | * {output}: table with sockets ready for output | ||
| 548 | * err: "timeout" or nil | ||
| 549 | \*-------------------------------------------------------------------------*/ | ||
| 550 | int global_select(lua_State *L) | ||
| 551 | { | ||
| 552 | p_tags tags = pop_tags(L); | ||
| 553 | int ms = lua_isnil(L, 3) ? -1 : (int) (luaL_opt_number(L, 3, -1) * 1000); | ||
| 554 | fd_set readfds, *prfds = NULL, writefds, *pwfds = NULL; | ||
| 555 | struct timeval tm, *ptm = NULL; | ||
| 556 | int ret, s, max = -1; | ||
| 557 | int byfds, canread, canwrite; | ||
| 558 | /* reset the file descriptor sets */ | ||
| 559 | FD_ZERO(&readfds); FD_ZERO(&writefds); | ||
| 560 | /* all sockets, indexed by socket number, for internal use */ | ||
| 561 | lua_newtable(L); byfds = lua_gettop(L); | ||
| 562 | /* readable sockets table to be returned */ | ||
| 563 | lua_newtable(L); canread = lua_gettop(L); | ||
| 564 | /* writable sockets table to be returned */ | ||
| 565 | lua_newtable(L); canwrite = lua_gettop(L); | ||
| 566 | /* get sockets we will test for readability into fd_set */ | ||
| 567 | if (!lua_isnil(L, 1)) { | ||
| 568 | lua_pushnil(L); | ||
| 569 | while (lua_next(L, 1)) { | ||
| 570 | if (lua_tag(L, -1) == tags->table) { | ||
| 571 | p_sock sock = get_sock(L, -1, tags, NULL); | ||
| 572 | lua_pushnumber(L, sock->sock); | ||
| 573 | lua_pushvalue(L, -2); | ||
| 574 | lua_settable(L, byfds); | ||
| 575 | if (sock->sock > max) max = sock->sock; | ||
| 576 | /* a socket can have unread data in our internal buffer. in | ||
| 577 | * that case, we only call select to find out which of the | ||
| 578 | * other sockets can be written to or read from immediately. */ | ||
| 579 | if (!bf_isempty(sock)) { | ||
| 580 | ms = 0; | ||
| 581 | lua_pushnumber(L, lua_getn(L, canread) + 1); | ||
| 582 | lua_pushvalue(L, -2); | ||
| 583 | lua_settable(L, canread); | ||
| 584 | } else { | ||
| 585 | FD_SET(sock->sock, &readfds); | ||
| 586 | prfds = &readfds; | ||
| 587 | } | ||
| 588 | } | ||
| 589 | /* get rid of lua_next value and expose index */ | ||
| 590 | lua_pop(L, 1); | ||
| 591 | } | ||
| 592 | } | ||
| 593 | /* get sockets we will test for writability into fd_set */ | ||
| 594 | if (!lua_isnil(L, 2)) { | ||
| 595 | lua_pushnil(L); | ||
| 596 | while (lua_next(L, 2)) { | ||
| 597 | if (lua_tag(L, -1) == tags->table) { | ||
| 598 | p_sock sock = get_sock(L, -1, tags, NULL); | ||
| 599 | lua_pushnumber(L, sock->sock); | ||
| 600 | lua_pushvalue(L, -2); | ||
| 601 | lua_settable(L, byfds); | ||
| 602 | if (sock->sock > max) max = sock->sock; | ||
| 603 | FD_SET(sock->sock, &writefds); | ||
| 604 | pwfds = &writefds; | ||
| 605 | } | ||
| 606 | /* get rid of lua_next value and expose index */ | ||
| 607 | lua_pop(L, 1); | ||
| 608 | } | ||
| 609 | } | ||
| 610 | max++; | ||
| 611 | /* configure timeout value */ | ||
| 612 | if (ms >= 0) { | ||
| 613 | ptm = &tm; /* ptm == NULL when we don't have timeout */ | ||
| 614 | /* fill timeval structure */ | ||
| 615 | tm.tv_sec = ms / 1000; | ||
| 616 | tm.tv_usec = (ms % 1000) * 1000; | ||
| 617 | } | ||
| 618 | /* see if we can read, write or if we timedout */ | ||
| 619 | ret = select(max, prfds, pwfds, NULL, ptm); | ||
| 620 | /* did we timeout? */ | ||
| 621 | if (ret <= 0 && ms > 0) { | ||
| 622 | push_error(L, NET_TIMEOUT); | ||
| 623 | return 3; | ||
| 624 | } | ||
| 625 | /* collect readable sockets */ | ||
| 626 | if (prfds) { | ||
| 627 | for (s = 0; s < max; s++) { | ||
| 628 | if (FD_ISSET(s, prfds)) { | ||
| 629 | lua_pushnumber(L, lua_getn(L, canread) + 1); | ||
| 630 | lua_pushnumber(L, s); | ||
| 631 | lua_gettable(L, byfds); | ||
| 632 | lua_settable(L, canread); | ||
| 633 | } | ||
| 634 | } | ||
| 635 | } | ||
| 636 | /* collect writable sockets */ | ||
| 637 | if (pwfds) { | ||
| 638 | for (s = 0; s < max; s++) { | ||
| 639 | if (FD_ISSET(s, pwfds)) { | ||
| 640 | lua_pushnumber(L, lua_getn(L, canwrite) + 1); | ||
| 641 | lua_pushnumber(L, s); | ||
| 642 | lua_gettable(L, byfds); | ||
| 643 | lua_settable(L, canwrite); | ||
| 644 | } | ||
| 645 | } | ||
| 646 | } | ||
| 647 | lua_pushnil(L); | ||
| 648 | return 3; | ||
| 649 | } | ||
| 650 | |||
| 651 | /*-------------------------------------------------------------------------*\ | ||
| 564 | * Returns the list of ip addresses associated with a host name | 652 | * Returns the list of ip addresses associated with a host name |
| 565 | * Lua Input: address | 653 | * Lua Input: address |
| 566 | * address: ip address or hostname to dns lookup | 654 | * address: ip address or hostname to dns lookup |
| @@ -581,7 +669,7 @@ static int global_toip(lua_State *L) | |||
| 581 | lua_pushstring(L, host_strerror()); | 669 | lua_pushstring(L, host_strerror()); |
| 582 | return 2; | 670 | return 2; |
| 583 | } | 671 | } |
| 584 | addr = *((struct in_addr *) hp->h_addr); | 672 | addr = *((struct in_addr *) hp->h_addr); |
| 585 | lua_pushstring(L, inet_ntoa(addr)); | 673 | lua_pushstring(L, inet_ntoa(addr)); |
| 586 | push_resolved(L, hp); | 674 | push_resolved(L, hp); |
| 587 | return 2; | 675 | return 2; |
| @@ -609,7 +697,7 @@ static int global_tohostname(lua_State *L) | |||
| 609 | return 2; | 697 | return 2; |
| 610 | } | 698 | } |
| 611 | lua_pushstring(L, hp->h_name); | 699 | lua_pushstring(L, hp->h_name); |
| 612 | push_resolved(L, hp); | 700 | push_resolved(L, hp); |
| 613 | return 2; | 701 | return 2; |
| 614 | } | 702 | } |
| 615 | 703 | ||
| @@ -649,7 +737,7 @@ static int table_udpsend(lua_State *L) | |||
| 649 | * Receives a datagram from a UDP socket | 737 | * Receives a datagram from a UDP socket |
| 650 | * Lua Input: sock [, wanted] | 738 | * Lua Input: sock [, wanted] |
| 651 | * sock: client socket created by the connect function | 739 | * sock: client socket created by the connect function |
| 652 | * wanted: the number of bytes expected (default: UDPMAX) | 740 | * wanted: the number of bytes expected (default: LUASOCKET_UDPBUFFERSIZE) |
| 653 | * Lua Returns | 741 | * Lua Returns |
| 654 | * On success: datagram received, ip and port of sender | 742 | * On success: datagram received, ip and port of sender |
| 655 | * On error: nil, followed by an error message | 743 | * On error: nil, followed by an error message |
| @@ -657,10 +745,10 @@ static int table_udpsend(lua_State *L) | |||
| 657 | static int table_udpreceivefrom(lua_State *L) | 745 | static int table_udpreceivefrom(lua_State *L) |
| 658 | { | 746 | { |
| 659 | p_sock sock = pop_sock(L); | 747 | p_sock sock = pop_sock(L); |
| 660 | size_t wanted = (int) luaL_opt_number(L, 2, UDPMAX); | 748 | size_t wanted = (int) luaL_opt_number(L, 2, LUASOCKET_UDPBUFFERSIZE); |
| 661 | struct sockaddr_in peer; | 749 | struct sockaddr_in peer; |
| 662 | size_t peer_len = sizeof(peer); | 750 | size_t peer_len = sizeof(peer); |
| 663 | unsigned char buffer[UDPMAX]; | 751 | unsigned char buffer[LUASOCKET_UDPBUFFERSIZE]; |
| 664 | int got; | 752 | int got; |
| 665 | if (sock->is_connected) lua_error(L, "receivefrom on connected socket"); | 753 | if (sock->is_connected) lua_error(L, "receivefrom on connected socket"); |
| 666 | tm_markstart(sock); | 754 | tm_markstart(sock); |
| @@ -669,7 +757,7 @@ static int table_udpreceivefrom(lua_State *L) | |||
| 669 | push_error(L, NET_TIMEOUT); | 757 | push_error(L, NET_TIMEOUT); |
| 670 | return 2; | 758 | return 2; |
| 671 | } | 759 | } |
| 672 | wanted = min(wanted, sizeof(buffer)); | 760 | wanted = MIN(wanted, sizeof(buffer)); |
| 673 | got = recvfrom(sock->sock, buffer, wanted, 0, (SA *) &peer, &peer_len); | 761 | got = recvfrom(sock->sock, buffer, wanted, 0, (SA *) &peer, &peer_len); |
| 674 | if (got >= 0) { | 762 | if (got >= 0) { |
| 675 | lua_pushlstring(L, buffer, got); | 763 | lua_pushlstring(L, buffer, got); |
| @@ -687,7 +775,7 @@ static int table_udpreceivefrom(lua_State *L) | |||
| 687 | * Receives data from a UDP socket | 775 | * Receives data from a UDP socket |
| 688 | * Lua Input: sock [, wanted] | 776 | * Lua Input: sock [, wanted] |
| 689 | * sock: client socket created by the connect function | 777 | * sock: client socket created by the connect function |
| 690 | * wanted: the number of bytes expected (default: UDPMAX) | 778 | * wanted: the number of bytes expected (default: LUASOCKET_UDPBUFFERSIZE) |
| 691 | * Lua Returns | 779 | * Lua Returns |
| 692 | * On success: datagram received | 780 | * On success: datagram received |
| 693 | * On error: nil, followed by an error message | 781 | * On error: nil, followed by an error message |
| @@ -695,8 +783,8 @@ static int table_udpreceivefrom(lua_State *L) | |||
| 695 | static int table_udpreceive(lua_State *L) | 783 | static int table_udpreceive(lua_State *L) |
| 696 | { | 784 | { |
| 697 | p_sock sock = pop_sock(L); | 785 | p_sock sock = pop_sock(L); |
| 698 | size_t wanted = (size_t) luaL_opt_number(L, 2, UDPMAX); | 786 | size_t wanted = (size_t) luaL_opt_number(L, 2, LUASOCKET_UDPBUFFERSIZE); |
| 699 | unsigned char buffer[UDPMAX]; | 787 | unsigned char buffer[LUASOCKET_UDPBUFFERSIZE]; |
| 700 | int got; | 788 | int got; |
| 701 | tm_markstart(sock); | 789 | tm_markstart(sock); |
| 702 | if (tm_timedout(sock, TM_RECEIVE)) { | 790 | if (tm_timedout(sock, TM_RECEIVE)) { |
| @@ -704,7 +792,7 @@ static int table_udpreceive(lua_State *L) | |||
| 704 | push_error(L, NET_TIMEOUT); | 792 | push_error(L, NET_TIMEOUT); |
| 705 | return 2; | 793 | return 2; |
| 706 | } | 794 | } |
| 707 | got = recv(sock->sock, buffer, min(wanted, sizeof(buffer)), 0); | 795 | got = recv(sock->sock, buffer, MIN(wanted, sizeof(buffer)), 0); |
| 708 | if (got >= 0) { | 796 | if (got >= 0) { |
| 709 | lua_pushlstring(L, buffer, got); | 797 | lua_pushlstring(L, buffer, got); |
| 710 | return 1; | 798 | return 1; |
| @@ -745,11 +833,11 @@ static int table_tcpreceive(lua_State *L) | |||
| 745 | lua_pushstring(L, "*l"); | 833 | lua_pushstring(L, "*l"); |
| 746 | top++; | 834 | top++; |
| 747 | } | 835 | } |
| 748 | /* make sure we have enough stack space */ | 836 | /* make sure we have enough stack space */ |
| 749 | luaL_checkstack(L, top+LUA_MINSTACK, "too many arguments"); | 837 | luaL_checkstack(L, top+LUA_MINSTACK, "too many arguments"); |
| 750 | /* receive all patterns */ | 838 | /* receive all patterns */ |
| 751 | for (arg = 2; arg <= top; arg++) { | 839 | for (arg = 2; arg <= top; arg++) { |
| 752 | /* if one pattern failed, we just skip all other patterns */ | 840 | /* if one pattern fails, we just skip all other patterns */ |
| 753 | if (err != NET_DONE) { | 841 | if (err != NET_DONE) { |
| 754 | lua_pushnil(L); | 842 | lua_pushnil(L); |
| 755 | continue; | 843 | continue; |
| @@ -841,54 +929,15 @@ static int table_getsockname(lua_State *L) | |||
| 841 | static int table_close(lua_State *L) | 929 | static int table_close(lua_State *L) |
| 842 | { | 930 | { |
| 843 | /* close socket and set value to INVALID_SOCKET so that | 931 | /* close socket and set value to INVALID_SOCKET so that |
| 844 | ** pop_socket can later detect the use of a closed socket */ | 932 | ** pop_sock can later detect the use of a closed socket */ |
| 845 | p_sock sock = pop_sock(L); | 933 | p_sock sock = (p_sock) lua_touserdata(L, -1); |
| 846 | closesocket(sock->sock); | 934 | if (!sock) lua_error(L, "invalid socket object"); |
| 935 | if (sock->sock != INVALID_SOCKET) closesocket(sock->sock); | ||
| 847 | sock->sock = INVALID_SOCKET; | 936 | sock->sock = INVALID_SOCKET; |
| 848 | return 0; | 937 | return 0; |
| 849 | } | 938 | } |
| 850 | 939 | ||
| 851 | /*-------------------------------------------------------------------------*\ | 940 | /*-------------------------------------------------------------------------*\ |
| 852 | * Tests if we can immediately read or write on a socket | ||
| 853 | * Lua Input | ||
| 854 | * sock: socket to be closed | ||
| 855 | * operation: operation to query "*r", "*s" | ||
| 856 | * Lua Returns | ||
| 857 | * 1 if operation will be accepted, nil otherwise | ||
| 858 | \*-------------------------------------------------------------------------*/ | ||
| 859 | static int table_poll(lua_State *L) | ||
| 860 | { | ||
| 861 | p_sock sock = pop_sock(L); | ||
| 862 | const char *op = luaL_check_string(L, 2); | ||
| 863 | int tm_block = sock->tm_block; | ||
| 864 | int tm_return = sock->tm_return; | ||
| 865 | if (!*op || *op != '*') lua_error(L, "invalid poll pattern"); | ||
| 866 | op++; | ||
| 867 | tm_markstart(sock); | ||
| 868 | switch (*op) { | ||
| 869 | case 'r': | ||
| 870 | sock->tm_block = sock->tm_return = 0; | ||
| 871 | if (bf_isempty(sock) && tm_timedout(sock, TM_RECEIVE)) | ||
| 872 | lua_pushnil(L); | ||
| 873 | else lua_pushnumber(L, 1); | ||
| 874 | sock->tm_block = tm_block; | ||
| 875 | sock->tm_return = tm_return; | ||
| 876 | break; | ||
| 877 | case 's': | ||
| 878 | sock->tm_block = sock->tm_return = 0; | ||
| 879 | if (tm_timedout(sock, TM_SEND)) lua_pushnil(L); | ||
| 880 | else lua_pushnumber(L, 1); | ||
| 881 | sock->tm_block = tm_block; | ||
| 882 | sock->tm_return = tm_return; | ||
| 883 | break; | ||
| 884 | default: | ||
| 885 | lua_error(L, "invalid poll pattern"); | ||
| 886 | break; | ||
| 887 | } | ||
| 888 | return 1; | ||
| 889 | } | ||
| 890 | |||
| 891 | /*-------------------------------------------------------------------------*\ | ||
| 892 | * Garbage collection fallback for the socket objects. This function | 941 | * Garbage collection fallback for the socket objects. This function |
| 893 | * makes sure that all collected sockets are closed. | 942 | * makes sure that all collected sockets are closed. |
| 894 | \*-------------------------------------------------------------------------*/ | 943 | \*-------------------------------------------------------------------------*/ |
| @@ -959,7 +1008,7 @@ const char *tcp_tryconnect(p_sock sock, const char *address, | |||
| 959 | sock->sock = socket(AF_INET, SOCK_STREAM, 0); | 1008 | sock->sock = socket(AF_INET, SOCK_STREAM, 0); |
| 960 | if (sock->sock == INVALID_SOCKET) return socket_strerror(); | 1009 | if (sock->sock == INVALID_SOCKET) return socket_strerror(); |
| 961 | if (connect(sock->sock, (SA *) &remote, sizeof(remote)) == 0) | 1010 | if (connect(sock->sock, (SA *) &remote, sizeof(remote)) == 0) |
| 962 | break; | 1011 | break; |
| 963 | closesocket(sock->sock); | 1012 | closesocket(sock->sock); |
| 964 | sock->sock = INVALID_SOCKET; | 1013 | sock->sock = INVALID_SOCKET; |
| 965 | memset(&remote, 0, sizeof(remote)); | 1014 | memset(&remote, 0, sizeof(remote)); |
| @@ -1140,13 +1189,13 @@ static int tm_gettimeleft(p_sock sock) | |||
| 1140 | return -1; | 1189 | return -1; |
| 1141 | /* there is no block timeout, we use the return timeout */ | 1190 | /* there is no block timeout, we use the return timeout */ |
| 1142 | else if (sock->tm_block < 0) | 1191 | else if (sock->tm_block < 0) |
| 1143 | return max(sock->tm_return - tm_gettime() + sock->tm_start, 0); | 1192 | return MAX(sock->tm_return - tm_gettime() + sock->tm_start, 0); |
| 1144 | /* there is no return timeout, we use the block timeout */ | 1193 | /* there is no return timeout, we use the block timeout */ |
| 1145 | else if (sock->tm_return < 0) | 1194 | else if (sock->tm_return < 0) |
| 1146 | return sock->tm_block; | 1195 | return sock->tm_block; |
| 1147 | /* both timeouts are specified */ | 1196 | /* both timeouts are specified */ |
| 1148 | else return min(sock->tm_block, | 1197 | else return MIN(sock->tm_block, |
| 1149 | max(sock->tm_return - tm_gettime() + sock->tm_start, 0)); | 1198 | MAX(sock->tm_return - tm_gettime() + sock->tm_start, 0)); |
| 1150 | } | 1199 | } |
| 1151 | 1200 | ||
| 1152 | /*-------------------------------------------------------------------------*\ | 1201 | /*-------------------------------------------------------------------------*\ |
| @@ -1253,7 +1302,7 @@ static void bf_skip(p_sock sock, int length) | |||
| 1253 | static const unsigned char *bf_receive(p_sock sock, int *length) | 1302 | static const unsigned char *bf_receive(p_sock sock, int *length) |
| 1254 | { | 1303 | { |
| 1255 | if (bf_isempty(sock)) { | 1304 | if (bf_isempty(sock)) { |
| 1256 | int got = recv(sock->sock, sock->bf_buffer, LUASOCKET_BUFFERSIZE, 0); | 1305 | int got = recv(sock->sock, sock->bf_buffer, LUASOCKET_TCPBUFFERSIZE, 0); |
| 1257 | sock->bf_first = 0; | 1306 | sock->bf_first = 0; |
| 1258 | if (got >= 0) sock->bf_last = got; | 1307 | if (got >= 0) sock->bf_last = got; |
| 1259 | else sock->bf_last = 0; | 1308 | else sock->bf_last = 0; |
| @@ -1294,15 +1343,15 @@ static int send_raw(p_sock sock, const char *data, int wanted, int *total) | |||
| 1294 | continue; | 1343 | continue; |
| 1295 | #endif | 1344 | #endif |
| 1296 | #ifdef __CYGWIN__ | 1345 | #ifdef __CYGWIN__ |
| 1297 | /* this is for CYGWIN, which is like Unix but with Win32 Bugs */ | 1346 | /* this is for CYGWIN, which is like Unix but with Win32 Bugs */ |
| 1298 | if (put < 0 && errno == EWOULDBLOCK) | 1347 | if (put < 0 && errno == EWOULDBLOCK) |
| 1299 | continue; | 1348 | continue; |
| 1300 | #endif | 1349 | #endif |
| 1301 | 1350 | ||
| 1302 | return NET_CLOSED; | 1351 | return NET_CLOSED; |
| 1303 | } | 1352 | } |
| 1304 | wanted -= put; | 1353 | wanted -= put; |
| 1305 | data += put; | 1354 | data += put; |
| 1306 | *total += put; | 1355 | *total += put; |
| 1307 | } | 1356 | } |
| 1308 | return NET_DONE; | 1357 | return NET_DONE; |
| @@ -1333,7 +1382,7 @@ static int receive_raw(lua_State *L, p_sock sock, int wanted) | |||
| 1333 | luaL_pushresult(&b); | 1382 | luaL_pushresult(&b); |
| 1334 | return NET_CLOSED; | 1383 | return NET_CLOSED; |
| 1335 | } | 1384 | } |
| 1336 | got = min(got, wanted); | 1385 | got = MIN(got, wanted); |
| 1337 | luaL_addlstring(&b, buffer, got); | 1386 | luaL_addlstring(&b, buffer, got); |
| 1338 | bf_skip(sock, got); | 1387 | bf_skip(sock, got); |
| 1339 | wanted -= got; | 1388 | wanted -= got; |
| @@ -1466,11 +1515,12 @@ static int receive_unixline(lua_State *L, p_sock sock) | |||
| 1466 | void lua_socketlibopen(lua_State *L) | 1515 | void lua_socketlibopen(lua_State *L) |
| 1467 | { | 1516 | { |
| 1468 | static struct luaL_reg funcs[] = { | 1517 | static struct luaL_reg funcs[] = { |
| 1469 | {"connect", global_tcpconnect}, | ||
| 1470 | {"udpsocket", global_udpsocket}, | ||
| 1471 | {"bind", global_tcpbind}, | 1518 | {"bind", global_tcpbind}, |
| 1519 | {"connect", global_tcpconnect}, | ||
| 1520 | {"select", global_select}, | ||
| 1472 | {"toip", global_toip}, | 1521 | {"toip", global_toip}, |
| 1473 | {"tohostname", global_tohostname}, | 1522 | {"tohostname", global_tohostname}, |
| 1523 | {"udpsocket", global_udpsocket}, | ||
| 1474 | }; | 1524 | }; |
| 1475 | unsigned int i; | 1525 | unsigned int i; |
| 1476 | /* declare new Lua tags for used userdata values */ | 1526 | /* declare new Lua tags for used userdata values */ |
| @@ -1490,30 +1540,6 @@ void lua_socketlibopen(lua_State *L) | |||
| 1490 | lua_pushuserdata(L, tags); | 1540 | lua_pushuserdata(L, tags); |
| 1491 | lua_pushcclosure(L, gc_table, 1); | 1541 | lua_pushcclosure(L, gc_table, 1); |
| 1492 | lua_settagmethod(L, tags->table, "gc"); | 1542 | lua_settagmethod(L, tags->table, "gc"); |
| 1493 | |||
| 1494 | #ifndef LUASOCKET_NOGLOBALS | ||
| 1495 | /* global version of socket table functions */ | ||
| 1496 | { static struct luaL_reg opt_funcs[] = { | ||
| 1497 | {"accept", global_tcpaccept}, | ||
| 1498 | {"setpeername", global_udpsetpeername}, | ||
| 1499 | {"setsockname", global_udpsetsockname}, | ||
| 1500 | {"getsockname", global_getsockname}, | ||
| 1501 | {"getpeername", global_getpeername}, | ||
| 1502 | {"sendto", global_udpsendto}, | ||
| 1503 | {"receivefrom", global_udpreceivefrom}, | ||
| 1504 | {"timeout", global_timeout}, | ||
| 1505 | {"send", global_send}, | ||
| 1506 | {"poll", global_poll}, | ||
| 1507 | {"receive", global_receive}, | ||
| 1508 | {"close", global_close}, | ||
| 1509 | }; | ||
| 1510 | for (i = 0; i < sizeof(opt_funcs)/sizeof(opt_funcs[0]); i++) { | ||
| 1511 | lua_pushuserdata(L, tags); | ||
| 1512 | lua_pushcclosure(L, opt_funcs[i].func, 1); | ||
| 1513 | lua_setglobal(L, opt_funcs[i].name); | ||
| 1514 | } | ||
| 1515 | } | ||
| 1516 | #endif | ||
| 1517 | #ifdef WIN32 | 1543 | #ifdef WIN32 |
| 1518 | /* WinSock needs special initialization */ | 1544 | /* WinSock needs special initialization */ |
| 1519 | winsock_open(); | 1545 | winsock_open(); |
| @@ -1529,134 +1555,6 @@ void lua_socketlibopen(lua_State *L) | |||
| 1529 | } | 1555 | } |
| 1530 | 1556 | ||
| 1531 | /*=========================================================================*\ | 1557 | /*=========================================================================*\ |
| 1532 | * Optional global version of socket table methods | ||
| 1533 | * Simply push socket object on top or stack and call the table methods. | ||
| 1534 | \*=========================================================================*/ | ||
| 1535 | #ifndef LUASOCKET_NOGLOBALS | ||
| 1536 | int global_tcpaccept(lua_State *L) | ||
| 1537 | { | ||
| 1538 | p_tags tags = pop_tags(L); | ||
| 1539 | p_sock sock = get_selfserversock(L, tags); | ||
| 1540 | lua_pushuserdata(L, tags); | ||
| 1541 | lua_pushusertag(L, sock, tags->server); | ||
| 1542 | return table_tcpaccept(L); | ||
| 1543 | } | ||
| 1544 | |||
| 1545 | int global_udpsendto(lua_State *L) | ||
| 1546 | { | ||
| 1547 | p_tags tags = pop_tags(L); | ||
| 1548 | p_sock sock = get_selfudpsock(L, tags); | ||
| 1549 | lua_pushusertag(L, sock, tags->udp); | ||
| 1550 | return table_udpsendto(L); | ||
| 1551 | } | ||
| 1552 | |||
| 1553 | int global_udpsetpeername(lua_State *L) | ||
| 1554 | { | ||
| 1555 | p_tags tags = pop_tags(L); | ||
| 1556 | p_sock sock = get_selfudpsock(L, tags); | ||
| 1557 | lua_pushusertag(L, sock, tags->udp); | ||
| 1558 | return table_udpsetpeername(L); | ||
| 1559 | } | ||
| 1560 | |||
| 1561 | int global_udpsetsockname(lua_State *L) | ||
| 1562 | { | ||
| 1563 | p_tags tags = pop_tags(L); | ||
| 1564 | p_sock sock = get_selfudpsock(L, tags); | ||
| 1565 | lua_pushusertag(L, sock, tags->udp); | ||
| 1566 | return table_udpsetsockname(L); | ||
| 1567 | } | ||
| 1568 | |||
| 1569 | int global_udpreceivefrom(lua_State *L) | ||
| 1570 | { | ||
| 1571 | p_tags tags = pop_tags(L); | ||
| 1572 | p_sock sock = get_selfudpsock(L, tags); | ||
| 1573 | lua_pushusertag(L, sock, tags->udp); | ||
| 1574 | return table_udpreceivefrom(L); | ||
| 1575 | } | ||
| 1576 | |||
| 1577 | int global_poll(lua_State *L) | ||
| 1578 | { | ||
| 1579 | p_tags tags = pop_tags(L); | ||
| 1580 | int tag; | ||
| 1581 | p_sock sock = get_selfsock(L, tags, &tag); | ||
| 1582 | lua_pushusertag(L, sock, tag); | ||
| 1583 | return table_poll(L); | ||
| 1584 | } | ||
| 1585 | |||
| 1586 | int global_send(lua_State *L) | ||
| 1587 | { | ||
| 1588 | p_tags tags = pop_tags(L); | ||
| 1589 | int tag; | ||
| 1590 | p_sock sock = get_selfsock(L, tags, &tag); | ||
| 1591 | if (tag == tags->udp) { | ||
| 1592 | lua_pushusertag(L, sock, tags->udp); | ||
| 1593 | return table_udpsend(L); | ||
| 1594 | } else if (tag == tags->client) { | ||
| 1595 | lua_pushusertag(L, sock, tags->client); | ||
| 1596 | return table_tcpsend(L); | ||
| 1597 | } else if (tag == tags->server) { | ||
| 1598 | lua_error(L, "send on server socket"); | ||
| 1599 | } else | ||
| 1600 | lua_error(L, "invalid socket object"); | ||
| 1601 | /* avoid compiler warnings */ | ||
| 1602 | return 0; | ||
| 1603 | } | ||
| 1604 | |||
| 1605 | int global_receive(lua_State *L) | ||
| 1606 | { | ||
| 1607 | p_tags tags = pop_tags(L); | ||
| 1608 | int tag; | ||
| 1609 | p_sock sock = get_selfsock(L, tags, &tag); | ||
| 1610 | if (tag == tags->udp) { | ||
| 1611 | lua_pushusertag(L, sock, tags->udp); | ||
| 1612 | return table_udpreceive(L); | ||
| 1613 | } else if (tag == tags->client) { | ||
| 1614 | lua_pushusertag(L, sock, tags->client); | ||
| 1615 | return table_tcpreceive(L); | ||
| 1616 | } else if (tag == tags->server) { | ||
| 1617 | lua_error(L, "receive on server socket"); | ||
| 1618 | } else | ||
| 1619 | lua_error(L, "invalid socket object"); | ||
| 1620 | /* avoid compiler warnings */ | ||
| 1621 | return 0; | ||
| 1622 | } | ||
| 1623 | |||
| 1624 | int global_timeout(lua_State *L) | ||
| 1625 | { | ||
| 1626 | p_tags tags = pop_tags(L); | ||
| 1627 | int tag; | ||
| 1628 | p_sock sock = get_selfsock(L, tags, &tag); | ||
| 1629 | lua_pushusertag(L, sock, tag); | ||
| 1630 | return table_timeout(L); | ||
| 1631 | } | ||
| 1632 | |||
| 1633 | int global_getpeername(lua_State *L) | ||
| 1634 | { | ||
| 1635 | p_tags tags = pop_tags(L); | ||
| 1636 | int tag; | ||
| 1637 | p_sock sock = get_selfsock(L, tags, &tag); | ||
| 1638 | if (tag == tags->server) lua_error(L, "getpeername on server socket"); | ||
| 1639 | lua_pushusertag(L, sock, tag); | ||
| 1640 | return table_getpeername(L); | ||
| 1641 | } | ||
| 1642 | |||
| 1643 | int global_getsockname(lua_State *L) | ||
| 1644 | { | ||
| 1645 | p_tags tags = pop_tags(L); | ||
| 1646 | int tag; | ||
| 1647 | p_sock sock = get_selfsock(L, tags, &tag); | ||
| 1648 | lua_pushusertag(L, sock, tag); | ||
| 1649 | return table_getsockname(L); | ||
| 1650 | } | ||
| 1651 | |||
| 1652 | int global_close(lua_State *L) | ||
| 1653 | { | ||
| 1654 | /* just call the garbage collection tag method. it knows what to do */ | ||
| 1655 | return gc_table(L); | ||
| 1656 | } | ||
| 1657 | #endif | ||
| 1658 | |||
| 1659 | /*=========================================================================*\ | ||
| 1660 | * Lua Stack manipulation functions | 1558 | * Lua Stack manipulation functions |
| 1661 | \*=========================================================================*/ | 1559 | \*=========================================================================*/ |
| 1662 | /*-------------------------------------------------------------------------*\ | 1560 | /*-------------------------------------------------------------------------*\ |
| @@ -1673,7 +1571,6 @@ static p_sock push_clienttable(lua_State *L, p_tags tags) | |||
| 1673 | {"close", table_close}, | 1571 | {"close", table_close}, |
| 1674 | {"getsockname", table_getsockname}, | 1572 | {"getsockname", table_getsockname}, |
| 1675 | {"getpeername", table_getpeername}, | 1573 | {"getpeername", table_getpeername}, |
| 1676 | {"poll", table_poll}, | ||
| 1677 | {"receive", table_tcpreceive}, | 1574 | {"receive", table_tcpreceive}, |
| 1678 | {"send", table_tcpsend}, | 1575 | {"send", table_tcpsend}, |
| 1679 | {"timeout", table_timeout}, | 1576 | {"timeout", table_timeout}, |
| @@ -1713,7 +1610,6 @@ static p_sock push_servertable(lua_State *L, p_tags tags) | |||
| 1713 | static struct luaL_reg funcs[] = { | 1610 | static struct luaL_reg funcs[] = { |
| 1714 | {"close", table_close}, | 1611 | {"close", table_close}, |
| 1715 | {"getsockname", table_getsockname}, | 1612 | {"getsockname", table_getsockname}, |
| 1716 | {"poll", table_poll}, | ||
| 1717 | {"timeout", table_timeout}, | 1613 | {"timeout", table_timeout}, |
| 1718 | }; | 1614 | }; |
| 1719 | unsigned int i; | 1615 | unsigned int i; |
| @@ -1759,7 +1655,6 @@ static p_sock push_udptable(lua_State *L, p_tags tags) | |||
| 1759 | {"setsockname", table_udpsetsockname}, | 1655 | {"setsockname", table_udpsetsockname}, |
| 1760 | {"getpeername", table_getpeername}, | 1656 | {"getpeername", table_getpeername}, |
| 1761 | {"getsockname", table_getsockname}, | 1657 | {"getsockname", table_getsockname}, |
| 1762 | {"poll", table_poll}, | ||
| 1763 | {"receivefrom", table_udpreceivefrom}, | 1658 | {"receivefrom", table_udpreceivefrom}, |
| 1764 | {"receive", table_udpreceive}, | 1659 | {"receive", table_udpreceive}, |
| 1765 | {"send", table_udpsend}, | 1660 | {"send", table_udpsend}, |
| @@ -1804,40 +1699,40 @@ static p_sock push_udptable(lua_State *L, p_tags tags) | |||
| 1804 | \*-------------------------------------------------------------------------*/ | 1699 | \*-------------------------------------------------------------------------*/ |
| 1805 | static void push_resolved(lua_State *L, struct hostent *hp) | 1700 | static void push_resolved(lua_State *L, struct hostent *hp) |
| 1806 | { | 1701 | { |
| 1807 | char **alias; | 1702 | char **alias; |
| 1808 | struct in_addr **addr; | 1703 | struct in_addr **addr; |
| 1809 | int i, resolved; | 1704 | int i, resolved; |
| 1810 | 1705 | ||
| 1811 | lua_newtable(L); resolved = lua_gettop(L); | 1706 | lua_newtable(L); resolved = lua_gettop(L); |
| 1812 | 1707 | ||
| 1813 | lua_pushstring(L, "name"); | 1708 | lua_pushstring(L, "name"); |
| 1814 | lua_pushstring(L, hp->h_name); | 1709 | lua_pushstring(L, hp->h_name); |
| 1815 | lua_settable(L, resolved); | 1710 | lua_settable(L, resolved); |
| 1816 | 1711 | ||
| 1817 | lua_pushstring(L, "ip"); | 1712 | lua_pushstring(L, "ip"); |
| 1818 | lua_pushstring(L, "alias"); | 1713 | lua_pushstring(L, "alias"); |
| 1819 | 1714 | ||
| 1820 | i = 1; | 1715 | i = 1; |
| 1821 | alias = hp->h_aliases; | 1716 | alias = hp->h_aliases; |
| 1822 | lua_newtable(L); | 1717 | lua_newtable(L); |
| 1823 | while (*alias) { | 1718 | while (*alias) { |
| 1824 | lua_pushnumber(L, i); | 1719 | lua_pushnumber(L, i); |
| 1825 | lua_pushstring(L, *alias); | 1720 | lua_pushstring(L, *alias); |
| 1826 | lua_settable(L, -3); | 1721 | lua_settable(L, -3); |
| 1827 | i++; alias++; | 1722 | i++; alias++; |
| 1828 | } | 1723 | } |
| 1829 | lua_settable(L, resolved); | 1724 | lua_settable(L, resolved); |
| 1830 | 1725 | ||
| 1831 | i = 1; | 1726 | i = 1; |
| 1832 | lua_newtable(L); | 1727 | lua_newtable(L); |
| 1833 | addr = (struct in_addr **) hp->h_addr_list; | 1728 | addr = (struct in_addr **) hp->h_addr_list; |
| 1834 | while (*addr) { | 1729 | while (*addr) { |
| 1835 | lua_pushnumber(L, i); | 1730 | lua_pushnumber(L, i); |
| 1836 | lua_pushstring(L, inet_ntoa(**addr)); | 1731 | lua_pushstring(L, inet_ntoa(**addr)); |
| 1837 | lua_settable(L, -3); | 1732 | lua_settable(L, -3); |
| 1838 | i++; addr++; | 1733 | i++; addr++; |
| 1839 | } | 1734 | } |
| 1840 | lua_settable(L, resolved); | 1735 | lua_settable(L, resolved); |
| 1841 | } | 1736 | } |
| 1842 | 1737 | ||
| 1843 | /*-------------------------------------------------------------------------*\ | 1738 | /*-------------------------------------------------------------------------*\ |
| @@ -1881,12 +1776,12 @@ static p_sock pop_sock(lua_State *L) | |||
| 1881 | return sock; | 1776 | return sock; |
| 1882 | } | 1777 | } |
| 1883 | 1778 | ||
| 1884 | static p_sock get_selfsock(lua_State *L, p_tags tags, int *tag) | 1779 | static p_sock get_sock(lua_State *L, int s, p_tags tags, int *tag) |
| 1885 | { | 1780 | { |
| 1886 | p_sock sock; | 1781 | p_sock sock; |
| 1887 | if (lua_tag(L, 1) != tags->table) lua_error(L, "invalid socket object"); | 1782 | if (lua_tag(L, s) != tags->table) lua_error(L, "invalid socket object"); |
| 1888 | lua_pushstring(L, P_SOCK); | 1783 | lua_pushstring(L, P_SOCK); |
| 1889 | lua_gettable(L, 1); | 1784 | lua_gettable(L, s > 0 ? s : s-1); |
| 1890 | sock = lua_touserdata(L, -1); | 1785 | sock = lua_touserdata(L, -1); |
| 1891 | if (!sock) lua_error(L, "invalid socket object"); | 1786 | if (!sock) lua_error(L, "invalid socket object"); |
| 1892 | if (tag) *tag = lua_tag(L, -1); | 1787 | if (tag) *tag = lua_tag(L, -1); |
| @@ -1894,33 +1789,10 @@ static p_sock get_selfsock(lua_State *L, p_tags tags, int *tag) | |||
| 1894 | return sock; | 1789 | return sock; |
| 1895 | } | 1790 | } |
| 1896 | 1791 | ||
| 1897 | #ifndef LUASOCKET_NOGLOBALS | 1792 | static p_sock get_selfsock(lua_State *L, p_tags tags, int *tag) |
| 1898 | static p_sock get_selfudpsock(lua_State *L, p_tags tags) | ||
| 1899 | { | ||
| 1900 | p_sock sock; | ||
| 1901 | if (lua_tag(L, 1) != tags->table) lua_error(L, "invalid socket object"); | ||
| 1902 | lua_pushstring(L, P_SOCK); | ||
| 1903 | lua_gettable(L, 1); | ||
| 1904 | sock = lua_touserdata(L, -1); | ||
| 1905 | if (!sock || lua_tag(L, -1) != tags->udp) | ||
| 1906 | lua_error(L, "udp socket expected"); | ||
| 1907 | lua_pop(L, 1); | ||
| 1908 | return sock; | ||
| 1909 | } | ||
| 1910 | |||
| 1911 | static p_sock get_selfserversock(lua_State *L, p_tags tags) | ||
| 1912 | { | 1793 | { |
| 1913 | p_sock sock; | 1794 | return get_sock(L, 1, tags, tag); |
| 1914 | if (lua_tag(L, 1) != tags->table) lua_error(L, "invalid socket object"); | ||
| 1915 | lua_pushstring(L, P_SOCK); | ||
| 1916 | lua_gettable(L, 1); | ||
| 1917 | sock = lua_touserdata(L, -1); | ||
| 1918 | if (!sock || lua_tag(L, -1) != tags->server) | ||
| 1919 | lua_error(L, "server socket expected"); | ||
| 1920 | lua_pop(L, 1); | ||
| 1921 | return sock; | ||
| 1922 | } | 1795 | } |
| 1923 | #endif | ||
| 1924 | 1796 | ||
| 1925 | /*=========================================================================*\ | 1797 | /*=========================================================================*\ |
| 1926 | * WinSock2 specific functions. | 1798 | * WinSock2 specific functions. |
