r4566 - trunk/varnish-cache/lib/libvarnish
phk at projects.linpro.no
phk at projects.linpro.no
Tue Feb 16 22:12:23 CET 2010
Author: phk
Date: 2010-02-16 22:12:23 +0100 (Tue, 16 Feb 2010)
New Revision: 4566
Modified:
trunk/varnish-cache/lib/libvarnish/tcp.c
Log:
Pretend to use variable, even if kernel is deficient.
Modified: trunk/varnish-cache/lib/libvarnish/tcp.c
===================================================================
--- trunk/varnish-cache/lib/libvarnish/tcp.c 2010-02-16 21:11:05 UTC (rev 4565)
+++ trunk/varnish-cache/lib/libvarnish/tcp.c 2010-02-16 21:12:23 UTC (rev 4566)
@@ -61,6 +61,45 @@
#include "libvarnish.h"
+/*--------------------------------------------------------------------
+ * Recognize errno's we see when the remote end closed the connection.
+ *
+ * This "magic" is mostly needed because solaris wrongly returns EBADF
+ * when they should return ECONNRESET upon receiving a TCP-RST from the
+ * far end.
+ *
+ * My theory is, that some genius decided that since the socket is now
+ * officially useless, and since they already have found and locked
+ * the socket/pcb, they might as well get rid off it right away.
+ *
+ * On next use from the program, EBADF happens to be the errno, but since
+ * all programs just call strerror(), who cares ?
+ *
+ * Well, I do. EBADF is the canonical "Programmer goofed" errno, and
+ * it should not be issued for other reasons.
+ *
+ * An interesting question here, is if the kernel might conceiveably
+ * reallocate the fd# before the application closes it, on the mistaken
+ * belief that it is unused ? That would be bad news...
+ *
+ */
+
+int
+TCP_Errno(void)
+{
+
+ switch (errno) {
+ case ECONNRESET:
+ case ENOTCONN:
+#if defined (__SVR4) && defined (__sun)
+ case EBADF:
+#endif
+ return (1);
+ default:
+ return (0);
+ }
+}
+
/*--------------------------------------------------------------------*/
void
@@ -232,9 +271,8 @@
void
TCP_close(int *s)
{
- assert (close(*s) == 0 ||
- errno == ECONNRESET ||
- errno == ENOTCONN);
+
+ assert (close(*s) == 0 || TCP_Errno());
*s = -1;
}
@@ -246,6 +284,8 @@
timeout.tv_usec = (int)(1e6 * (seconds - timeout.tv_sec));
#ifdef SO_RCVTIMEO_WORKS
AZ(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout));
+#else
+ (void)s;
#endif
}
More information about the varnish-commit
mailing list