diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/luasocket.c | 366 |
1 files changed, 222 insertions, 144 deletions
diff --git a/src/luasocket.c b/src/luasocket.c index c4f51bd..1f9780d 100644 --- a/src/luasocket.c +++ b/src/luasocket.c | |||
| @@ -9,9 +9,9 @@ | |||
| 9 | * of the IPv4 Socket layer available to Lua scripts. | 9 | * of the IPv4 Socket layer available to Lua scripts. |
| 10 | * The Lua interface to TCP/IP follows the BSD TCP/IP API closely, | 10 | * The Lua interface to TCP/IP follows the BSD TCP/IP API closely, |
| 11 | * trying to simplify all tasks involved in setting up a client connection | 11 | * trying to simplify all tasks involved in setting up a client connection |
| 12 | * and simple server connections. | 12 | * and server connections. |
| 13 | * The provided IO routines, send and receive, follow the Lua style, being | 13 | * The provided IO routines, send and receive, follow the Lua style, being |
| 14 | * very similar to the read and write functions found in that language. | 14 | * very similar to the standard Lua read and write functions. |
| 15 | * The module implements both a BSD bind and a Winsock2 bind, and has | 15 | * The module implements both a BSD bind and a Winsock2 bind, and has |
| 16 | * been tested on several Unix flavors, as well as Windows 98 and NT. | 16 | * been tested on several Unix flavors, as well as Windows 98 and NT. |
| 17 | \*=========================================================================*/ | 17 | \*=========================================================================*/ |
| @@ -19,16 +19,13 @@ | |||
| 19 | /*=========================================================================*\ | 19 | /*=========================================================================*\ |
| 20 | * Common include files | 20 | * Common include files |
| 21 | \*=========================================================================*/ | 21 | \*=========================================================================*/ |
| 22 | #include <assert.h> | ||
| 23 | #include <errno.h> | 22 | #include <errno.h> |
| 24 | #include <signal.h> | 23 | #include <signal.h> |
| 25 | #include <stdio.h> | ||
| 26 | #include <stdlib.h> | 24 | #include <stdlib.h> |
| 27 | #include <string.h> | 25 | #include <ctype.h> |
| 28 | 26 | ||
| 29 | #include <lauxlib.h> | 27 | #include <lauxlib.h> |
| 30 | #include <lua.h> | 28 | #include <lua.h> |
| 31 | #include <lualib.h> | ||
| 32 | 29 | ||
| 33 | #include "luasocket.h" | 30 | #include "luasocket.h" |
| 34 | 31 | ||
| @@ -161,6 +158,10 @@ static int global_toip(lua_State *L); | |||
| 161 | static int global_tohostname(lua_State *L); | 158 | static int global_tohostname(lua_State *L); |
| 162 | static int global_udpsocket(lua_State *L); | 159 | static int global_udpsocket(lua_State *L); |
| 163 | 160 | ||
| 161 | #ifndef LUASOCKET_NOGLOBALS | ||
| 162 | static int global_calltable(lua_State *L); | ||
| 163 | #endif | ||
| 164 | |||
| 164 | /* luasocket table method API functions */ | 165 | /* luasocket table method API functions */ |
| 165 | static int table_tcpaccept(lua_State *L); | 166 | static int table_tcpaccept(lua_State *L); |
| 166 | static int table_tcpsend(lua_State *L); | 167 | static int table_tcpsend(lua_State *L); |
| @@ -187,6 +188,7 @@ static void tm_markstart(p_sock sock); | |||
| 187 | /* I/O */ | 188 | /* I/O */ |
| 188 | static int send_raw(p_sock sock, const char *data, int wanted, int *err); | 189 | static int send_raw(p_sock sock, const char *data, int wanted, int *err); |
| 189 | static int receive_raw(lua_State *L, p_sock sock, int wanted); | 190 | static int receive_raw(lua_State *L, p_sock sock, int wanted); |
| 191 | static int receive_word(lua_State *L, p_sock sock); | ||
| 190 | static int receive_dosline(lua_State *L, p_sock sock); | 192 | static int receive_dosline(lua_State *L, p_sock sock); |
| 191 | static int receive_unixline(lua_State *L, p_sock sock); | 193 | static int receive_unixline(lua_State *L, p_sock sock); |
| 192 | static int receive_all(lua_State *L, p_sock sock); | 194 | static int receive_all(lua_State *L, p_sock sock); |
| @@ -537,6 +539,21 @@ static int table_udpsendto(lua_State *L) | |||
| 537 | } | 539 | } |
| 538 | 540 | ||
| 539 | /*-------------------------------------------------------------------------*\ | 541 | /*-------------------------------------------------------------------------*\ |
| 542 | * Global function that calls corresponding table method. | ||
| 543 | \*-------------------------------------------------------------------------*/ | ||
| 544 | #ifndef LUASOCKET_NOGLOBALS | ||
| 545 | int global_calltable(lua_State *L) | ||
| 546 | { | ||
| 547 | p_tags tags = pop_tags(L); | ||
| 548 | if (lua_tag(L, 1) != tags->table) lua_error(L, "invalid socket object"); | ||
| 549 | lua_gettable(L, 1); | ||
| 550 | lua_insert(L, 1); | ||
| 551 | lua_call(L, lua_gettop(L)-1, LUA_MULTRET); | ||
| 552 | return lua_gettop(L); | ||
| 553 | } | ||
| 554 | #endif | ||
| 555 | |||
| 556 | /*-------------------------------------------------------------------------*\ | ||
| 540 | * Waits for a set of sockets until a condition is met or timeout. | 557 | * Waits for a set of sockets until a condition is met or timeout. |
| 541 | * Lua Input: {input}, {output} [, timeout] | 558 | * Lua Input: {input}, {output} [, timeout] |
| 542 | * {input}: table of sockets to be tested for input | 559 | * {input}: table of sockets to be tested for input |
| @@ -549,103 +566,105 @@ static int table_udpsendto(lua_State *L) | |||
| 549 | \*-------------------------------------------------------------------------*/ | 566 | \*-------------------------------------------------------------------------*/ |
| 550 | int global_select(lua_State *L) | 567 | int global_select(lua_State *L) |
| 551 | { | 568 | { |
| 552 | p_tags tags = pop_tags(L); | 569 | p_tags tags = pop_tags(L); |
| 553 | int ms = lua_isnil(L, 3) ? -1 : (int) (luaL_opt_number(L, 3, -1) * 1000); | 570 | int ms = lua_isnil(L, 3) ? -1 : (int) (luaL_opt_number(L, 3, -1) * 1000); |
| 554 | fd_set readfds, *prfds = NULL, writefds, *pwfds = NULL; | 571 | fd_set readfds, *prfds = NULL, writefds, *pwfds = NULL; |
| 555 | struct timeval tm, *ptm = NULL; | 572 | struct timeval tm, *ptm = NULL; |
| 556 | int ret, s, max = -1; | 573 | int ret; |
| 557 | int byfds, canread, canwrite; | 574 | unsigned max = 0; |
| 558 | /* reset the file descriptor sets */ | 575 | SOCKET s; |
| 576 | int byfds, canread, canwrite; | ||
| 577 | /* reset the file descriptor sets */ | ||
| 559 | FD_ZERO(&readfds); FD_ZERO(&writefds); | 578 | FD_ZERO(&readfds); FD_ZERO(&writefds); |
| 560 | /* all sockets, indexed by socket number, for internal use */ | 579 | /* all sockets, indexed by socket number, for internal use */ |
| 561 | lua_newtable(L); byfds = lua_gettop(L); | 580 | lua_newtable(L); byfds = lua_gettop(L); |
| 562 | /* readable sockets table to be returned */ | 581 | /* readable sockets table to be returned */ |
| 563 | lua_newtable(L); canread = lua_gettop(L); | 582 | lua_newtable(L); canread = lua_gettop(L); |
| 564 | /* writable sockets table to be returned */ | 583 | /* writable sockets table to be returned */ |
| 565 | lua_newtable(L); canwrite = lua_gettop(L); | 584 | lua_newtable(L); canwrite = lua_gettop(L); |
| 566 | /* get sockets we will test for readability into fd_set */ | 585 | /* get sockets we will test for readability into fd_set */ |
| 567 | if (!lua_isnil(L, 1)) { | 586 | if (!lua_isnil(L, 1)) { |
| 568 | lua_pushnil(L); | 587 | lua_pushnil(L); |
| 569 | while (lua_next(L, 1)) { | 588 | while (lua_next(L, 1)) { |
| 570 | if (lua_tag(L, -1) == tags->table) { | 589 | if (lua_tag(L, -1) == tags->table) { |
| 571 | p_sock sock = get_sock(L, -1, tags, NULL); | 590 | p_sock sock = get_sock(L, -1, tags, NULL); |
| 572 | lua_pushnumber(L, sock->sock); | 591 | lua_pushnumber(L, sock->sock); |
| 573 | lua_pushvalue(L, -2); | 592 | lua_pushvalue(L, -2); |
| 574 | lua_settable(L, byfds); | 593 | lua_settable(L, byfds); |
| 575 | if (sock->sock > max) max = sock->sock; | 594 | if (sock->sock > max) max = sock->sock; |
| 576 | /* a socket can have unread data in our internal buffer. in | 595 | /* a socket can have unread data in our internal buffer. in |
| 577 | * that case, we only call select to find out which of the | 596 | * that case, we only call select to find out which of the |
| 578 | * other sockets can be written to or read from immediately. */ | 597 | * other sockets can be written to or read from immediately. */ |
| 579 | if (!bf_isempty(sock)) { | 598 | if (!bf_isempty(sock)) { |
| 580 | ms = 0; | 599 | ms = 0; |
| 581 | lua_pushnumber(L, lua_getn(L, canread) + 1); | 600 | lua_pushnumber(L, lua_getn(L, canread) + 1); |
| 582 | lua_pushvalue(L, -2); | 601 | lua_pushvalue(L, -2); |
| 583 | lua_settable(L, canread); | 602 | lua_settable(L, canread); |
| 584 | } else { | 603 | } else { |
| 585 | FD_SET(sock->sock, &readfds); | 604 | FD_SET(sock->sock, &readfds); |
| 586 | prfds = &readfds; | 605 | prfds = &readfds; |
| 587 | } | 606 | } |
| 588 | } | 607 | } |
| 589 | /* get rid of lua_next value and expose index */ | 608 | /* get rid of lua_next value and expose index */ |
| 590 | lua_pop(L, 1); | 609 | lua_pop(L, 1); |
| 591 | } | 610 | } |
| 592 | } | 611 | } |
| 593 | /* get sockets we will test for writability into fd_set */ | 612 | /* get sockets we will test for writability into fd_set */ |
| 594 | if (!lua_isnil(L, 2)) { | 613 | if (!lua_isnil(L, 2)) { |
| 595 | lua_pushnil(L); | 614 | lua_pushnil(L); |
| 596 | while (lua_next(L, 2)) { | 615 | while (lua_next(L, 2)) { |
| 597 | if (lua_tag(L, -1) == tags->table) { | 616 | if (lua_tag(L, -1) == tags->table) { |
| 598 | p_sock sock = get_sock(L, -1, tags, NULL); | 617 | p_sock sock = get_sock(L, -1, tags, NULL); |
| 599 | lua_pushnumber(L, sock->sock); | 618 | lua_pushnumber(L, sock->sock); |
| 600 | lua_pushvalue(L, -2); | 619 | lua_pushvalue(L, -2); |
| 601 | lua_settable(L, byfds); | 620 | lua_settable(L, byfds); |
| 602 | if (sock->sock > max) max = sock->sock; | 621 | if (sock->sock > max) max = sock->sock; |
| 603 | FD_SET(sock->sock, &writefds); | 622 | FD_SET(sock->sock, &writefds); |
| 604 | pwfds = &writefds; | 623 | pwfds = &writefds; |
| 605 | } | 624 | } |
| 606 | /* get rid of lua_next value and expose index */ | 625 | /* get rid of lua_next value and expose index */ |
| 607 | lua_pop(L, 1); | 626 | lua_pop(L, 1); |
| 608 | } | 627 | } |
| 609 | } | 628 | } |
| 610 | max++; | 629 | max++; |
| 611 | /* configure timeout value */ | 630 | /* configure timeout value */ |
| 612 | if (ms >= 0) { | 631 | if (ms >= 0) { |
| 613 | ptm = &tm; /* ptm == NULL when we don't have timeout */ | 632 | ptm = &tm; /* ptm == NULL when we don't have timeout */ |
| 614 | /* fill timeval structure */ | 633 | /* fill timeval structure */ |
| 615 | tm.tv_sec = ms / 1000; | 634 | tm.tv_sec = ms / 1000; |
| 616 | tm.tv_usec = (ms % 1000) * 1000; | 635 | tm.tv_usec = (ms % 1000) * 1000; |
| 617 | } | 636 | } |
| 618 | /* see if we can read, write or if we timedout */ | 637 | /* see if we can read, write or if we timedout */ |
| 619 | ret = select(max, prfds, pwfds, NULL, ptm); | 638 | ret = select(max, prfds, pwfds, NULL, ptm); |
| 620 | /* did we timeout? */ | 639 | /* did we timeout? */ |
| 621 | if (ret <= 0 && ms > 0) { | 640 | if (ret <= 0 && ms > 0) { |
| 622 | push_error(L, NET_TIMEOUT); | 641 | push_error(L, NET_TIMEOUT); |
| 623 | return 3; | 642 | return 3; |
| 624 | } | 643 | } |
| 625 | /* collect readable sockets */ | 644 | /* collect readable sockets */ |
| 626 | if (prfds) { | 645 | if (prfds) { |
| 627 | for (s = 0; s < max; s++) { | 646 | for (s = 0; s < max; s++) { |
| 628 | if (FD_ISSET(s, prfds)) { | 647 | if (FD_ISSET(s, prfds)) { |
| 629 | lua_pushnumber(L, lua_getn(L, canread) + 1); | 648 | lua_pushnumber(L, lua_getn(L, canread) + 1); |
| 630 | lua_pushnumber(L, s); | 649 | lua_pushnumber(L, s); |
| 631 | lua_gettable(L, byfds); | 650 | lua_gettable(L, byfds); |
| 632 | lua_settable(L, canread); | 651 | lua_settable(L, canread); |
| 633 | } | 652 | } |
| 634 | } | 653 | } |
| 635 | } | 654 | } |
| 636 | /* collect writable sockets */ | 655 | /* collect writable sockets */ |
| 637 | if (pwfds) { | 656 | if (pwfds) { |
| 638 | for (s = 0; s < max; s++) { | 657 | for (s = 0; s < max; s++) { |
| 639 | if (FD_ISSET(s, pwfds)) { | 658 | if (FD_ISSET(s, pwfds)) { |
| 640 | lua_pushnumber(L, lua_getn(L, canwrite) + 1); | 659 | lua_pushnumber(L, lua_getn(L, canwrite) + 1); |
| 641 | lua_pushnumber(L, s); | 660 | lua_pushnumber(L, s); |
| 642 | lua_gettable(L, byfds); | 661 | lua_gettable(L, byfds); |
| 643 | lua_settable(L, canwrite); | 662 | lua_settable(L, canwrite); |
| 644 | } | 663 | } |
| 645 | } | 664 | } |
| 646 | } | 665 | } |
| 647 | lua_pushnil(L); | 666 | lua_pushnil(L); |
| 648 | return 3; | 667 | return 3; |
| 649 | } | 668 | } |
| 650 | 669 | ||
| 651 | /*-------------------------------------------------------------------------*\ | 670 | /*-------------------------------------------------------------------------*\ |
| @@ -821,7 +840,7 @@ static int table_udpreceive(lua_State *L) | |||
| 821 | \*-------------------------------------------------------------------------*/ | 840 | \*-------------------------------------------------------------------------*/ |
| 822 | static int table_tcpreceive(lua_State *L) | 841 | static int table_tcpreceive(lua_State *L) |
| 823 | { | 842 | { |
| 824 | static const char *const modenames[] = {"*l", "*lu", "*a", NULL}; | 843 | static const char *const modenames[] = {"*l", "*lu", "*a", "*w", NULL}; |
| 825 | const char *mode; | 844 | const char *mode; |
| 826 | int err = NET_DONE; | 845 | int err = NET_DONE; |
| 827 | int arg; | 846 | int arg; |
| @@ -850,17 +869,13 @@ static int table_tcpreceive(lua_State *L) | |||
| 850 | /* get next pattern */ | 869 | /* get next pattern */ |
| 851 | switch (luaL_findstring(mode, modenames)) { | 870 | switch (luaL_findstring(mode, modenames)) { |
| 852 | /* DOS line mode */ | 871 | /* DOS line mode */ |
| 853 | case 0: | 872 | case 0: err = receive_dosline(L, sock); break; |
| 854 | err = receive_dosline(L, sock); | ||
| 855 | break; | ||
| 856 | /* Unix line mode */ | 873 | /* Unix line mode */ |
| 857 | case 1: | 874 | case 1: err = receive_unixline(L, sock); break; |
| 858 | err = receive_unixline(L, sock); | ||
| 859 | break; | ||
| 860 | /* until closed mode */ | 875 | /* until closed mode */ |
| 861 | case 2: | 876 | case 2: err = receive_all(L, sock); break; |
| 862 | err = receive_all(L, sock); | 877 | /* word */ |
| 863 | break; | 878 | case 3: err = receive_word(L, sock); break; |
| 864 | /* else it is an error */ | 879 | /* else it is an error */ |
| 865 | default: | 880 | default: |
| 866 | luaL_arg_check(L, 0, arg, "invalid receive pattern"); | 881 | luaL_arg_check(L, 0, arg, "invalid receive pattern"); |
| @@ -1431,7 +1446,7 @@ static int receive_all(lua_State *L, p_sock sock) | |||
| 1431 | \*-------------------------------------------------------------------------*/ | 1446 | \*-------------------------------------------------------------------------*/ |
| 1432 | static int receive_dosline(lua_State *L, p_sock sock) | 1447 | static int receive_dosline(lua_State *L, p_sock sock) |
| 1433 | { | 1448 | { |
| 1434 | int got = 0; | 1449 | int got, pos; |
| 1435 | const unsigned char *buffer = NULL; | 1450 | const unsigned char *buffer = NULL; |
| 1436 | luaL_Buffer b; | 1451 | luaL_Buffer b; |
| 1437 | luaL_buffinit(L, &b); | 1452 | luaL_buffinit(L, &b); |
| @@ -1441,26 +1456,21 @@ static int receive_dosline(lua_State *L, p_sock sock) | |||
| 1441 | return NET_TIMEOUT; | 1456 | return NET_TIMEOUT; |
| 1442 | } | 1457 | } |
| 1443 | buffer = bf_receive(sock, &got); | 1458 | buffer = bf_receive(sock, &got); |
| 1444 | if (got > 0) { | 1459 | if (got <= 0) { |
| 1445 | int len = 0, end = 1; | 1460 | luaL_pushresult(&b); |
| 1446 | while (len < got) { | ||
| 1447 | if (buffer[len] == '\n') { /* found eol */ | ||
| 1448 | if (len > 0 && buffer[len-1] == '\r') { | ||
| 1449 | end++; len--; | ||
| 1450 | } | ||
| 1451 | luaL_addlstring(&b, buffer, len); | ||
| 1452 | bf_skip(sock, len + end); /* skip '\r\n' in stream */ | ||
| 1453 | luaL_pushresult(&b); | ||
| 1454 | return NET_DONE; | ||
| 1455 | } | ||
| 1456 | len++; | ||
| 1457 | } | ||
| 1458 | luaL_addlstring(&b, buffer, got); | ||
| 1459 | bf_skip(sock, got); | ||
| 1460 | } else { | ||
| 1461 | luaL_pushresult(&b); | ||
| 1462 | return NET_CLOSED; | 1461 | return NET_CLOSED; |
| 1463 | } | 1462 | } |
| 1463 | pos = 0; | ||
| 1464 | while (pos < got && buffer[pos] != '\n') { | ||
| 1465 | /* we ignore all \r's */ | ||
| 1466 | if (buffer[pos] != '\r') luaL_putchar(&b, buffer[pos]); | ||
| 1467 | pos++; | ||
| 1468 | } | ||
| 1469 | if (pos < got) { | ||
| 1470 | luaL_pushresult(&b); | ||
| 1471 | bf_skip(sock, pos+1); /* skip '\n' too */ | ||
| 1472 | return NET_DONE; | ||
| 1473 | } else bf_skip(sock, pos); | ||
| 1464 | } | 1474 | } |
| 1465 | } | 1475 | } |
| 1466 | 1476 | ||
| @@ -1475,7 +1485,7 @@ static int receive_dosline(lua_State *L, p_sock sock) | |||
| 1475 | \*-------------------------------------------------------------------------*/ | 1485 | \*-------------------------------------------------------------------------*/ |
| 1476 | static int receive_unixline(lua_State *L, p_sock sock) | 1486 | static int receive_unixline(lua_State *L, p_sock sock) |
| 1477 | { | 1487 | { |
| 1478 | int got = 0; | 1488 | int got, pos; |
| 1479 | const unsigned char *buffer = NULL; | 1489 | const unsigned char *buffer = NULL; |
| 1480 | luaL_Buffer b; | 1490 | luaL_Buffer b; |
| 1481 | luaL_buffinit(L, &b); | 1491 | luaL_buffinit(L, &b); |
| @@ -1485,23 +1495,75 @@ static int receive_unixline(lua_State *L, p_sock sock) | |||
| 1485 | return NET_TIMEOUT; | 1495 | return NET_TIMEOUT; |
| 1486 | } | 1496 | } |
| 1487 | buffer = bf_receive(sock, &got); | 1497 | buffer = bf_receive(sock, &got); |
| 1488 | if (got > 0) { | 1498 | if (got <= 0) { |
| 1489 | int len = 0; | 1499 | luaL_pushresult(&b); |
| 1490 | while (len < got) { | 1500 | return NET_CLOSED; |
| 1491 | if (buffer[len] == '\n') { /* found eol */ | 1501 | } |
| 1492 | luaL_addlstring(&b, buffer, len); | 1502 | pos = 0; |
| 1493 | bf_skip(sock, len + 1); /* skip '\n' in stream */ | 1503 | while (pos < got && buffer[pos] != '\n') pos++; |
| 1494 | luaL_pushresult(&b); | 1504 | luaL_addlstring(&b, buffer, pos); |
| 1495 | return NET_DONE; | 1505 | if (pos < got) { |
| 1496 | } | 1506 | luaL_pushresult(&b); |
| 1497 | len++; | 1507 | bf_skip(sock, pos+1); /* skip '\n' too */ |
| 1498 | } | 1508 | return NET_DONE; |
| 1499 | luaL_addlstring(&b, buffer, got); | 1509 | } else bf_skip(sock, pos); |
| 1500 | bf_skip(sock, got); | 1510 | } |
| 1501 | } else { | 1511 | } |
| 1512 | |||
| 1513 | /*-------------------------------------------------------------------------*\ | ||
| 1514 | * Reads a word (maximal sequence of non--white-space characters), skipping | ||
| 1515 | * white-spaces if needed. | ||
| 1516 | * Input | ||
| 1517 | * sock: socket structure being used in operation | ||
| 1518 | * Result | ||
| 1519 | * operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED | ||
| 1520 | \*-------------------------------------------------------------------------*/ | ||
| 1521 | static int receive_word(lua_State *L, p_sock sock) | ||
| 1522 | { | ||
| 1523 | int pos, got; | ||
| 1524 | const unsigned char *buffer = NULL; | ||
| 1525 | luaL_Buffer b; | ||
| 1526 | luaL_buffinit(L, &b); | ||
| 1527 | /* skip leading white-spaces */ | ||
| 1528 | for ( ;; ) { | ||
| 1529 | if (bf_isempty(sock) && tm_timedout(sock, TM_RECEIVE)) { | ||
| 1530 | lua_pushstring(L, ""); | ||
| 1531 | return NET_TIMEOUT; | ||
| 1532 | } | ||
| 1533 | buffer = bf_receive(sock, &got); | ||
| 1534 | if (got <= 0) { | ||
| 1535 | lua_pushstring(L, ""); | ||
| 1536 | return NET_CLOSED; | ||
| 1537 | } | ||
| 1538 | pos = 0; | ||
| 1539 | while (pos < got && isspace(buffer[pos])) pos++; | ||
| 1540 | bf_skip(sock, pos); | ||
| 1541 | if (pos < got) { | ||
| 1542 | buffer += pos; | ||
| 1543 | got -= pos; | ||
| 1544 | pos = 0; | ||
| 1545 | break; | ||
| 1546 | } | ||
| 1547 | } | ||
| 1548 | /* capture word */ | ||
| 1549 | for ( ;; ) { | ||
| 1550 | while (pos < got && !isspace(buffer[pos])) pos++; | ||
| 1551 | luaL_addlstring(&b, buffer, pos); | ||
| 1552 | bf_skip(sock, pos); | ||
| 1553 | if (pos < got) { | ||
| 1554 | luaL_pushresult(&b); | ||
| 1555 | return NET_DONE; | ||
| 1556 | } | ||
| 1557 | if (bf_isempty(sock) && tm_timedout(sock, TM_RECEIVE)) { | ||
| 1558 | luaL_pushresult(&b); | ||
| 1559 | return NET_TIMEOUT; | ||
| 1560 | } | ||
| 1561 | buffer = bf_receive(sock, &got); | ||
| 1562 | if (got <= 0) { | ||
| 1502 | luaL_pushresult(&b); | 1563 | luaL_pushresult(&b); |
| 1503 | return NET_CLOSED; | 1564 | return NET_CLOSED; |
| 1504 | } | 1565 | } |
| 1566 | pos = 0; | ||
| 1505 | } | 1567 | } |
| 1506 | } | 1568 | } |
| 1507 | 1569 | ||
| @@ -1514,7 +1576,7 @@ static int receive_unixline(lua_State *L, p_sock sock) | |||
| 1514 | \*-------------------------------------------------------------------------*/ | 1576 | \*-------------------------------------------------------------------------*/ |
| 1515 | void lua_socketlibopen(lua_State *L) | 1577 | void lua_socketlibopen(lua_State *L) |
| 1516 | { | 1578 | { |
| 1517 | static struct luaL_reg funcs[] = { | 1579 | struct luaL_reg funcs[] = { |
| 1518 | {"bind", global_tcpbind}, | 1580 | {"bind", global_tcpbind}, |
| 1519 | {"connect", global_tcpconnect}, | 1581 | {"connect", global_tcpconnect}, |
| 1520 | {"select", global_select}, | 1582 | {"select", global_select}, |
| @@ -1552,6 +1614,22 @@ void lua_socketlibopen(lua_State *L) | |||
| 1552 | lua_pushcfunction(L, global_sleep); lua_setglobal(L, "sleep"); | 1614 | lua_pushcfunction(L, global_sleep); lua_setglobal(L, "sleep"); |
| 1553 | lua_pushcfunction(L, global_time); lua_setglobal(L, "time"); | 1615 | lua_pushcfunction(L, global_time); lua_setglobal(L, "time"); |
| 1554 | #endif | 1616 | #endif |
| 1617 | #ifndef LUASOCKET_NOGLOBALS | ||
| 1618 | { | ||
| 1619 | char *global[] = { | ||
| 1620 | "accept", "close", "getpeername", | ||
| 1621 | "getsockname", "receive", "send", | ||
| 1622 | "receivefrom", "sendto" | ||
| 1623 | }; | ||
| 1624 | unsigned int i; | ||
| 1625 | for (i = 0; i < sizeof(global)/sizeof(char *); i++) { | ||
| 1626 | lua_pushstring(L, global[i]); | ||
| 1627 | lua_pushuserdata(L, tags); | ||
| 1628 | lua_pushcclosure(L, global_calltable, 2); | ||
| 1629 | lua_setglobal(L, global[i]); | ||
| 1630 | } | ||
| 1631 | } | ||
| 1632 | #endif | ||
| 1555 | } | 1633 | } |
| 1556 | 1634 | ||
| 1557 | /*=========================================================================*\ | 1635 | /*=========================================================================*\ |
| @@ -1583,7 +1661,7 @@ static p_sock push_clienttable(lua_State *L, p_tags tags) | |||
| 1583 | if (!sock) return NULL; | 1661 | if (!sock) return NULL; |
| 1584 | lua_settag(L, tags->client); | 1662 | lua_settag(L, tags->client); |
| 1585 | lua_settable(L, -3); | 1663 | lua_settable(L, -3); |
| 1586 | sock->sock = -1; | 1664 | sock->sock = INVALID_SOCKET; |
| 1587 | sock->is_connected = 0; | 1665 | sock->is_connected = 0; |
| 1588 | sock->tm_block = -1; | 1666 | sock->tm_block = -1; |
| 1589 | sock->tm_return = -1; | 1667 | sock->tm_return = -1; |
