aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/luasocket.c530
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 */
161static int global_tcpconnect(lua_State *L); 157static int global_tcpconnect(lua_State *L);
162static int global_tcpbind(lua_State *L); 158static int global_tcpbind(lua_State *L);
163static int global_udpsocket(lua_State *L); 159static int global_select(lua_State *L);
164static int global_toip(lua_State *L); 160static int global_toip(lua_State *L);
165static int global_tohostname(lua_State *L); 161static int global_tohostname(lua_State *L);
162static int global_udpsocket(lua_State *L);
166 163
167/* luasocket table method API functions */ 164/* luasocket table method API functions */
168static int table_tcpaccept(lua_State *L); 165static int table_tcpaccept(lua_State *L);
@@ -173,26 +170,9 @@ static int table_udpreceivefrom(lua_State *L);
173static int table_udpsetpeername(lua_State *L); 170static int table_udpsetpeername(lua_State *L);
174static int table_timeout(lua_State *L); 171static int table_timeout(lua_State *L);
175static int table_close(lua_State *L); 172static int table_close(lua_State *L);
176static int table_poll(lua_State *L);
177static int table_getpeername(lua_State *L); 173static int table_getpeername(lua_State *L);
178static int table_getsockname(lua_State *L); 174static int table_getsockname(lua_State *L);
179 175
180/* luasocket optional global API functions */
181#ifndef LUASOCKET_NOGLOBALS
182static int global_tcpaccept(lua_State *L);
183static int global_udpsendto(lua_State *L);
184static int global_udpreceivefrom(lua_State *L);
185static int global_udpsetpeername(lua_State *L);
186static int global_udpsetsockname(lua_State *L);
187static int global_getsockname(lua_State *L);
188static int global_getpeername(lua_State *L);
189static int global_send(lua_State *L);
190static int global_receive(lua_State *L);
191static int global_timeout(lua_State *L);
192static int global_close(lua_State *L);
193static int global_poll(lua_State *L);
194#endif
195
196/* buffered I/O management */ 176/* buffered I/O management */
197static const unsigned char *bf_receive(p_sock sock, int *length); 177static const unsigned char *bf_receive(p_sock sock, int *length);
198static void bf_skip(p_sock sock, int length); 178static 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 */
215static p_tags pop_tags(lua_State *L); 195static p_tags pop_tags(lua_State *L);
216static p_sock pop_sock(lua_State *L); 196static p_sock pop_sock(lua_State *L);
197static p_sock get_sock(lua_State *L, int s, p_tags tags, int *tag);
217static p_sock get_selfsock(lua_State *L, p_tags tags, int *tag); 198static p_sock get_selfsock(lua_State *L, p_tags tags, int *tag);
218static p_sock push_servertable(lua_State *L, p_tags tags); 199static p_sock push_servertable(lua_State *L, p_tags tags);
219static p_sock push_clienttable(lua_State *L, p_tags tags); 200static p_sock push_clienttable(lua_State *L, p_tags tags);
@@ -249,11 +230,6 @@ static int winsock_open(void);
249static int inet_aton(const char *cp, struct in_addr *inp); 230static int inet_aton(const char *cp, struct in_addr *inp);
250#endif 231#endif
251 232
252#ifndef LUASOCKET_NOGLOBALS
253static p_sock get_selfserversock(lua_State *L, p_tags tags);
254static p_sock get_selfudpsock(lua_State *L, p_tags tags);
255#endif
256
257/* tag methods */ 233/* tag methods */
258static int gc_table(lua_State *L); 234static 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\*-------------------------------------------------------------------------*/
550int 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)
657static int table_udpreceivefrom(lua_State *L) 745static 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)
695static int table_udpreceive(lua_State *L) 783static 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)
841static int table_close(lua_State *L) 929static 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\*-------------------------------------------------------------------------*/
859static 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)
1253static const unsigned char *bf_receive(p_sock sock, int *length) 1302static 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)
1466void lua_socketlibopen(lua_State *L) 1515void 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
1536int 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
1545int 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
1553int 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
1561int 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
1569int 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
1577int 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
1586int 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
1605int 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
1624int 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
1633int 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
1643int 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
1652int 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\*-------------------------------------------------------------------------*/
1805static void push_resolved(lua_State *L, struct hostent *hp) 1700static 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
1884static p_sock get_selfsock(lua_State *L, p_tags tags, int *tag) 1779static 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 1792static p_sock get_selfsock(lua_State *L, p_tags tags, int *tag)
1898static 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
1911static 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.