void setupcrashsignal(lua_State * L) { lua_getglobal(L, "terralib"); lua_getfield(L, -1, "traceback"); const void * tb = lua_topointer(L,-1); if(!tb) return; //debug not supported terratraceback = *(void(**)(void*))tb; registerhandler(); lua_pop(L,2); }
void _init() { nicks=0; quits=0; registerhook(HOOK_NICK_NEWNICK, &nr_nick); registerhook(HOOK_NICK_LOSTNICK, &nr_nick); nickrate_listenfd=nr_openlistensocket(6002); if (nickrate_listenfd>0) { registerhandler(nickrate_listenfd,POLLIN,&nr_handlelistensocket); } }
static int lua_socket_write(lua_State *l) { char *buf; long len; lua_socket *ls; int ret; buf = (char *)lua_tostring(l, 2); if(!lua_islong(l, 1) || !buf) { lua_pushint(l, -1); return 1; } len = lua_strlen(l, 2); ls = socketbyidentifier(lua_tolong(l, 1)); if(!ls || (ls->state != SOCKET_CONNECTED)) { lua_pushint(l, -1); return 1; } ret = write(ls->fd, buf, len); if(ret == -1 && (errno == EAGAIN)) { deregisterhandler(ls->fd, 0); registerhandler(ls->fd, POLLIN | POLLOUT | POLLERR | POLLHUP, lua_socket_poll_event); lua_pushint(l, 0); return 1; } if(ret == -1) lua_socket_call_close(ls); if(ret < len) { deregisterhandler(ls->fd, 0); registerhandler(ls->fd, POLLIN | POLLOUT | POLLERR | POLLHUP, lua_socket_poll_event); } lua_pushint(l, ret); return 1; }
static void registerluasocket(lua_list *ll, lua_socket *ls, int mask, int settag) { /* this whole identifier thing should probably use userdata stuff */ ls->identifier = nextidentifier++; if(settag) { ls->tag = luaL_ref(ll->l, LUA_REGISTRYINDEX); ls->handler = luaL_ref(ll->l, LUA_REGISTRYINDEX); } ls->l = ll; ls->next = ll->sockets; ll->sockets = ls; registerhandler(ls->fd, mask, lua_socket_poll_event); }
static void lua_socket_poll_event(int fd, short events) { lua_socket *ls = socketbyfd(fd); if(!ls || (ls->state == SOCKET_CLOSED)) return; if(events & (POLLERR | POLLHUP)) { lua_socket_call_close(ls); return; } switch(ls->state) { case SOCKET_CONNECTING: if(events & POLLOUT) { deregisterhandler(fd, 0); registerhandler(fd, POLLIN | POLLERR | POLLHUP, lua_socket_poll_event); ls->state = SOCKET_CONNECTED; lua_vnpcall(ls, "connect", ""); } break; case SOCKET_CONNECTED: if(events & POLLOUT) { deregisterhandler(fd, 0); registerhandler(fd, POLLIN | POLLERR | POLLHUP, lua_socket_poll_event); lua_vnpcall(ls, "flush", ""); } if(events & POLLIN) { char buf[8192 * 2]; int bytesread; bytesread = read(fd, buf, sizeof(buf)); if((bytesread == -1) && (errno == EAGAIN)) return; if(bytesread <= 0) { lua_socket_call_close(ls); return; } lua_vnpcall(ls, "read", "L", buf, (long)bytesread); } break; case SOCKET_LISTENING: if(events & POLLIN) { struct sockaddr_in rip; struct sockaddr_un run; lua_socket *ls2; unsigned int len; int fd2; if(ls->sockettype == PF_INET) { len = sizeof(rip); fd2 = accept(fd, (struct sockaddr *)&rip, &len); } else { len = sizeof(run); fd2 = accept(fd, (struct sockaddr *)&run, &len); } if(fd2 == -1) return; ls2 = (lua_socket *)luamalloc(sizeof(lua_socket)); if(!ls2) { close(fd2); return; } ls2->fd = fd2; ls2->state = SOCKET_CONNECTED; ls2->tag = ls->tag; ls2->handler = ls->handler; ls2->parent = ls; ls2->sockettype = ls->sockettype; registerluasocket(ls->l, ls2, POLLIN | POLLERR | POLLHUP, 0); lua_vnpcall(ls, "accept", "l", ls2->identifier); } break; } }