]> granicus.if.org Git - icinga2/commitdiff
Use non-blocking open() for the command pipe
authorGunnar Beutner <gunnar@beutner.name>
Mon, 9 Nov 2015 19:39:26 +0000 (20:39 +0100)
committerGunnar Beutner <gunnar@beutner.name>
Mon, 9 Nov 2015 19:39:26 +0000 (20:39 +0100)
fixes #10410

lib/base/utility.cpp
lib/base/utility.hpp
lib/compat/externalcommandlistener.cpp

index 5e2ff7d6d23fcc956fb2acece36e5529b2d1e922..1101b4cba58db57ef586da8b8f1a7814277713ef 100644 (file)
@@ -806,7 +806,7 @@ bool Utility::SetFileOwnership(const String& file, const String& user, const Str
 }
 
 #ifndef _WIN32
-void Utility::SetNonBlocking(int fd)
+void Utility::SetNonBlocking(int fd, bool nb)
 {
        int flags = fcntl(fd, F_GETFL, 0);
 
@@ -816,14 +816,19 @@ void Utility::SetNonBlocking(int fd)
                    << boost::errinfo_errno(errno));
        }
 
-       if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
+       if (nb)
+               flags |= O_NONBLOCK;
+       else
+               flags &= ~O_NONBLOCK;
+
+       if (fcntl(fd, F_SETFL, flags) < 0) {
                BOOST_THROW_EXCEPTION(posix_error()
                    << boost::errinfo_api_function("fcntl")
                    << boost::errinfo_errno(errno));
        }
 }
 
-void Utility::SetCloExec(int fd)
+void Utility::SetCloExec(int fd, bool cloexec)
 {
        int flags = fcntl(fd, F_GETFD, 0);
 
@@ -833,7 +838,12 @@ void Utility::SetCloExec(int fd)
                    << boost::errinfo_errno(errno));
        }
 
-       if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
+       if (cloexec)
+               flags |= FD_CLOEXEC;
+       else
+               flags &= ~FD_CLOEXEC;
+
+       if (fcntl(fd, F_SETFD, flags) < 0) {
                BOOST_THROW_EXCEPTION(posix_error()
                    << boost::errinfo_api_function("fcntl")
                    << boost::errinfo_errno(errno));
@@ -841,13 +851,13 @@ void Utility::SetCloExec(int fd)
 }
 #endif /* _WIN32 */
 
-void Utility::SetNonBlockingSocket(SOCKET s)
+void Utility::SetNonBlockingSocket(SOCKET s, bool nb)
 {
 #ifndef _WIN32
-       SetNonBlocking(s);
+       SetNonBlocking(s, nb);
 #else /* _WIN32 */
-       unsigned long lTrue = 1;
-       ioctlsocket(s, FIONBIO, &lTrue);
+       unsigned long lflag = nb;
+       ioctlsocket(s, FIONBIO, &lflag);
 #endif /* _WIN32 */
 }
 
index 8f386b05230413d50771046485fef7f27e2c83a5..0dbfc6e604a0ed25ea9f1b17e71000cf27b82037 100644 (file)
@@ -96,11 +96,11 @@ public:
        static String FormatErrorNumber(int code);
 
 #ifndef _WIN32
-       static void SetNonBlocking(int fd);
-       static void SetCloExec(int fd);
+       static void SetNonBlocking(int fd, bool nb = true);
+       static void SetCloExec(int fd, bool cloexec = true);
 #endif /* _WIN32 */
 
-       static void SetNonBlockingSocket(SOCKET s);
+       static void SetNonBlockingSocket(SOCKET s, bool nb = true);
 
        static String EscapeShellCmd(const String& s);
        static String EscapeShellArg(const String& s);
index 8785ba5249db52f63d2a0e80bc25fb180689370a..15df2b782a22c1ab79cf834c123bcf2f23796f64 100644 (file)
@@ -94,11 +94,7 @@ void ExternalCommandListener::CommandPipeThread(const String& commandPath)
        }
 
        for (;;) {
-               int fd;
-
-               do {
-                       fd = open(commandPath.CStr(), O_RDONLY);
-               } while (fd < 0 && errno == EINTR);
+               int fd = open(commandPath.CStr(), O_RDONLY | O_NONBLOCK);
 
                if (fd < 0) {
                        Log(LogCritical, "ExternalCommandListener")
@@ -106,6 +102,8 @@ void ExternalCommandListener::CommandPipeThread(const String& commandPath)
                        return;
                }
 
+               Utility::SetNonBlocking(fd, false);
+
                FILE *fp = fdopen(fd, "r");
 
                if (fp == NULL) {