changeset 2435:f019e484f471 draft

Support older linux without SOCK_CLOEXEC.
author Roy Marples <roy@marples.name>
date Thu, 24 Apr 2014 08:56:21 +0000
parents 58c54320c5a6
children 39ad227cc122
files if-linux.c
diffstat 1 files changed, 32 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/if-linux.c	Wed Apr 23 23:29:41 2014 +0000
+++ b/if-linux.c	Thu Apr 24 08:56:21 2014 +0000
@@ -217,9 +217,23 @@
 {
 	int fd;
 
+#ifdef SOCK_CLOEXEC
 	fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
 	if (fd == -1)
 		return -1;
+#else
+	int flags;
+
+	fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+	if (fd == -1)
+		return -1;
+	if ((flags = fcntl(fd, F_GETFD, 0)) == -1 ||
+	    fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
+	{
+		close(fd);
+	        return -1;
+	}
+#endif
 	nl->nl_family = AF_NETLINK;
 	if (bind(fd, (struct sockaddr *)nl, sizeof(*nl)) == -1)
 		return -1;
@@ -739,11 +753,28 @@
 	int n;
 #endif
 
+#ifdef SOCK_CLOEXEC
 	if ((s = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
 	    htons(protocol))) == -1)
 		return -1;
+#else
+	int flags;
 
-	memset(&su, 0, sizeof(su));
+	if ((s = socket(PF_PACKET, SOCK_DGRAM, htons(protocol))) == -1)
+		return -1;
+	if ((flags = fcntl(s, F_GETFD, 0)) == -1 ||
+	    fcntl(s, F_SETFD, flags | FD_CLOEXEC) == -1)
+	{
+		close(s);
+	        return -1;
+	}
+	if ((flags = fcntl(s, F_GETFL, 0)) == -1 ||
+	    fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1)
+	{
+		close(s);
+	        return -1;
+	}
+#endif
 	su.sll.sll_family = PF_PACKET;
 	su.sll.sll_protocol = htons(protocol);
 	su.sll.sll_ifindex = (int)ifp->index;