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;
+}