aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2001-03-06 19:03:10 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2001-03-06 19:03:10 +0000
commit27371883efefbafe485edd62f771e12beff903d1 (patch)
tree4409f3a221671841011a3ed50b6544fe39de630b /src
parent297576affae2113dce05970591adab3e75be65c0 (diff)
downloadluasocket-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.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.