| @@ -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;
} |
| @@ -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); |
| @@ -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); |