X-Git-Url: http://git.thejh.net/?p=libjh.git;a=blobdiff_plain;f=net.c;h=8fe59802e318cbe7a9ee147604d6ddbb96bdbda0;hp=8d67e71be62b551f4eed403da97de9b992cf3690;hb=0fa47e6453747e3ef4ab707a5bcb34980a465a75;hpb=ae33d7fe92d8dd8593e7a2b938d1f42d2aa60896 diff --git a/net.c b/net.c index 8d67e71..8fe5980 100644 --- a/net.c +++ b/net.c @@ -40,20 +40,63 @@ err_socket: return EAI_SYSTEM; } -// err points to where the error from netopen() should be stored -PUBLIC_FN FILE *fnetopen(const char *node, const char *service, const struct addrinfo *hints, int *err) { - int rval = netopen(node, service, hints); - if (rval < 0) goto err; +PUBLIC_FN int fnetopen(FILE **in, FILE **out, const char *node, const char *service, const struct addrinfo *hints) { + int fd = netopen(node, service, hints); + if (fd < 0) return EAI_SYSTEM; + int ret = fopen_bistream(in, out, fd, 0); + if (ret) close(fd); + return ret; +} + +HEADER // negative return value for error, else a socket +PUBLIC_FN int netopen_server(const char *node /*NULL for ANY*/, const char *service, const struct addrinfo *hints) { + struct addrinfo hints_; + if (hints == &libjh_tcp_hints) { + hints_ = *hints; + hints_.ai_flags |= AI_PASSIVE; + hints_.ai_flags &= ~AI_ADDRCONFIG; + hints = &hints_; + } + + struct addrinfo *addrs; + int gai_res = getaddrinfo(node, service, hints, &addrs); + if (gai_res) return gai_res; - FILE *res = fdopen(rval, "r+"); - if (res) return res; + int s = socket(addrs[0].ai_family, addrs[0].ai_socktype, addrs[0].ai_protocol); + if (s == -1) goto err_socket; + if (bind(s, addrs[0].ai_addr, addrs[0].ai_addrlen)) goto err_bind_n_listen; + if (listen(s, 16)) goto err_bind_n_listen; + + freeaddrinfo(addrs); + return s; + +err_bind_n_listen:; int errno_ = errno; - close(rval); + close(s); errno = errno_; - rval = EAI_SYSTEM; +err_socket: + freeaddrinfo(addrs); + return EAI_SYSTEM; +} -err: - if (err) *err = rval; - return NULL; -} \ No newline at end of file +/********************** SERVER SOCKET STUFF **********************/ +HEADER typedef void (*jh_ev_io_ssock_cb)(EV_P_ ev_io *w, int socket); +static void ev_io_ssock_cb(EV_P_ ev_io *w, int revents) { + jh_ev_io_ssock_cb cb = (jh_ev_io_ssock_cb)w->data; + if (revents == EV_ERROR) { + cb(EV_A_ w, -1); + return; + } + int fd = accept(w->fd, NULL, NULL); + if (fd == -1) { + fprintf(stderr, "\nLIBJH ERROR: ACCEPT() FAILED - SLEEPING 1s\n"); + sleep(1); + return; + } + cb(EV_A_ w, fd); +} +PUBLIC_FN void jh_ev_io_ssock_init(ev_io *w, jh_ev_io_ssock_cb cb, int fd) { + ev_io_init(w, ev_io_ssock_cb, fd, EV_READ); + w->data = cb; +}