diff options
author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2001-03-06 19:03:10 +0000 |
---|---|---|
committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2001-03-06 19:03:10 +0000 |
commit | 27371883efefbafe485edd62f771e12beff903d1 (patch) | |
tree | 4409f3a221671841011a3ed50b6544fe39de630b /src | |
parent | 297576affae2113dce05970591adab3e75be65c0 (diff) | |
download | luasocket-27371883efefbafe485edd62f771e12beff903d1.tar.gz luasocket-27371883efefbafe485edd62f771e12beff903d1.tar.bz2 luasocket-27371883efefbafe485edd62f771e12beff903d1.zip |
Removed global version of table methods.
Close method is now permitted on closed sockets.
Added generalized select support.
Removed poll method, replaced by select with advantage.
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. |