From 3a7ea6b21781c58b5843db3bac63bf1e57d2178c Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 6 May 2021 14:38:35 -0600 Subject: [PATCH] use poll(2) rather than select(2) for reading output from an exec'ed process select(2) can only handle file descriptors up to 1024, and there are fairly easy to reproduce cases where the file descriptor used here is larger than that. --- libs/pbd/system_exec.cc | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/libs/pbd/system_exec.cc b/libs/pbd/system_exec.cc index 6e66b134c2..87ca6c803a 100644 --- a/libs/pbd/system_exec.cc +++ b/libs/pbd/system_exec.cc @@ -18,6 +18,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include #include #include #include @@ -835,17 +836,28 @@ SystemExec::output_interposer () for (;fcntl (rfd, F_GETFL) != -1;) { r = read (rfd, buf, BUFSIZ - 1); if (r < 0 && (errno == EINTR || errno == EAGAIN)) { - fd_set rfds; - struct timeval tv; - FD_ZERO (&rfds); - FD_SET (rfd, &rfds); - tv.tv_sec = 0; - tv.tv_usec = 10000; - int rv = select (1, &rfds, NULL, NULL, &tv); + + /* wait till ready to read */ + + struct pollfd pfd; + + pfd.fd = rfd; + pfd.events = POLLIN|POLLERR|POLLHUP; + + int rv = poll (&pfd, 1, 10000); + if (rv == -1) { break; } - continue; + + if (pfd.revents & (POLLERR|POLLHUP)) { + break; + } + + if (rv == 1 && pfd.revents & POLLIN) { + /* back to read(2) call */ + continue; + } } if (r <= 0) { break;