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 | } |