| Reworking the socket closing handling. - geomyidae - A small C-based gopherd. | |
| git clone git://bitreich.org/geomyidae/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfri… | |
| Log | |
| Files | |
| Refs | |
| Tags | |
| README | |
| LICENSE | |
| --- | |
| commit ecf782f0557effe122f791f839a509ec428d236e | |
| parent f4cac1fea572c34eaf23baef928d7aa313ae9ccf | |
| Author: Christoph Lohmann <[email protected]> | |
| 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, cha… | |
| 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 <netinet/in.h> | |
| #include <netinet/tcp.h> | |
| #include <arpa/inet.h> | |
| +#include <sys/ioctl.h> | |
| -/* for sendfile(2) */ | |
| +/* for sendfile(2) and SIOCOUTQ */ | |
| #ifdef __linux__ | |
| #include <sys/sendfile.h> | |
| +#include <linux/sockios.h> | |
| #elif defined(__FreeBSD__) || defined(__DragonFly__) | |
| #include <sys/types.h> | |
| #include <sys/uio.h> | |
| #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 <sys/stat.h> | |
| #include <sys/wait.h> | |
| #include <sys/types.h> | |
| +#include <sys/ioctl.h> | |
| +#include <linux/sockios.h> | |
| #include <signal.h> | |
| #include <string.h> | |
| #include <strings.h> | |
| @@ -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 *por… | |
| 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 *por… | |
| 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); |