static int Socket_new(lua_State *L){ int argc = lua_gettop(L); if (argc != 2 && argc != 1){ return luaL_error(L, "Argument error: geSocket.new([hostname, ]port) takes one or two arguments."); } lua_gc(L, LUA_GCCOLLECT, 0); if(argc == 1){ *pushNewSocket(L) = geCreateSocket( GE_SOCKET_TYPE_SERVER, "0.0.0.0", (int)luaL_checknumber(L, 1), GE_PORT_TYPE_TCP ); }else{ *pushNewSocket(L) = geCreateSocket( GE_SOCKET_TYPE_CLIENT, luaL_checkstring(L, 1), (int)luaL_checknumber(L, 2), GE_PORT_TYPE_TCP ); } return 1; }
/** Accept a new incomming connection. * @return a new lk.Socket connected to the remote end. */ LuaStackSize lk::Socket::accept(lua_State *L) { // <self> lua_pop(L, 1); if (local_port_ == -1) throw dub::Exception("Accept called before bind."); struct sockaddr sa; memset(&sa, 0, sizeof(struct sockaddr)); // length has to be in a variable socklen_t sa_len = sizeof(sa); int fd; fd = ::accept(socket_fd_, &sa, &sa_len); //printf("[%p] accept(%i) --> %i\n", this, socket_fd_, fd); if (fd == -1) { throw dub::Exception("Error while accepting connection (%s).", strerror(errno)); } // get remote name / port int remote_port; if (sa.sa_family == AF_INET) { remote_port = ntohs(((struct sockaddr_in *)&sa)->sin_port); } else { remote_port = ntohs(((struct sockaddr_in6 *)&sa)->sin6_port); } char remote_host[NI_MAXHOST]; if (getnameinfo(&sa, sizeof(sa), remote_host, sizeof(remote_host), NULL, 0, 0)) { throw dub::Exception("Could not get remote host name (%s).", strerror(errno)); } return pushNewSocket(L, socket_type_, fd, local_host_.c_str(), remote_host, remote_port); }