Don't try to read from invalid file descriptors in QProcess
strace reveals that we do ioctl(-1, FIONREAD) and get EBADF. The only case where this could happen is inside _q_processDied, which calls the read functions without checking if the pipe is still open. Change-Id: I67637fc4267be73fc03d40c444fdfea89e1ef715 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
This commit is contained in:
parent
25ef58fe18
commit
6ca3ab626a
@ -903,6 +903,9 @@ void QProcessPrivate::cleanup()
|
|||||||
bool QProcessPrivate::tryReadFromChannel(Channel *channel)
|
bool QProcessPrivate::tryReadFromChannel(Channel *channel)
|
||||||
{
|
{
|
||||||
Q_Q(QProcess);
|
Q_Q(QProcess);
|
||||||
|
if (channel->pipe[0] == INVALID_Q_PIPE)
|
||||||
|
return false;
|
||||||
|
|
||||||
qint64 available = bytesAvailableInChannel(channel);
|
qint64 available = bytesAvailableInChannel(channel);
|
||||||
if (available == 0) {
|
if (available == 0) {
|
||||||
if (channel->notifier)
|
if (channel->notifier)
|
||||||
|
@ -965,6 +965,7 @@ bool QProcessPrivate::processStarted()
|
|||||||
|
|
||||||
qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const
|
qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE);
|
||||||
int nbytes = 0;
|
int nbytes = 0;
|
||||||
qint64 available = 0;
|
qint64 available = 0;
|
||||||
if (::ioctl(channel->pipe[0], FIONREAD, (char *) &nbytes) >= 0)
|
if (::ioctl(channel->pipe[0], FIONREAD, (char *) &nbytes) >= 0)
|
||||||
@ -977,6 +978,7 @@ qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const
|
|||||||
|
|
||||||
qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint64 maxlen)
|
qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint64 maxlen)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE);
|
||||||
qint64 bytesRead = qt_safe_read(channel->pipe[0], data, maxlen);
|
qint64 bytesRead = qt_safe_read(channel->pipe[0], data, maxlen);
|
||||||
#if defined QPROCESS_DEBUG
|
#if defined QPROCESS_DEBUG
|
||||||
qDebug("QProcessPrivate::readFromChannel(%d, %p \"%s\", %lld) == %lld",
|
qDebug("QProcessPrivate::readFromChannel(%d, %p \"%s\", %lld) == %lld",
|
||||||
|
@ -566,11 +566,8 @@ bool QProcessPrivate::processStarted()
|
|||||||
|
|
||||||
qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const
|
qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const
|
||||||
{
|
{
|
||||||
if (channel->pipe[0] == INVALID_Q_PIPE)
|
Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE);
|
||||||
return 0;
|
Q_ASSERT(channel->reader);
|
||||||
|
|
||||||
if (!channel->reader)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
DWORD bytesAvail = channel->reader->bytesAvailable();
|
DWORD bytesAvail = channel->reader->bytesAvailable();
|
||||||
#if defined QPROCESS_DEBUG
|
#if defined QPROCESS_DEBUG
|
||||||
@ -581,7 +578,9 @@ qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const
|
|||||||
|
|
||||||
qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint64 maxlen)
|
qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint64 maxlen)
|
||||||
{
|
{
|
||||||
return channel->reader ? channel->reader->read(data, maxlen) : 0;
|
Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE);
|
||||||
|
Q_ASSERT(channel->reader);
|
||||||
|
return channel->reader->read(data, maxlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL QT_WIN_CALLBACK qt_terminateApp(HWND hwnd, LPARAM procId)
|
static BOOL QT_WIN_CALLBACK qt_terminateApp(HWND hwnd, LPARAM procId)
|
||||||
|
Loading…
Reference in New Issue
Block a user