add code for simple network connections
authorJann Horn <jann@thejh.net>
Thu, 14 Nov 2013 02:27:05 +0000 (03:27 +0100)
committerJann Horn <jann@thejh.net>
Thu, 14 Nov 2013 02:27:05 +0000 (03:27 +0100)
net.c [new file with mode: 0644]

diff --git a/net.c b/net.c
new file mode 100644 (file)
index 0000000..8d67e71
--- /dev/null
+++ b/net.c
@@ -0,0 +1,59 @@
+HEADER #include <netdb.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <unistd.h>
+#include <errno.h>
+
+HEADER extern const struct addrinfo libjh_tcp_hints;
+HEADER #define JH_TCP_HINTS (&libjh_tcp_hints)
+const struct addrinfo libjh_tcp_hints = {
+  .ai_flags = AI_ADDRCONFIG,
+  .ai_family = AF_UNSPEC,
+  .ai_socktype = SOCK_STREAM,
+  .ai_protocol = 0
+};
+
+// negative return value: interpret as a getaddrinfo() error (non-gai errors become EAI_SYSTEM)
+// >=0 return value: interpret as resulting fd
+PUBLIC_FN int netopen(const char *node, const char *service, const struct addrinfo *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 (connect(s, addrs[0].ai_addr, addrs[0].ai_addrlen)) goto err_connect;
+
+  freeaddrinfo(addrs);
+  return s;
+
+err_connect:;
+  int errno_ = errno;
+  close(s);
+  errno = errno_;
+err_socket:
+  freeaddrinfo(addrs);
+  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;
+
+  FILE *res = fdopen(rval, "r+");
+  if (res) return res;
+
+  int errno_ = errno;
+  close(rval);
+  errno = errno_;
+  rval = EAI_SYSTEM;
+
+err:
+  if (err) *err = rval;
+  return NULL;
+}
\ No newline at end of file