⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qfilesystemwatcher_inotify.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtCore module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.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 GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qfilesystemwatcher.h"#include "qfilesystemwatcher_inotify_p.h"#ifndef QT_NO_FILESYSTEMWATCHER#include <qdebug.h>#include <qfile.h>#include <qfileinfo.h>#include <qsocketnotifier.h>#include <qvarlengtharray.h>#include <sys/syscall.h>#include <sys/ioctl.h>#include <unistd.h>#include <fcntl.h>#if defined(QT_NO_INOTIFY)#include <linux/types.h>#if defined(__i386__)# define __NR_inotify_init      291# define __NR_inotify_add_watch 292# define __NR_inotify_rm_watch  293#elif defined(__x86_64__)# define __NR_inotify_init      253# define __NR_inotify_add_watch 254# define __NR_inotify_rm_watch  255#elif defined(__powerpc__) || defined(__powerpc64__)# define __NR_inotify_init      275# define __NR_inotify_add_watch 276# define __NR_inotify_rm_watch  277#elif defined (__ia64__)# define __NR_inotify_init      1277# define __NR_inotify_add_watch 1278# define __NR_inotify_rm_watch  1279#elif defined (__s390__) || defined (__s390x__)# define __NR_inotify_init      284# define __NR_inotify_add_watch 285# define __NR_inotify_rm_watch  286#elif defined (__alpha__)# define __NR_inotify_init      444# define __NR_inotify_add_watch 445# define __NR_inotify_rm_watch  446#elif defined (__sparc__) || defined (__sparc64__)# define __NR_inotify_init      151# define __NR_inotify_add_watch 152# define __NR_inotify_rm_watch  156#elif defined (__arm__)# define __NR_inotify_init      316# define __NR_inotify_add_watch 317# define __NR_inotify_rm_watch  318#elif defined (__SH4__)# define __NR_inotify_init      290# define __NR_inotify_add_watch 291# define __NR_inotify_rm_watch  292#elif defined (__SH5__)# define __NR_inotify_init      318# define __NR_inotify_add_watch 319# define __NR_inotify_rm_watch  320#elif defined (__mips__)# define __NR_inotify_init      284# define __NR_inotify_add_watch 285# define __NR_inotify_rm_watch  286#elif defined (__hppa__)# define __NR_inotify_init      269# define __NR_inotify_add_watch 270# define __NR_inotify_rm_watch  271#else# error "This architecture is not supported. Please talk to qt-bugs@trolltech.com"#endif#ifdef QT_LSB// ### the LSB doesn't standardize syscall, need to wait until glib2.4 is standardizedstatic inline int syscall(...) { return -1; }#endifstatic inline int inotify_init(){    return syscall(__NR_inotify_init);}static inline int inotify_add_watch(int fd, const char *name, __u32 mask){    return syscall(__NR_inotify_add_watch, fd, name, mask);}static inline int inotify_rm_watch(int fd, __u32 wd){    return syscall(__NR_inotify_rm_watch, fd, wd);}// the following struct and values are documented in linux/inotify.hextern "C" {struct inotify_event {        __s32           wd;        __u32           mask;        __u32           cookie;        __u32           len;        char            name[0];};#define IN_ACCESS               0x00000001#define IN_MODIFY               0x00000002#define IN_ATTRIB               0x00000004#define IN_CLOSE_WRITE          0x00000008#define IN_CLOSE_NOWRITE        0x00000010#define IN_OPEN                 0x00000020#define IN_MOVED_FROM           0x00000040#define IN_MOVED_TO             0x00000080#define IN_CREATE               0x00000100#define IN_DELETE               0x00000200#define IN_DELETE_SELF          0x00000400#define IN_MOVE_SELF            0x00000800#define IN_UNMOUNT              0x00002000#define IN_Q_OVERFLOW           0x00004000#define IN_CLOSE                (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)#define IN_MOVE                 (IN_MOVED_FROM | IN_MOVED_TO)}// --------- inotify.h end ----------#else /* QT_NO_INOTIFY */#include <sys/inotify.h>#endifQInotifyFileSystemWatcherEngine *QInotifyFileSystemWatcherEngine::create(){    int fd = inotify_init();    if (fd <= 0)        return 0;    return new QInotifyFileSystemWatcherEngine(fd);}QInotifyFileSystemWatcherEngine::QInotifyFileSystemWatcherEngine(int fd)    : inotifyFd(fd){    fcntl(inotifyFd, F_SETFD, FD_CLOEXEC);    moveToThread(this);}QInotifyFileSystemWatcherEngine::~QInotifyFileSystemWatcherEngine(){    foreach (int id, pathToID.values())        inotify_rm_watch(inotifyFd, id < 0 ? -id : id);    ::close(inotifyFd);}void QInotifyFileSystemWatcherEngine::run(){    QSocketNotifier sn(inotifyFd, QSocketNotifier::Read, this);    connect(&sn, SIGNAL(activated(int)), SLOT(readFromInotify()));    (void) exec();}QStringList QInotifyFileSystemWatcherEngine::addPaths(const QStringList &paths,                                                      QStringList *files,                                                      QStringList *directories){    QMutexLocker locker(&mutex);    QStringList p = paths;    QMutableListIterator<QString> it(p);    while (it.hasNext()) {        QString path = it.next();        QFileInfo fi(path);        bool isDir = fi.isDir();        if (isDir) {            if (directories->contains(path))                continue;        } else {            if (files->contains(path))                continue;        }        int wd = inotify_add_watch(inotifyFd,                                   QFile::encodeName(path),                                   (isDir                                    ? (0                                       | IN_ATTRIB                                       | IN_MOVE                                       | IN_CREATE                                       | IN_DELETE                                       | IN_DELETE_SELF                                       )                                    : (0                                       | IN_ATTRIB                                       | IN_MODIFY                                       | IN_MOVE                                       | IN_DELETE_SELF                                       )));        if (wd <= 0) {            perror("QInotifyFileSystemWatcherEngine::addPaths: inotify_add_watch failed");            continue;        }        it.remove();        int id = isDir ? -wd : wd;        if (id < 0) {            directories->append(path);        } else {            files->append(path);        }        pathToID.insert(path, id);        idToPath.insert(id, path);    }    start();    return p;}QStringList QInotifyFileSystemWatcherEngine::removePaths(const QStringList &paths,                                                         QStringList *files,                                                         QStringList *directories){    QMutexLocker locker(&mutex);    QStringList p = paths;    QMutableListIterator<QString> it(p);    while (it.hasNext()) {        QString path = it.next();        int id = pathToID.take(path);        QString x = idToPath.take(id);        if (x.isEmpty() || x != path)            continue;        int wd = id < 0 ? -id : id;        // qDebug() << "removing watch for path" << path << "wd" << wd;        inotify_rm_watch(inotifyFd, wd);        it.remove();        if (id < 0) {            directories->removeAll(path);        } else {            files->removeAll(path);        }    }    return p;}void QInotifyFileSystemWatcherEngine::stop(){    QMetaObject::invokeMethod(this, "quit");}void QInotifyFileSystemWatcherEngine::readFromInotify(){    QMutexLocker locker(&mutex);    // qDebug() << "QInotifyFileSystemWatcherEngine::readFromInotify";    int buffSize = 0;    ioctl(inotifyFd, FIONREAD, &buffSize);    QVarLengthArray<char, 4096> buffer(buffSize);    buffSize = read(inotifyFd, buffer.data(), buffSize);    inotify_event *ev = reinterpret_cast<inotify_event *>(buffer.data());    inotify_event *end = reinterpret_cast<inotify_event *>(buffer.data() + buffSize);    while (ev < end) {        // qDebug() << "inotify event, wd" << ev->wd << "mask" << hex << ev->mask;        int id = ev->wd;        QString path = idToPath.value(id);        if (path.isEmpty()) {            // perhaps a directory?            id = -id;            path = idToPath.value(id);            if (path.isEmpty()) {                ev += sizeof(inotify_event) + ev->len;                continue;            }        }        // qDebug() << "event for path" << path;        if ((ev->mask & (IN_DELETE_SELF | IN_UNMOUNT)) != 0) {            pathToID.remove(path);            idToPath.remove(id);            inotify_rm_watch(inotifyFd, ev->wd);            if (id < 0)                emit directoryChanged(path, true);            else                emit fileChanged(path, true);        } else {            if (id < 0)                emit directoryChanged(path, false);            else                emit fileChanged(path, false);        }        ev += sizeof(inotify_event) + ev->len;    }}#endif // QT_NO_FILESYSTEMWATCHER

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -