diff options
| author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2001-09-26 20:31:59 +0000 |
|---|---|---|
| committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2001-09-26 20:31:59 +0000 |
| commit | 6f02d1444bdf351f1008eb09546802985da49fdb (patch) | |
| tree | 123099bd67d7c20afbfbc99326e590722ed9fb3b /src | |
| parent | 6eb7f22c4b23a1b8175222001435fa45d7b570b3 (diff) | |
| download | luasocket-6f02d1444bdf351f1008eb09546802985da49fdb.tar.gz luasocket-6f02d1444bdf351f1008eb09546802985da49fdb.tar.bz2 luasocket-6f02d1444bdf351f1008eb09546802985da49fdb.zip | |
Almost ready for Lua 4.1
Diffstat (limited to 'src')
| -rw-r--r-- | src/luasocket.c | 184 |
1 files changed, 87 insertions, 97 deletions
diff --git a/src/luasocket.c b/src/luasocket.c index bbf7ca7..5168fbd 100644 --- a/src/luasocket.c +++ b/src/luasocket.c | |||
| @@ -291,13 +291,7 @@ static int global_tcpconnect(lua_State *L) | |||
| 291 | const char *address = luaL_check_string(L, 1); | 291 | const char *address = luaL_check_string(L, 1); |
| 292 | unsigned short port = (unsigned short) luaL_check_number(L, 2); | 292 | unsigned short port = (unsigned short) luaL_check_number(L, 2); |
| 293 | p_sock sock = push_clienttable(L, tags); | 293 | p_sock sock = push_clienttable(L, tags); |
| 294 | const char *err; | 294 | const char *err = tcp_tryconnect(sock, address, port); |
| 295 | if (!sock) { | ||
| 296 | lua_pushnil(L); | ||
| 297 | lua_pushstring(L, "out of memory"); | ||
| 298 | return 2; | ||
| 299 | } | ||
| 300 | err = tcp_tryconnect(sock, address, port); | ||
| 301 | if (err) { | 295 | if (err) { |
| 302 | lua_pushnil(L); | 296 | lua_pushnil(L); |
| 303 | lua_pushstring(L, err); | 297 | lua_pushstring(L, err); |
| @@ -316,18 +310,18 @@ static int global_tcpconnect(lua_State *L) | |||
| 316 | static int global_udpsocket(lua_State *L) | 310 | static int global_udpsocket(lua_State *L) |
| 317 | { | 311 | { |
| 318 | p_tags tags = pop_tags(L); | 312 | p_tags tags = pop_tags(L); |
| 319 | int top = lua_gettop(L); | 313 | int top = lua_gettop(L); |
| 320 | p_sock sock = push_udptable(L, tags); | 314 | p_sock sock = push_udptable(L, tags); |
| 321 | if (!sock) return 2; | 315 | if (!sock) return 2; |
| 322 | if (top >= 1 ) { | 316 | if (top >= 1 ) { |
| 323 | if (lua_istable(L, 1)) { | 317 | if (lua_istable(L, 1)) { |
| 324 | lua_pushnil(L); | 318 | lua_pushnil(L); |
| 325 | while (lua_next(L, 1)) { | 319 | while (lua_next(L, 1)) { |
| 326 | if (!set_option(L, sock)) lua_error(L, "error setting option"); | 320 | if (!set_option(L, sock)) lua_error(L, "error setting option"); |
| 327 | lua_pop(L, 1); | 321 | lua_pop(L, 1); |
| 328 | } | 322 | } |
| 329 | } else luaL_argerror(L, 1, "invalid options"); | 323 | } else luaL_argerror(L, 1, "invalid options"); |
| 330 | } | 324 | } |
| 331 | return 1; | 325 | return 1; |
| 332 | } | 326 | } |
| 333 | 327 | ||
| @@ -1072,63 +1066,63 @@ void set_reuseaddr(p_sock sock) | |||
| 1072 | \*-------------------------------------------------------------------------*/ | 1066 | \*-------------------------------------------------------------------------*/ |
| 1073 | static int set_option(lua_State *L, p_sock sock) | 1067 | static int set_option(lua_State *L, p_sock sock) |
| 1074 | { | 1068 | { |
| 1075 | static const char *const optionnames[] = { | 1069 | static const char *const optionnames[] = { |
| 1076 | "SO_KEEPALIVE", "SO_DONTROUTE", "SO_BROADCAST", "SO_LINGER", NULL | 1070 | "SO_KEEPALIVE", "SO_DONTROUTE", "SO_BROADCAST", "SO_LINGER", NULL |
| 1077 | }; | 1071 | }; |
| 1078 | const char *option; | 1072 | const char *option; |
| 1079 | int err; | 1073 | int err; |
| 1080 | if (!lua_isstring(L, -2)) return 0; | 1074 | if (!lua_isstring(L, -2)) return 0; |
| 1081 | option = lua_tostring(L, -2); | 1075 | option = lua_tostring(L, -2); |
| 1082 | switch (luaL_findstring(option, optionnames)) { | 1076 | switch (luaL_findstring(option, optionnames)) { |
| 1083 | case 0: { | 1077 | case 0: { |
| 1084 | int bool; | 1078 | int bool; |
| 1085 | if (!lua_isnumber(L, -1)) | 1079 | if (!lua_isnumber(L, -1)) |
| 1086 | lua_error(L, "invalid SO_KEEPALIVE value"); | 1080 | lua_error(L, "invalid SO_KEEPALIVE value"); |
| 1087 | bool = (int) lua_tonumber(L, -1); | 1081 | bool = (int) lua_tonumber(L, -1); |
| 1088 | err = setsockopt(sock->sock, SOL_SOCKET, SO_KEEPALIVE, | 1082 | err = setsockopt(sock->sock, SOL_SOCKET, SO_KEEPALIVE, |
| 1089 | (char *) &bool, sizeof(bool)); | 1083 | (char *) &bool, sizeof(bool)); |
| 1090 | return err >= 0; | 1084 | return err >= 0; |
| 1091 | } | 1085 | } |
| 1092 | case 1: { | 1086 | case 1: { |
| 1093 | int bool; | 1087 | int bool; |
| 1094 | if (!lua_isnumber(L, -1)) | 1088 | if (!lua_isnumber(L, -1)) |
| 1095 | lua_error(L, "invalid SO_DONTROUTE value"); | 1089 | lua_error(L, "invalid SO_DONTROUTE value"); |
| 1096 | bool = (int) lua_tonumber(L, -1); | 1090 | bool = (int) lua_tonumber(L, -1); |
| 1097 | err = setsockopt(sock->sock, SOL_SOCKET, SO_DONTROUTE, | 1091 | err = setsockopt(sock->sock, SOL_SOCKET, SO_DONTROUTE, |
| 1098 | (char *) &bool, sizeof(bool)); | 1092 | (char *) &bool, sizeof(bool)); |
| 1099 | return err >= 0; | 1093 | return err >= 0; |
| 1100 | } | 1094 | } |
| 1101 | case 2: { | 1095 | case 2: { |
| 1102 | int bool; | 1096 | int bool; |
| 1103 | if (!lua_isnumber(L, -1)) | 1097 | if (!lua_isnumber(L, -1)) |
| 1104 | lua_error(L, "invalid SO_BROADCAST value"); | 1098 | lua_error(L, "invalid SO_BROADCAST value"); |
| 1105 | bool = (int) lua_tonumber(L, -1); | 1099 | bool = (int) lua_tonumber(L, -1); |
| 1106 | err = setsockopt(sock->sock, SOL_SOCKET, SO_BROADCAST, | 1100 | err = setsockopt(sock->sock, SOL_SOCKET, SO_BROADCAST, |
| 1107 | (char *) &bool, sizeof(bool)); | 1101 | (char *) &bool, sizeof(bool)); |
| 1108 | return err >= 0; | 1102 | return err >= 0; |
| 1109 | } | 1103 | } |
| 1110 | case 3: { | 1104 | case 3: { |
| 1111 | struct linger linger; | 1105 | struct linger linger; |
| 1112 | if (!lua_istable(L, -1)) | 1106 | if (!lua_istable(L, -1)) |
| 1113 | lua_error(L, "invalid SO_LINGER value"); | 1107 | lua_error(L, "invalid SO_LINGER value"); |
| 1114 | lua_pushstring(L, "l_onoff"); | 1108 | lua_pushstring(L, "l_onoff"); |
| 1115 | lua_gettable(L, -2); | 1109 | lua_gettable(L, -2); |
| 1116 | if (!lua_isnumber(L, -1)) | 1110 | if (!lua_isnumber(L, -1)) |
| 1117 | lua_error(L, "invalid SO_LINGER (l_onoff) value"); | 1111 | lua_error(L, "invalid SO_LINGER (l_onoff) value"); |
| 1118 | linger.l_onoff = (int) lua_tonumber(L, -1); | 1112 | linger.l_onoff = (int) lua_tonumber(L, -1); |
| 1119 | lua_pop(L, 1); | 1113 | lua_pop(L, 1); |
| 1120 | lua_pushstring(L, "l_linger"); | 1114 | lua_pushstring(L, "l_linger"); |
| 1121 | lua_gettable(L, -2); | 1115 | lua_gettable(L, -2); |
| 1122 | if (!lua_isnumber(L, -1)) | 1116 | if (!lua_isnumber(L, -1)) |
| 1123 | lua_error(L, "invalid SO_LINGER (l_linger) value"); | 1117 | lua_error(L, "invalid SO_LINGER (l_linger) value"); |
| 1124 | linger.l_linger = (int) lua_tonumber(L, -1); | 1118 | linger.l_linger = (int) lua_tonumber(L, -1); |
| 1125 | lua_pop(L, 1); | 1119 | lua_pop(L, 1); |
| 1126 | err = setsockopt(sock->sock, SOL_SOCKET, SO_LINGER, | 1120 | err = setsockopt(sock->sock, SOL_SOCKET, SO_LINGER, |
| 1127 | (char *) &linger, sizeof(linger)); | 1121 | (char *) &linger, sizeof(linger)); |
| 1128 | return err >= 0; | 1122 | return err >= 0; |
| 1129 | } | 1123 | } |
| 1130 | default: return 0; | 1124 | default: return 0; |
| 1131 | } | 1125 | } |
| 1132 | } | 1126 | } |
| 1133 | 1127 | ||
| 1134 | 1128 | ||
| @@ -1675,21 +1669,18 @@ LUASOCKET_API int lua_socketlibopen(lua_State *L) | |||
| 1675 | unsigned int i; | 1669 | unsigned int i; |
| 1676 | /* declare new Lua tags for used userdata values */ | 1670 | /* declare new Lua tags for used userdata values */ |
| 1677 | p_tags tags = (p_tags) lua_newuserdata(L, sizeof(t_tags)); | 1671 | p_tags tags = (p_tags) lua_newuserdata(L, sizeof(t_tags)); |
| 1678 | if (!tags) lua_error(L, "out of memory"); | ||
| 1679 | /* remove tags userdatum from stack but avoid garbage collection */ | ||
| 1680 | lua_ref(L, 1); | ||
| 1681 | tags->client = lua_newtag(L); | 1672 | tags->client = lua_newtag(L); |
| 1682 | tags->server = lua_newtag(L); | 1673 | tags->server = lua_newtag(L); |
| 1683 | tags->table = lua_newtag(L); | 1674 | tags->table = lua_newtag(L); |
| 1684 | tags->udp = lua_newtag(L); | 1675 | tags->udp = lua_newtag(L); |
| 1685 | /* global functions exported */ | 1676 | /* global functions exported */ |
| 1686 | for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) { | 1677 | for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) { |
| 1687 | lua_pushuserdata(L, tags); | 1678 | lua_pushvalue(L, -1); |
| 1688 | lua_pushcclosure(L, funcs[i].func, 1); | 1679 | lua_pushcclosure(L, funcs[i].func, 1); |
| 1689 | lua_setglobal(L, funcs[i].name); | 1680 | lua_setglobal(L, funcs[i].name); |
| 1690 | } | 1681 | } |
| 1691 | /* socket garbage collection */ | 1682 | /* socket garbage collection */ |
| 1692 | lua_pushuserdata(L, tags); | 1683 | lua_pushvalue(L, -1); |
| 1693 | lua_pushcclosure(L, gc_table, 1); | 1684 | lua_pushcclosure(L, gc_table, 1); |
| 1694 | lua_settagmethod(L, tags->table, "gc"); | 1685 | lua_settagmethod(L, tags->table, "gc"); |
| 1695 | #ifdef WIN32 | 1686 | #ifdef WIN32 |
| @@ -1714,13 +1705,15 @@ LUASOCKET_API int lua_socketlibopen(lua_State *L) | |||
| 1714 | unsigned int i; | 1705 | unsigned int i; |
| 1715 | for (i = 0; i < sizeof(global)/sizeof(char *); i++) { | 1706 | for (i = 0; i < sizeof(global)/sizeof(char *); i++) { |
| 1716 | lua_pushstring(L, global[i]); | 1707 | lua_pushstring(L, global[i]); |
| 1717 | lua_pushuserdata(L, tags); | 1708 | lua_pushvalue(L, -2); |
| 1718 | lua_pushcclosure(L, global_callfromtable, 2); | 1709 | lua_pushcclosure(L, global_callfromtable, 2); |
| 1719 | lua_setglobal(L, global[i]); | 1710 | lua_setglobal(L, global[i]); |
| 1720 | } | 1711 | } |
| 1721 | } | 1712 | } |
| 1722 | #endif | 1713 | #endif |
| 1723 | return 1; | 1714 | /* remove tags userdatum from stack */ |
| 1715 | lua_pop(L, 1); | ||
| 1716 | return 1; | ||
| 1724 | } | 1717 | } |
| 1725 | 1718 | ||
| 1726 | /*=========================================================================*\ | 1719 | /*=========================================================================*\ |
| @@ -1745,12 +1738,11 @@ static p_sock push_clienttable(lua_State *L, p_tags tags) | |||
| 1745 | {"timeout", table_timeout}, | 1738 | {"timeout", table_timeout}, |
| 1746 | }; | 1739 | }; |
| 1747 | unsigned int i; | 1740 | unsigned int i; |
| 1748 | p_sock sock; | 1741 | p_sock sock = (p_sock) lua_newuserdata(L, sizeof(t_sock)); |
| 1742 | lua_settag(L, tags->client); | ||
| 1749 | lua_newtable(L); lua_settag(L, tags->table); | 1743 | lua_newtable(L); lua_settag(L, tags->table); |
| 1750 | lua_pushstring(L, P_SOCK); | 1744 | lua_pushstring(L, P_SOCK); |
| 1751 | sock = (p_sock) lua_newuserdata(L, sizeof(t_sock)); | 1745 | lua_pushvalue(L, -3); |
| 1752 | if (!sock) return NULL; | ||
| 1753 | lua_settag(L, tags->client); | ||
| 1754 | lua_settable(L, -3); | 1746 | lua_settable(L, -3); |
| 1755 | sock->sock = INVALID_SOCKET; | 1747 | sock->sock = INVALID_SOCKET; |
| 1756 | sock->is_connected = 0; | 1748 | sock->is_connected = 0; |
| @@ -1759,7 +1751,7 @@ static p_sock push_clienttable(lua_State *L, p_tags tags) | |||
| 1759 | sock->bf_first = sock->bf_last = 0; | 1751 | sock->bf_first = sock->bf_last = 0; |
| 1760 | for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) { | 1752 | for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) { |
| 1761 | lua_pushstring(L, funcs[i].name); | 1753 | lua_pushstring(L, funcs[i].name); |
| 1762 | lua_pushusertag(L, sock, tags->client); | 1754 | lua_pushvalue(L, -3); |
| 1763 | lua_pushcclosure(L, funcs[i].func, 1); | 1755 | lua_pushcclosure(L, funcs[i].func, 1); |
| 1764 | lua_settable(L, -3); | 1756 | lua_settable(L, -3); |
| 1765 | } | 1757 | } |
| @@ -1782,12 +1774,11 @@ static p_sock push_servertable(lua_State *L, p_tags tags) | |||
| 1782 | {"timeout", table_timeout}, | 1774 | {"timeout", table_timeout}, |
| 1783 | }; | 1775 | }; |
| 1784 | unsigned int i; | 1776 | unsigned int i; |
| 1785 | p_sock sock; | 1777 | p_sock sock = (p_sock) lua_newuserdata(L, sizeof(t_sock)); |
| 1778 | lua_settag(L, tags->server); | ||
| 1786 | lua_newtable(L); lua_settag(L, tags->table); | 1779 | lua_newtable(L); lua_settag(L, tags->table); |
| 1787 | lua_pushstring(L, P_SOCK); | 1780 | lua_pushstring(L, P_SOCK); |
| 1788 | sock = (p_sock) lua_newuserdata(L, sizeof(t_sock)); | 1781 | lua_pushvalue(L, -3); |
| 1789 | if (!sock) return NULL; | ||
| 1790 | lua_settag(L, tags->server); | ||
| 1791 | lua_settable(L, -3); | 1782 | lua_settable(L, -3); |
| 1792 | sock->sock = INVALID_SOCKET; | 1783 | sock->sock = INVALID_SOCKET; |
| 1793 | sock->tm_block = -1; | 1784 | sock->tm_block = -1; |
| @@ -1795,14 +1786,18 @@ static p_sock push_servertable(lua_State *L, p_tags tags) | |||
| 1795 | sock->bf_first = sock->bf_last = 0; | 1786 | sock->bf_first = sock->bf_last = 0; |
| 1796 | for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) { | 1787 | for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) { |
| 1797 | lua_pushstring(L, funcs[i].name); | 1788 | lua_pushstring(L, funcs[i].name); |
| 1798 | lua_pushusertag(L, sock, tags->client); | 1789 | lua_pushvalue(L, -3); |
| 1799 | lua_pushcclosure(L, funcs[i].func, 1); | 1790 | lua_pushcclosure(L, funcs[i].func, 1); |
| 1800 | lua_settable(L, -3); | 1791 | lua_settable(L, -3); |
| 1801 | } | 1792 | } |
| 1802 | /* the accept method is different, it needs the tags closure too */ | 1793 | /* the accept method is different, it needs the tags closure too */ |
| 1803 | lua_pushstring(L, "accept"); | 1794 | lua_pushstring(L, "accept"); |
| 1795 | #ifdef LUASOCKET_41FRIENDLY | ||
| 1796 | lua_newuserdatabox(L, tags); | ||
| 1797 | #else | ||
| 1804 | lua_pushuserdata(L, tags); | 1798 | lua_pushuserdata(L, tags); |
| 1805 | lua_pushusertag(L, sock, tags->client); | 1799 | #endif |
| 1800 | lua_pushvalue(L, -4); | ||
| 1806 | lua_pushcclosure(L, table_tcpaccept, 2); | 1801 | lua_pushcclosure(L, table_tcpaccept, 2); |
| 1807 | lua_settable(L, -3); | 1802 | lua_settable(L, -3); |
| 1808 | return sock; | 1803 | return sock; |
| @@ -1831,16 +1826,11 @@ static p_sock push_udptable(lua_State *L, p_tags tags) | |||
| 1831 | {"timeout", table_timeout}, | 1826 | {"timeout", table_timeout}, |
| 1832 | }; | 1827 | }; |
| 1833 | unsigned int i; | 1828 | unsigned int i; |
| 1834 | p_sock sock; | 1829 | p_sock sock = (p_sock) lua_newuserdata(L, sizeof(t_sock)); |
| 1830 | lua_settag(L, tags->udp); | ||
| 1835 | lua_newtable(L); lua_settag(L, tags->table); | 1831 | lua_newtable(L); lua_settag(L, tags->table); |
| 1836 | lua_pushstring(L, P_SOCK); | 1832 | lua_pushstring(L, P_SOCK); |
| 1837 | sock = (p_sock) lua_newuserdata(L, sizeof(t_sock)); | 1833 | lua_pushvalue(L, -3); |
| 1838 | if (!sock) { | ||
| 1839 | lua_pushnil(L); | ||
| 1840 | lua_pushstring(L, "out of memory"); | ||
| 1841 | return NULL; | ||
| 1842 | } | ||
| 1843 | lua_settag(L, tags->udp); | ||
| 1844 | lua_settable(L, -3); | 1834 | lua_settable(L, -3); |
| 1845 | sock->sock = socket(AF_INET, SOCK_DGRAM, 0); | 1835 | sock->sock = socket(AF_INET, SOCK_DGRAM, 0); |
| 1846 | if (sock->sock == INVALID_SOCKET) { | 1836 | if (sock->sock == INVALID_SOCKET) { |
| @@ -1854,7 +1844,7 @@ static p_sock push_udptable(lua_State *L, p_tags tags) | |||
| 1854 | sock->bf_first = sock->bf_last = 0; | 1844 | sock->bf_first = sock->bf_last = 0; |
| 1855 | for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) { | 1845 | for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) { |
| 1856 | lua_pushstring(L, funcs[i].name); | 1846 | lua_pushstring(L, funcs[i].name); |
| 1857 | lua_pushusertag(L, sock, tags->udp); | 1847 | lua_pushvalue(L, -3); |
| 1858 | lua_pushcclosure(L, funcs[i].func, 1); | 1848 | lua_pushcclosure(L, funcs[i].func, 1); |
| 1859 | lua_settable(L, -3); | 1849 | lua_settable(L, -3); |
| 1860 | } | 1850 | } |
