From e8c8e9b9b2967f9d56498061baec523b5238c1ce Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Thu, 13 Feb 2014 12:58:58 +0000 Subject: [PATCH] Work without SOCK_CLOEXEC again. --- control.c | 21 +++++++++++++++++++++ dhcp.c | 11 +++++++++++ dhcp6.c | 19 +++++++++++++++++++ if-bsd.c | 20 ++++++++++++++++++++ ipv6nd.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 115 insertions(+), 2 deletions(-) diff --git a/control.c b/control.c index 14d07b2c..bba78c11 100644 --- a/control.c +++ b/control.c @@ -133,9 +133,30 @@ static int make_sock(struct dhcpcd_ctx *ctx, struct sockaddr_un *sun) { +#ifdef SOCK_CLOEXEC if ((ctx->control_fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) == -1) return -1; +#else + int flags; + + if ((ctx->control_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + return -1; + if ((flags = fcntl(ctx->control_fd, F_GETFD, 0)) == -1 || + fcntl(ctx->control_fd, F_SETFD, flags | FD_CLOEXEC) == -1) + { + close(ctx->control_fd); + ctx->control_fd = -1; + return -1; + } + if ((flags = fcntl(ctx->control_fd, F_GETFL, 0)) == -1 || + fcntl(ctx->control_fd, F_SETFL, flags | O_NONBLOCK) == -1) + { + close(ctx->control_fd); + ctx->control_fd = -1; + return -1; + } +#endif memset(sun, 0, sizeof(*sun)); sun->sun_family = AF_UNIX; strlcpy(sun->sun_path, CONTROLSOCKET, sizeof(sun->sun_path)); diff --git a/dhcp.c b/dhcp.c index fb642d39..6a10b781 100644 --- a/dhcp.c +++ b/dhcp.c @@ -1360,8 +1360,19 @@ dhcp_openudp(struct dhcpcd_ctx *ctx, struct interface *ifp) char *p; #endif +#ifdef SOCK_CLOEXEC if ((s = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP)) == -1) return -1; +#else + if ((s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1) + return -1; + if ((n = fcntl(s, F_GETFD, 0)) == -1 || + fcntl(s, F_SETFD, n | FD_CLOEXEC) == -1) + { + close(s); + return -1; + } +#endif n = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1) diff --git a/dhcp6.c b/dhcp6.c index 57add6af..1db65f8f 100644 --- a/dhcp6.c +++ b/dhcp6.c @@ -2447,11 +2447,30 @@ dhcp6_open(struct dhcpcd_ctx *dctx) #endif ctx = dctx->ipv6; +#ifdef SOCK_CLOEXEC ctx->dhcp_fd = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, IPPROTO_UDP); if (ctx->dhcp_fd == -1) return -1; +#else + if ((ctx->dhcp_fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1) + return -1; + if ((n = fcntl(ctx->dhcp_fd, F_GETFD, 0)) == -1 || + fcntl(ctx->dhcp_fd, F_SETFD, n | FD_CLOEXEC) == -1) + { + close(ctx->dhcp_fd); + ctx->dhcp_fd = -1; + return -1; + } + if ((n = fcntl(ctx->dhcp_fd, F_GETFL, 0)) == -1 || + fcntl(ctx->dhcp_fd, F_SETFL, n | O_NONBLOCK) == -1) + { + close(ctx->dhcp_fd); + ctx->dhcp_fd = -1; + return -1; + } +#endif n = 1; if (setsockopt(ctx->dhcp_fd, SOL_SOCKET, SO_REUSEADDR, diff --git a/if-bsd.c b/if-bsd.c index 3af7e95e..c1102823 100644 --- a/if-bsd.c +++ b/if-bsd.c @@ -51,6 +51,7 @@ #endif #include +#include #include #include #include @@ -102,7 +103,26 @@ int open_link_socket(void) { +#ifdef SOCK_CLOEXEC return socket(PF_ROUTE, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); +#else + int s, flags; + + if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -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 } int diff --git a/ipv6nd.c b/ipv6nd.c index acc2699f..2bcb701d 100644 --- a/ipv6nd.c +++ b/ipv6nd.c @@ -39,6 +39,7 @@ #endif #include +#include #include #include #include @@ -178,10 +179,29 @@ ipv6nd_open(struct dhcpcd_ctx *dctx) ctx = dctx->ipv6; if (ctx->nd_fd != -1) goto unspec; +#ifdef SOCK_CLOEXEC ctx->nd_fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, IPPROTO_ICMPV6); if (ctx->nd_fd == -1) return -1; +#else + if ((ctx->nd_fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) == -1) + return -1; + if ((on = fcntl(ctx->nd_fd, F_GETFD, 0)) == -1 || + fcntl(ctx->nd_fd, F_SETFD, on | FD_CLOEXEC) == -1) + { + close(ctx->nd_fd); + ctx->nd_fd = -1; + return -1; + } + if ((on = fcntl(ctx->nd_fd, F_GETFL, 0)) == -1 || + fcntl(ctx->nd_fd, F_SETFL, on | O_NONBLOCK) == -1) + { + close(ctx->nd_fd); + ctx->nd_fd = -1; + return -1; + } +#endif on = 1; if (setsockopt(ctx->nd_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, @@ -210,9 +230,31 @@ unspec: ICMP6_FILTER_SETBLOCKALL(&filt); /* We send DAD requests from the unspecified address. */ - ctx->unspec_fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); +#ifdef SOCK_CLOEXEC + ctx->unspec_fd = socket(AF_INET6, + SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, + IPPROTO_ICMPV6); if (ctx->unspec_fd == -1) - goto eexit; + return -1; +#else + if ((ctx->unspec_fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) == -1) + return -1; + if ((on = fcntl(ctx->unspec_fd, F_GETFD, 0)) == -1 || + fcntl(ctx->unspec_fd, F_SETFD, on | FD_CLOEXEC) == -1) + { + close(ctx->unspec_fd); + ctx->unspec_fd = -1; + return -1; + } + if ((on = fcntl(ctx->unspec_fd, F_GETFL, 0)) == -1 || + fcntl(ctx->unspec_fd, F_SETFL, on | O_NONBLOCK) == -1) + { + close(ctx->unspec_fd); + ctx->unspec_fd = -1; + return -1; + } +#endif + if (setsockopt(ctx->unspec_fd, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, sizeof(filt)) == -1) goto eexit;