Added support for creating a TCP server.
authorThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Thu, 2 Jul 2009 15:37:55 +0000 (12:37 -0300)
committerThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Thu, 2 Jul 2009 15:38:11 +0000 (12:38 -0300)
tcp_connect.h
tcp_server.c [new file with mode: 0644]

index cb323d9..249d654 100644 (file)
@@ -20,5 +20,6 @@
 #define HC_TCP_CONNECT_H
 
 int hc_tcp_connect (char *, char*);
+int hc_tcp_server (char*);
 
 #endif
diff --git a/tcp_server.c b/tcp_server.c
new file mode 100644 (file)
index 0000000..35ad630
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2008-2009  Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static int
+tcp_server (struct addrinfo *ai)
+{
+  int fd;
+  fd = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+  if (fd < 0)
+    return -1;
+  if (bind (fd, ai->ai_addr, ai->ai_addrlen) < 0)
+    {
+      close (fd);
+      return -1;
+    }
+  if (listen (fd, 5) < 0)
+    {
+      close (fd);
+      return -1;
+    }
+  return fd;
+}
+
+static int
+tcp_server_list (struct addrinfo *ai)
+{
+  int fd = -1;
+  for (; ai; ai = ai->ai_next)
+    {
+      fd = tcp_server (ai);
+      if (fd >= 0)
+        {
+          return fd;
+        }
+    }
+  return fd;
+}
+
+int
+hc_tcp_server (char *service)
+{
+  struct addrinfo hint;
+  struct addrinfo *ai = NULL;
+  int fd;
+  hint.ai_family = AF_UNSPEC;
+  hint.ai_socktype = SOCK_STREAM;
+  hint.ai_protocol = 0;
+  hint.ai_flags = AI_PASSIVE | AI_ADDRCONFIG | AI_V4MAPPED;
+  if (getaddrinfo (NULL, service, &hint, &ai) < 0)
+    return -1;
+  fd = tcp_server_list (ai);
+  freeaddrinfo (ai);
+  return fd;
+}
+
+#ifdef TEST
+int
+main (int argc, char **argv)
+{
+  char *service;
+  int fd;
+  service = (argc >= 2) ? argv[1] : "110";
+  fd = hc_tcp_server (service);
+  if (fd > 0)
+    close (fd);
+  return 0;
+}
+#endif