summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2016-11-08 20:46:05 +0100
committerDavid Lamparter <equinox@opensourcerouting.org>2016-11-09 13:40:05 +0100
commit2da59394ec858ae5aecf2b26ab8d9fefdae17bb8 (patch)
tree720795e72480f81c7f1cbabe1445bbd4ba8acc1c /lib
parent73ea75daa522a43ad0be9bff1f26a98bc2e105b0 (diff)
lib: add and use set_cloexec()
watchquagga is already leaking an open file descriptor on its pid file on fork+exec() invocations; next up is adding vtysh support with even more fds. Mark things CLOEXEC before going there. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/network.c14
-rw-r--r--lib/network.h2
-rw-r--r--lib/pid_output.c3
-rw-r--r--lib/vty.c8
4 files changed, 26 insertions, 1 deletions
diff --git a/lib/network.c b/lib/network.c
index 5379ecb5a6..506e019136 100644
--- a/lib/network.c
+++ b/lib/network.c
@@ -94,6 +94,20 @@ set_nonblocking(int fd)
return 0;
}
+int
+set_cloexec(int fd)
+{
+ int flags;
+ flags = fcntl(fd, F_GETFD, 0);
+ if (flags == -1)
+ return -1;
+
+ flags |= FD_CLOEXEC;
+ if (fcntl(fd, F_SETFD, flags) == -1)
+ return -1;
+ return 0;
+}
+
float
htonf (float host)
{
diff --git a/lib/network.h b/lib/network.h
index 0fcb575d1c..a9126caf7f 100644
--- a/lib/network.h
+++ b/lib/network.h
@@ -33,6 +33,8 @@ extern int writen (int, const u_char *, int);
-1 on error. */
extern int set_nonblocking(int fd);
+extern int set_cloexec(int fd);
+
/* Does the I/O error indicate that the operation should be retried later? */
#define ERRNO_IO_RETRY(EN) \
(((EN) == EAGAIN) || ((EN) == EWOULDBLOCK) || ((EN) == EINTR))
diff --git a/lib/pid_output.c b/lib/pid_output.c
index 5261babc6d..de4c2fba99 100644
--- a/lib/pid_output.c
+++ b/lib/pid_output.c
@@ -24,6 +24,7 @@
#include <fcntl.h>
#include <log.h>
#include "version.h"
+#include "network.h"
#define PIDFILE_MASK 0644
#ifndef HAVE_FCNTL
@@ -84,6 +85,8 @@ pid_output (const char *path)
umask(oldumask);
memset (&lock, 0, sizeof(lock));
+ set_cloexec(fd);
+
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
diff --git a/lib/vty.c b/lib/vty.c
index 171aca1739..10ae99db07 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -1841,6 +1841,7 @@ vty_accept (struct thread *thread)
return -1;
}
set_nonblocking(vty_sock);
+ set_cloexec(vty_sock);
sockunion2hostprefix (&su, &p);
@@ -1939,6 +1940,7 @@ vty_serv_sock_addrinfo (const char *hostname, unsigned short port)
sockopt_v6only (ainfo->ai_family, sock);
sockopt_reuseaddr (sock);
sockopt_reuseport (sock);
+ set_cloexec (sock);
ret = bind (sock, ainfo->ai_addr, ainfo->ai_addrlen);
if (ret < 0)
@@ -2006,6 +2008,7 @@ vty_serv_sock_family (const char* addr, unsigned short port, int family)
/* This is server, so reuse address. */
sockopt_reuseaddr (accept_sock);
sockopt_reuseport (accept_sock);
+ set_cloexec (accept_sock);
/* Bind socket to universal address and given port. */
ret = sockunion_bind (accept_sock, &su, port, naddr);
@@ -2068,6 +2071,8 @@ vty_serv_un (const char *path)
len = sizeof (serv.sun_family) + strlen (serv.sun_path);
#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
+ set_cloexec (sock);
+
ret = bind (sock, (struct sockaddr *) &serv, len);
if (ret < 0)
{
@@ -2135,7 +2140,8 @@ vtysh_accept (struct thread *thread)
close (sock);
return -1;
}
-
+ set_cloexec(sock);
+
#ifdef VTYSH_DEBUG
printf ("VTY shell accept\n");
#endif /* VTYSH_DEBUG */