--- luasocket-2.0.2/src/tcp.c 2007-10-15 06:21:05.000000000 +0200 +++ luasocket-2.0.2.new/src/tcp.c 2009-08-24 23:58:47.000000000 +0200 @@ -30,6 +30,7 @@ static int meth_shutdown(lua_State *L); static int meth_receive(lua_State *L); static int meth_accept(lua_State *L); +static int meth_acceptfd(lua_State *L); static int meth_close(lua_State *L); static int meth_setoption(lua_State *L); static int meth_settimeout(lua_State *L); @@ -42,6 +43,7 @@ {"__gc", meth_close}, {"__tostring", auxiliar_tostring}, {"accept", meth_accept}, + {"acceptfd", meth_acceptfd}, {"bind", meth_bind}, {"close", meth_close}, {"connect", meth_connect}, @@ -186,6 +188,27 @@ } /*-------------------------------------------------------------------------*\ +* Waits for and returns a client object attempting connection to the +* server object +\*-------------------------------------------------------------------------*/ +static int meth_acceptfd(lua_State *L) +{ + p_tcp server = (p_tcp) auxiliar_checkclass(L, "tcp{server}", 1); + p_timeout tm = timeout_markstart(&server->tm); + t_socket sock; + int err = socket_accept(&server->sock, &sock, NULL, NULL, tm); + /* if successful, push client socket */ + if (err == IO_DONE) { + lua_pushnumber(L, sock); + return 1; + } else { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(err)); + return 2; + } +} + +/*-------------------------------------------------------------------------*\ * Binds an object to an address \*-------------------------------------------------------------------------*/ static int meth_bind(lua_State *L) @@ -316,12 +339,19 @@ static int global_create(lua_State *L) { t_socket sock; - const char *err = inet_trycreate(&sock, SOCK_STREAM); + const char *err = NULL; + int fd = luaL_optnumber(L, 1, -1); + if (fd < 1) + err = inet_trycreate(&sock, SOCK_STREAM); + else + sock = fd; /* try to allocate a system socket */ if (!err) { /* allocate tcp object */ p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); - /* set its type as master object */ + if (fd >= 1) + auxiliar_setclass(L, "tcp{client}", -1); + else auxiliar_setclass(L, "tcp{master}", -1); /* initialize remaining structure fields */ socket_setnonblocking(&sock);