Reworking the socket closing handling. - geomyidae - A small C-based gopherd.
git clone git://bitreich.org/geomyidae/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/geomyidae/
Log
Files
Refs
Tags
README
LICENSE
---
commit ecf782f0557effe122f791f839a509ec428d236e
parent f4cac1fea572c34eaf23baef928d7aa313ae9ccf
Author: Christoph Lohmann <20h@r-36.net>
Date:   Wed,  7 Feb 2018 19:57:42 +0100

Reworking the socket closing handling.

Thanks Evil_Bob for much input.

Geomyidae now supports the ugly event code of curl.

Diffstat:
  M handlr.c                            |       1 -
  M ind.c                               |      29 ++++++++++++++++++++++++++---
  M ind.h                               |       2 ++
  M main.c                              |      30 ++++++++++++++++++++----------

4 files changed, 48 insertions(+), 14 deletions(-)
---
diff --git a/handlr.c b/handlr.c
@@ -116,7 +116,6 @@ handlebin(int sock, char *file, char *port, char *base, char *args,
         if (fd >= 0) {
                 if (xsendfile(fd, sock) < 0)
                         perror("sendfile");
-                close(fd);
         }
 }
 
diff --git a/ind.c b/ind.c
@@ -16,15 +16,18 @@
 #include 
 #include 
 #include 
+#include 
 
-/* for sendfile(2) */
+/* for sendfile(2) and SIOCOUTQ */
 #ifdef __linux__
 #include 
+#include 
 #elif defined(__FreeBSD__) || defined(__DragonFly__)
 #include 
 #include 
 #endif
 
+#include "arg.h"
 #include "ind.h"
 #include "handlr.h"
 
@@ -53,6 +56,25 @@ filetype type[] = {
 };
 
 int
+pendingbytes(int sock)
+{
+        int pending;
+
+        pending = 0;
+        ioctl(sock, SIOCOUTQ, &pending);
+
+        return pending;
+}
+
+void
+waitforpendingbytes(int sock)
+{
+
+        while (pendingbytes(sock) > 0)
+                usleep(10);
+}
+
+int
 xsendfile(int fd, int sock)
 {
         struct stat st;
@@ -60,6 +82,8 @@ xsendfile(int fd, int sock)
         size_t bufsiz = BUFSIZ, count = 0;
         int len, sent, optval;
 
+        USED(optval);
+
 /* Tell the kernel to not send small packets on every write. */
 #ifdef TCP_CORK
         optval = 1;
@@ -94,12 +118,11 @@ xsendfile(int fd, int sock)
         count = 0;
 #endif
 
-        if (count == 0) {
+        if (count > 0) {
                 sendb = xmalloc(bufsiz);
                 while ((len = read(fd, sendb, bufsiz)) > 0) {
                         while (len > 0) {
                                 if ((sent = send(sock, sendb, len, 0)) < 0) {
-                                        close(fd);
                                         free(sendb);
                                         return -1;
                                 }
diff --git a/ind.h b/ind.h
@@ -39,6 +39,8 @@ char *xstrdup(const char *str);
 int xsendfile(int, int);
 Indexs *scanfile(char *fname);
 Elems *getadv(char *str);
+int pendingbytes(int sock);
+void waitforpendingbytes(int sock);
 int printelem(int fd, Elems *el, char *addr, char *port);
 void addindexs(Indexs *idx, Elems *el);
 void addelem(Elems *e, char *s);
diff --git a/main.c b/main.c
@@ -15,6 +15,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -39,7 +41,6 @@ enum {
 
 int glfd = -1;
 int loglvl = 15;
-int running = 1;
 int listfd = -1;
 int revlookup = 1;
 char *logfile = nil;
@@ -121,8 +122,11 @@ handlerequest(int sock, char *base, char *ohost, char *port, char *clienth,
         args = nil;
 
         len = recv(sock, recvb, sizeof(recvb)-1, 0);
-        if (len <= 0)
+        if (len <= 0) {
+                if (len < 0)
+                        perror("recv");
                 return;
+        }
 
         c = strchr(recvb, '\r');
         if (c)
@@ -293,6 +297,7 @@ getlistenfd(struct addrinfo *hints, char *bindip, char *port)
                         continue;
                 if (setsockopt(listfd, SOL_SOCKET, SO_REUSEADDR, &on,
                                         sizeof(on)) < 0) {
+                        close(listfd);
                         break;
                 }
 
@@ -402,6 +407,9 @@ main(int argc, char *argv[])
                 usage();
         } ARGEND;
 
+        if (argc != 0)
+                usage();
+
         if (ohost == nil) {
                 ohost = xcalloc(1, 513);
                 if (gethostname(ohost, 512) < 0) {
@@ -507,17 +515,12 @@ main(int argc, char *argv[])
         initsignals();
 
         cltlen = sizeof(clt);
-        while (running) {
+        while (1) {
                 sock = accept(listfd, (struct sockaddr *)&clt, &cltlen);
                 if (sock < 0) {
                         switch (errno) {
                         case ECONNABORTED:
                         case EINTR:
-                                if (!running) {
-                                        shutdown(listfd, SHUT_RDWR);
-                                        close(listfd);
-                                        return 0;
-                                }
                                 continue;
                         default:
                                 perror("accept");
@@ -542,6 +545,8 @@ main(int argc, char *argv[])
                         shutdown(sock, SHUT_RDWR);
                         break;
                 case 0:
+                        close(listfd);
+
                         signal(SIGHUP, SIG_DFL);
                         signal(SIGQUIT, SIG_DFL);
                         signal(SIGINT, SIG_DFL);
@@ -550,15 +555,20 @@ main(int argc, char *argv[])
 
                         handlerequest(sock, base, ohost, sport, clienth,
                                                 clientp);
+
+                        waitforpendingbytes(sock);
+
                         shutdown(sock, SHUT_RDWR);
                         close(sock);
+
+                        if (loglvl & CONN)
+                                logentry(clienth, clientp, "-", "disconnected");
+
                         return 0;
                 default:
                         break;
                 }
                 close(sock);
-                if (loglvl & CONN)
-                        logentry(clienth, clientp, "-", "disconnected");
         }
 
         shutdown(listfd, SHUT_RDWR);