48 #include <io/config-kdirwatch.h>
54 #include <QtCore/QDir>
55 #include <QtCore/QFile>
56 #include <QtCore/QSocketNotifier>
57 #include <QtCore/QTimer>
58 #include <QtCore/QCoreApplication>
71 #include <sys/ioctl.h>
74 #include <sys/utsname.h>
89 if (method == QLatin1String(
"Fam")) {
91 }
else if (method == QLatin1String(
"Stat")) {
93 }
else if (method == QLatin1String(
"QFSWatch")) {
158 delayRemove( false ),
162 timer.setObjectName(QLatin1String(
"KDirWatchPrivate::timer"));
177 availableMethods <<
"Stat";
180 rescan_timer.setObjectName(QString::fromLatin1(
"KDirWatchPrivate::rescan_timer"));
186 if (FAMOpen(&fc) ==0) {
187 availableMethods <<
"FAM";
189 sn =
new QSocketNotifier( FAMCONNECTION_GETFD(&fc),
190 QSocketNotifier::Read,
this);
191 connect( sn, SIGNAL(activated(
int)),
195 kDebug(7001) <<
"Can't use FAM (fam daemon not running?)";
200 #ifdef HAVE_SYS_INOTIFY_H
201 supports_inotify =
true;
203 m_inotify_fd = inotify_init();
205 if ( m_inotify_fd <= 0 ) {
206 kDebug(7001) <<
"Can't use Inotify, kernel doesn't support it";
207 supports_inotify =
false;
212 int major, minor, patch;
213 if (uname(&uts) < 0) {
214 supports_inotify =
false;
215 kDebug(7001) <<
"Unable to get uname";
216 }
else if (sscanf(uts.release,
"%d.%d", &major, &minor) != 2) {
217 supports_inotify =
false;
218 kDebug(7001) <<
"The version is malformed: " << uts.release;
219 }
else if(major == 2 && minor == 6) {
220 if (sscanf(uts.release,
"%d.%d.%d", &major, &minor, &patch) != 3) {
221 supports_inotify =
false;
222 kDebug() <<
"Detected 2.6 kernel but can't know more: " << uts.release;
223 }
else if (major * 1000000 + minor * 1000 + patch < 2006014 ){
224 supports_inotify =
false;
225 kDebug(7001) <<
"Can't use INotify, Linux kernel too old " << uts.release;
230 kDebug(7001) <<
"INotify available: " << supports_inotify;
231 if ( supports_inotify ) {
232 availableMethods <<
"INotify";
233 (void)fcntl(m_inotify_fd, F_SETFD, FD_CLOEXEC);
235 mSn =
new QSocketNotifier( m_inotify_fd, QSocketNotifier::Read,
this );
236 connect( mSn, SIGNAL(activated(
int)),
240 #ifdef HAVE_QFILESYSTEMWATCHER
241 availableMethods <<
"QFileSystemWatcher";
262 #ifdef HAVE_SYS_INOTIFY_H
263 if ( supports_inotify )
264 ::close( m_inotify_fd );
266 #ifdef HAVE_QFILESYSTEMWATCHER
274 #ifdef HAVE_SYS_INOTIFY_H
275 if ( !supports_inotify )
279 int offsetStartRead = 0;
281 assert( m_inotify_fd > -1 );
282 ioctl( m_inotify_fd, FIONREAD, &pending );
284 while ( pending > 0 ) {
286 const int bytesToRead = qMin( pending, (
int)
sizeof( buf ) - offsetStartRead );
288 int bytesAvailable = read( m_inotify_fd, &buf[offsetStartRead], bytesToRead );
289 pending -= bytesAvailable;
290 bytesAvailable += offsetStartRead;
293 int offsetCurrent = 0;
294 while ( bytesAvailable >= (
int)
sizeof(
struct inotify_event ) ) {
295 const struct inotify_event *
const event = (
struct inotify_event *) &buf[offsetCurrent];
296 const int eventSize =
sizeof(
struct inotify_event ) + event->len;
297 if ( bytesAvailable < eventSize ) {
301 bytesAvailable -= eventSize;
302 offsetCurrent += eventSize;
305 QByteArray cpath(event->name, event->len);
307 path = QFile::decodeName ( cpath );
313 const bool isDir = (
event->mask & (IN_ISDIR));
323 if ( e->wd == event->wd ) {
324 const bool wasDirty = e->
dirty;
327 const QString tpath = e->
path + QLatin1Char(
'/') + path;
333 if( event->mask & IN_DELETE_SELF) {
334 if (s_verboseDebug) {
335 kDebug(7001) <<
"-->got deleteself signal for" << e->
path;
344 parentEntry->
dirty =
true;
348 if ( event->mask & IN_IGNORED ) {
352 if ( event->mask & (IN_CREATE|IN_MOVED_TO) ) {
355 if (s_verboseDebug) {
356 kDebug(7001) <<
"-->got CREATE signal for" << (tpath) <<
"sub_entry=" << sub_entry;
363 sub_entry->
dirty =
true;
367 Q_FOREACH(
Client *client, clients) {
375 if (!clients.isEmpty()) {
377 kDebug(7001).nospace() << clients.count() <<
" instance(s) monitoring the new "
378 << (isDir ?
"dir " :
"file ") << tpath;
380 e->m_pendingFileChanges.append(e->
path);
385 if (event->mask & (IN_DELETE|IN_MOVED_FROM)) {
386 if (s_verboseDebug) {
387 kDebug(7001) <<
"-->got DELETE signal for" << tpath;
407 if (event->mask & (IN_MODIFY|IN_ATTRIB)) {
409 if (s_verboseDebug) {
410 kDebug(7001) <<
"-->got MODIFY signal for" << (tpath);
427 e->m_pendingFileChanges.append(tpath);
429 e->
dirty = (wasDirty || (path.isEmpty() && (
event->mask & IN_ATTRIB)));
440 if (bytesAvailable > 0) {
442 memmove(buf, &buf[offsetCurrent], bytesAvailable);
443 offsetStartRead = bytesAvailable;
457 if (!sub_entry->
dirty)
459 sub_entry->
dirty =
true;
470 KDirWatch::WatchModes watchModes)
475 foreach(
Client* client, m_clients) {
490 m_clients.append(client);
497 for ( ; it != end ; ++it ) {
501 if (client->
count == 0) {
514 foreach(
Client* client, m_clients)
515 clients += client->
count;
522 return QDir::cleanPath(path + QLatin1String(
"/.."));
528 KDE_struct_stat stat_buf;
530 *isDir = S_ISDIR(stat_buf.st_mode);
531 const KDirWatch::WatchModes flag =
533 Q_FOREACH(
Client *client, this->m_clients) {
553 Q_FOREACH(
Client *client, this->m_clients) {
563 debug.nospace() <<
"[ Entry for " << entry.
path <<
", " << (entry.
isDir ?
"dir" :
"file");
565 debug <<
", non-existent";
571 #ifdef HAVE_SYS_INOTIFY_H
573 debug <<
" inotify_wd=" << entry.wd;
575 debug <<
", has " << entry.
m_clients.count() <<
" clients";
578 debug <<
", nonexistent subentries:";
580 debug << subEntry << subEntry->
path;
589 if (_path.isEmpty() || QDir::isRelativePath(_path)) {
595 if ( path.length() > 1 && path.endsWith( QLatin1Char(
'/' ) ) )
596 path.truncate( path.length() - 1 );
614 kDebug(7001) <<
"Global Poll Freq is now" <<
freq <<
"msec";
619 #if defined(HAVE_FAM)
621 bool KDirWatchPrivate::useFAM(Entry* e)
623 if (!use_fam)
return false;
635 addEntry(0, e->parentDirectory(), e,
true);
638 int res =FAMMonitorDirectory(&fc, QFile::encodeName(e->path),
646 kDebug(7001).nospace() <<
" Setup FAM (Req " << FAMREQUEST_GETREQNUM(&(e->fr))
647 <<
") for " << e->path;
653 addEntry(0, QFileInfo(e->path).absolutePath(), e,
true);
656 int res = FAMMonitorFile(&fc, QFile::encodeName(e->path),
665 kDebug(7001).nospace() <<
" Setup FAM (Req " << FAMREQUEST_GETREQNUM(&(e->fr))
666 <<
") for " << e->path;
678 #ifdef HAVE_SYS_INOTIFY_H
680 bool KDirWatchPrivate::useINotify( Entry* e )
687 if (!supports_inotify)
return false;
692 addEntry(0, e->parentDirectory(), e,
true);
697 int mask = IN_DELETE|IN_DELETE_SELF|IN_CREATE|IN_MOVE|IN_MOVE_SELF|IN_DONT_FOLLOW|IN_MOVED_FROM|IN_MODIFY|IN_ATTRIB;
699 if ( ( e->wd = inotify_add_watch( m_inotify_fd,
700 QFile::encodeName( e->path ), mask) ) >= 0)
702 if (s_verboseDebug) {
703 kDebug(7001) <<
"inotify successfully used for monitoring" << e->path <<
"wd=" << e->wd;
708 kDebug(7001) <<
"inotify failed for monitoring" << e->path <<
":" << strerror(errno);
712 #ifdef HAVE_QFILESYSTEMWATCHER
723 kDebug(7001) <<
"fsWatcher->addPath" << e->
path;
748 kDebug(7001) <<
" Started Polling Timer, freq " <<
freq;
752 kDebug(7001) <<
" Setup Stat (freq " << e->
freq <<
") for " << e->
path;
764 Entry* sub_entry,
bool isDir, KDirWatch::WatchModes watchModes)
769 || path == QLatin1String(
"/dev")
770 || (path.startsWith(QLatin1String(
"/dev/")) && !path.startsWith(QLatin1String(
"/dev/.")))
775 if ( path.length() > 1 && path.endsWith( QLatin1Char(
'/' ) ) )
776 path.truncate( path.length() - 1 );
782 (*it).m_entries.append(sub_entry);
783 if (s_verboseDebug) {
784 kDebug(7001) <<
"Added already watched Entry" << path
785 <<
"(for" << sub_entry->
path <<
")";
787 #ifdef HAVE_SYS_INOTIFY_H
790 int mask = IN_DELETE|IN_DELETE_SELF|IN_CREATE|IN_MOVE|IN_MOVE_SELF|IN_DONT_FOLLOW;
792 mask |= IN_MODIFY|IN_ATTRIB;
796 inotify_rm_watch (m_inotify_fd, e->wd);
797 e->wd = inotify_add_watch( m_inotify_fd, QFile::encodeName( e->
path ),
804 (*it).addClient(instance, watchModes);
805 if (s_verboseDebug) {
806 kDebug(7001) <<
"Added already watched Entry" << path
807 <<
"(now" << (*it).clientCount() <<
"clients)"
808 << QString::fromLatin1(
"[%1]").arg(instance->objectName());
816 KDE_struct_stat stat_buf;
817 bool exists = (
KDE::stat(path, &stat_buf) == 0);
821 Entry* e = &(*newIt);
824 e->
isDir = S_ISDIR(stat_buf.st_mode);
826 if (e->
isDir && !isDir) {
828 if (S_ISLNK(stat_buf.st_mode))
832 qWarning() <<
"KDirWatch:" << path <<
"is a directory. Use addDir!";
834 }
else if (!e->
isDir && isDir)
835 qWarning(
"KDirWatch: %s is a file. Use addFile!", qPrintable(path));
838 qWarning() <<
"KDirWatch:" << path <<
"is a file. You can't use recursive or "
839 "watchFiles options";
845 e->
m_ctime = stat_buf.st_mtime;
847 e->
m_ctime = stat_buf.st_ctime;
850 e->
m_nlink = stat_buf.st_nlink;
851 e->
m_ino = stat_buf.st_ino;
867 kDebug(7001).nospace() <<
"Added " << (e->
isDir ?
"Dir " :
"File ") << path
869 <<
" for " << (sub_entry ? sub_entry->
path :
QString())
870 <<
" [" << (instance ? instance->objectName() :
QString()) <<
"]";
880 QFlags<QDir::Filter> filters = QDir::NoDotAndDotDot;
884 filters |= (QDir::Dirs|QDir::Files);
885 }
else if (watchModes & KDirWatch::WatchSubDirs) {
886 filters |= QDir::Dirs;
888 filters |= QDir::Files;
891 #if defined(HAVE_SYS_INOTIFY_H)
898 filters &= ~QDir::Files;
902 QDir basedir (e->
path);
903 const QFileInfoList contents = basedir.entryInfoList(filters);
904 for (QFileInfoList::const_iterator iter = contents.constBegin();
905 iter != contents.constEnd(); ++iter)
907 const QFileInfo &fileInfo = *iter;
909 bool isDir = fileInfo.isDir() && !fileInfo.isSymLink();
911 addEntry (instance, fileInfo.absoluteFilePath(), 0, isDir,
937 bool entryAdded =
false;
938 switch (preferredMethod) {
939 #if defined(HAVE_FAM)
942 #if defined(HAVE_SYS_INOTIFY_H)
945 #if defined(HAVE_QFILESYSTEMWATCHER)
954 #if defined(HAVE_SYS_INOTIFY_H)
955 if (useINotify(e))
return;
957 #if defined(HAVE_FAM)
958 if (useFAM(e))
return;
960 #if defined(HAVE_QFILESYSTEMWATCHER)
971 FAMCancelMonitor(&fc, &(e->fr) );
972 kDebug(7001).nospace() <<
"Cancelled FAM (Req " << FAMREQUEST_GETREQNUM(&(e->fr))
973 <<
") for " << e->
path;
976 #ifdef HAVE_SYS_INOTIFY_H
978 (void) inotify_rm_watch( m_inotify_fd, e->wd );
979 if (s_verboseDebug) {
980 kDebug(7001).nospace() <<
"Cancelled INotify (fd " << m_inotify_fd <<
", "
981 << e->wd <<
") for " << e->
path;
985 #ifdef HAVE_QFILESYSTEMWATCHER
988 kDebug(7001) <<
"fsWatcher->removePath" << e->
path;
998 if (s_verboseDebug) {
999 kDebug(7001) <<
"path=" << _path <<
"sub_entry:" << sub_entry;
1044 kDebug(7001) <<
" Stopped Polling Timer";
1048 if (s_verboseDebug) {
1049 kDebug(7001).nospace() <<
"Removed " << (e->
isDir ?
"Dir ":
"File ") << e->
path
1050 <<
" for " << (sub_entry ? sub_entry->
path :
QString())
1051 <<
" [" << (instance ? instance->objectName() :
QString()) <<
"]";
1062 int minfreq = 3600000;
1069 foreach(
Client* client, (*it).m_clients) {
1070 if (client->
instance == instance) {
1077 pathList.append((*it).path);
1079 else if ( (*it).m_mode ==
StatMode && (*it).freq < minfreq )
1080 minfreq = (*it).freq;
1083 foreach(
const QString &path, pathList)
1086 if (minfreq >
freq) {
1090 kDebug(7001) <<
"Poll Freq now" <<
freq <<
"msec";
1097 int stillWatching = 0;
1099 if (!instance || instance == client->
instance)
1102 stillWatching += client->
count;
1105 kDebug(7001) << (instance ? instance->objectName() : QString::fromLatin1(
"all"))
1106 <<
"stopped scanning" << e->
path <<
"(now"
1107 << stillWatching <<
"watchers)";
1109 if (stillWatching == 0) {
1124 int wasWatching = 0, newWatching = 0;
1127 wasWatching += client->
count;
1128 else if (!instance || instance == client->
instance) {
1130 newWatching += client->
count;
1133 if (newWatching == 0)
1136 kDebug(7001) << (instance ? instance->objectName() : QString::fromLatin1(
"all"))
1137 <<
"restarted scanning" << e->
path
1138 <<
"(now" << wasWatching+newWatching <<
"watchers)";
1143 if (wasWatching == 0) {
1145 KDE_struct_stat stat_buf;
1150 e->
m_ctime = stat_buf.st_mtime;
1152 e->
m_ctime = stat_buf.st_ctime;
1155 if (s_verboseDebug) {
1156 kDebug(7001) <<
"Setting status to Normal for" << e << e->
path;
1158 e->
m_nlink = stat_buf.st_nlink;
1159 e->
m_ino = stat_buf.st_ino;
1168 if (s_verboseDebug) {
1169 kDebug(7001) <<
"Setting status to NonExistent for" << e << e->
path;
1191 bool notify,
bool skippedToo )
1210 foreach(
Client* client, (*it).m_clients) {
1240 KDE_struct_stat stat_buf;
1247 e->
m_ctime = qMax(stat_buf.st_ctime, stat_buf.st_mtime);
1249 e->
m_ino = stat_buf.st_ino;
1250 if (s_verboseDebug) {
1251 kDebug(7001) <<
"Setting status to Normal for just created" << e << e->
path;
1259 #if 1 // for debugging the if() below
1260 if (s_verboseDebug) {
1261 struct tm* tmp = localtime(&e->
m_ctime);
1263 strftime(outstr,
sizeof(outstr),
"%T", tmp);
1265 <<
"stat_buf.st_ctime=" << stat_buf.st_ctime
1266 <<
"e->m_nlink=" << e->
m_nlink
1267 <<
"stat_buf.st_nlink=" << stat_buf.st_nlink
1268 <<
"e->m_ino=" << e->
m_ino
1269 <<
"stat_buf.st_ino=" << stat_buf.st_ino;
1274 (qMax(stat_buf.st_ctime, stat_buf.st_mtime) != e->
m_ctime ||
1275 stat_buf.st_ino != e->
m_ino ||
1276 stat_buf.st_nlink != nlink_t(e->
m_nlink)))
1282 e->
m_ctime = qMax(stat_buf.st_ctime, stat_buf.st_mtime);
1283 e->
m_nlink = stat_buf.st_nlink;
1284 if (e->
m_ino != stat_buf.st_ino) {
1289 e->
m_ino = stat_buf.st_ino;
1317 if (!fileName.isEmpty()) {
1318 if (!QDir::isRelativePath(fileName))
1322 path += QLatin1Char(
'/') + fileName;
1323 #elif defined(Q_WS_WIN)
1325 path += QDir::currentPath().left(2) + QLatin1Char(
'/') + fileName;
1330 if (s_verboseDebug) {
1355 QMetaObject::invokeMethod(c->
instance,
"setDeleted", Qt::QueuedConnection, Q_ARG(
QString, path));
1361 QMetaObject::invokeMethod(c->
instance,
"setCreated", Qt::QueuedConnection, Q_ARG(
QString, path));
1366 QMetaObject::invokeMethod(c->
instance,
"setDirty", Qt::QueuedConnection, Q_ARG(
QString, path));
1392 EntryMap::Iterator it;
1398 bool timerRunning =
timer.isActive();
1421 (*it).propagate_dirty();
1424 #ifdef HAVE_SYS_INOTIFY_H
1432 if (!entry->
isValid())
continue;
1436 kDebug(7001) <<
"scanEntry for" << entry->
path <<
"says" << ev;
1439 #ifdef HAVE_SYS_INOTIFY_H
1443 kDebug(7001) <<
"scanEntry says" << entry->
path <<
"was deleted";
1447 kDebug(7001) <<
"scanEntry says" << entry->
path <<
"was created. wd=" << entry->wd;
1448 if (entry->wd < 0) {
1449 cList.append(entry);
1466 #ifdef HAVE_SYS_INOTIFY_H
1472 QStringList pendingFileChanges = entry->m_pendingFileChanges;
1473 pendingFileChanges.removeDuplicates();
1474 Q_FOREACH(
const QString &changedFilename, pendingFileChanges) {
1475 if (s_verboseDebug) {
1476 kDebug(7001) <<
"processing pending file change for" << changedFilename;
1480 entry->m_pendingFileChanges.clear();
1492 #ifdef HAVE_SYS_INOTIFY_H
1494 Q_FOREACH(
Entry* e, cList)
1504 if ( *filename ==
'.') {
1505 if (strncmp(filename,
".X.err", 6) == 0)
return true;
1506 if (strncmp(filename,
".xsession-errors", 16) == 0)
return true;
1509 if (strncmp(filename,
".fonts.cache", 12) == 0)
return true;
1524 while(use_fam && FAMPending(&fc)) {
1525 if (FAMNextEvent(&fc, &fe) == -1) {
1526 kWarning(7001) <<
"FAM connection problem, switching to polling.";
1533 if ((*it).m_mode ==
FAMMode && (*it).m_clients.count()>0) {
1545 void KDirWatchPrivate::checkFAMEvent(FAMEvent* fe)
1550 if ((fe->code == FAMExists) ||
1551 (fe->code == FAMEndExist) ||
1552 (fe->code == FAMAcknowledge))
return;
1560 if (FAMREQUEST_GETREQNUM(&( (*it).fr )) ==
1561 FAMREQUEST_GETREQNUM(&(fe->fr)) ) {
1568 if (s_verboseDebug) {
1569 kDebug(7001) <<
"Processing FAM event ("
1570 << ((fe->code == FAMChanged) ?
"FAMChanged" :
1571 (fe->code == FAMDeleted) ?
"FAMDeleted" :
1572 (fe->code == FAMStartExecuting) ?
"FAMStartExecuting" :
1573 (fe->code == FAMStopExecuting) ?
"FAMStopExecuting" :
1574 (fe->code == FAMCreated) ?
"FAMCreated" :
1575 (fe->code == FAMMoved) ?
"FAMMoved" :
1576 (fe->code == FAMAcknowledge) ?
"FAMAcknowledge" :
1577 (fe->code == FAMExists) ?
"FAMExists" :
1578 (fe->code == FAMEndExist) ?
"FAMEndExist" :
"Unknown Code")
1579 <<
", " << fe->filename
1580 <<
", Req " << FAMREQUEST_GETREQNUM(&(fe->fr)) <<
") e=" << e;
1590 kDebug(7001) <<
"FAM event for nonExistent entry " << e->path;
1603 if (!QDir::isRelativePath(QFile::decodeName(fe->filename))) {
1604 FAMCancelMonitor(&fc, &(e->fr) );
1605 kDebug(7001) <<
"Cancelled FAMReq"
1606 << FAMREQUEST_GETREQNUM(&(e->fr))
1607 <<
"for" << e->path;
1612 Entry* parentEntry =
entry(e->parentDirectory());
1614 parentEntry->
dirty =
true;
1616 addEntry(0, e->parentDirectory(), e,
true );
1627 QString tpath(e->path + QLatin1Char(
'/') + QFile::decodeName(fe->filename));
1630 Entry* sub_entry = e->findSubEntry(tpath);
1634 sub_entry->dirty =
true;
1636 }
else if (e->isDir && !e->m_clients.empty()) {
1638 const QList<Client *> clients = e->clientsForFileOrDir(tpath, &isDir);
1639 Q_FOREACH(Client *client, clients) {
1640 addEntry (client->instance, tpath, 0, isDir,
1644 if (!clients.isEmpty()) {
1647 kDebug(7001).nospace() << clients.count() <<
" instance(s) monitoring the new "
1648 << (isDir ?
"dir " :
"file ") << tpath;
1660 kWarning (7001) <<
"Fam event received but FAM is not supported";
1667 EntryMap::Iterator it;
1669 kDebug(7001) <<
"Entries watched:";
1671 kDebug(7001) <<
" None.";
1677 kDebug(7001) <<
" " << *e;
1685 if (!pending.isEmpty()) pending =
" (pending: " + pending +
')';
1686 pending =
", stopped" + pending;
1689 <<
" (" << c->
count <<
" times)" << pending;
1692 kDebug(7001) <<
" dependent entries:";
1695 if (s_verboseDebug) {
1704 #ifdef HAVE_QFILESYSTEMWATCHER
1716 kDebug(7001) <<
"scanEntry for" << e->
path <<
"says" << ev;
1723 addEntry(0, QFileInfo(e->
path).absolutePath(), e,
true);
1727 }
else if (e->
isDir) {
1739 kWarning (7001) <<
"QFileSystemWatcher event received but QFileSystemWatcher is not supported";
1741 #endif // HAVE_QFILESYSTEMWATCHER
1750 return s_pKDirWatchSelf;
1756 return s_pKDirWatchSelf.exists();
1761 s_pKDirWatchSelf->deleteQFSWatcher();
1767 static int nameCounter = 0;
1770 setObjectName(QString::fromLatin1(
"KDirWatch-%1").arg(nameCounter) );
1776 static bool cleanupRegistered =
false;
1777 if (!cleanupRegistered) {
1778 cleanupRegistered =
true;
1797 if (d) d->
addEntry(
this, _path, 0,
true, watchModes);
1805 d->
addEntry(
this, _path, 0,
false);
1822 kWarning() <<
"doesn't know" << _path;
1831 kWarning() <<
"doesn't know" << _path;
1901 kDebug(7001) <<
"KDirWatch not used";
1910 kDebug(7001) << objectName() <<
"emitting created" << _file;
1917 emit
dirty( _file );
1922 kDebug(7001) << objectName() <<
"emitting deleted" << _file;
1932 #include "kdirwatch.moc"
1933 #include "kdirwatch_p.moc"
QString parentDirectory() const
static const char * methodToString(KDirWatch::Method method)
QList< Client * > inotifyClientsForFileOrDir(bool isDir) const
static KDirWatchPrivate * createPrivate()
QList< Client * > clientsForFileOrDir(const QString &tpath, bool *isDir) const
void setCreated(const QString &path)
Emits created().
void addFile(const QString &file)
Adds a file to be watched.
QList< Client * > m_clients
void useFreq(Entry *e, int newFreq)
bool removeEntry(KDirWatch *, const QString &, Entry *sub_entry)
static bool isNoisyFile(const char *filename)
KDirWatch(QObject *parent=0)
Constructor.
void stopScan()
Stops scanning of all directories in internal list.
Watch just the specified directory.
void stopScan(KDirWatch *)
bool stopEntryScan(KDirWatch *, Entry *)
static QDateTime fromTime_t(qint32 seconds)
#define K_GLOBAL_STATIC(TYPE, NAME)
This macro makes it easy to use non-POD types as global statics.
void startScan(bool notify=false, bool skippedToo=false)
Starts scanning of all dirs in list.
Method internalMethod()
Returns the preferred internal method to watch for changes.
int stat(const QString &path, KDE_struct_stat *buf)
bool restartEntryScan(KDirWatch *, Entry *, bool)
QList< Entry * > m_entries
void removeEntries(KDirWatch *)
KDirWatch::WatchModes m_watchModes
void removePath(const QString &file)
Type fileSystemType(const QString &path)
KSharedConfigPtr config()
Returns the general config object.
bool stopDirScan(const QString &path)
Stops scanning the specified path.
void deleted(const QString &path)
Emitted when a file or directory is deleted.
void resetList(KDirWatch *, bool)
bool useQFSWatch(Entry *e)
void emitEvent(const Entry *e, int event, const QString &fileName=QString())
KDirWatch::Method m_preferredMethod
KDirWatch::Method m_nfsPreferredMethod
static void statistics()
Dump statistic information about the KDirWatch::self() instance.
KFileSystemWatcher * fsWatcher
void fswEventReceived(const QString &path)
void setDeleted(const QString &path)
Emits deleted().
void removeWatch(Entry *entry)
static KDirWatchPrivate * dwp_self
QDateTime ctime(const QString &path) const
Returns the time the directory/file was last changed.
void created(const QString &path)
Emitted when a file or directory is created.
void startScan(KDirWatch *, bool, bool)
int lstat(const QString &path, KDE_struct_stat *buf)
Watch also all files contained by the directory.
bool contains(const QString &path) const
Check if a directory is being watched by this KDirWatch instance.
A class for one specific group in a KConfig object.
void inotifyEventReceived()
static void cleanupQFSWatcher()
void removeClient(KDirWatch *)
QDebug operator<<(QDebug debug, const KDirWatchPrivate::Entry &entry)
QSet< Entry * > removeList
void addPath(const QString &file)
void removeDir(const QString &path)
Removes a directory from the list of scanned directories.
void addDir(const QString &path, WatchModes watchModes=WatchDirOnly)
Adds a directory to be watched.
Entry * entry(const QString &)
static bool exists()
Returns true if there is an instance of KDirWatch.
Class for watching directory and file changes.
void dirty(const QString &path)
Emitted when a watched object is changed.
Watch also all the subdirs contained by the directory.
void setDirty(const QString &path)
Emits dirty().
bool isStopped()
Is scanning stopped? After creation of a KDirWatch instance, this is false.
void removeFile(const QString &file)
Removes a file from the list of watched files.
Entry * findSubEntry(const QString &path) const
static KDirWatch::Method methodFromString(const QString &method)
T readEntry(const QString &key, const T &aDefault) const
Reads the value of an entry specified by pKey in the current group.
void addClient(KDirWatch *, KDirWatch::WatchModes)
void addEntry(KDirWatch *instance, const QString &_path, Entry *sub_entry, bool isDir, KDirWatch::WatchModes watchModes=KDirWatch::WatchDirOnly)
bool restartDirScan(const QString &path)
Restarts scanning for specified path.
void addWatch(Entry *entry)
static const bool s_verboseDebug