summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2009-06-04 14:14:14 +1000
committerAndrew Bartlett <abartlet@samba.org>2009-06-04 14:19:17 +1000
commit4c70a5b405d2ee6b8a47118fd731a0fb64dda2ff (patch)
treeed707a68f5926b664d268db52133a5148be371d2
parentdfd56dd29415b06b5ea137f8c333da42e8ff1aa6 (diff)
downloadsamba-4c70a5b405d2ee6b8a47118fd731a0fb64dda2ff.tar.gz
samba-4c70a5b405d2ee6b8a47118fd731a0fb64dda2ff.tar.bz2
samba-4c70a5b405d2ee6b8a47118fd731a0fb64dda2ff.zip
socket_wrapper Cope with SOCK_CLOEXEC and SOCK_NONBLOCK flags
Heimdal will, on supporting systems, set these flags in the type argument of socket(), causing breakage when combined with socket_wrapper. For background on these flags, see http://lwn.net/Articles/281965/ Andrew Bartlett
-rw-r--r--lib/socket_wrapper/socket_wrapper.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c
index bd848f920b..071060c864 100644
--- a/lib/socket_wrapper/socket_wrapper.c
+++ b/lib/socket_wrapper/socket_wrapper.c
@@ -1384,6 +1384,13 @@ _PUBLIC_ int swrap_socket(int family, int type, int protocol)
{
struct socket_info *si;
int fd;
+ int real_type = type;
+#ifdef SOCK_CLOEXEC
+ real_type &= ~SOCK_CLOEXEC;
+#endif
+#ifdef SOCK_NONBLOCK
+ real_type &= ~SOCK_NONBLOCK;
+#endif
if (!socket_wrapper_dir()) {
return real_socket(family, type, protocol);
@@ -1402,7 +1409,7 @@ _PUBLIC_ int swrap_socket(int family, int type, int protocol)
return -1;
}
- switch (type) {
+ switch (real_type) {
case SOCK_STREAM:
break;
case SOCK_DGRAM:
@@ -1416,12 +1423,12 @@ _PUBLIC_ int swrap_socket(int family, int type, int protocol)
case 0:
break;
case 6:
- if (type == SOCK_STREAM) {
+ if (real_type == SOCK_STREAM) {
break;
}
/*fall through*/
case 17:
- if (type == SOCK_DGRAM) {
+ if (real_type == SOCK_DGRAM) {
break;
}
/*fall through*/
@@ -1430,6 +1437,8 @@ _PUBLIC_ int swrap_socket(int family, int type, int protocol)
return -1;
}
+ /* We must call real_socket with type, from the caller, not the version we removed
+ SOCK_CLOEXEC and SOCK_NONBLOCK from */
fd = real_socket(AF_UNIX, type, 0);
if (fd == -1) return -1;
@@ -1437,7 +1446,10 @@ _PUBLIC_ int swrap_socket(int family, int type, int protocol)
si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
si->family = family;
- si->type = type;
+
+ /* however, the rest of the socket_wrapper code expects just
+ * the type, not the flags */
+ si->type = real_type;
si->protocol = protocol;
si->fd = fd;