fix compilation
[libjh.git] / net.c
diff --git a/net.c b/net.c
index 2fba39a..8fe5980 100644 (file)
--- a/net.c
+++ b/net.c
@@ -46,4 +46,57 @@ PUBLIC_FN int fnetopen(FILE **in, FILE **out, const char *node, const char *serv
   int ret = fopen_bistream(in, out, fd, 0);
   if (ret) close(fd);
   return ret;
   int ret = fopen_bistream(in, out, fd, 0);
   if (ret) close(fd);
   return ret;
-}
\ No newline at end of file
+}
+
+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;
+
+  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(s);
+  errno = errno_;
+err_socket:
+  freeaddrinfo(addrs);
+  return EAI_SYSTEM;
+}
+
+/**********************   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;
+}