[icinga-checkins] icinga.org: icinga2/master: Refactor the FD_CLOEXEC/O_NONBLOCK code.

git at icinga.org git at icinga.org
Wed Feb 13 13:03:49 CET 2013


Module: icinga2
Branch: master
Commit: 26e2da7a7d992844801f2e527b3b62c204133498
URL:    https://git.icinga.org/?p=icinga2.git;a=commit;h=26e2da7a7d992844801f2e527b3b62c204133498

Author: Gunnar Beutner <gunnar.beutner at netways.de>
Date:   Wed Feb 13 13:03:21 2013 +0100

Refactor the FD_CLOEXEC/O_NONBLOCK code.

---

 lib/base/application.cpp  |   18 +---------------
 lib/base/process-unix.cpp |   50 ++++++++++++++++----------------------------
 lib/base/socket.cpp       |   14 ++---------
 lib/base/utility.cpp      |   32 ++++++++++++++++++++++++++++
 lib/base/utility.h        |    7 ++++++
 5 files changed, 61 insertions(+), 60 deletions(-)

diff --git a/lib/base/application.cpp b/lib/base/application.cpp
index 9632c2a..b7a99b6 100644
--- a/lib/base/application.cpp
+++ b/lib/base/application.cpp
@@ -456,23 +456,7 @@ void Application::UpdatePidFile(const String& filename)
 		BOOST_THROW_EXCEPTION(runtime_error("Could not open PID file '" + filename + "'"));
 
 #ifndef _WIN32
-	int flags;
-	flags = fcntl(fileno(m_PidFile), F_GETFD, 0);
-	if (flags < 0)
-		BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
-
-	if (fcntl(fileno(m_PidFile), F_SETFD, flags | FD_CLOEXEC) < 0)
-		BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
-
-	if (flock(fileno(m_PidFile), LOCK_EX | LOCK_NB) < 0) {
-		ClosePidFile();
-
-		Logger::Write(LogCritical, "base",
-		    "Another instance of the application is "
-		    "already running. Remove the '" + filename + "' file if "
-		    "you're certain that this is not the case.");
-		Terminate(EXIT_FAILURE);
-	}
+	Utility::SetCloExec(fileno(m_PidFile));
 #endif /* _WIN32 */
 
 	fprintf(m_PidFile, "%d", Utility::GetPid());
diff --git a/lib/base/process-unix.cpp b/lib/base/process-unix.cpp
index 2c89c4c..88c5602 100644
--- a/lib/base/process-unix.cpp
+++ b/lib/base/process-unix.cpp
@@ -30,34 +30,30 @@ void Process::CreateWorkers(void)
 {
 	int fds[2];
 
+#ifdef HAVE_PIPE2
+	if (pipe2(fds, O_NONBLOCK | O_CLOEXEC) < 0)
+		BOOST_THROW_EXCEPTION(PosixException("pipe2() failed.", errno));
+#else /* HAVE_PIPE2 */
 	if (pipe(fds) < 0)
 		BOOST_THROW_EXCEPTION(PosixException("pipe() failed.", errno));
 
-	m_TaskFd = fds[1];
+	/* Don't bother setting fds[1] to non-blocking/clo-exec as we'll only
+	 * use it in the following dup() call. */
 
-	int flags;
-	flags = fcntl(fds[1], F_GETFD, 0);
-	if (flags < 0)
-		BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
+	Utility::SetNonBlocking(fds[1]);
+	Utility::SetCloExec(fds[1]);
+#endif /* HAVE_PIPE2 */
 
-	if (fcntl(fds[1], F_SETFD, flags | O_NONBLOCK | FD_CLOEXEC) < 0)
-		BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
+	m_TaskFd = fds[1];
 
 	for (int i = 0; i < thread::hardware_concurrency(); i++) {
-		int childTaskFd;
-
-		childTaskFd = dup(fds[0]);
+		int childTaskFd = dup(fds[0]);
 
 		if (childTaskFd < 0)
 			BOOST_THROW_EXCEPTION(PosixException("dup() failed.", errno));
 
-		int flags;
-		flags = fcntl(childTaskFd, F_GETFD, 0);
-		if (flags < 0)
-			BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
-
-		if (fcntl(childTaskFd, F_SETFD, flags | O_NONBLOCK | FD_CLOEXEC) < 0)
-			BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
+		Utility::SetNonBlocking(childTaskFd);
+		Utility::SetCloExec(childTaskFd);
 
 		thread t(&Process::WorkerThreadProc, childTaskFd);
 		t.detach();
@@ -179,26 +175,16 @@ void Process::InitTask(void)
 
 #ifdef HAVE_PIPE2
 	if (pipe2(fds, O_NONBLOCK | O_CLOEXEC) < 0)
+		BOOST_THROW_EXCEPTION(PosixException("pipe2() failed.", errno));
 #else /* HAVE_PIPE2 */
 	if (pipe(fds) < 0)
-#endif /* HAVE_PIPE2 */
 		BOOST_THROW_EXCEPTION(PosixException("pipe() failed.", errno));
 
-#ifndef HAVE_PIPE2
-	int flags;
-	flags = fcntl(fds[0], F_GETFD, 0);
-	if (flags < 0)
-		BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
-
-	if (fcntl(fds[0], F_SETFD, flags | O_NONBLOCK | FD_CLOEXEC) < 0)
-		BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
-
-	flags = fcntl(fds[1], F_GETFD, 0);
-	if (flags < 0)
-		BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
+	Utility::SetNonBlocking(fds[0]);
+	Utility::SetCloExec(fds[0]);
 
-	if (fcntl(fds[1], F_SETFD, flags | O_NONBLOCK | FD_CLOEXEC) < 0)
-		BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
+	Utility::SetNonBlocking(fds[1]);
+	Utility::SetCloExec(fds[1]);
 #endif /* HAVE_PIPE2 */
 
 	// build argv
diff --git a/lib/base/socket.cpp b/lib/base/socket.cpp
index 286548f..466c195 100644
--- a/lib/base/socket.cpp
+++ b/lib/base/socket.cpp
@@ -70,17 +70,9 @@ void Socket::SetFD(SOCKET fd)
 {
 	/* mark the socket as non-blocking and close-on-exec */
 	if (fd != INVALID_SOCKET) {
+		Utility::SetNonBlockingSocket(fd);
 #ifndef _WIN32
-		int flags;
-		flags = fcntl(fd, F_GETFD, 0);
-		if (flags < 0)
-			BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
-
-		if (fcntl(fd, F_SETFD, flags | O_NONBLOCK | FD_CLOEXEC) < 0)
-			BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
-#else /* _WIN32 */
-		unsigned long lTrue = 1;
-		ioctlsocket(fd, FIONBIO, &lTrue);
+		Utility::SetCloExec(fd);
 #endif /* _WIN32 */
 	}
 
@@ -219,7 +211,7 @@ String Socket::GetPeerAddress(void)
  * @param message The error message.
  * @param errorCode The error code.
  */
-SocketException::SocketException(const String& message, int errorCode)	
+SocketException::SocketException(const String& message, int errorCode)
 {
 #ifdef _WIN32
 	String details = Win32Exception::FormatErrorCode(errorCode);
diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp
index e8b9de8..1cecfc3 100644
--- a/lib/base/utility.cpp
+++ b/lib/base/utility.cpp
@@ -526,3 +526,35 @@ void Utility::WaitUntil(const function<bool (void)>& predicate)
 		Application::ProcessEvents();
 }
 
+void Utility::SetNonBlocking(int fd)
+{
+	int flags;
+	flags = fcntl(fd, F_GETFL, 0);
+	if (flags < 0)
+		BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
+
+	if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0)
+		BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
+}
+
+void Utility::SetCloExec(int fd)
+{
+	int flags;
+	flags = fcntl(fd, F_GETFD, 0);
+	if (flags < 0)
+		BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
+
+	if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
+		BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
+}
+
+void Utility::SetNonBlockingSocket(SOCKET s)
+{
+#ifndef _WIN32
+	SetNonBlocking(s);
+#else /* _WIN32 */
+	unsigned long lTrue = 1;
+	ioctlsocket(s, FIONBIO, &lTrue);
+#endif /* _WIN32 */
+}
+
diff --git a/lib/base/utility.h b/lib/base/utility.h
index 3638d12..fabd99f 100644
--- a/lib/base/utility.h
+++ b/lib/base/utility.h
@@ -68,6 +68,13 @@ public:
 #endif /* _WIN32 */
 	LoadIcingaLibrary(const String& library, bool module);
 
+#ifndef _WIN32
+	static void SetNonBlocking(int fd);
+	static void SetCloExec(int fd);
+#endif /* _WIN32 */
+
+	static void SetNonBlockingSocket(SOCKET s);
+
 private:
 	static bool m_SSLInitialized;
 





More information about the icinga-checkins mailing list