/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. */ #include #include #include #include #include #include #include #include "smdirwatcher.h" extern int errno; SmDirWatcher::SmDirWatcher(QObject *parent) : QThread(parent), mFd(0), mDescr(0) { mFd = inotify_init1(IN_NONBLOCK); } SmDirWatcher::~SmDirWatcher(){ if(mFd && mDescr){ inotify_rm_watch(mFd, mDescr); } } void SmDirWatcher::setDir(const QString &dir){ QMutexLocker lock(&mWatchMx); if(mDescr){ inotify_rm_watch(mFd, mDescr); //generates IN_IGNORE ??? } /* mask rationale: * IN_DELETE_SELF, IN_MOVE_TO and IN_MOVE_FROM cannot happen, * since we're only watching one directory at all times * don't care about the other events */ mDescr = inotify_add_watch(mFd, qPrintable(dir), IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | IN_MODIFY); mCurrent = dir; } #include void SmDirWatcher::run(){ QMutexLocker lock(&mWatchMx); QVarLengthArray data(ioctl(mFd, FIONREAD) + 1); int r = read(mFd, data.data(), data.size()); while(r < 0){ int err = errno; // buffer too small if(err == EINVAL){ data.resize(data.size() * 2); r = read(mFd, data.data(), data.size()); continue; // dunno }else{ return; } } // inspect data char *at = data.data(); char *end = at + data.size(); while(at < end){ inotify_event *e = reinterpret_cast(at); qDebug() << "inotify:" << e->name; if(e->mask & IN_IGNORED){ at += sizeof(inotify_event) + e->len; continue; } if(e->mask & IN_CREATE){ emit dwEvent(e->name, Added); } if(e->mask & IN_DELETE){ emit dwEvent(e->name, Deleted); } if((e->mask & IN_CLOSE_WRITE) || (e->mask & IN_MODIFY)){ emit dwEvent(e->name, Modified); } at += sizeof(inotify_event) + e->len; } }