static int _sock_accept(lua_State *L) { socket_t *sock = _getsock(L, 1); int fd = accept(sock->fd, NULL, NULL); if(fd < 0) { lua_pushnil(L); lua_pushinteger(L, errno); return 2; } _setsock(L, fd, sock->family, sock->type, sock->protocol); return 1; }
/* * args: int domain, int type, int protocal */ static int _socket(lua_State *L) { int family = luaL_checkinteger(L, 1); int type = luaL_checkinteger(L, 2); int protocol = luaL_optinteger(L,3,0); int fd = socket(family, type, protocol); if(fd < 0) { lua_pushnil(L); lua_pushinteger(L, errno); return 2; } _setsock(L, fd, family, type, protocol); return 1; }
int tobindex(const char *addr, int qlen, int (*_setsock)(int), int do_listen) { const int v_on = 1; int sockfd; assert(addr && *addr); if (!isdigit(addr[0]) && addr[0] != ':' && addr[0] != '*') { struct sockaddr_un servaddr; if ( (sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0 ) { perror("socket()"); exit(1); } servaddr.sun_family = AF_UNIX; strlcpy(servaddr.sun_path, addr, sizeof(servaddr.sun_path)); setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&v_on, sizeof(v_on)); if (_setsock) _setsock(sockfd); // remove the file first if it exists. unlink(servaddr.sun_path); if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { perror("bind()"); exit(1); } } else { char buf[64], *port; struct sockaddr_in servaddr; if ( (sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0 ) { perror("socket()"); exit(1); } strlcpy(buf, addr, sizeof(buf)); if ( (port = strchr(buf, ':')) != NULL) *port++ = '\0'; assert(port && atoi(port) != 0); setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&v_on, sizeof(v_on)); if (_setsock) _setsock(sockfd); if (!buf[0]) servaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); else if (buf[0] == '*') servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // XXX use INADDR_LOOPBACK? else if (inet_aton(buf, &servaddr.sin_addr) == 0) { perror("inet_aton()"); exit(1); } servaddr.sin_port = htons(atoi(port)); servaddr.sin_family = AF_INET; if( bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 ) { perror("bind()"); exit(1); } } if (do_listen && listen(sockfd, qlen) < 0) { perror("listen()"); exit(1); } return sockfd; }