static int cond_wait(lua_State *L) { pthread_cond_t *cond = (pthread_cond_t *) aux_checkclass(L, "cond", 1); srm_t *srm = (srm_t *) aux_checkclass(L, "mutex", 2); if (srm_cond_wait(cond, srm) != 0) luaL_error(L, "unable to wait"); return 0; }
/*-------------------------------------------------------------------------*\ * Send data through unconnected udp socket \*-------------------------------------------------------------------------*/ static int meth_sendto(lua_State *L) { p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); size_t count, sent = 0; const char *data = luaL_checklstring(L, 2, &count); const char *ip = luaL_checkstring(L, 3); unsigned short port = (unsigned short) luaL_checknumber(L, 4); p_tm tm = &udp->tm; struct sockaddr_in addr; int err; memset(&addr, 0, sizeof(addr)); if (!inet_aton(ip, &addr.sin_addr)) luaL_argerror(L, 3, "invalid ip address"); addr.sin_family = AF_INET; addr.sin_port = htons(port); tm_markstart(tm); err = sock_sendto(&udp->sock, data, count, &sent, (SA *) &addr, sizeof(addr), tm); if (err != IO_DONE) { lua_pushnil(L); lua_pushstring(L, udp_strerror(err)); return 2; } lua_pushnumber(L, sent); return 1; }
/*-------------------------------------------------------------------------*\ * Turns a master object into a server object \*-------------------------------------------------------------------------*/ static int meth_setsockname(lua_State *L) { p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); const char *address = luaL_checkstring(L, 2); unsigned short port = (unsigned short) luaL_checknumber(L, 3); const char *err = inet_trybind(&udp->sock, address, port); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } lua_pushnumber(L, 1); return 1; }
/*-------------------------------------------------------------------------*\ * Send data through connected udp socket \*-------------------------------------------------------------------------*/ static int meth_send(lua_State *L) { p_udp udp = (p_udp) aux_checkclass(L, "udp{connected}", 1); p_tm tm = &udp->tm; size_t count, sent = 0; int err; const char *data = luaL_checklstring(L, 2, &count); tm_markstart(tm); err = sock_send(&udp->sock, data, count, &sent, tm); if (err != IO_DONE) { lua_pushnil(L); lua_pushstring(L, udp_strerror(err)); return 2; } lua_pushnumber(L, sent); return 1; }
/*-------------------------------------------------------------------------*\ * Turns a master udp object into a client object. \*-------------------------------------------------------------------------*/ static int meth_setpeername(lua_State *L) { p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); p_tm tm = &udp->tm; const char *address = luaL_checkstring(L, 2); int connecting = strcmp(address, "*"); unsigned short port = connecting ? (unsigned short) luaL_checknumber(L, 3) : (unsigned short) luaL_optnumber(L, 3, 0); const char *err = inet_tryconnect(&udp->sock, address, port, tm); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } /* change class to connected or unconnected depending on address */ if (connecting) aux_setclass(L, "udp{connected}", 1); else aux_setclass(L, "udp{unconnected}", 1); lua_pushnumber(L, 1); return 1; }
/*-------------------------------------------------------------------------*\ * Receives data and sender from a UDP socket \*-------------------------------------------------------------------------*/ static int meth_receivefrom(lua_State *L) { p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); struct sockaddr_in addr; socklen_t addr_len = sizeof(addr); char buffer[UDP_DATAGRAMSIZE]; size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); int err; p_tm tm = &udp->tm; tm_markstart(tm); count = MIN(count, sizeof(buffer)); err = sock_recvfrom(&udp->sock, buffer, count, &got, (SA *) &addr, &addr_len, tm); if (err == IO_DONE) { lua_pushlstring(L, buffer, got); lua_pushstring(L, inet_ntoa(addr.sin_addr)); lua_pushnumber(L, ntohs(addr.sin_port)); return 3; } else { lua_pushnil(L); lua_pushstring(L, udp_strerror(err)); return 2; } }
static int cond_broadcast (lua_State *L) { pthread_cond_t *cond = (pthread_cond_t *) aux_checkclass(L, "cond", 1); if (pthread_cond_broadcast(cond) != 0) luaL_error(L, "unable to broadcast"); return 0; }
static int cond_signal(lua_State *L) { pthread_cond_t *cond = (pthread_cond_t *) aux_checkclass(L, "cond", 1); if (pthread_cond_signal(cond) != 0) luaL_error(L, "unable to signal"); return 0; }
static int mutex_unlock(lua_State *L) { srm_t *srm = (srm_t *) aux_checkclass(L, "mutex", 1); if (srm_unlock(srm) != 0) luaL_error(L, "unable to unlock mutex"); return 0; }
/*-------------------------------------------------------------------------*\ * Just call inet methods \*-------------------------------------------------------------------------*/ static int meth_getpeername(lua_State *L) { p_udp udp = (p_udp) aux_checkclass(L, "udp{connected}", 1); return inet_meth_getpeername(L, &udp->sock); }