From: Roy Marples Date: Fri, 11 Mar 2016 13:44:42 +0000 (+0000) Subject: Fix compile on older platforms which lack O_CLOEXEC. X-Git-Tag: v6.10.2~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9843976ae092495eb37e397a6f36432411010d00;p=thirdparty%2Fdhcpcd.git Fix compile on older platforms which lack O_CLOEXEC. Thanks to OBATA Akio. --- diff --git a/common.c b/common.c index c3224b49..27a47b6e 100644 --- a/common.c +++ b/common.c @@ -69,7 +69,7 @@ logger_open(struct dhcpcd_ctx *ctx) warn("open: %s", ctx->logfile); #ifndef O_CLOEXEC else { - if (fcntl(ctx->log_fd, F_GETFD, &f) == -1 || + if ((f = fcntl(ctx->log_fd, F_GETFD)) == -1 || fcntl(ctx->log_fd, F_SETFD, f | FD_CLOEXEC) == -1) warn("fcntl: %s", ctx->logfile); } diff --git a/control.c b/control.c index 540f4b4c..273cc142 100644 --- a/control.c +++ b/control.c @@ -208,8 +208,10 @@ make_sock(struct sockaddr_un *sa, const char *ifname, int unpriv) { int fd; - if ((fd = xsocket(AF_UNIX, SOCK_STREAM, 0, O_NONBLOCK|O_CLOEXEC)) == -1) +#define SOCK_FLAGS SOCK_CLOEXEC | SOCK_NONBLOCK + if ((fd = xsocket(AF_UNIX, SOCK_STREAM, 0, SOCK_FLAGS)) == -1) return -1; +#undef SOCK_FLAGS memset(sa, 0, sizeof(*sa)); sa->sun_family = AF_UNIX; if (unpriv) diff --git a/dhcp.c b/dhcp.c index b098b9a4..3893675c 100644 --- a/dhcp.c +++ b/dhcp.c @@ -1489,7 +1489,7 @@ dhcp_openudp(struct interface *ifp) char *p; #endif - if ((s = xsocket(PF_INET, SOCK_DGRAM, IPPROTO_UDP, O_CLOEXEC)) == -1) + if ((s = xsocket(PF_INET, SOCK_DGRAM, IPPROTO_UDP, SOCK_CLOEXEC)) == -1) return -1; n = 1; diff --git a/dhcp6.c b/dhcp6.c index ec300959..057654a5 100644 --- a/dhcp6.c +++ b/dhcp6.c @@ -3135,8 +3135,9 @@ dhcp6_open(struct dhcpcd_ctx *dctx) #endif ctx = dctx->ipv6; - ctx->dhcp_fd = xsocket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP, - O_NONBLOCK|O_CLOEXEC); +#define SOCK_FLAGS SOCK_CLOEXEC | SOCK_NONBLOCK + ctx->dhcp_fd = xsocket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP, SOCK_FLAGS); +#undef SOCK_FLAGS if (ctx->dhcp_fd == -1) return -1; diff --git a/dhcpcd.c b/dhcpcd.c index 23af13f7..079e0b14 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -1859,7 +1859,7 @@ printpidfile: } #endif #ifndef O_CLOEXEC - if (fcntl(ctx.pid_fd, F_GETFD, &opt) == -1 || + if ((opt = fcntl(ctx.pid_fd, F_GETFD)) == -1 || fcntl(ctx.pid_fd, F_SETFD, opt | FD_CLOEXEC) == -1) { logger(&ctx, LOG_ERR, "fcntl: %m"); diff --git a/if-bsd.c b/if-bsd.c index 74b3c8df..4db0a0b0 100644 --- a/if-bsd.c +++ b/if-bsd.c @@ -124,7 +124,7 @@ int if_openlinksocket(void) { - return xsocket(PF_ROUTE, SOCK_RAW, 0, O_NONBLOCK|O_CLOEXEC); + return xsocket(PF_ROUTE, SOCK_RAW, 0, SOCK_NONBLOCK | SOCK_CLOEXEC); } #if defined(INET) || defined(INET6) @@ -292,21 +292,40 @@ if_openrawsocket(struct interface *ifp, uint16_t protocol) #ifdef BIOCIMMEDIATE int flags; #endif +#ifndef O_CLOEXEC + int fd_opts; +#endif + #ifdef _PATH_BPF - fd = open(_PATH_BPF, O_RDWR | O_CLOEXEC | O_NONBLOCK); + fd = open(_PATH_BPF, O_RDWR | O_NONBLOCK +#ifdef O_CLOEXEC + | O_CLOEXEC +#endif + ); #else char device[32]; int n = 0; do { snprintf(device, sizeof(device), "/dev/bpf%d", n++); - fd = open(device, O_RDWR | O_CLOEXEC | O_NONBLOCK); + fd = open(device, O_RDWR | O_NONBLOCK +#ifdef O_CLOEXEC + | O_CLOEXEC +#endif + ); } while (fd == -1 && errno == EBUSY); #endif if (fd == -1) return -1; +#ifndef O_CLOEXEC + if ((fd_opts = fcntl(fd, F_GETFD)) == -1 || + fcntl(fd, F_SETFD, fd_opts | FD_CLOEXEC) == -1) { + close(fd); + return -1; + } +#endif state = IPV4_STATE(ifp); memset(&pv, 0, sizeof(pv)); if (ioctl(fd, BIOCVERSION, &pv) == -1) diff --git a/if-linux.c b/if-linux.c index 0f7143ce..eae9be9b 100644 --- a/if-linux.c +++ b/if-linux.c @@ -249,7 +249,7 @@ _open_link_socket(struct sockaddr_nl *nl, int protocol) { int fd; - if ((fd = xsocket(AF_NETLINK, SOCK_RAW, protocol, O_CLOEXEC)) == -1) + if ((fd = xsocket(AF_NETLINK, SOCK_RAW, protocol, SOCK_CLOEXEC)) == -1) return -1; nl->nl_family = AF_NETLINK; if (bind(fd, (struct sockaddr *)nl, sizeof(*nl)) == -1) { @@ -1191,9 +1191,10 @@ if_openrawsocket(struct interface *ifp, uint16_t protocol) int n; #endif - if ((s = xsocket(PF_PACKET, SOCK_DGRAM, htons(protocol), - O_CLOEXEC | O_NONBLOCK)) == -1) +#define SF SOCK_CLOEXEC | SOCK_NONBLOCK + if ((s = xsocket(PF_PACKET, SOCK_DGRAM, htons(protocol), SF)) == -1) return -1; +#undef SF /* Install the DHCP filter */ memset(&pf, 0, sizeof(pf)); diff --git a/if.c b/if.c index 1b902479..1acff974 100644 --- a/if.c +++ b/if.c @@ -93,19 +93,19 @@ if_opensockets(struct dhcpcd_ctx *ctx) return -1; /* We use this socket for some operations without INET. */ - ctx->pf_inet_fd = xsocket(PF_INET, SOCK_DGRAM, 0, O_CLOEXEC); + ctx->pf_inet_fd = xsocket(PF_INET, SOCK_DGRAM, 0, SOCK_CLOEXEC); if (ctx->pf_inet_fd == -1) return -1; #if defined(INET6) && defined(BSD) - ctx->pf_inet6_fd = xsocket(PF_INET6, SOCK_DGRAM, 0, O_CLOEXEC); + ctx->pf_inet6_fd = xsocket(PF_INET6, SOCK_DGRAM, 0, SOCK_CLOEXEC); /* Don't return an error so we at least work on kernels witout INET6 * even though we expect INET6 support. * We will fail noisily elsewhere anyway. */ #endif #ifdef IFLR_ACTIVE - ctx->pf_link_fd = xsocket(PF_LINK, SOCK_DGRAM, 0, O_CLOEXEC); + ctx->pf_link_fd = xsocket(PF_LINK, SOCK_DGRAM, 0, SOCK_CLOEXEC); if (ctx->pf_link_fd == -1) return -1; #endif @@ -675,25 +675,37 @@ if_sortinterfaces(struct dhcpcd_ctx *ctx) int xsocket(int domain, int type, int protocol, int flags) { -#ifdef SOCK_CLOEXEC - if (flags & O_CLOEXEC) + int s; +#if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK) + int xflags; +#endif + +#ifdef HAVE_SOCK_CLOEXEC + if (flags & SOCK_CLOEXEC) type |= SOCK_CLOEXEC; - if (flags & O_NONBLOCK) +#endif +#ifdef HAVE_SOCK_NONBLOCK + if (flags & SOCK_NONBLOCK) type |= SOCK_NONBLOCK; - - return socket(domain, type, protocol); -#else - int s, xflags; +#endif if ((s = socket(domain, type, protocol)) == -1) return -1; - if ((flags & O_CLOEXEC) && ((xflags = fcntl(s, F_GETFD, 0)) == -1 || + +#ifndef HAVE_SOCK_CLOEXEC + if ((flags & SOCK_CLOEXEC) && ((xflags = fcntl(s, F_GETFD)) == -1 || fcntl(s, F_SETFD, xflags | FD_CLOEXEC) == -1)) goto out; - if ((flags & O_NONBLOCK) && ((xflags = fcntl(s, F_GETFL, 0)) == -1 || +#endif +#ifndef HAVE_SOCK_NONBLOCK + if ((flags & SOCK_NONBLOCK) && ((xflags = fcntl(s, F_GETFL)) == -1 || fcntl(s, F_SETFL, xflags | O_NONBLOCK) == -1)) goto out; +#endif + return s; + +#if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK) out: close(s); return -1; diff --git a/if.h b/if.h index 379a5a94..62de36f3 100644 --- a/if.h +++ b/if.h @@ -114,6 +114,19 @@ int if_managelink(struct dhcpcd_ctx *); #define RTM_GET 0x4 /* Report Metrics */ #endif +/* Define SOCK_CLOEXEC and SOCK_NONBLOCK for systems that lack it. + * xsocket() in if.c will map them to fctnl FD_CLOEXEC and O_NONBLOCK. */ +#ifdef SOCK_CLOEXEC +# define HAVE_SOCK_CLOEXEC +#else +# define SOCK_CLOEXEC 0x10000000 +#endif +#ifdef SOCK_NONBLOCK +# define HAVE_SOCK_NONBLOCK +#else +# define SOCK_NONBLOCK 0x20000000 +#endif + #ifdef INET extern const char *if_pfname; int if_openrawsocket(struct interface *, uint16_t); diff --git a/ipv6.h b/ipv6.h index 35e9f075..33a620d0 100644 --- a/ipv6.h +++ b/ipv6.h @@ -221,7 +221,8 @@ struct ipv6_state { #define IPV6_STATE_RUNNING(ifp) ipv6_staticdadcompleted((ifp)) /* dhcpcd requires CMSG_SPACE to evaluate to a compile time constant. */ -#ifdef __QNX__ +#if defined(__QNX) || \ + (defined(__NetBSD_Version__) && __NetBSD_Version__ < 600000000) #undef CMSG_SPACE #endif diff --git a/ipv6nd.c b/ipv6nd.c index 010a8d96..84af56ac 100644 --- a/ipv6nd.c +++ b/ipv6nd.c @@ -189,8 +189,9 @@ ipv6nd_open(struct dhcpcd_ctx *dctx) ctx = dctx->ipv6; if (ctx->nd_fd != -1) return ctx->nd_fd; - ctx->nd_fd = xsocket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, - O_NONBLOCK|O_CLOEXEC); +#define SOCK_FLAGS SOCK_CLOEXEC | SOCK_NONBLOCK + ctx->nd_fd = xsocket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, SOCK_FLAGS); +#undef SOCK_FLAGS if (ctx->nd_fd == -1) return -1;