Rex Dieter 8ec4a9e
diff -up qt-everywhere-opensource-src-4.8.6/src/corelib/io/qprocess_unix.cpp.poll qt-everywhere-opensource-src-4.8.6/src/corelib/io/qprocess_unix.cpp
Rex Dieter 8ec4a9e
--- qt-everywhere-opensource-src-4.8.6/src/corelib/io/qprocess_unix.cpp.poll	2014-03-30 15:36:48.000000000 -0500
Rex Dieter 8ec4a9e
+++ qt-everywhere-opensource-src-4.8.6/src/corelib/io/qprocess_unix.cpp	2014-03-31 18:04:05.958260978 -0500
Rex Dieter 8ec4a9e
@@ -158,13 +158,6 @@ static void qt_sa_sigchld_sigaction(int
Rex Dieter 8ec4a9e
     }
8e4c02d
 }
8e4c02d
 
8e4c02d
-static inline void add_fd(int &nfds, int fd, fd_set *fdset)
8e4c02d
-{
8e4c02d
-    FD_SET(fd, fdset);
8e4c02d
-    if ((fd) > nfds)
8e4c02d
-        nfds = fd;
8e4c02d
-}
8e4c02d
-
8e4c02d
 struct QProcessInfo {
8e4c02d
     QProcess *process;
8e4c02d
     int deathPipe;
Rex Dieter 8ec4a9e
@@ -256,9 +249,9 @@ QProcessManager::~QProcessManager()
8e4c02d
 void QProcessManager::run()
8e4c02d
 {
8e4c02d
     forever {
8e4c02d
-        fd_set readset;
8e4c02d
-        FD_ZERO(&readset);
8e4c02d
-        FD_SET(qt_qprocess_deadChild_pipe[0], &readset);
8e4c02d
+	pollfd fd;
8e4c02d
+	fd.fd = qt_qprocess_deadChild_pipe[0];
8e4c02d
+	fd.events = POLLIN;
8e4c02d
 
8e4c02d
 #if defined (QPROCESS_DEBUG)
8e4c02d
         qDebug() << "QProcessManager::run() waiting for children to die";
Rex Dieter 8ec4a9e
@@ -267,8 +260,8 @@ void QProcessManager::run()
8e4c02d
         // block forever, or until activity is detected on the dead child
8e4c02d
         // pipe. the only other peers are the SIGCHLD signal handler, and the
8e4c02d
         // QProcessManager destructor.
8e4c02d
-        int nselect = select(qt_qprocess_deadChild_pipe[0] + 1, &readset, 0, 0, 0);
8e4c02d
-        if (nselect < 0) {
8e4c02d
+        int ret = qt_safe_poll(&fd, 1, -1, /* retry_eintr */ false);
8e4c02d
+        if (ret < 0) {
8e4c02d
             if (errno == EINTR)
8e4c02d
                 continue;
8e4c02d
             break;
Rex Dieter 8ec4a9e
@@ -1027,17 +1020,6 @@ void QProcessPrivate::killProcess()
8e4c02d
         ::kill(pid_t(pid), SIGKILL);
8e4c02d
 }
8e4c02d
 
8e4c02d
-static int select_msecs(int nfds, fd_set *fdread, fd_set *fdwrite, int timeout)
8e4c02d
-{
8e4c02d
-    if (timeout < 0)
8e4c02d
-        return qt_safe_select(nfds, fdread, fdwrite, 0, 0);
8e4c02d
-
8e4c02d
-    struct timeval tv;
8e4c02d
-    tv.tv_sec = timeout / 1000;
8e4c02d
-    tv.tv_usec = (timeout % 1000) * 1000;
8e4c02d
-    return qt_safe_select(nfds, fdread, fdwrite, 0, &tv;;
8e4c02d
-}
8e4c02d
-
8e4c02d
 /*
8e4c02d
    Returns the difference between msecs and elapsed. If msecs is -1,
8e4c02d
    however, -1 is returned.
Rex Dieter 8ec4a9e
@@ -1060,10 +1042,10 @@ bool QProcessPrivate::waitForStarted(int
8e4c02d
 	   childStartedPipe[0]);
8e4c02d
 #endif
8e4c02d
 
8e4c02d
-    fd_set fds;
8e4c02d
-    FD_ZERO(&fds);
8e4c02d
-    FD_SET(childStartedPipe[0], &fds);
8e4c02d
-    if (select_msecs(childStartedPipe[0] + 1, &fds, 0, msecs) == 0) {
8e4c02d
+    pollfd fd;
8e4c02d
+    fd.fd = childStartedPipe[0];
8e4c02d
+    fd.events = POLLIN;
8e4c02d
+    if (qt_safe_poll(&fd, 1, msecs) == 0) {
8e4c02d
         processError = QProcess::Timedout;
8e4c02d
         q->setErrorString(QProcess::tr("Process operation timed out"));
8e4c02d
 #if defined (QPROCESS_DEBUG)
Rex Dieter 8ec4a9e
@@ -1079,6 +1061,47 @@ bool QProcessPrivate::waitForStarted(int
8e4c02d
     return startedEmitted;
8e4c02d
 }
8e4c02d
 
8e4c02d
+class QProcessFDSet {
8e4c02d
+    pollfd fds[5];
8e4c02d
+
8e4c02d
+    static size_t size()
8e4c02d
+    {
8e4c02d
+	return sizeof(fds)/sizeof(fds[0]);
8e4c02d
+    }
8e4c02d
+
8e4c02d
+public:
8e4c02d
+    QProcessFDSet(QProcessPrivate &proc)
8e4c02d
+    {
8e4c02d
+	for (size_t i = 0; i < size(); ++i) {
8e4c02d
+	    fds[i].fd = -1;
8e4c02d
+	    fds[i].events = POLLIN;
8e4c02d
+	}
8e4c02d
+	death().fd = proc.deathPipe[0];
8e4c02d
+
8e4c02d
+        if (proc.processState == QProcess::Starting)
8e4c02d
+	    started().fd = proc.childStartedPipe[0];
8e4c02d
+
8e4c02d
+	stdout().fd = proc.stdoutChannel.pipe[0];
8e4c02d
+	stderr().fd = proc.stderrChannel.pipe[0];
8e4c02d
+
8e4c02d
+        if (!proc.writeBuffer.isEmpty()) {
8e4c02d
+	    stdin().fd = proc.stdinChannel.pipe[1];
8e4c02d
+	    stdin().events = POLLOUT;
8e4c02d
+	}
8e4c02d
+    }
8e4c02d
+
8e4c02d
+    int poll(int timeout)
8e4c02d
+    {
8e4c02d
+	return qt_safe_poll(fds, size(), timeout);
8e4c02d
+    }
8e4c02d
+
8e4c02d
+    pollfd &death() { return fds[0]; }
8e4c02d
+    pollfd &started() { return fds[1]; }
8e4c02d
+    pollfd &stdout() { return fds[2]; }
8e4c02d
+    pollfd &stderr() { return fds[3]; }
8e4c02d
+    pollfd &stdin() { return fds[4]; }
8e4c02d
+};
8e4c02d
+
8e4c02d
 bool QProcessPrivate::waitForReadyRead(int msecs)
8e4c02d
 {
8e4c02d
     Q_Q(QProcess);
Rex Dieter 8ec4a9e
@@ -1090,28 +1113,9 @@ bool QProcessPrivate::waitForReadyRead(i
8e4c02d
     stopWatch.start();
8e4c02d
 
8e4c02d
     forever {
8e4c02d
-        fd_set fdread;
8e4c02d
-        fd_set fdwrite;
8e4c02d
-
8e4c02d
-        FD_ZERO(&fdread);
8e4c02d
-        FD_ZERO(&fdwrite);
8e4c02d
-
8e4c02d
-        int nfds = deathPipe[0];
8e4c02d
-        FD_SET(deathPipe[0], &fdread);
8e4c02d
-
8e4c02d
-        if (processState == QProcess::Starting)
8e4c02d
-            add_fd(nfds, childStartedPipe[0], &fdread);
8e4c02d
-
8e4c02d
-        if (stdoutChannel.pipe[0] != -1)
8e4c02d
-            add_fd(nfds, stdoutChannel.pipe[0], &fdread);
8e4c02d
-        if (stderrChannel.pipe[0] != -1)
8e4c02d
-            add_fd(nfds, stderrChannel.pipe[0], &fdread);
8e4c02d
-
8e4c02d
-        if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1)
8e4c02d
-            add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
8e4c02d
-
8e4c02d
+	QProcessFDSet fdset(*this);
8e4c02d
         int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
8e4c02d
-        int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
8e4c02d
+        int ret = fdset.poll(timeout);
8e4c02d
         if (ret < 0) {
8e4c02d
             break;
8e4c02d
         }
Rex Dieter 8ec4a9e
@@ -1121,18 +1125,18 @@ bool QProcessPrivate::waitForReadyRead(i
8e4c02d
 	    return false;
8e4c02d
 	}
8e4c02d
 
8e4c02d
-	if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
8e4c02d
+	if (qt_readable(fdset.started())) {
8e4c02d
             if (!_q_startupNotification())
8e4c02d
                 return false;
8e4c02d
 	}
8e4c02d
 
8e4c02d
         bool readyReadEmitted = false;
8e4c02d
-	if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) {
8e4c02d
+	if (qt_readable(fdset.stdout())) {
8e4c02d
 	    bool canRead = _q_canReadStandardOutput();
8e4c02d
             if (processChannel == QProcess::StandardOutput && canRead)
8e4c02d
                 readyReadEmitted = true;
8e4c02d
 	}
8e4c02d
-	if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) {
8e4c02d
+	if (qt_readable(fdset.stderr())) {
8e4c02d
 	    bool canRead = _q_canReadStandardError();
8e4c02d
             if (processChannel == QProcess::StandardError && canRead)
8e4c02d
                 readyReadEmitted = true;
Rex Dieter 8ec4a9e
@@ -1140,13 +1144,13 @@ bool QProcessPrivate::waitForReadyRead(i
8e4c02d
         if (readyReadEmitted)
8e4c02d
             return true;
8e4c02d
 
8e4c02d
-	if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
8e4c02d
+	if (qt_writable(fdset.stdin()))
8e4c02d
 	    _q_canWrite();
8e4c02d
 
8e4c02d
-	if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
8e4c02d
+	if (qt_readable(fdset.death())) {
8e4c02d
             if (_q_processDied())
8e4c02d
                 return false;
8e4c02d
-        }
8e4c02d
+	}
8e4c02d
     }
8e4c02d
     return false;
8e4c02d
 }
Rex Dieter 8ec4a9e
@@ -1162,29 +1166,9 @@ bool QProcessPrivate::waitForBytesWritte
8e4c02d
     stopWatch.start();
8e4c02d
 
8e4c02d
     while (!writeBuffer.isEmpty()) {
8e4c02d
-        fd_set fdread;
8e4c02d
-        fd_set fdwrite;
8e4c02d
-
8e4c02d
-        FD_ZERO(&fdread);
8e4c02d
-        FD_ZERO(&fdwrite);
8e4c02d
-
8e4c02d
-        int nfds = deathPipe[0];
8e4c02d
-        FD_SET(deathPipe[0], &fdread);
8e4c02d
-
8e4c02d
-        if (processState == QProcess::Starting)
8e4c02d
-            add_fd(nfds, childStartedPipe[0], &fdread);
8e4c02d
-
8e4c02d
-        if (stdoutChannel.pipe[0] != -1)
8e4c02d
-            add_fd(nfds, stdoutChannel.pipe[0], &fdread);
8e4c02d
-        if (stderrChannel.pipe[0] != -1)
8e4c02d
-            add_fd(nfds, stderrChannel.pipe[0], &fdread);
8e4c02d
-
8e4c02d
-
8e4c02d
-        if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1)
8e4c02d
-            add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
8e4c02d
-
8e4c02d
+	QProcessFDSet fdset(*this);
8e4c02d
 	int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
8e4c02d
-	int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
8e4c02d
+	int ret = fdset.poll(timeout);
8e4c02d
         if (ret < 0) {
8e4c02d
             break;
8e4c02d
         }
Rex Dieter 8ec4a9e
@@ -1195,24 +1179,24 @@ bool QProcessPrivate::waitForBytesWritte
8e4c02d
 	    return false;
8e4c02d
 	}
8e4c02d
 
8e4c02d
-	if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
8e4c02d
+	if (qt_readable(fdset.started())) {
8e4c02d
 	    if (!_q_startupNotification())
8e4c02d
 		return false;
8e4c02d
 	}
8e4c02d
 
8e4c02d
-	if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
8e4c02d
+	if (qt_writable(fdset.stdin()))
8e4c02d
 	    return _q_canWrite();
8e4c02d
 
8e4c02d
-	if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread))
8e4c02d
+	if (qt_readable(fdset.stdout()))
8e4c02d
 	    _q_canReadStandardOutput();
8e4c02d
 
8e4c02d
-	if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread))
8e4c02d
+	if (qt_readable(fdset.stderr()))
8e4c02d
 	    _q_canReadStandardError();
8e4c02d
 
8e4c02d
-	if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
8e4c02d
-            if (_q_processDied())
8e4c02d
-                return false;
8e4c02d
-        }
8e4c02d
+	if (qt_readable(fdset.death())) {
8e4c02d
+	    if (_q_processDied())
8e4c02d
+		return false;
8e4c02d
+	}
8e4c02d
     }
8e4c02d
 
8e4c02d
     return false;
Rex Dieter 8ec4a9e
@@ -1229,29 +1213,9 @@ bool QProcessPrivate::waitForFinished(in
8e4c02d
     stopWatch.start();
8e4c02d
 
8e4c02d
     forever {
8e4c02d
-        fd_set fdread;
8e4c02d
-        fd_set fdwrite;
8e4c02d
-        int nfds = -1;
8e4c02d
-
8e4c02d
-        FD_ZERO(&fdread);
8e4c02d
-        FD_ZERO(&fdwrite);
8e4c02d
-
8e4c02d
-        if (processState == QProcess::Starting)
8e4c02d
-            add_fd(nfds, childStartedPipe[0], &fdread);
8e4c02d
-
8e4c02d
-        if (stdoutChannel.pipe[0] != -1)
8e4c02d
-            add_fd(nfds, stdoutChannel.pipe[0], &fdread);
8e4c02d
-        if (stderrChannel.pipe[0] != -1)
8e4c02d
-            add_fd(nfds, stderrChannel.pipe[0], &fdread);
8e4c02d
-
8e4c02d
-        if (processState == QProcess::Running)
8e4c02d
-            add_fd(nfds, deathPipe[0], &fdread);
8e4c02d
-
8e4c02d
-        if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1)
8e4c02d
-            add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
8e4c02d
-
8e4c02d
+	QProcessFDSet fdset(*this);
8e4c02d
 	int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
8e4c02d
-	int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
8e4c02d
+	int ret = fdset.poll(timeout);
8e4c02d
         if (ret < 0) {
8e4c02d
             break;
8e4c02d
         }
Rex Dieter 8ec4a9e
@@ -1261,20 +1225,20 @@ bool QProcessPrivate::waitForFinished(in
8e4c02d
 	    return false;
8e4c02d
 	}
8e4c02d
 
8e4c02d
-	if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
8e4c02d
+	if (qt_readable(fdset.started())) {
8e4c02d
 	    if (!_q_startupNotification())
8e4c02d
 		return false;
8e4c02d
 	}
8e4c02d
-	if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
8e4c02d
+	if (qt_writable(fdset.stdin()))
8e4c02d
 	    _q_canWrite();
8e4c02d
 
8e4c02d
-	if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread))
8e4c02d
+	if (qt_readable(fdset.stdout()))
8e4c02d
 	    _q_canReadStandardOutput();
8e4c02d
 
8e4c02d
-	if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread))
8e4c02d
+	if (qt_readable(fdset.stderr()))
8e4c02d
 	    _q_canReadStandardError();
8e4c02d
 
8e4c02d
-	if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
8e4c02d
+	if (qt_readable(fdset.death())) {
8e4c02d
             if (_q_processDied())
8e4c02d
                 return true;
8e4c02d
 	}
Rex Dieter 8ec4a9e
@@ -1284,10 +1248,10 @@ bool QProcessPrivate::waitForFinished(in
8e4c02d
 
8e4c02d
 bool QProcessPrivate::waitForWrite(int msecs)
8e4c02d
 {
8e4c02d
-    fd_set fdwrite;
8e4c02d
-    FD_ZERO(&fdwrite);
8e4c02d
-    FD_SET(stdinChannel.pipe[1], &fdwrite);
8e4c02d
-    return select_msecs(stdinChannel.pipe[1] + 1, 0, &fdwrite, msecs < 0 ? 0 : msecs) == 1;
8e4c02d
+    pollfd fd;
8e4c02d
+    fd.fd = stdinChannel.pipe[1];
8e4c02d
+    fd.events = POLLIN;
8e4c02d
+    return qt_safe_poll(&fd, 1, msecs);
8e4c02d
 }
8e4c02d
 
8e4c02d
 void QProcessPrivate::findExitCode()
Rex Dieter 8ec4a9e
diff -up qt-everywhere-opensource-src-4.8.6/src/corelib/kernel/qcore_unix.cpp.poll qt-everywhere-opensource-src-4.8.6/src/corelib/kernel/qcore_unix.cpp
Rex Dieter 8ec4a9e
--- qt-everywhere-opensource-src-4.8.6/src/corelib/kernel/qcore_unix.cpp.poll	2014-03-30 15:36:48.000000000 -0500
Rex Dieter 8ec4a9e
+++ qt-everywhere-opensource-src-4.8.6/src/corelib/kernel/qcore_unix.cpp	2014-03-31 18:01:59.369715403 -0500
Rex Dieter 8ec4a9e
@@ -99,4 +99,165 @@ int qt_safe_select(int nfds, fd_set *fdr
8e4c02d
     }
8e4c02d
 }
8e4c02d
 
8e4c02d
+#ifndef Q_OS_VXWORKS
8e4c02d
+
8e4c02d
+int qt_safe_poll(struct pollfd *fds, int nfds, int timeout_ms, bool retry_eintr)
8e4c02d
+{
8e4c02d
+    if (nfds == 0)
8e4c02d
+	return 0;
8e4c02d
+    if (nfds < 0) {
8e4c02d
+	errno = EINVAL;
8e4c02d
+	return -1;
8e4c02d
+    }
8e4c02d
+
8e4c02d
+    // Retry on ret == 0 if the deadline has not yet passed because
8e4c02d
+    // Linux can return early from the syscall, without setting EINTR.
8e4c02d
+    if (timeout_ms < 0) {
8e4c02d
+	forever {
8e4c02d
+	    int ret = ::poll(fds, nfds, -1);
8e4c02d
+	    if (ret > 0)
8e4c02d
+		return ret;
8e4c02d
+	    if (retry_eintr) {
8e4c02d
+		if (ret == 0 || ret == -1 && errno == EINTR) {
8e4c02d
+		    continue;
8e4c02d
+		} else {
8e4c02d
+		    return -1;
8e4c02d
+		}
8e4c02d
+	    }
8e4c02d
+	    if (ret == 0) {
8e4c02d
+		errno = EINTR;
8e4c02d
+		return -1;
8e4c02d
+	    }
8e4c02d
+	    return ret;
8e4c02d
+	}
8e4c02d
+    }
8e4c02d
+
8e4c02d
+    timeval previous = qt_gettime();
8e4c02d
+    timeval deadline = previous;
8e4c02d
+    deadline.tv_sec += timeout_ms / 1000;
8e4c02d
+    deadline.tv_usec += (timeout_ms % 1000) * 1000;
8e4c02d
+    if (deadline.tv_usec >= 1000000) {
8e4c02d
+	++deadline.tv_sec;
8e4c02d
+	deadline.tv_usec -= 1000000;
8e4c02d
+    }
8e4c02d
+    int remaining = timeout_ms;
8e4c02d
+
8e4c02d
+    forever {
8e4c02d
+	int ret = ::poll(fds, nfds, remaining);
8e4c02d
+	if (ret > 0)
8e4c02d
+	    return ret;
8e4c02d
+	timeval now = qt_gettime();
8e4c02d
+	if ((now.tv_sec > deadline.tv_sec // past deadline
8e4c02d
+	     || (now.tv_sec == deadline.tv_sec
8e4c02d
+		 && now.tv_usec >= deadline.tv_usec))
8e4c02d
+	    || (now.tv_sec < previous.tv_sec // time warp
8e4c02d
+		|| (now.tv_sec == previous.tv_sec
8e4c02d
+		    && now.tv_usec < previous.tv_usec))
8e4c02d
+	    || (ret < 0 && (errno != EINTR || !retry_eintr))) // other error
8e4c02d
+	    return ret;
8e4c02d
+	if (ret == 0 && !retry_eintr) {
8e4c02d
+	    errno = EINTR;
8e4c02d
+	    return -1;
8e4c02d
+	}
8e4c02d
+        remaining = (deadline.tv_sec - now.tv_sec) * 1000
8e4c02d
+		     + (deadline.tv_usec - now.tv_usec) / 1000;
8e4c02d
+	previous = now;
8e4c02d
+    }
8e4c02d
+}
8e4c02d
+
8e4c02d
+#else
8e4c02d
+
8e4c02d
+// Poll emulation for VxWorks.
8e4c02d
+
8e4c02d
+static int mark_bad_descriptors(pollfd *fds, int nfds)
8e4c02d
+{
8e4c02d
+    fd_set r;
8e4c02d
+    FD_ZERO(&r);
8e4c02d
+    struct timeval tv;
8e4c02d
+    tv.tv_sec = 0;
8e4c02d
+    tv.tv_usec = 0;
8e4c02d
+    int ret = 0;
8e4c02d
+
8e4c02d
+    // Check each descriptor invidually for badness.
8e4c02d
+    for (int i = 0; i < nfds; ++i) {
8e4c02d
+        pollfd &fd(fds[i]);
8e4c02d
+        if (fd.fd >= 0) {
8e4c02d
+            FD_SET(fd.fd, &r);
8e4c02d
+            int ret = qt_safe_select(fd.fd + 1, &r, NULL, NULL, &tv;;
8e4c02d
+            FD_CLR(fd.fd, &r);
8e4c02d
+            if (ret < 0 && errno == EBADF) {
8e4c02d
+                fd.revents = POLLNVAL;
8e4c02d
+                ++ret;
8e4c02d
+            }
8e4c02d
+        }
8e4c02d
+    }
8e4c02d
+    Q_ASSERT(ret > 0);
8e4c02d
+    return ret;
8e4c02d
+}
8e4c02d
+
8e4c02d
+int qt_safe_poll(pollfd *fds, int nfds, int timeout, bool retry_eintr)
8e4c02d
+{
8e4c02d
+    fd_set r, w;
8e4c02d
+    FD_ZERO(&r);
8e4c02d
+    FD_ZERO(&w);
8e4c02d
+    int maxfd = -1;
8e4c02d
+
8e4c02d
+    // Extract the watched descriptors.
8e4c02d
+    for (int i = 0; i < nfds; ++i) {
8e4c02d
+        pollfd &fd(fds[i]);
8e4c02d
+        if (fd.fd >= 0 && fd.fd < FD_SETSIZE) {
8e4c02d
+            if (fd.events & POLLIN) {
8e4c02d
+                FD_SET(fd.fd, &r);
8e4c02d
+                if (fd.fd > maxfd)
8e4c02d
+                    maxfd = fd.fd;
8e4c02d
+            }
8e4c02d
+            if (fd.events & POLLOUT) {
8e4c02d
+                FD_SET(fd.fd, &w);
8e4c02d
+                if (fd.fd > maxfd)
8e4c02d
+                    maxfd = fd.fd;
8e4c02d
+            }
8e4c02d
+        }
8e4c02d
+    }
8e4c02d
+
8e4c02d
+    // If timeout is negative, wait indefinitely for activity.
8e4c02d
+    timeval tv;
8e4c02d
+    timeval *ptv;
8e4c02d
+    if (timeout >= 0) {
8e4c02d
+        tv.tv_sec = timeout / 1000;
8e4c02d
+        tv.tv_usec = (timeout % 1000) * 1000;
8e4c02d
+        ptv = &tv;
8e4c02d
+    } else
8e4c02d
+        ptv = NULL;
8e4c02d
+
8e4c02d
+    int ret;
8e4c02d
+    if (retry_eintr)
8e4c02d
+        ret = qt_safe_select(maxfd + 1, &r, &w, NULL, ptv);
8e4c02d
+    else
8e4c02d
+        ret = ::select(maxfd + 1, &r, &w, NULL, ptv);
8e4c02d
+    if (ret < 0 && errno == EBADF) {
8e4c02d
+        return mark_bad_descriptors(fds, nfds);
8e4c02d
+    }
8e4c02d
+    if (ret <= 0)
8e4c02d
+        return ret;
8e4c02d
+
8e4c02d
+    // Set the revents flags.
8e4c02d
+    ret = 0;
8e4c02d
+    for (int i = 0; i < nfds; ++i) {
8e4c02d
+        pollfd &fd(fds[i]);
8e4c02d
+        fd.revents = 0;
8e4c02d
+        if (fd.fd >= 0 && fd.fd < FD_SETSIZE) {
8e4c02d
+            if ((fd.events & POLLIN) && FD_ISSET(fd.fd, &r))
8e4c02d
+                fd.revents |= POLLIN;
8e4c02d
+            if ((fd.events & POLLOUT) && FD_ISSET(fd.fd, &w))
8e4c02d
+                fd.revents |= POLLOUT;
8e4c02d
+            if (fd.revents)
8e4c02d
+                ++ret;
8e4c02d
+        }
8e4c02d
+    }
8e4c02d
+    Q_ASSERT(ret > 0);
8e4c02d
+    return ret;
8e4c02d
+}
8e4c02d
+
8e4c02d
+#endif
8e4c02d
+
8e4c02d
 QT_END_NAMESPACE
Rex Dieter 8ec4a9e
diff -up qt-everywhere-opensource-src-4.8.6/src/corelib/kernel/qcore_unix_p.h.poll qt-everywhere-opensource-src-4.8.6/src/corelib/kernel/qcore_unix_p.h
Rex Dieter 8ec4a9e
--- qt-everywhere-opensource-src-4.8.6/src/corelib/kernel/qcore_unix_p.h.poll	2014-03-30 15:36:48.000000000 -0500
Rex Dieter 8ec4a9e
+++ qt-everywhere-opensource-src-4.8.6/src/corelib/kernel/qcore_unix_p.h	2014-03-31 18:01:59.370715392 -0500
Rex Dieter 8ec4a9e
@@ -345,9 +345,42 @@ static inline pid_t qt_safe_waitpid(pid_
8e4c02d
 
8e4c02d
 timeval qt_gettime(); // in qelapsedtimer_mac.cpp or qtimestamp_unix.cpp
8e4c02d
 
8e4c02d
+// Deprecated due to FD_SETSIZE limitation, use qt_safe_poll instead.
8e4c02d
 Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
8e4c02d
                                  const struct timeval *tv);
8e4c02d
 
8e4c02d
+#ifndef Q_OS_VXWORKS
8e4c02d
+#include <poll.h>
8e4c02d
+#else
8e4c02d
+
8e4c02d
+// Poll emulation for VxWorks.
8e4c02d
+
8e4c02d
+struct pollfd {
8e4c02d
+  int fd;
8e4c02d
+  short events;
8e4c02d
+  short revents;
8e4c02d
+};
8e4c02d
+
8e4c02d
+#define POLLIN 1
8e4c02d
+#define POLLOUT 2
8e4c02d
+#define POLLERR 4
8e4c02d
+#define POLLHUP 8
8e4c02d
+#define POLLNVAL 16
8e4c02d
+#endif
8e4c02d
+
8e4c02d
+inline bool qt_readable(const pollfd &fd)
8e4c02d
+{
8e4c02d
+  return fd.fd >= 0 && (fd.revents & (POLLIN | POLLHUP | POLLERR | POLLNVAL)) != 0;
8e4c02d
+}
8e4c02d
+
8e4c02d
+inline bool qt_writable(const pollfd &fd)
8e4c02d
+{
8e4c02d
+  return fd.fd >= 0 && (fd.revents & (POLLOUT | POLLHUP | POLLERR | POLLNVAL)) != 0;
8e4c02d
+}
8e4c02d
+
8e4c02d
+Q_CORE_EXPORT int qt_safe_poll(pollfd *fds, int nfds, int timeout,
8e4c02d
+                               bool retry_eintr = true);
8e4c02d
+
8e4c02d
 // according to X/OPEN we have to define semun ourselves
8e4c02d
 // we use prefix as on some systems sem.h will have it
8e4c02d
 struct semid_ds;
Rex Dieter 8ec4a9e
diff -up qt-everywhere-opensource-src-4.8.6/src/network/socket/qlocalserver_unix.cpp.poll qt-everywhere-opensource-src-4.8.6/src/network/socket/qlocalserver_unix.cpp
Rex Dieter 8ec4a9e
--- qt-everywhere-opensource-src-4.8.6/src/network/socket/qlocalserver_unix.cpp.poll	2014-03-30 15:36:49.000000000 -0500
Rex Dieter 8ec4a9e
+++ qt-everywhere-opensource-src-4.8.6/src/network/socket/qlocalserver_unix.cpp	2014-03-31 18:01:59.370715392 -0500
Rex Dieter 8ec4a9e
@@ -208,16 +208,11 @@ void QLocalServerPrivate::_q_onNewConnec
8e4c02d
 
8e4c02d
 void QLocalServerPrivate::waitForNewConnection(int msec, bool *timedOut)
8e4c02d
 {
8e4c02d
-    fd_set readfds;
8e4c02d
-    FD_ZERO(&readfds);
8e4c02d
-    FD_SET(listenSocket, &readfds);
8e4c02d
+    struct pollfd fd;
8e4c02d
+    fd.fd = listenSocket;
8e4c02d
+    fd.events = POLLIN;
8e4c02d
 
8e4c02d
-    timeval timeout;
8e4c02d
-    timeout.tv_sec = msec / 1000;
8e4c02d
-    timeout.tv_usec = (msec % 1000) * 1000;
8e4c02d
-
8e4c02d
-    int result = -1;
8e4c02d
-    result = qt_safe_select(listenSocket + 1, &readfds, 0, 0, (msec == -1) ? 0 : &timeout);
8e4c02d
+    int result = qt_safe_poll(&fd, 1, msec);
8e4c02d
     if (-1 == result) {
8e4c02d
         setError(QLatin1String("QLocalServer::waitForNewConnection"));
8e4c02d
         closeServer();
Rex Dieter 8ec4a9e
diff -up qt-everywhere-opensource-src-4.8.6/src/network/socket/qlocalsocket_unix.cpp.poll qt-everywhere-opensource-src-4.8.6/src/network/socket/qlocalsocket_unix.cpp
Rex Dieter 8ec4a9e
--- qt-everywhere-opensource-src-4.8.6/src/network/socket/qlocalsocket_unix.cpp.poll	2014-03-30 15:36:49.000000000 -0500
Rex Dieter 8ec4a9e
+++ qt-everywhere-opensource-src-4.8.6/src/network/socket/qlocalsocket_unix.cpp	2014-03-31 18:01:59.370715392 -0500
Rex Dieter 8ec4a9e
@@ -56,10 +56,6 @@
8e4c02d
 #include <qdebug.h>
8e4c02d
 #include <qelapsedtimer.h>
8e4c02d
 
8e4c02d
-#ifdef Q_OS_VXWORKS
8e4c02d
-#  include <selectLib.h>
8e4c02d
-#endif
8e4c02d
-
8e4c02d
 #define QT_CONNECT_TIMEOUT 30000
8e4c02d
 
8e4c02d
 QT_BEGIN_NAMESPACE
Rex Dieter 8ec4a9e
@@ -520,32 +516,17 @@ bool QLocalSocket::waitForConnected(int
8e4c02d
     if (state() != ConnectingState)
8e4c02d
         return (state() == ConnectedState);
8e4c02d
 
8e4c02d
-    fd_set fds;
8e4c02d
-    FD_ZERO(&fds);
8e4c02d
-    FD_SET(d->connectingSocket, &fds);
8e4c02d
-
8e4c02d
-    timeval timeout;
8e4c02d
-    timeout.tv_sec = msec / 1000;
8e4c02d
-    timeout.tv_usec = (msec % 1000) * 1000;
8e4c02d
-
8e4c02d
-    // timeout can not be 0 or else select will return an error.
8e4c02d
-    if (0 == msec)
8e4c02d
-        timeout.tv_usec = 1000;
8e4c02d
+    pollfd fd;
8e4c02d
+    fd.fd = d->connectingSocket;
8e4c02d
+    fd.events = POLLIN | POLLOUT;
8e4c02d
 
8e4c02d
     int result = -1;
8e4c02d
     // on Linux timeout will be updated by select, but _not_ on other systems.
8e4c02d
     QElapsedTimer timer;
8e4c02d
+    int remaining = msec;
8e4c02d
     timer.start();
8e4c02d
-    while (state() == ConnectingState
8e4c02d
-           && (-1 == msec || timer.elapsed() < msec)) {
8e4c02d
-#ifdef Q_OS_SYMBIAN
8e4c02d
-        // On Symbian, ready-to-write is signaled when non-blocking socket
8e4c02d
-        // connect is finised. Is ready-to-read really used on other
8e4c02d
-        // UNIX paltforms when using non-blocking AF_UNIX socket?
8e4c02d
-        result = ::select(d->connectingSocket + 1, 0, &fds, 0, &timeout);
8e4c02d
-#else
8e4c02d
-        result = ::select(d->connectingSocket + 1, &fds, 0, 0, &timeout);
8e4c02d
-#endif
8e4c02d
+    while (state() == ConnectingState) {
8e4c02d
+        result = qt_safe_poll(&fd, 1, remaining, /* retry_eintr */ false);
8e4c02d
         if (-1 == result && errno != EINTR) {
8e4c02d
             d->errorOccurred( QLocalSocket::UnknownSocketError,
8e4c02d
                     QLatin1String("QLocalSocket::waitForConnected"));
Rex Dieter 8ec4a9e
@@ -553,6 +534,11 @@ bool QLocalSocket::waitForConnected(int
8e4c02d
         }
8e4c02d
         if (result > 0)
8e4c02d
             d->_q_connectToSocket();
8e4c02d
+        if (msec >= 0) {
8e4c02d
+            remaining = timer.elapsed() - msec;
8e4c02d
+            if (remaining < 0)
8e4c02d
+                break;
8e4c02d
+        }
8e4c02d
     }
8e4c02d
 
8e4c02d
     return (state() == ConnectedState);
Rex Dieter 8ec4a9e
diff -up qt-everywhere-opensource-src-4.8.6/src/network/socket/qnativesocketengine_unix.cpp.poll qt-everywhere-opensource-src-4.8.6/src/network/socket/qnativesocketengine_unix.cpp
Rex Dieter 8ec4a9e
--- qt-everywhere-opensource-src-4.8.6/src/network/socket/qnativesocketengine_unix.cpp.poll	2014-03-30 15:36:49.000000000 -0500
Rex Dieter 8ec4a9e
+++ qt-everywhere-opensource-src-4.8.6/src/network/socket/qnativesocketengine_unix.cpp	2014-03-31 18:01:59.371715381 -0500
Rex Dieter 8ec4a9e
@@ -1068,48 +1068,40 @@ qint64 QNativeSocketEnginePrivate::nativ
8e4c02d
 
8e4c02d
 int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) const
8e4c02d
 {
8e4c02d
-    fd_set fds;
8e4c02d
-    FD_ZERO(&fds);
8e4c02d
-    FD_SET(socketDescriptor, &fds);
8e4c02d
-
8e4c02d
-    struct timeval tv;
8e4c02d
-    tv.tv_sec = timeout / 1000;
8e4c02d
-    tv.tv_usec = (timeout % 1000) * 1000;
8e4c02d
-
8e4c02d
-    int retval;
8e4c02d
-    if (selectForRead)
8e4c02d
-        retval = qt_safe_select(socketDescriptor + 1, &fds, 0, 0, timeout < 0 ? 0 : &tv;;
8e4c02d
-    else
8e4c02d
-        retval = qt_safe_select(socketDescriptor + 1, 0, &fds, 0, timeout < 0 ? 0 : &tv;;
8e4c02d
-
8e4c02d
-    return retval;
8e4c02d
+    struct pollfd fd;
8e4c02d
+    fd.fd = socketDescriptor;
8e4c02d
+    if (selectForRead) {
8e4c02d
+	fd.events = POLLIN;
8e4c02d
+    } else {
8e4c02d
+	fd.events = POLLOUT;
8e4c02d
+    }
8e4c02d
+    return qt_safe_poll(&fd, 1, timeout);
8e4c02d
 }
8e4c02d
 
8e4c02d
 int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool checkWrite,
8e4c02d
                        bool *selectForRead, bool *selectForWrite) const
8e4c02d
 {
8e4c02d
-    fd_set fdread;
8e4c02d
-    FD_ZERO(&fdread);
8e4c02d
+    struct pollfd fd;
8e4c02d
+    fd.fd = socketDescriptor;
8e4c02d
     if (checkRead)
8e4c02d
-        FD_SET(socketDescriptor, &fdread);
8e4c02d
-
8e4c02d
-    fd_set fdwrite;
8e4c02d
-    FD_ZERO(&fdwrite);
8e4c02d
+	fd.events =  POLLIN;
8e4c02d
+    else
8e4c02d
+	fd.events = 0;
8e4c02d
     if (checkWrite)
8e4c02d
-        FD_SET(socketDescriptor, &fdwrite);
8e4c02d
-
8e4c02d
-    struct timeval tv;
8e4c02d
-    tv.tv_sec = timeout / 1000;
8e4c02d
-    tv.tv_usec = (timeout % 1000) * 1000;
8e4c02d
-
8e4c02d
-    int ret;
8e4c02d
-    ret = qt_safe_select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv;;
8e4c02d
-
8e4c02d
+	fd.events |= POLLOUT;
8e4c02d
+    int ret = qt_safe_poll(&fd, 1, timeout);
8e4c02d
     if (ret <= 0)
8e4c02d
-        return ret;
8e4c02d
-    *selectForRead = FD_ISSET(socketDescriptor, &fdread);
8e4c02d
-    *selectForWrite = FD_ISSET(socketDescriptor, &fdwrite);
8e4c02d
-
8e4c02d
+	return ret;
8e4c02d
+    bool r = (fd.revents & (POLLIN | POLLHUP | POLLERR)) != 0;
8e4c02d
+    bool w = (fd.revents & (POLLOUT | POLLHUP | POLLERR)) != 0;
8e4c02d
+    // Emulate the return value from select(2).
8e4c02d
+    ret = 0;
8e4c02d
+    if (r)
8e4c02d
+	++ret;
8e4c02d
+    if (w)
8e4c02d
+	++ret;
8e4c02d
+    *selectForRead = r;
8e4c02d
+    *selectForWrite = w;
8e4c02d
     return ret;
8e4c02d
 }
8e4c02d
 
Rex Dieter 8ec4a9e
diff -up qt-everywhere-opensource-src-4.8.6/src/qt3support/network/q3socketdevice_unix.cpp.poll qt-everywhere-opensource-src-4.8.6/src/qt3support/network/q3socketdevice_unix.cpp
Rex Dieter 8ec4a9e
--- qt-everywhere-opensource-src-4.8.6/src/qt3support/network/q3socketdevice_unix.cpp.poll	2014-03-30 15:36:49.000000000 -0500
Rex Dieter 8ec4a9e
+++ qt-everywhere-opensource-src-4.8.6/src/qt3support/network/q3socketdevice_unix.cpp	2014-03-31 18:01:59.371715381 -0500
Rex Dieter 8ec4a9e
@@ -68,6 +68,7 @@ static inline int qt_socket_socket(int d
8e4c02d
 #endif
8e4c02d
 
8e4c02d
 #include "q3socketdevice.h"
8e4c02d
+#include "private/qcore_unix_p.h"
8e4c02d
 
8e4c02d
 #ifndef QT_NO_NETWORK
8e4c02d
 
Rex Dieter 8ec4a9e
@@ -588,19 +589,10 @@ Q_LONG Q3SocketDevice::waitForMore( int
8e4c02d
 {
8e4c02d
     if ( !isValid() )
8e4c02d
 	return -1;
8e4c02d
-    if ( fd >= FD_SETSIZE )
8e4c02d
-	return -1;
8e4c02d
-
8e4c02d
-    fd_set fds;
8e4c02d
-    struct timeval tv;
8e4c02d
-
8e4c02d
-    FD_ZERO( &fds );
8e4c02d
-    FD_SET( fd, &fds );
8e4c02d
-
8e4c02d
-    tv.tv_sec = msecs / 1000;
8e4c02d
-    tv.tv_usec = (msecs % 1000) * 1000;
8e4c02d
 
8e4c02d
-    int rv = select( fd+1, &fds, 0, 0, msecs < 0 ? 0 : &tv );
8e4c02d
+    pollfd pfd;
8e4c02d
+    pfd.fd = fd;
8e4c02d
+    int rv = qt_safe_poll(&pfd, 1, msecs, /* retry_eintr */ false);
8e4c02d
 
8e4c02d
     if ( rv < 0 )
8e4c02d
 	return -1;
Rex Dieter 8ec4a9e
diff -up qt-everywhere-opensource-src-4.8.6/src/qt3support/other/q3process_unix.cpp.poll qt-everywhere-opensource-src-4.8.6/src/qt3support/other/q3process_unix.cpp
Rex Dieter 8ec4a9e
--- qt-everywhere-opensource-src-4.8.6/src/qt3support/other/q3process_unix.cpp.poll	2014-03-30 15:36:49.000000000 -0500
Rex Dieter 8ec4a9e
+++ qt-everywhere-opensource-src-4.8.6/src/qt3support/other/q3process_unix.cpp	2014-03-31 18:01:59.372715370 -0500
8e4c02d
@@ -981,13 +981,10 @@ bool Q3Process::isRunning() const
8e4c02d
 	// On heavy processing, the socket notifier for the sigchild might not
8e4c02d
 	// have found time to fire yet.
8e4c02d
 	if ( d->procManager && d->procManager->sigchldFd[1] < FD_SETSIZE ) {
8e4c02d
-	    fd_set fds;
8e4c02d
-	    struct timeval tv;
8e4c02d
-	    FD_ZERO( &fds );
8e4c02d
-	    FD_SET( d->procManager->sigchldFd[1], &fds );
8e4c02d
-	    tv.tv_sec = 0;
8e4c02d
-	    tv.tv_usec = 0;
8e4c02d
-	    if ( ::select( d->procManager->sigchldFd[1]+1, &fds, 0, 0, &tv ) > 0 )
8e4c02d
+	    pollfd fd;
8e4c02d
+	    fd.fd = d->procManager->sigchldFd[1];
8e4c02d
+	    fd.events = POLLIN;
8e4c02d
+	    if ( qt_safe_poll(&fd, 1, 0, /* retry_eintr */ false) > 0 )
8e4c02d
 		d->procManager->sigchldHnd( d->procManager->sigchldFd[1] );
8e4c02d
 	}
8e4c02d
 
8e4c02d
@@ -1124,29 +1121,21 @@ void Q3Process::socketRead( int fd )
8e4c02d
 	}
8e4c02d
     }
8e4c02d
 
8e4c02d
-    if ( fd < FD_SETSIZE ) {
8e4c02d
-	fd_set fds;
8e4c02d
-	struct timeval tv;
8e4c02d
-	FD_ZERO( &fds );
8e4c02d
-	FD_SET( fd, &fds );
8e4c02d
-	tv.tv_sec = 0;
8e4c02d
-	tv.tv_usec = 0;
8e4c02d
-	while ( ::select( fd+1, &fds, 0, 0, &tv ) > 0 ) {
8e4c02d
-	    // prepare for the next round
8e4c02d
-	    FD_ZERO( &fds );
8e4c02d
-	    FD_SET( fd, &fds );
8e4c02d
-	    // read data
8e4c02d
-	    ba = new QByteArray( basize );
8e4c02d
-	    n = ::read( fd, ba->data(), basize );
8e4c02d
-	    if ( n > 0 ) {
8e4c02d
-		ba->resize( n );
8e4c02d
-		buffer->append( ba );
8e4c02d
-		ba = 0;
8e4c02d
-	    } else {
8e4c02d
-		delete ba;
8e4c02d
-		ba = 0;
8e4c02d
-		break;
8e4c02d
-	    }
8e4c02d
+    pollfd pfd;
8e4c02d
+    pfd.fd = fd;
8e4c02d
+    pfd.events = POLLIN;
8e4c02d
+    while (qt_safe_poll(&pfd, 1, 0)) {
8e4c02d
+	// read data
8e4c02d
+	ba = new QByteArray( basize );
8e4c02d
+	n = ::read( fd, ba->data(), basize );
8e4c02d
+	if ( n > 0 ) {
8e4c02d
+	    ba->resize( n );
8e4c02d
+	    buffer->append( ba );
8e4c02d
+	    ba = 0;
8e4c02d
+	} else {
8e4c02d
+	    delete ba;
8e4c02d
+	    ba = 0;
8e4c02d
+	    break;
8e4c02d
 	}
8e4c02d
     }
8e4c02d