Use non-blocking open() for the command pipe

fixes #10410
This commit is contained in:
Gunnar Beutner 2015-11-09 20:39:26 +01:00
parent 2cf0df2675
commit 9ea51aa86e
3 changed files with 24 additions and 16 deletions

View 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 */
}

View 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);

View 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) {