summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io')
-rw-r--r--src/corelib/io/qfilesystemengine.cpp14
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp5
-rw-r--r--src/corelib/io/qprocess.cpp23
-rw-r--r--src/corelib/io/qprocess_p.h2
-rw-r--r--src/corelib/io/qprocess_unix.cpp35
-rw-r--r--src/corelib/io/qprocess_win.cpp10
-rw-r--r--src/corelib/io/qprocess_wince.cpp6
-rw-r--r--src/corelib/io/qwindowspipewriter.cpp41
-rw-r--r--src/corelib/io/qwindowspipewriter_p.h4
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(), &copyParams) != 0;
+ HRESULT hres = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(),
+ (const wchar_t*)target.nativeFilePath().utf16(), &copyParams);
+ 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;