}
#ifndef _WIN32
-void Utility::SetNonBlocking(int fd)
+void Utility::SetNonBlocking(int fd, bool nb)
{
int flags = fcntl(fd, F_GETFL, 0);
<< 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);
<< 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));
}
#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 */
}
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);
}
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")
return;
}
+ Utility::SetNonBlocking(fd, false);
+
FILE *fp = fdopen(fd, "r");
if (fp == NULL) {