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:
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 <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 *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);