Introduction
Introduction Statistics Contact Development Disclaimer Help
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);
You are viewing proxied material from bitreich.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.