From 9ea51aa86edac407411376d2ed18a494368b9e31 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Mon, 9 Nov 2015 20:39:26 +0100 Subject: [PATCH] Use non-blocking open() for the command pipe fixes #10410 --- lib/base/utility.cpp | 26 ++++++++++++++++++-------- lib/base/utility.hpp | 6 +++--- lib/compat/externalcommandlistener.cpp | 8 +++----- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp index 5e2ff7d6d..1101b4cba 100644 --- a/lib/base/utility.cpp +++ b/lib/base/utility.cpp @@ -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 */ } diff --git a/lib/base/utility.hpp b/lib/base/utility.hpp index 8f386b052..0dbfc6e60 100644 --- a/lib/base/utility.hpp +++ b/lib/base/utility.hpp @@ -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); diff --git a/lib/compat/externalcommandlistener.cpp b/lib/compat/externalcommandlistener.cpp index 8785ba524..15df2b782 100644 --- a/lib/compat/externalcommandlistener.cpp +++ b/lib/compat/externalcommandlistener.cpp @@ -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) { -- 2.40.0