From 0a6505ce2d778d46863345ad7b457cbe911a3176 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 10 Nov 2015 11:41:21 +0100 Subject: [PATCH] Use poll() for the command pipe fd refs #10410 --- lib/base/socket.cpp | 16 +++++++-- lib/compat/externalcommandlistener.cpp | 48 ++++++++++++-------------- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/lib/base/socket.cpp b/lib/base/socket.cpp index 0289d4258..c51052f42 100644 --- a/lib/base/socket.cpp +++ b/lib/base/socket.cpp @@ -262,7 +262,13 @@ void Socket::Listen(void) */ size_t Socket::Write(const void *buffer, size_t count) { - int rc = send(GetFD(), (const char *)buffer, count, 0); + int rc; + +#ifndef _WIN32 + rc = write(GetFD(), (const char *)buffer, count); +#else /* _WIN32 */ + rc = send(GetFD(), (const char *)buffer, count, 0); +#endif /* _WIN32 */ if (rc < 0) { #ifndef _WIN32 @@ -290,7 +296,13 @@ size_t Socket::Write(const void *buffer, size_t count) */ size_t Socket::Read(void *buffer, size_t count) { - int rc = recv(GetFD(), (char *)buffer, count, 0); + int rc; + +#ifndef _WIN32 + rc = read(GetFD(), (char *)buffer, count); +#else /* _WIN32 */ + rc = recv(GetFD(), (char *)buffer, count); +#endif /* _WIN32 */ if (rc < 0) { #ifndef _WIN32 diff --git a/lib/compat/externalcommandlistener.cpp b/lib/compat/externalcommandlistener.cpp index 15df2b782..0b1c6bcbf 100644 --- a/lib/compat/externalcommandlistener.cpp +++ b/lib/compat/externalcommandlistener.cpp @@ -102,40 +102,38 @@ void ExternalCommandListener::CommandPipeThread(const String& commandPath) return; } - Utility::SetNonBlocking(fd, false); + FIFO::Ptr fifo = new FIFO(); + Socket::Ptr sock = new Socket(fd); + StreamReadContext src; - FILE *fp = fdopen(fd, "r"); + for (;;) { + sock->Poll(true, false); - if (fp == NULL) { - Log(LogCritical, "ExternalCommandListener") - << "fdopen() for fifo path '" << commandPath << "' failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\""; - return; - } + char buffer[8192]; + size_t rc = sock->Read(buffer, sizeof(buffer)); + if (rc <= 0) + break; - const int linesize = 128 * 1024; - char *line = new char[linesize]; + fifo->Write(buffer, rc); - while (fgets(line, linesize, fp) != NULL) { - // remove trailing new-line - while (strlen(line) > 0 && - (line[strlen(line) - 1] == '\r' || line[strlen(line) - 1] == '\n')) - line[strlen(line) - 1] = '\0'; + for (;;) { + String command; + StreamReadStatus srs = fifo->ReadLine(&command, src); - String command = line; + if (srs != StatusNewItem) + break; - try { - Log(LogInformation, "ExternalCommandListener") - << "Executing external command: " << command; + try { + Log(LogInformation, "ExternalCommandListener") + << "Executing external command: " << command; - ExternalCommandProcessor::Execute(command); - } catch (const std::exception& ex) { - Log(LogWarning, "ExternalCommandListener") - << "External command failed." << DiagnosticInformation(ex); + ExternalCommandProcessor::Execute(command); + } catch (const std::exception& ex) { + Log(LogWarning, "ExternalCommandListener") + << "External command failed." << DiagnosticInformation(ex); + } } } - - delete [] line; - fclose(fp); } } #endif /* _WIN32 */ -- 2.40.0