Thanks to OBATA Akio.
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);
}
{
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)
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;
#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;
}
#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");
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)
#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)
{
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) {
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));
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
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;
#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);
#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
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;