diff options
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qfilesystemengine.cpp | 14 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_win.cpp | 5 | ||||
-rw-r--r-- | src/corelib/io/qprocess.cpp | 23 | ||||
-rw-r--r-- | src/corelib/io/qprocess_p.h | 2 | ||||
-rw-r--r-- | src/corelib/io/qprocess_unix.cpp | 35 | ||||
-rw-r--r-- | src/corelib/io/qprocess_win.cpp | 10 | ||||
-rw-r--r-- | src/corelib/io/qprocess_wince.cpp | 6 | ||||
-rw-r--r-- | src/corelib/io/qwindowspipewriter.cpp | 41 | ||||
-rw-r--r-- | src/corelib/io/qwindowspipewriter_p.h | 4 |
9 files changed, 82 insertions, 58 deletions
diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index 2dad56befd..fd8f251ccb 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -264,7 +264,7 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) entryFlags |= QFileSystemMetaData::FileType; else if ((statBuffer.st_mode & S_IFMT) == S_IFDIR) entryFlags |= QFileSystemMetaData::DirectoryType; - else + else if ((statBuffer.st_mode & S_IFMT) != S_IFBLK) entryFlags |= QFileSystemMetaData::SequentialType; // Attributes @@ -347,6 +347,18 @@ void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry) break; case DT_BLK: + knownFlagsMask = QFileSystemMetaData::LinkType + | QFileSystemMetaData::FileType + | QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::BundleType + | QFileSystemMetaData::AliasType + | QFileSystemMetaData::SequentialType + | QFileSystemMetaData::ExistsAttribute; + + entryFlags = QFileSystemMetaData::ExistsAttribute; + + break; + case DT_CHR: case DT_FIFO: case DT_SOCK: diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 0829bbc6e8..115b31dd2e 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -1422,8 +1422,9 @@ bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSyst COPYFILE2_EXTENDED_PARAMETERS copyParams = { sizeof(copyParams), COPY_FILE_FAIL_IF_EXISTS, NULL, NULL, NULL }; - bool ret = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(), - (const wchar_t*)target.nativeFilePath().utf16(), ©Params) != 0; + HRESULT hres = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(), + (const wchar_t*)target.nativeFilePath().utf16(), ©Params); + bool ret = SUCCEEDED(hres); #endif // Q_OS_WINRT if(!ret) error = QSystemError(::GetLastError(), QSystemError::NativeError); diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 854db31a79..a9d3e0bfe8 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1103,7 +1103,6 @@ bool QProcessPrivate::_q_canReadStandardError() */ bool QProcessPrivate::_q_canWrite() { - Q_Q(QProcess); if (stdinChannel.notifier) stdinChannel.notifier->setEnabled(false); @@ -1114,31 +1113,13 @@ bool QProcessPrivate::_q_canWrite() return false; } - qint64 written = writeToStdin(writeBuffer.readPointer(), writeBuffer.nextDataBlockSize()); - if (written < 0) { - closeChannel(&stdinChannel); - setErrorAndEmit(QProcess::WriteError); - return false; - } + const bool writeSucceeded = writeToStdin(); -#if defined QPROCESS_DEBUG - qDebug("QProcessPrivate::canWrite(), wrote %d bytes to the process input", int(written)); -#endif - - if (written != 0) { - writeBuffer.free(written); - if (!emittedBytesWritten) { - emittedBytesWritten = true; - emit q->bytesWritten(written); - emittedBytesWritten = false; - } - emit q->channelBytesWritten(0, written); - } if (stdinChannel.notifier && !writeBuffer.isEmpty()) stdinChannel.notifier->setEnabled(true); if (writeBuffer.isEmpty() && stdinChannel.closed) closeWriteChannel(); - return true; + return writeSucceeded; } /*! diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index 1f88c3a043..ae236c8c60 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -379,7 +379,7 @@ public: qint64 bytesAvailableInChannel(const Channel *channel) const; qint64 readFromChannel(const Channel *channel, char *data, qint64 maxlen); - qint64 writeToStdin(const char *data, qint64 maxlen); + bool writeToStdin(); void cleanup(); void setError(QProcess::ProcessError error, const QString &description = QString()); diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index a5b7692fc9..8c5589538d 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -681,21 +681,36 @@ qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint return bytesRead; } -qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) +bool QProcessPrivate::writeToStdin() { - qint64 written = qt_safe_write_nosignal(stdinChannel.pipe[1], data, maxlen); + const char *data = writeBuffer.readPointer(); + const qint64 bytesToWrite = writeBuffer.nextDataBlockSize(); + + qint64 written = qt_safe_write_nosignal(stdinChannel.pipe[1], data, bytesToWrite); #if defined QPROCESS_DEBUG - qDebug("QProcessPrivate::writeToStdin(%p \"%s\", %lld) == %lld", - data, qt_prettyDebug(data, maxlen, 16).constData(), maxlen, written); + qDebug("QProcessPrivate::writeToStdin(), write(%p \"%s\", %lld) == %lld", + data, qt_prettyDebug(data, bytesToWrite, 16).constData(), bytesToWrite, written); if (written == -1) qDebug("QProcessPrivate::writeToStdin(), failed to write (%s)", qPrintable(qt_error_string(errno))); #endif - // If the O_NONBLOCK flag is set and If some data can be written without blocking - // the process, write() will transfer what it can and return the number of bytes written. - // Otherwise, it will return -1 and set errno to EAGAIN - if (written == -1 && errno == EAGAIN) - written = 0; - return written; + if (written == -1) { + // If the O_NONBLOCK flag is set and If some data can be written without blocking + // the process, write() will transfer what it can and return the number of bytes written. + // Otherwise, it will return -1 and set errno to EAGAIN + if (errno == EAGAIN) + return true; + + closeChannel(&stdinChannel); + setErrorAndEmit(QProcess::WriteError); + return false; + } + writeBuffer.free(written); + if (!emittedBytesWritten && written != 0) { + emittedBytesWritten = true; + emit q_func()->bytesWritten(written); + emittedBytesWritten = false; + } + return true; } void QProcessPrivate::terminateProcess() diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index ed540f9e5b..96b39efe3a 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -805,17 +805,23 @@ qint64 QProcessPrivate::pipeWriterBytesToWrite() const return stdinChannel.writer ? stdinChannel.writer->bytesToWrite() : qint64(0); } -qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) +bool QProcessPrivate::writeToStdin() { Q_Q(QProcess); if (!stdinChannel.writer) { stdinChannel.writer = new QWindowsPipeWriter(stdinChannel.pipe[1], q); + QObject::connect(stdinChannel.writer, &QWindowsPipeWriter::bytesWritten, + q, &QProcess::bytesWritten); QObjectPrivate::connect(stdinChannel.writer, &QWindowsPipeWriter::canWrite, this, &QProcessPrivate::_q_canWrite); + } else { + if (stdinChannel.writer->isWriteOperationActive()) + return true; } - return stdinChannel.writer->write(data, maxlen); + stdinChannel.writer->write(writeBuffer.read()); + return true; } // Use ShellExecuteEx() to trigger an UAC prompt when CreateProcess()fails diff --git a/src/corelib/io/qprocess_wince.cpp b/src/corelib/io/qprocess_wince.cpp index 564b3f520d..824a6158dc 100644 --- a/src/corelib/io/qprocess_wince.cpp +++ b/src/corelib/io/qprocess_wince.cpp @@ -271,11 +271,9 @@ qint64 QProcessPrivate::pipeWriterBytesToWrite() const return 0; } -qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) +bool QProcessPrivate::writeToStdin() { - Q_UNUSED(data); - Q_UNUSED(maxlen); - return -1; + return false; } bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDir, qint64 *pid) diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index 79e7d13eb5..ab179641f8 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -79,21 +79,19 @@ QWindowsPipeWriter::~QWindowsPipeWriter() bool QWindowsPipeWriter::waitForWrite(int msecs) { - if (!writeSequenceStarted) - return false; - if (bytesWrittenPending) { - if (!inBytesWritten) - emitPendingBytesWrittenValue(); + emitPendingBytesWrittenValue(); return true; } + if (!writeSequenceStarted) + return false; + if (!waitForNotification(msecs)) return false; if (bytesWrittenPending) { - if (!inBytesWritten) - emitPendingBytesWrittenValue(); + emitPendingBytesWrittenValue(); return true; } @@ -102,20 +100,24 @@ bool QWindowsPipeWriter::waitForWrite(int msecs) qint64 QWindowsPipeWriter::bytesToWrite() const { - return numberOfBytesToWrite; + return numberOfBytesToWrite + pendingBytesWrittenValue; } void QWindowsPipeWriter::emitPendingBytesWrittenValue() { if (bytesWrittenPending) { + // Reset the state even if we don't emit bytesWritten(). + // It's a defined behavior to not re-emit this signal recursively. bytesWrittenPending = false; const qint64 bytes = pendingBytesWrittenValue; pendingBytesWrittenValue = 0; - inBytesWritten = true; - emit bytesWritten(bytes); - inBytesWritten = false; emit canWrite(); + if (!inBytesWritten) { + inBytesWritten = true; + emit bytesWritten(bytes); + inBytesWritten = false; + } } } @@ -135,6 +137,8 @@ void QWindowsPipeWriter::notified(DWORD errorCode, DWORD numberOfBytesWritten) notifiedCalled = true; writeSequenceStarted = false; numberOfBytesToWrite = 0; + Q_ASSERT(errorCode != ERROR_SUCCESS || numberOfBytesWritten == DWORD(buffer.size())); + buffer.clear(); switch (errorCode) { case ERROR_SUCCESS: @@ -179,21 +183,26 @@ bool QWindowsPipeWriter::waitForNotification(int timeout) return notifiedCalled; } -qint64 QWindowsPipeWriter::write(const char *ptr, qint64 maxlen) +bool QWindowsPipeWriter::write(const QByteArray &ba) { if (writeSequenceStarted) - return 0; + return false; overlapped.clear(); - numberOfBytesToWrite = maxlen; + buffer = ba; + numberOfBytesToWrite = buffer.size(); stopped = false; writeSequenceStarted = true; - if (!WriteFileEx(handle, ptr, maxlen, &overlapped, &writeFileCompleted)) { + if (!WriteFileEx(handle, buffer.constData(), numberOfBytesToWrite, + &overlapped, &writeFileCompleted)) { writeSequenceStarted = false; + numberOfBytesToWrite = 0; + buffer.clear(); qErrnoWarning("QWindowsPipeWriter::write failed."); + return false; } - return maxlen; + return true; } void QWindowsPipeWriter::stop() diff --git a/src/corelib/io/qwindowspipewriter_p.h b/src/corelib/io/qwindowspipewriter_p.h index 59f20edae0..3c641670b6 100644 --- a/src/corelib/io/qwindowspipewriter_p.h +++ b/src/corelib/io/qwindowspipewriter_p.h @@ -53,6 +53,7 @@ #include <qelapsedtimer.h> #include <qobject.h> +#include <qbytearray.h> #include <qt_windows.h> QT_BEGIN_NAMESPACE @@ -112,7 +113,7 @@ public: explicit QWindowsPipeWriter(HANDLE pipeWriteEnd, QObject *parent = 0); ~QWindowsPipeWriter(); - qint64 write(const char *data, qint64 maxlen); + bool write(const QByteArray &ba); void stop(); bool waitForWrite(int msecs); bool isWriteOperationActive() const { return writeSequenceStarted; } @@ -142,6 +143,7 @@ private: HANDLE handle; Overlapped overlapped; + QByteArray buffer; qint64 numberOfBytesToWrite; qint64 pendingBytesWrittenValue; bool stopped; |