From 467a000089f741dd6def17dacb7f1bcc98a9249a Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Tue, 27 Dec 2011 18:11:08 +0100 Subject: [PATCH] Remove Symbian support from src/corelib/io/. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: I52c2a58396e03f29ca478de34c914535c7ae1012 Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll Reviewed-by: Bradley T. Hughes Reviewed-by: João Abecasis --- src/corelib/io/io.pri | 25 +- src/corelib/io/qfilesystemengine_symbian.cpp | 406 --------- src/corelib/io/qfilesystemiterator_symbian.cpp | 127 --- src/corelib/io/qfilesystemwatcher.cpp | 4 - src/corelib/io/qfilesystemwatcher_symbian.cpp | 273 ------ src/corelib/io/qfilesystemwatcher_symbian_p.h | 130 --- src/corelib/io/qprocess_symbian.cpp | 1072 ------------------------ 7 files changed, 7 insertions(+), 2030 deletions(-) delete mode 100644 src/corelib/io/qfilesystemengine_symbian.cpp delete mode 100644 src/corelib/io/qfilesystemiterator_symbian.cpp delete mode 100644 src/corelib/io/qfilesystemwatcher_symbian.cpp delete mode 100644 src/corelib/io/qfilesystemwatcher_symbian_p.h delete mode 100644 src/corelib/io/qprocess_symbian.cpp diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 84bc6f3..a8c1222 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -83,16 +83,12 @@ win32 { SOURCES += io/qfilesystemiterator_win.cpp SOURCES += io/qstandardpaths_win.cpp } else:unix { - SOURCES += io/qfsfileengine_unix.cpp - symbian { - SOURCES += io/qfilesystemengine_symbian.cpp - SOURCES += io/qprocess_symbian.cpp - SOURCES += io/qfilesystemiterator_symbian.cpp - } else { - SOURCES += io/qfilesystemengine_unix.cpp - SOURCES += io/qprocess_unix.cpp - SOURCES += io/qfilesystemiterator_unix.cpp - } + SOURCES += \ + io/qfsfileengine_unix.cpp \ + io/qfilesystemengine_unix.cpp \ + io/qprocess_unix.cpp \ + io/qfilesystemiterator_unix.cpp \ + !nacl:macx-*: { HEADERS += io/qfilesystemwatcher_fsevents_p.h SOURCES += io/qfilesystemengine_mac.cpp @@ -104,7 +100,7 @@ win32 { SOURCES += io/qstandardpaths_unix.cpp } - linux-*:!symbian { + linux-* { SOURCES += \ io/qfilesystemwatcher_inotify.cpp \ io/qfilesystemwatcher_dnotify.cpp @@ -120,13 +116,6 @@ win32 { HEADERS += io/qfilesystemwatcher_kqueue_p.h } } - - symbian { - SOURCES += io/qfilesystemwatcher_symbian.cpp - HEADERS += io/qfilesystemwatcher_symbian_p.h - INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE - LIBS += -lplatformenv -lesock - } } integrity { SOURCES += io/qfsfileengine_unix.cpp \ diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp deleted file mode 100644 index c8c1dfd..0000000 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ /dev/null @@ -1,406 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qfilesystemengine_p.h" -#include "qfsfileengine.h" -#include -#include - -#include -#include -#include - -QT_BEGIN_NAMESPACE - -bool QFileSystemEngine::isCaseSensitive() -{ - return false; -} - -//TODO: resolve this with QDir::cleanPath, without breaking the behaviour of that -//function which is documented only by autotest -//input: a dirty absolute path, e.g. c:/../../foo/./ -//output: a clean absolute path, e.g. c:/foo/ -static QString symbianCleanAbsolutePath(const QString& path) -{ - bool isDir = path.endsWith(QLatin1Char('/')); - //using SkipEmptyParts flag to eliminate duplicated slashes - QStringList components = path.split(QLatin1Char('/'), QString::SkipEmptyParts); - int cdups = 0; - for(int i=components.count() - 1; i>=0; --i) { - if(components.at(i) == QLatin1String("..")) { - components.removeAt(i); - cdups++; - } - else if(components.at(i) == QLatin1String(".")) { - components.removeAt(i); - } - else if(cdups && i > 0) { - --cdups; - components.removeAt(i); - } - } - QString result = components.join(QLatin1String("/")); - if ((isDir&& !result.endsWith(QLatin1Char('/'))) - || (result.length() == 2 && result.at(1).unicode() == ':')) - result.append(QLatin1Char('/')); - return result; -} - -//static -QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data) -{ - Q_UNUSED(data); - return link; -} - -//static -QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data) -{ - if (entry.isEmpty() || entry.isRoot()) - return entry; - - QFileSystemEntry result = absoluteName(entry); - if (!data.hasFlags(QFileSystemMetaData::ExistsAttribute)) - fillMetaData(result, data, QFileSystemMetaData::ExistsAttribute); - if (!data.exists()) { - // file doesn't exist - return QFileSystemEntry(); - } else { - return result; - } -} - -//static -QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) -{ - QString orig = entry.filePath(); - const bool isAbsolute = entry.isAbsolute(); - const bool isDirty = !entry.isClean(); - if (isAbsolute && !isDirty) - return entry; - - const bool isRelative = entry.isRelative(); - const bool needsDrive = (!orig.isEmpty() && orig.at(0).unicode() == '/'); - const bool isDriveLetter = !needsDrive && !isAbsolute && !isRelative && orig.length() == 2; - const bool isDriveRelative = !needsDrive && !isAbsolute && !isRelative && orig.length() > 2; - - QString result; - if (needsDrive || isDriveLetter || isDriveRelative || !isAbsolute || orig.isEmpty()) { - QFileSystemEntry cur(currentPath()); - if(needsDrive) - result = cur.filePath().left(2); - else if(isDriveRelative && cur.filePath().at(0) != orig.at(0)) - result = orig.left(2); // for BC, see tst_QFileInfo::absolutePath(:my.dll) - else - result = cur.filePath(); - if(isDriveLetter) { - result[0] = orig.at(0); //copy drive letter - orig.clear(); - } - if(isDriveRelative) { - orig = orig.mid(2); //discard the drive specifier from orig - } - } - if (!orig.isEmpty() && !(orig.length() == 1 && orig.at(0).unicode() == '.')) { - if (!result.isEmpty() && !result.endsWith(QLatin1Char('/'))) - result.append(QLatin1Char('/')); - result.append(orig); - } - - return QFileSystemEntry(symbianCleanAbsolutePath(result), QFileSystemEntry::FromInternalPath()); -} - -void QFileSystemMetaData::fillFromTEntry(const TEntry& entry) -{ - entryFlags &= ~(QFileSystemMetaData::SymbianTEntryFlags); - knownFlagsMask |= QFileSystemMetaData::SymbianTEntryFlags; - //Symbian doesn't have unix type file permissions - entryFlags |= QFileSystemMetaData::ReadPermissions; - if(!entry.IsReadOnly()) { - entryFlags |= QFileSystemMetaData::WritePermissions; - } - //set the type - if(entry.IsDir()) - entryFlags |= (QFileSystemMetaData::DirectoryType | QFileSystemMetaData::ExecutePermissions); - else - entryFlags |= QFileSystemMetaData::FileType; - - //set the attributes - entryFlags |= QFileSystemMetaData::ExistsAttribute; - if(entry.IsHidden()) - entryFlags |= QFileSystemMetaData::HiddenAttribute; - -#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API - size_ = entry.FileSize(); -#else - size_ = (TUint)(entry.iSize); -#endif - - modificationTime_ = entry.iModified; -} - -void QFileSystemMetaData::fillFromVolumeInfo(const TVolumeInfo& info) -{ - entryFlags &= ~(QFileSystemMetaData::SymbianTEntryFlags); - knownFlagsMask |= QFileSystemMetaData::SymbianTEntryFlags; - entryFlags |= QFileSystemMetaData::ExistsAttribute; - entryFlags |= QFileSystemMetaData::Permissions; - if(info.iDrive.iDriveAtt & KDriveAttRom) { - entryFlags &= ~(QFileSystemMetaData::WritePermissions); - } - entryFlags |= QFileSystemMetaData::DirectoryType; - size_ = info.iSize; - modificationTime_ = qt_symbian_time_t_To_TTime(0); -} - -//static -bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) -{ - if (what & QFileSystemMetaData::SymbianTEntryFlags) { - RFs& fs(qt_s60GetRFs()); - TInt err; - QFileSystemEntry absentry(absoluteName(entry)); - if (entry.isEmpty()) { - err = KErrNotFound; - } else if (absentry.isRoot()) { - //Root directories don't have an entry, and Entry() returns KErrBadName. - //Therefore get information about the volume instead. - TInt drive; - err = RFs::CharToDrive(TChar(absentry.nativeFilePath().at(0).unicode()), drive); - if (!err) { - TVolumeInfo info; - err = fs.Volume(info, drive); - if (!err) - data.fillFromVolumeInfo(info); - } - } else { - TEntry ent; - err = fs.Entry(qt_QString2TPtrC(absentry.nativeFilePath()), ent); - if (!err) - data.fillFromTEntry(ent); - } - if (err) { - data.size_ = 0; - data.modificationTime_ = TTime(0); - data.entryFlags &= ~(QFileSystemMetaData::SymbianTEntryFlags); - } - //files in /sys/bin on any drive are executable, even though we don't normally have permission to check whether they exist or not - if(absentry.filePath().midRef(1,10).compare(QLatin1String(":/sys/bin/"), Qt::CaseInsensitive) == 0) - data.entryFlags |= QFileSystemMetaData::ExecutePermissions; - } - return data.hasFlags(what); -} - -//static -bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool createParents) -{ - QString abspath = absoluteName(entry).nativeFilePath(); - if (!abspath.endsWith(QLatin1Char('\\'))) - abspath.append(QLatin1Char('\\')); - TInt r; - if (createParents) - r = qt_s60GetRFs().MkDirAll(qt_QString2TPtrC(abspath)); - else - r = qt_s60GetRFs().MkDir(qt_QString2TPtrC(abspath)); - if (createParents && r == KErrAlreadyExists) - return true; //# Qt5 - QDir::mkdir returns false for existing dir, QDir::mkpath returns true (should be made consistent in Qt 5) - return (r == KErrNone); -} - -//static -bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents) -{ - QString abspath = absoluteName(entry).nativeFilePath(); - if (!abspath.endsWith(QLatin1Char('\\'))) - abspath.append(QLatin1Char('\\')); - TPtrC dir(qt_QString2TPtrC(abspath)); - RFs& fs = qt_s60GetRFs(); - bool ok = false; - //behaviour of FS file engine: - //returns true if the directory could be removed - //success/failure of removing parent directories does not matter - while (KErrNone == fs.RmDir(dir)) { - ok = true; - if (!removeEmptyParents) - break; - //RFs::RmDir treats "c:\foo\bar" and "c:\foo\" the same, so it is sufficient to remove the last \ to the end - dir.Set(dir.Left(dir.LocateReverse(TChar('\\')))); - } - return ok; -} - -//static -bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) -{ - Q_UNUSED(source) - Q_UNUSED(target) - error = QSystemError(KErrNotSupported, QSystemError::NativeError); - return false; -} - -//static -bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) -{ - //CFileMan is allocated each time because it is not thread-safe - CFileMan *fm = 0; - TRAPD(err, fm = CFileMan::NewL(qt_s60GetRFs())); - if (err == KErrNone) { - err = fm->Copy(qt_QString2TPtrC(absoluteName(source).nativeFilePath()), qt_QString2TPtrC(absoluteName(target).nativeFilePath()), 0); - delete fm; - } - if (err == KErrNone) - return true; - error = QSystemError(err, QSystemError::NativeError); - return false; -} - -//static -bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) -{ - QString sourcepath = absoluteName(source).nativeFilePath(); - QString targetpath = absoluteName(target).nativeFilePath(); - RFs& fs(qt_s60GetRFs()); - TInt err = fs.Rename(qt_QString2TPtrC(sourcepath), qt_QString2TPtrC(targetpath)); - if (err == KErrNone) - return true; - error = QSystemError(err, QSystemError::NativeError); - return false; -} - -//static -bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry, QSystemError &error) -{ - QString targetpath = absoluteName(entry).nativeFilePath(); - RFs& fs(qt_s60GetRFs()); - TInt err = fs.Delete(qt_QString2TPtrC(targetpath)); - if (err == KErrNone) - return true; - error = QSystemError(err, QSystemError::NativeError); - return false; -} - -//static -bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QSystemError &error, QFileSystemMetaData *data) -{ - QString targetpath = absoluteName(entry).nativeFilePath(); - TUint setmask = 0; - TUint clearmask = 0; - RFs& fs(qt_s60GetRFs()); - if (permissions & (QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther)) - clearmask = KEntryAttReadOnly; //if anyone can write, it's not read-only - else - setmask = KEntryAttReadOnly; - TInt err = fs.SetAtt(qt_QString2TPtrC(targetpath), setmask, clearmask); - if (data && !err) { - data->entryFlags &= ~QFileSystemMetaData::Permissions; - data->entryFlags |= QFileSystemMetaData::MetaDataFlag(uint(permissions)); - data->knownFlagsMask |= QFileSystemMetaData::Permissions; - } - if (err == KErrNone) - return true; - error = QSystemError(err, QSystemError::NativeError); - return false; -} - -QString QFileSystemEngine::homePath() -{ - QString home = QDir::fromNativeSeparators(qt_TDesC2QString(PathInfo::PhoneMemoryRootPath())); - if(home.endsWith(QLatin1Char('/'))) - home.chop(1); - return home; -} - -QString QFileSystemEngine::rootPath() -{ - TChar drive; - TInt err = RFs::DriveToChar(RFs::GetSystemDrive(), drive); //RFs::GetSystemDriveChar not supported on S60 3.1 - Q_ASSERT(err == KErrNone); //RFs::GetSystemDrive() shall always return a convertible drive number on a valid OS configuration - return QString(QChar(drive)).append(QLatin1String(":/")); -} - -QString QFileSystemEngine::tempPath() -{ - return rootPath().append(QLatin1String("system/temp")); -} - -//static -bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry) -{ - QFileSystemMetaData meta; - QFileSystemEntry absname = absoluteName(entry); - fillMetaData(absname, meta, QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType); - if(!(meta.exists() && meta.isDirectory())) - return false; - - RFs& fs = qt_s60GetRFs(); - QString abspath = absname.nativeFilePath(); - if(!abspath.endsWith(QLatin1Char('\\'))) - abspath.append(QLatin1Char('\\')); - TInt r = fs.SetSessionPath(qt_QString2TPtrC(abspath)); - //SetSessionPath succeeds for non existent directory, which is why it's checked above - if (r == KErrNone) { - __ASSERT_COMPILE(sizeof(wchar_t) == sizeof(unsigned short)); - //attempt to set open C to the same path - r = ::wchdir(reinterpret_cast(absname.filePath().utf16())); - if (r < 0) - qWarning("failed to sync path to open C"); - return true; - } - return false; -} - -//static -QFileSystemEntry QFileSystemEngine::currentPath() -{ - TFileName fn; - QFileSystemEntry ret; - TInt r = qt_s60GetRFs().SessionPath(fn); - if(r == KErrNone) { - //remove terminating slash from non root paths (session path is clean, absolute and always ends in a \) - if(fn.Length() > 3 && fn[fn.Length() - 1] == '\\') - fn.SetLength(fn.Length() - 1); - ret = QFileSystemEntry(qt_TDesC2QString(fn), QFileSystemEntry::FromNativePath()); - } - return ret; -} - -QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemiterator_symbian.cpp b/src/corelib/io/qfilesystemiterator_symbian.cpp deleted file mode 100644 index 4347f6a..0000000 --- a/src/corelib/io/qfilesystemiterator_symbian.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qfilesystemiterator_p.h" -#include "qfilesystemengine_p.h" -#include - -QT_BEGIN_NAMESPACE - -QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &path, QDir::Filters filters, - const QStringList &nameFilters, QDirIterator::IteratorFlags iteratorFlags) - : lastError(KErrNone), entryIndex(-1) -{ - RFs& fs = qt_s60GetRFs(); - - nativePath = path.nativeFilePath(); - if (!nativePath.endsWith(QLatin1Char('\\'))) - nativePath.append(QLatin1Char('\\')); - - QString absPath = QFileSystemEngine::absoluteName(path).nativeFilePath(); - - if (!absPath.endsWith(QLatin1Char('\\'))) - absPath.append(QLatin1Char('\\')); - - int pathLen = absPath.length(); - if (pathLen > KMaxFileName) { - lastError = KErrBadName; - return; - } - - //set up server side filtering to reduce IPCs - //RDir won't accept all valid name filters e.g. "*. bar" - if (nameFilters.count() == 1 && !(filters & QDir::AllDirs) && iteratorFlags - == QDirIterator::NoIteratorFlags && pathLen + nameFilters[0].length() - <= KMaxFileName) { - //server side supports one mask - skip this for recursive mode or if only files should be filtered - absPath.append(nameFilters[0]); - } - - TUint symbianMask = 0; - if ((filters & QDir::Dirs) || (filters & QDir::AllDirs) || (iteratorFlags - & QDirIterator::Subdirectories)) - symbianMask |= KEntryAttDir; //include directories - if (filters & QDir::Hidden) - symbianMask |= KEntryAttHidden; - if (filters & QDir::System) - symbianMask |= KEntryAttSystem; - if (((filters & QDir::Files) == 0) && symbianMask == KEntryAttDir) - symbianMask |= KEntryAttMatchExclusive; //exclude non-directories - else if (symbianMask == 0) { - if ((filters & QDir::PermissionMask) == QDir::Writable) - symbianMask = KEntryAttMatchExclude | KEntryAttReadOnly; - } - - lastError = dirHandle.Open(fs, qt_QString2TPtrC(absPath), symbianMask); -} - -QFileSystemIterator::~QFileSystemIterator() -{ - dirHandle.Close(); -} - -bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData) -{ - //1st time, lastError is result of dirHandle.Open(), entries.Count() is 0 and entryIndex is -1 so initial read is triggered - //subsequent times, read is triggered each time we reach the end of the entry list - //final time, lastError is KErrEof so we don't need to read anymore. - ++entryIndex; - if (lastError == KErrNone && entryIndex >= entries.Count()) { - lastError = dirHandle.Read(entries); - entryIndex = 0; - } - - //each call to advance() gets the next entry from the entry list. - //from the final (or only) read call, KErrEof is returned together with a full buffer so we still need to go through the list - if ((lastError == KErrNone || lastError == KErrEof) && entryIndex < entries.Count()) { - Q_ASSERT(entryIndex >= 0); - const TEntry &entry(entries[entryIndex]); - fileEntry = QFileSystemEntry(nativePath + qt_TDesC2QString(entry.iName), QFileSystemEntry::FromNativePath()); - metaData.fillFromTEntry(entry); - return true; - } - - //TODO: error reporting, to allow user to distinguish empty directory from error condition. - - return false; -} - -QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp index 9739067..302b6e5 100644 --- a/src/corelib/io/qfilesystemwatcher.cpp +++ b/src/corelib/io/qfilesystemwatcher.cpp @@ -62,8 +62,6 @@ # include "qfilesystemwatcher_fsevents_p.h" # endif //MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) # include "qfilesystemwatcher_kqueue_p.h" -#elif defined(Q_OS_SYMBIAN) -# include "qfilesystemwatcher_symbian_p.h" #endif QT_BEGIN_NAMESPACE @@ -260,8 +258,6 @@ QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine() else # endif return QKqueueFileSystemWatcherEngine::create(); -#elif defined(Q_OS_SYMBIAN) - return new QSymbianFileSystemWatcherEngine; #else return 0; #endif diff --git a/src/corelib/io/qfilesystemwatcher_symbian.cpp b/src/corelib/io/qfilesystemwatcher_symbian.cpp deleted file mode 100644 index 6e5e911..0000000 --- a/src/corelib/io/qfilesystemwatcher_symbian.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qfilesystemwatcher.h" -#include "qfilesystemwatcher_symbian_p.h" -#include "qfileinfo.h" -#include "qdebug.h" -#include "private/qcore_symbian_p.h" -#include - -#ifndef QT_NO_FILESYSTEMWATCHER - - -QT_BEGIN_NAMESPACE - -QNotifyChangeEvent::QNotifyChangeEvent(RFs &fs, const TDesC &file, - QSymbianFileSystemWatcherEngine *e, bool aIsDir, - TInt aPriority) : - CActive(aPriority), - isDir(aIsDir), - fsSession(fs), - watchedPath(file), - engine(e), - failureCount(0) -{ - if (isDir) { - fsSession.NotifyChange(ENotifyEntry, iStatus, file); - } else { - fsSession.NotifyChange(ENotifyAll, iStatus, file); - } - CActiveScheduler::Add(this); - SetActive(); -} - -QNotifyChangeEvent::~QNotifyChangeEvent() -{ - Cancel(); -} - -void QNotifyChangeEvent::RunL() -{ - if(iStatus.Int() == KErrNone) { - failureCount = 0; - } else { - qWarning("QNotifyChangeEvent::RunL() - Failed to order change notifications: %d", iStatus.Int()); - failureCount++; - } - - // Re-request failed notification once, but if it won't start working, - // we can't do much besides just not request any more notifications. - if (failureCount < 2) { - if (isDir) { - fsSession.NotifyChange(ENotifyEntry, iStatus, watchedPath); - } else { - fsSession.NotifyChange(ENotifyAll, iStatus, watchedPath); - } - SetActive(); - - if (!failureCount) { - int err; - QT_TRYCATCH_ERROR(err, engine->emitPathChanged(this)); - if (err != KErrNone) - qWarning("QNotifyChangeEvent::RunL() - emitPathChanged threw exception (Converted error code: %d)", err); - } - } -} - -void QNotifyChangeEvent::DoCancel() -{ - fsSession.NotifyChangeCancel(iStatus); -} - -QSymbianFileSystemWatcherEngine::QSymbianFileSystemWatcherEngine() : - watcherStarted(false) -{ - moveToThread(this); -} - -QSymbianFileSystemWatcherEngine::~QSymbianFileSystemWatcherEngine() -{ - stop(); -} - -QStringList QSymbianFileSystemWatcherEngine::addPaths(const QStringList &paths, QStringList *files, - QStringList *directories) -{ - QMutexLocker locker(&mutex); - QStringList p = paths; - - startWatcher(); - - QMutableListIterator it(p); - while (it.hasNext()) { - QString path = it.next(); - QFileInfo fi(path); - if (!fi.exists()) - continue; - - bool isDir = fi.isDir(); - if (isDir) { - if (directories->contains(path)) - continue; - } else { - if (files->contains(path)) - continue; - } - - // Use absolute filepath as relative paths seem to have some issues. - QString filePath = fi.absoluteFilePath(); - if (isDir && filePath.at(filePath.size() - 1) != QChar(L'/')) { - filePath += QChar(L'/'); - } - - currentAddEvent = NULL; - QMetaObject::invokeMethod(this, - "addNativeListener", - Qt::QueuedConnection, - Q_ARG(QString, filePath)); - - syncCondition.wait(&mutex); - if (currentAddEvent) { - currentAddEvent->isDir = isDir; - - activeObjectToPath.insert(currentAddEvent, path); - it.remove(); - - if (isDir) - directories->append(path); - else - files->append(path); - } - } - - return p; -} - -QStringList QSymbianFileSystemWatcherEngine::removePaths(const QStringList &paths, - QStringList *files, - QStringList *directories) -{ - QMutexLocker locker(&mutex); - - QStringList p = paths; - QMutableListIterator it(p); - while (it.hasNext()) { - QString path = it.next(); - - currentRemoveEvent = activeObjectToPath.key(path); - if (!currentRemoveEvent) - continue; - activeObjectToPath.remove(currentRemoveEvent); - - QMetaObject::invokeMethod(this, - "removeNativeListener", - Qt::QueuedConnection); - - syncCondition.wait(&mutex); - - it.remove(); - - files->removeAll(path); - directories->removeAll(path); - } - - return p; -} - -void QSymbianFileSystemWatcherEngine::emitPathChanged(QNotifyChangeEvent *e) -{ - QMutexLocker locker(&mutex); - - QString path = activeObjectToPath.value(e); - QFileInfo fi(path); - - if (e->isDir) - emit directoryChanged(path, !fi.exists()); - else - emit fileChanged(path, !fi.exists()); -} - -void QSymbianFileSystemWatcherEngine::stop() -{ - quit(); - wait(); -} - -// This method must be called inside mutex -void QSymbianFileSystemWatcherEngine::startWatcher() -{ - if (!watcherStarted) { - setStackSize(0x5000); - start(); - syncCondition.wait(&mutex); - watcherStarted = true; - } -} - - -void QSymbianFileSystemWatcherEngine::run() -{ - mutex.lock(); - syncCondition.wakeOne(); - mutex.unlock(); - - exec(); - - foreach(QNotifyChangeEvent *e, activeObjectToPath.keys()) { - e->Cancel(); - delete e; - } - - activeObjectToPath.clear(); -} - -void QSymbianFileSystemWatcherEngine::addNativeListener(const QString &directoryPath) -{ - QMutexLocker locker(&mutex); - QString nativeDir(QDir::toNativeSeparators(directoryPath)); - TPtrC ptr(qt_QString2TPtrC(nativeDir)); - currentAddEvent = new QNotifyChangeEvent(qt_s60GetRFs(), ptr, this, directoryPath.endsWith(QChar(L'/'), Qt::CaseSensitive)); - syncCondition.wakeOne(); -} - -void QSymbianFileSystemWatcherEngine::removeNativeListener() -{ - QMutexLocker locker(&mutex); - currentRemoveEvent->Cancel(); - delete currentRemoveEvent; - currentRemoveEvent = NULL; - syncCondition.wakeOne(); -} - - -QT_END_NAMESPACE -#endif // QT_NO_FILESYSTEMWATCHER diff --git a/src/corelib/io/qfilesystemwatcher_symbian_p.h b/src/corelib/io/qfilesystemwatcher_symbian_p.h deleted file mode 100644 index 0b317a0..0000000 --- a/src/corelib/io/qfilesystemwatcher_symbian_p.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QFILESYSTEMWATCHER_SYMBIAN_P_H -#define QFILESYSTEMWATCHER_SYMBIAN_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qfilesystemwatcher_p.h" - -#ifndef QT_NO_FILESYSTEMWATCHER - -#include "qhash.h" -#include "qmutex.h" -#include "qwaitcondition.h" - -#include -#include - -QT_BEGIN_NAMESPACE - -class QSymbianFileSystemWatcherEngine; - -class QNotifyChangeEvent : public CActive -{ -public: - QNotifyChangeEvent(RFs &fsSession, const TDesC &file, QSymbianFileSystemWatcherEngine *engine, - bool aIsDir, TInt aPriority = EPriorityStandard); - ~QNotifyChangeEvent(); - - bool isDir; - -private: - void RunL(); - void DoCancel(); - - RFs &fsSession; - TPath watchedPath; - QSymbianFileSystemWatcherEngine *engine; - - int failureCount; -}; - -class QSymbianFileSystemWatcherEngine : public QFileSystemWatcherEngine -{ - Q_OBJECT - -public: - QSymbianFileSystemWatcherEngine(); - ~QSymbianFileSystemWatcherEngine(); - - QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories); - QStringList removePaths(const QStringList &paths, QStringList *files, - QStringList *directories); - - void stop(); - -protected: - void run(); - -public Q_SLOTS: - void addNativeListener(const QString &directoryPath); - void removeNativeListener(); - -private: - friend class QNotifyChangeEvent; - void emitPathChanged(QNotifyChangeEvent *e); - - void startWatcher(); - - QHash activeObjectToPath; - QMutex mutex; - QWaitCondition syncCondition; - bool watcherStarted; - QNotifyChangeEvent *currentAddEvent; - QNotifyChangeEvent *currentRemoveEvent; -}; - -#endif // QT_NO_FILESYSTEMWATCHER - -QT_END_NAMESPACE - -#endif // QFILESYSTEMWATCHER_WIN_P_H diff --git a/src/corelib/io/qprocess_symbian.cpp b/src/corelib/io/qprocess_symbian.cpp deleted file mode 100644 index 9fd0c3a..0000000 --- a/src/corelib/io/qprocess_symbian.cpp +++ /dev/null @@ -1,1072 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//#define QPROCESS_DEBUG - -#ifdef QPROCESS_DEBUG -#include "qdebug.h" -#define QPROCESS_DEBUG_PRINT(args...) qDebug(args); -#else -#define QPROCESS_DEBUG_PRINT(args...) -#endif - -#ifndef QT_NO_PROCESS - -#define QPROCESS_ASSERT(check, panicReason, args...) \ - if (!(check)) { \ - qWarning(args); \ - User::Panic(KQProcessPanic, panicReason); \ - } - -#include -#include -#include -#include -#include "qplatformdefs.h" - -#include "qdir.h" -#include "qstring.h" -#include "qprocess.h" -#include "qprocess_p.h" -#include "private/qeventdispatcher_symbian_p.h" - -#include -#include -#include -#include - -#include - - -QT_BEGIN_NAMESPACE - -_LIT(KQProcessManagerThreadName, "QProcManThread"); -_LIT(KQProcessPanic, "QPROCESS"); -enum TQProcessPanic { - EProcessManagerMediatorRunError = 1, - EProcessManagerMediatorInactive = 2, - EProcessManagerMediatorNotPending = 3, - EProcessManagerMediatorInvalidCmd = 4, - EProcessManagerMediatorCreationFailed = 5, - EProcessManagerMediatorThreadOpenFailed = 6, - EProcessManagerMediatorNullObserver = 7, - EProcessActiveRunError = 10, - EProcessActiveNullParameter = 11, - EProcessManagerMutexCreationFail = 20, - EProcessManagerThreadCreationFail = 21, - EProcessManagerSchedulerCreationFail = 22, - EProcessManagerNullParam = 23 -}; - -// Forward declarations -class QProcessManager; - - -// Active object to listen for child process death -class QProcessActive : public CActive -{ -public: - static QProcessActive *construct(QProcess *process, - RProcess **proc, - int serial, - int deathPipe); - - virtual ~QProcessActive(); - - void start(); - void stop(); - - bool error(); - -protected: - - // Inherited from CActive - void RunL(); - TInt RunError(TInt aError); - void DoCancel(); - - QProcessActive(); - -private: - - QProcess *process; - RProcess **pproc; - int serial; - int deathPipe; - bool errorValue; -}; - -// Active object to communicate synchronously with process manager thread -class QProcessManagerMediator : public CActive -{ -public: - static QProcessManagerMediator *construct(); - - virtual ~QProcessManagerMediator(); - - bool add(QProcessActive *processObserver); - void remove(QProcessActive *processObserver); - void terminate(); - -protected: - - enum Commands { - ENoCommand, - EAdd, - ERemove, - ETerminate - }; - - // Inherited from CActive - void RunL(); - TInt RunError(TInt aError); - void DoCancel(); - - QProcessManagerMediator(); - - bool notify(QProcessActive *processObserver, Commands command); - -private: - QProcessActive *currentObserver; - Commands currentCommand; - - RThread processManagerThread; -}; - -// Process manager manages child process death listeners. -// -// Note: Because QProcess can be used outside event loop, we cannot be guaranteed -// an active scheduler exists for us to add our process death listener objects. -// We can't just install active scheduler on the calling thread, as that would block it -// if we want to actually use it, so a separate manager thread is required. -class QProcessManager -{ -public: - QProcessManager(); - ~QProcessManager(); - - void startThread(); - - TInt run(void *param); - bool add(QProcess *process); - void remove(QProcess *process); - - inline void setMediator(QProcessManagerMediator *newMediator) { - mediator = newMediator; - }; - -private: - inline void lock() { - managerMutex.Wait(); - }; - inline void unlock() { - managerMutex.Signal(); - }; - - QMap children; - QProcessManagerMediator *mediator; - RMutex managerMutex; - bool threadStarted; - RThread managerThread; -}; - -static bool qt_rprocess_running(RProcess *proc) -{ - if (proc && proc->Handle()) { - TExitType et = proc->ExitType(); - if (et == EExitPending) - return true; - } - - return false; -} - -static void qt_create_symbian_commandline( - const QStringList &arguments, const QString &nativeArguments, QString &commandLine) -{ - for (int i = 0; i < arguments.size(); ++i) { - QString tmp = arguments.at(i); - // in the case of \" already being in the string the \ must also be escaped - tmp.replace(QLatin1String("\\\""), QLatin1String("\\\\\"")); - // escape a single " because the arguments will be parsed - tmp.replace(QLatin1String("\""), QLatin1String("\\\"")); - if (tmp.isEmpty() || tmp.contains(QLatin1Char(' ')) || tmp.contains(QLatin1Char('\t'))) { - // The argument must not end with a \ since this would be interpreted - // as escaping the quote -- rather put the \ behind the quote: e.g. - // rather use "foo"\ than "foo\" - QString endQuote(QLatin1String("\"")); - int i = tmp.length(); - while (i > 0 && tmp.at(i - 1) == QLatin1Char('\\')) { - --i; - endQuote += QLatin1String("\\"); - } - commandLine += QLatin1String("\"") + tmp.left(i) + endQuote + QLatin1Char(' '); - } else { - commandLine += tmp + QLatin1Char(' '); - } - } - - if (!nativeArguments.isEmpty()) - commandLine += nativeArguments; - else if (!commandLine.isEmpty()) // Chop the extra trailing space if any arguments were appended - commandLine.chop(1); -} - -static TInt qt_create_symbian_process(RProcess **proc, - const QString &programName, const QStringList &arguments, const QString &nativeArguments) -{ - RProcess *newProc = NULL; - newProc = new RProcess(); - - if (!newProc) - return KErrNoMemory; - - QString commandLine; - qt_create_symbian_commandline(arguments, nativeArguments, commandLine); - - TPtrC program_ptr(reinterpret_cast(programName.constData())); - TPtrC cmdline_ptr(reinterpret_cast(commandLine.constData())); - - TInt err = newProc->Create(program_ptr, cmdline_ptr); - - if (err == KErrNotFound) { - // Strip path from program name and try again (i.e. try from default location "\sys\bin") - int index = programName.lastIndexOf(QDir::separator()); - int index2 = programName.lastIndexOf(QChar(QLatin1Char('/'))); - index = qMax(index, index2); - - if (index != -1 && programName.length() >= index) { - QString strippedName; - strippedName = programName.mid(index + 1); - QPROCESS_DEBUG_PRINT("qt_create_symbian_process() Executable '%s' not found, trying stripped version '%s'", - qPrintable(programName), qPrintable(strippedName)); - - TPtrC stripped_ptr(reinterpret_cast(strippedName.constData())); - err = newProc->Create(stripped_ptr, cmdline_ptr); - - if (err != KErrNone) { - QPROCESS_DEBUG_PRINT("qt_create_symbian_process() Unable to create process '%s': %d", - qPrintable(strippedName), err); - } - } - } - - if (err == KErrNone) - *proc = newProc; - else - delete newProc; - - return err; -} - -static qint64 qt_native_read(int fd, char *data, qint64 maxlen) -{ - qint64 ret = 0; - do { - ret = ::read(fd, data, maxlen); - } while (ret == -1 && errno == EINTR); - - QPROCESS_DEBUG_PRINT("qt_native_read(): fd: %d, result: %d, errno = %d", fd, (int)ret, errno); - - return ret; -} - -static qint64 qt_native_write(int fd, const char *data, qint64 len) -{ - qint64 ret = 0; - do { - ret = ::write(fd, data, len); - } while (ret == -1 && errno == EINTR); - - QPROCESS_DEBUG_PRINT("qt_native_write(): fd: %d, result: %d, errno = %d", fd, (int)ret, errno); - - return ret; -} - -static void qt_native_close(int fd) -{ - int ret; - do { - ret = ::close(fd); - } while (ret == -1 && errno == EINTR); -} - -static void qt_create_pipe(int *pipe) -{ - if (pipe[0] != -1) - qt_native_close(pipe[0]); - if (pipe[1] != -1) - qt_native_close(pipe[1]); - if (::pipe(pipe) != 0) { - qWarning("QProcessPrivate::createPipe: Cannot create pipe %p: %s", - pipe, qPrintable(qt_error_string(errno))); - } else { - QPROCESS_DEBUG_PRINT("qt_create_pipe(): Created pipe %d - %d", pipe[0], pipe[1]); - } -} - -// Called from ProcessManagerThread -QProcessActive *QProcessActive::construct(QProcess *process, - RProcess **proc, - int serial, - int deathPipe) -{ - QPROCESS_ASSERT((process || proc || *proc), - EProcessActiveNullParameter, - "QProcessActive::construct(): process (0x%x), proc (0x%x) or *proc == NULL, not creating an instance", process, proc) - - QProcessActive *newInstance = new QProcessActive(); - - if (!newInstance) { - QPROCESS_DEBUG_PRINT("QProcessActive::construct(): Failed to create new instance"); - } else { - newInstance->process = process; - newInstance->pproc = proc; - newInstance->serial = serial; - newInstance->deathPipe = deathPipe; - newInstance->errorValue = false; - } - - return newInstance; -} - -// Called from ProcessManagerThread -QProcessActive::QProcessActive() - : CActive(CActive::EPriorityStandard) -{ - // Nothing to do -} - -// Called from main thread -QProcessActive::~QProcessActive() -{ - process = NULL; - pproc = NULL; -} - -// Called from ProcessManagerThread -void QProcessActive::start() -{ - if (qt_rprocess_running(*pproc)) { - CActiveScheduler::Add(this); - (*pproc)->Logon(iStatus); - SetActive(); - QPROCESS_DEBUG_PRINT("QProcessActive::start(): Started monitoring for process exit."); - } else { - QPROCESS_DEBUG_PRINT("QProcessActive::start(): Process doesn't exist or is already dead"); - // Assume process has already died - qt_native_write(deathPipe, "", 1); - errorValue = true; - } -} - -// Called from ProcessManagerThread -void QProcessActive::stop() -{ - QPROCESS_DEBUG_PRINT("QProcessActive::stop()"); - - // Remove this from scheduler (also cancels the request) - Deque(); -} - -bool QProcessActive::error() -{ - return errorValue; -} - -// Called from ProcessManagerThread -void QProcessActive::RunL() -{ - // If this method gets executed, the monitored process has died - - // Notify main thread - qt_native_write(deathPipe, "", 1); - QPROCESS_DEBUG_PRINT("QProcessActive::RunL() sending death notice to %d", deathPipe); -} - -// Called from ProcessManagerThread -TInt QProcessActive::RunError(TInt aError) -{ - Q_UNUSED(aError); - // Handle RunL leave (should never happen) - QPROCESS_ASSERT(0, EProcessActiveRunError, "QProcessActive::RunError(): Should never get here!") - return 0; -} - -// Called from ProcessManagerThread -void QProcessActive::DoCancel() -{ - QPROCESS_DEBUG_PRINT("QProcessActive::DoCancel()"); - - if (qt_rprocess_running(*pproc)) { - (*pproc)->LogonCancel(iStatus); - QPROCESS_DEBUG_PRINT("QProcessActive::DoCancel(): Stopped monitoring for process exit."); - } else { - QPROCESS_DEBUG_PRINT("QProcessActive::DoCancel(): Process doesn't exist"); - } -} - - -// Called from ProcessManagerThread -QProcessManagerMediator *QProcessManagerMediator::construct() -{ - QProcessManagerMediator *newInstance = new QProcessManagerMediator; - TInt err(KErrNone); - - newInstance->currentCommand = ENoCommand; - newInstance->currentObserver = NULL; - - if (newInstance) { - err = newInstance->processManagerThread.Open(newInstance->processManagerThread.Id()); - QPROCESS_ASSERT((err == KErrNone), - EProcessManagerMediatorThreadOpenFailed, - "QProcessManagerMediator::construct(): Failed to open processManagerThread (err:%d)", err) - } else { - QPROCESS_ASSERT(0, - EProcessManagerMediatorCreationFailed, - "QProcessManagerMediator::construct(): Failed to open construct mediator") - } - - // Activate mediator - CActiveScheduler::Add(newInstance); - newInstance->iStatus = KRequestPending; - newInstance->SetActive(); - QPROCESS_DEBUG_PRINT("QProcessManagerMediator::construct(): new instance successfully created and activated"); - - return newInstance; -} - -// Called from ProcessManagerThread -QProcessManagerMediator::QProcessManagerMediator() - : CActive(CActive::EPriorityStandard) -{ - // Nothing to do -} - -// Called from main thread -QProcessManagerMediator::~QProcessManagerMediator() -{ - processManagerThread.Close(); - currentCommand = ENoCommand; - currentObserver = NULL; -} - -// Called from main thread -bool QProcessManagerMediator::add(QProcessActive *processObserver) -{ - QPROCESS_DEBUG_PRINT("QProcessManagerMediator::add()"); - return notify(processObserver, EAdd); -} - -// Called from main thread -void QProcessManagerMediator::remove(QProcessActive *processObserver) -{ - QPROCESS_DEBUG_PRINT("QProcessManagerMediator::remove()"); - notify(processObserver, ERemove); -} - -// Called from main thread -void QProcessManagerMediator::terminate() -{ - QPROCESS_DEBUG_PRINT("QProcessManagerMediator::terminate()"); - notify(NULL, ETerminate); -} - -// Called from main thread -bool QProcessManagerMediator::notify(QProcessActive *processObserver, Commands command) -{ - bool success(true); - - QPROCESS_DEBUG_PRINT("QProcessManagerMediator::Notify(): Command: %d, processObserver: 0x%x", command, processObserver); - - QPROCESS_ASSERT((command == ETerminate || processObserver), - EProcessManagerMediatorNullObserver, - "QProcessManagerMediator::Notify(): NULL processObserver not allowed for command: %d", command) - - QPROCESS_ASSERT(IsActive(), - EProcessManagerMediatorInactive, - "QProcessManagerMediator::Notify(): Mediator is not active!") - - QPROCESS_ASSERT(iStatus == KRequestPending, - EProcessManagerMediatorNotPending, - "QProcessManagerMediator::Notify(): Mediator request not pending!") - - currentObserver = processObserver; - currentCommand = command; - - // Sync with process manager thread - TRequestStatus pmStatus; - processManagerThread.Rendezvous(pmStatus); - - // Complete request -> RunL will run in the process manager thread - TRequestStatus *status = &iStatus; - processManagerThread.RequestComplete(status, command); - - QPROCESS_DEBUG_PRINT("QProcessManagerMediator::Notify(): Waiting process manager to complete..."); - User::WaitForRequest(pmStatus); - QPROCESS_DEBUG_PRINT("QProcessManagerMediator::Notify(): Wait over"); - - if (currentObserver) { - success = !(currentObserver->error()); - QPROCESS_DEBUG_PRINT("QProcessManagerMediator::Notify(): success = %d", success); - } - - currentObserver = NULL; - currentCommand = ENoCommand; - - return success; -} - -// Called from ProcessManagerThread -void QProcessManagerMediator::RunL() -{ - QPROCESS_DEBUG_PRINT("QProcessManagerMediator::RunL(): currentCommand: %d, iStatus: %d", currentCommand, iStatus.Int()); - switch (currentCommand) { - case EAdd: - currentObserver->start(); - break; - case ERemove: - currentObserver->stop(); - break; - case ETerminate: - Deque(); - CActiveScheduler::Stop(); - return; - default: - QPROCESS_ASSERT(0, - EProcessManagerMediatorInvalidCmd, - "QProcessManagerMediator::RunL(): Invalid command!") - break; - } - - iStatus = KRequestPending; - SetActive(); - - // Notify main thread that we are done - RThread::Rendezvous(KErrNone); -} - -// Called from ProcessManagerThread -TInt QProcessManagerMediator::RunError(TInt aError) -{ - Q_UNUSED(aError); - // Handle RunL leave (should never happen) - QPROCESS_ASSERT(0, - EProcessManagerMediatorRunError, - "QProcessManagerMediator::RunError(): Should never get here!") - return 0; -} - -// Called from ProcessManagerThread -void QProcessManagerMediator::DoCancel() -{ - QPROCESS_DEBUG_PRINT("QProcessManagerMediator::DoCancel()"); - TRequestStatus *status = &iStatus; - processManagerThread.RequestComplete(status, KErrCancel); -} - -Q_GLOBAL_STATIC(QProcessManager, processManager) - -TInt processManagerThreadFunction(TAny *param) -{ - QPROCESS_ASSERT(param, - EProcessManagerNullParam, - "processManagerThreadFunction(): NULL param") - - QProcessManager *manager = reinterpret_cast(param); - - CActiveScheduler *scheduler = new CQtActiveScheduler(); - - QPROCESS_ASSERT(scheduler, - EProcessManagerSchedulerCreationFail, - "processManagerThreadFunction(): Scheduler creation failed") - - CActiveScheduler::Install(scheduler); - - //Creating mediator also adds it to scheduler and activates it. Failure will panic. - manager->setMediator(QProcessManagerMediator::construct()); - RThread::Rendezvous(KErrNone); - - CActiveScheduler::Start(); - - CActiveScheduler::Install(NULL); - delete scheduler; - - return KErrNone; -} - -QProcessManager::QProcessManager() - : mediator(NULL), threadStarted(false) -{ - TInt err = managerMutex.CreateLocal(); - - QPROCESS_ASSERT(err == KErrNone, - EProcessManagerMutexCreationFail, - "QProcessManager::QProcessManager(): Failed to create new managerMutex (err: %d)", err) -} - -QProcessManager::~QProcessManager() -{ - QPROCESS_DEBUG_PRINT("QProcessManager::~QProcessManager()"); - - // Check if manager thread is still alive. If this destructor is ran as part of global - // static cleanup, manager thread will most likely be terminated by kernel at this point, - // so trying to delete QProcessActives and QProcessMediators will panic as they - // will still be active. They can also no longer be canceled as the thread is already gone. - // In case manager thread has already died, we simply do nothing and let the deletion of - // the main heap at process exit take care of stray objects. - - if (managerThread.Handle() && managerThread.ExitType() == EExitPending) { - // Cancel death listening for all child processes - if (mediator) { - QMap::Iterator it = children.begin(); - while (it != children.end()) { - // Remove all monitors - QProcessActive *active = it.value(); - mediator->remove(active); - - QPROCESS_DEBUG_PRINT("QProcessManager::~QProcessManager() removed listening for a process"); - ++it; - } - - // Terminate process manager thread. - mediator->terminate(); - delete mediator; - } - - qDeleteAll(children.values()); - children.clear(); - } - - managerThread.Close(); - managerMutex.Close(); -} - -void QProcessManager::startThread() -{ - lock(); - - if (!threadStarted) { - TInt err = managerThread.Create(KQProcessManagerThreadName, - processManagerThreadFunction, - 0x5000, - (RAllocator*)NULL, - (TAny*)this, - EOwnerProcess); - - QPROCESS_ASSERT(err == KErrNone, - EProcessManagerThreadCreationFail, - "QProcessManager::startThread(): Failed to create new managerThread (err:%d)", err) - - threadStarted = true; - - // Manager thread must start running before we continue, so sync with rendezvous - TRequestStatus status; - managerThread.Rendezvous(status); - managerThread.Resume(); - User::WaitForRequest(status); - } - - unlock(); -} - -static QBasicAtomicInt idCounter = Q_BASIC_ATOMIC_INITIALIZER(1); - -bool QProcessManager::add(QProcess *process) -{ - QPROCESS_ASSERT(process, - EProcessManagerNullParam, - "QProcessManager::add(): Failed to add QProcessActive to ProcessManager - NULL process") - - lock(); - - int serial = idCounter.fetchAndAddRelaxed(1); - process->d_func()->serial = serial; - - QPROCESS_DEBUG_PRINT("QProcessManager::add(): serial: %d, deathPipe: %d - %d, symbianProcess: 0x%x", serial, process->d_func()->deathPipe[0], process->d_func()->deathPipe[1], process->d_func()->symbianProcess); - - QProcessActive *newActive = - QProcessActive::construct(process, - &(process->d_func()->symbianProcess), - serial, - process->d_func()->deathPipe[1]); - - if (newActive) { - if (mediator->add(newActive)) { - children.insert(serial, newActive); - unlock(); - return true; - } else { - QPROCESS_DEBUG_PRINT("QProcessManager::add(): Failed to add QProcessActive to ProcessManager"); - delete newActive; - } - } - - unlock(); - - return false; -} - -void QProcessManager::remove(QProcess *process) -{ - QPROCESS_ASSERT(process, - EProcessManagerNullParam, - "QProcessManager::remove(): Failed to remove QProcessActive from ProcessManager - NULL process") - - lock(); - - int serial = process->d_func()->serial; - QProcessActive *active = children.value(serial); - if (!active) { - unlock(); - return; - } - - mediator->remove(active); - - children.remove(serial); - delete active; - - unlock(); -} - -void QProcessPrivate::destroyPipe(int *pipe) -{ - if (pipe[1] != -1) { - qt_native_close(pipe[1]); - pipe[1] = -1; - } - if (pipe[0] != -1) { - qt_native_close(pipe[0]); - pipe[0] = -1; - } -} - -bool QProcessPrivate::createChannel(Channel &channel) -{ - Q_UNUSED(channel); - // No channels used - return false; -} - -void QProcessPrivate::startProcess() -{ - Q_Q(QProcess); - - QPROCESS_DEBUG_PRINT("QProcessPrivate::startProcess()"); - - // Start the process (platform dependent) - q->setProcessState(QProcess::Starting); - - processManager()->startThread(); - - qt_create_pipe(deathPipe); - if (threadData->eventDispatcher) { - deathNotifier = new QSocketNotifier(deathPipe[0], - QSocketNotifier::Read, q); - QObject::connect(deathNotifier, SIGNAL(activated(int)), - q, SLOT(_q_processDied())); - } - - TInt err = qt_create_symbian_process(&symbianProcess, program, arguments, nativeArguments); - - if (err == KErrNone) { - pid = symbianProcess->Id().Id(); - - ::fcntl(deathPipe[0], F_SETFL, ::fcntl(deathPipe[0], F_GETFL) | O_NONBLOCK); - - if (!processManager()->add(q)) { - qWarning("QProcessPrivate::startProcess(): Failed to start monitoring for process death."); - err = KErrNoMemory; - } - } - - if (err != KErrNone) { - // Cleanup, report error and return - QPROCESS_DEBUG_PRINT("QProcessPrivate::startProcess() Process open failed, err: %d, '%s'", err, qPrintable(program)); - q->setProcessState(QProcess::NotRunning); - processError = QProcess::FailedToStart; - q->setErrorString(QLatin1String(QT_TRANSLATE_NOOP(QProcess, "Resource error (qt_create_symbian_process failure)"))); - emit q->error(processError); - cleanup(); - return; - } - - processLaunched = true; - - symbianProcess->Resume(); - - QPROCESS_DEBUG_PRINT("QProcessPrivate::startProcess(): this: 0x%x, pid: %ld", this, pid); - - // Notify child start - _q_startupNotification(); - -} - -bool QProcessPrivate::processStarted() -{ - QPROCESS_DEBUG_PRINT("QProcessPrivate::processStarted() == %s", processLaunched ? "true" : "false"); - - // Since we cannot get information whether process has actually been launched - // or not in Symbian, we need to fake it. Assume process is started if launch was - // successful. - - return processLaunched; -} - -qint64 QProcessPrivate::bytesAvailableFromStdout() const -{ - // In Symbian, stdout is not supported - return 0; -} - -qint64 QProcessPrivate::bytesAvailableFromStderr() const -{ - // In Symbian, stderr is not supported - return 0; -} - -qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen) -{ - Q_UNUSED(data); - Q_UNUSED(maxlen); - // In Symbian, stdout is not supported - return 0; -} - -qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen) -{ - Q_UNUSED(data); - Q_UNUSED(maxlen); - // In Symbian, stderr is not supported - return 0; -} - -qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) -{ - Q_UNUSED(data); - Q_UNUSED(maxlen); - // In Symbian, stdin is not supported - return 0; -} - -void QProcessPrivate::terminateProcess() -{ - // Needs PowerMgmt capability if process has been started; will panic kern-exec 46 otherwise. - // Always works if process is not yet started. - if (qt_rprocess_running(symbianProcess)) { - symbianProcess->Terminate(0); - } else { - QPROCESS_DEBUG_PRINT("QProcessPrivate::terminateProcess(), Process not running"); - } -} - -void QProcessPrivate::killProcess() -{ - // Needs PowerMgmt capability if process has been started; will panic kern-exec 46 otherwise. - // Always works if process is not yet started. - if (qt_rprocess_running(symbianProcess)) { - symbianProcess->Kill(0); - } else { - QPROCESS_DEBUG_PRINT("QProcessPrivate::killProcess(), Process not running"); - } -} - -bool QProcessPrivate::waitForStarted(int msecs) -{ - Q_UNUSED(msecs); - // Since we can get no actual feedback from process beyond its death, - // assume that started has already been emitted if process has been launched - return processLaunched; -} - -bool QProcessPrivate::waitForReadyRead(int msecs) -{ - // Functionality not supported in Symbian - Q_UNUSED(msecs); - return false; -} - -bool QProcessPrivate::waitForBytesWritten(int msecs) -{ - // Functionality not supported in Symbian - Q_UNUSED(msecs); - return false; -} - -bool QProcessPrivate::waitForFinished(int msecs) -{ - Q_Q(QProcess); - QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForFinished(%d)", msecs); - - TRequestStatus timerStatus = KErrNone; - TRequestStatus logonStatus = KErrNone; - bool timeoutOccurred = false; - - // Logon to process to observe its death - if (qt_rprocess_running(symbianProcess)) { - symbianProcess->Logon(logonStatus); - - if (msecs < 0) { - // If timeout is negative, there is no timeout - QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForFinished() - Waiting (just logon)..."); - User::WaitForRequest(logonStatus); - QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForFinished() - Wait completed"); - } else { - // Create timer - RTimer timer; - timer.CreateLocal(); - TTimeIntervalMicroSeconds32 interval(msecs*1000); - timer.After(timerStatus, interval); - - QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForFinished() - Waiting (logon + timer)..."); - User::WaitForRequest(logonStatus, timerStatus); - QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForFinished() - Wait completed"); - - if (logonStatus != KRequestPending) { - timer.Cancel(); - User::WaitForRequest(timerStatus); - } else { - timeoutOccurred = true; - symbianProcess->LogonCancel(logonStatus); - User::WaitForRequest(logonStatus); - } - timer.Close(); - } - } else { - QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForFinished(), qt_rprocess_running returned false"); - } - - if (timeoutOccurred) { - processError = QProcess::Timedout; - q->setErrorString(QLatin1String(QT_TRANSLATE_NOOP(QProcess, "Process operation timed out"))); - return false; - } - - _q_processDied(); - - return true; -} - -bool QProcessPrivate::waitForWrite(int msecs) -{ - // Functionality not supported in Symbian - Q_UNUSED(msecs); - return false; -} - -// Deceptively named function. Exit code is actually got in waitForDeadChild(). -void QProcessPrivate::findExitCode() -{ - Q_Q(QProcess); - processManager()->remove(q); -} - -bool QProcessPrivate::waitForDeadChild() -{ - Q_Q(QProcess); - - // read a byte from the death pipe - char c; - qt_native_read(deathPipe[0], &c, 1); - - if (symbianProcess && symbianProcess->Handle()) { - TExitType et = symbianProcess->ExitType(); - QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForDeadChild() symbianProcess->ExitType: %d", et); - if (et != EExitPending) { - processManager()->remove(q); - exitCode = symbianProcess->ExitReason(); - crashed = (et == EExitPanic); -#if defined QPROCESS_DEBUG - TExitCategoryName catName = symbianProcess->ExitCategory(); - qDebug() << "QProcessPrivate::waitForDeadChild() dead with exitCode" - << exitCode << ", crashed:" << crashed - << ", category:" << QString((const QChar *)catName.Ptr()); -#endif - } else { - QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForDeadChild() not dead!"); - } - } - - return true; -} - -void QProcessPrivate::_q_notified() -{ - // Nothing to do in Symbian -} - -bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid) -{ - QPROCESS_DEBUG_PRINT("QProcessPrivate::startDetached()"); - Q_UNUSED(workingDirectory); - - RProcess *newProc = NULL; - - TInt err = qt_create_symbian_process(&newProc, program, arguments, QString()); - - if (err == KErrNone) { - if (pid) - *pid = newProc->Id().Id(); - - newProc->Resume(); - newProc->Close(); - delete newProc; - return true; - } - - return false; -} - - -void QProcessPrivate::initializeProcessManager() -{ - (void) processManager(); -} - -QProcessEnvironment QProcessEnvironment::systemEnvironment() -{ - return QProcessEnvironment(); -} - -QT_END_NAMESPACE - -#endif // QT_NO_PROCESS -- 2.7.4