diff --git a/src/tcp.c b/src/tcp.c index 6594bda..198e5fc 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -171,8 +171,11 @@ static int meth_getfd(lua_State *L) static int meth_setfd(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); - tcp->sock = (t_socket) luaL_checknumber(L, 2); - return 0; + t_socket fd = tcp->sock; + if(lua_gettop(L) == 1) tcp->sock = SOCKET_INVALID; + else tcp->sock = (t_socket) luaL_checknumber(L, 2); + lua_pushnumber(L, (int) fd); + return 1; } static int meth_dirty(lua_State *L) @@ -356,14 +359,24 @@ static int meth_settimeout(lua_State *L) \*-------------------------------------------------------------------------*/ static int tcp_create(lua_State *L, int family) { t_socket sock; - const char *err = inet_trycreate(&sock, family, SOCK_STREAM); + const char *err; + const int is_inherite = lua_isnumber(L,1); + const char *obj_type = "tcp{master}"; + if (is_inherite){ + err = NULL; + sock = (t_socket)lua_tonumber(L, 1); + if(strstr(luaL_optstring(L,2,""),"client")) + obj_type = "tcp{client}"; + } + else + err = inet_trycreate(&sock, family, SOCK_STREAM); /* try to allocate a system socket */ if (!err) { /* allocate tcp object */ p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); memset(tcp, 0, sizeof(t_tcp)); /* set its type as master object */ - auxiliar_setclass(L, "tcp{master}", -1); + auxiliar_setclass(L, obj_type, -1); /* initialize remaining structure fields */ socket_setnonblocking(&sock); if (family == PF_INET6) { diff --git a/src/udp.c b/src/udp.c index a9f2393..cecec76 100644 --- a/src/udp.c +++ b/src/udp.c @@ -284,8 +284,11 @@ static int meth_getfd(lua_State *L) { /* this is very dangerous, but can be handy for those that are brave enough */ static int meth_setfd(lua_State *L) { p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); - udp->sock = (t_socket) luaL_checknumber(L, 2); - return 0; + t_socket fd = udp->sock; + if(lua_gettop(L) == 1) udp->sock = SOCKET_INVALID; + else udp->sock = (t_socket) luaL_checknumber(L, 2); + lua_pushnumber(L, (int) fd); + return 1; } static int meth_dirty(lua_State *L) { @@ -408,7 +411,14 @@ static int meth_setsockname(lua_State *L) { \*-------------------------------------------------------------------------*/ static int udp_create(lua_State *L, int family) { t_socket sock; - const char *err = inet_trycreate(&sock, family, SOCK_DGRAM); + const char *err; + const int is_inherite = lua_isnumber(L,1); + if (is_inherite){ + err = NULL; + sock = (t_socket)lua_tonumber(L, 1); + } + else + err = inet_trycreate(&sock, family, SOCK_DGRAM); /* try to allocate a system socket */ if (!err) { /* allocate udp object */ diff --git a/test/test_setfd.lua b/test/test_setfd.lua new file mode 100644 index 0000000..89d377f --- /dev/null +++ b/test/test_setfd.lua @@ -0,0 +1,30 @@ +local socket = require "socket" + +local host, port = "127.0.0.1", "5462" + +local srv = assert(socket.bind(host, port)) + +local sock_cli = socket.tcp() +assert(sock_cli:connect(host, port)) + +local fd do + local sock_srv = assert(srv:accept()) + fd = assert(sock_srv:getfd()) + + assert(not pcall(function() sock_srv:setfd(nil) end)) + sock_srv:setfd() + assert(sock_srv:close()) +end + +local sock_srv = assert(socket.tcp(fd, "client")) +collectgarbage"collect" +collectgarbage"collect" + +assert(5 == assert(sock_srv:send("hello"))) +assert("hello" == assert(sock_cli:receive(5))) + +sock_cli:close() +sock_srv:close() +srv:close() + +print("done!") \ No newline at end of file