Changeset View
Changeset View
Standalone View
Standalone View
src/file/kinotify.cpp
Show All 36 Lines | |||||
37 | #include <sys/ioctl.h> | 37 | #include <sys/ioctl.h> | ||
38 | #include <unistd.h> | 38 | #include <unistd.h> | ||
39 | #include <fcntl.h> | 39 | #include <fcntl.h> | ||
40 | #include <errno.h> | 40 | #include <errno.h> | ||
41 | #include <dirent.h> | 41 | #include <dirent.h> | ||
42 | 42 | | |||
43 | namespace | 43 | namespace | ||
44 | { | 44 | { | ||
45 | QByteArray stripTrailingSlash(const QByteArray& path) | 45 | QByteArray normalizeTrailingSlash(QByteArray&& path) | ||
46 | { | 46 | { | ||
47 | QByteArray p(path); | 47 | if (!path.endsWith('/')) | ||
48 | if (p.endsWith('/')) | 48 | path.append('/'); | ||
49 | p.chop(1); | 49 | return path; | ||
50 | return p; | | |||
51 | } | 50 | } | ||
52 | 51 | | |||
53 | QByteArray concatPath(const QByteArray& p1, const QByteArray& p2) | 52 | QByteArray concatPath(const QByteArray& p1, const QByteArray& p2) | ||
54 | { | 53 | { | ||
55 | QByteArray p(p1); | 54 | QByteArray p(p1); | ||
56 | if (p.isEmpty() || (!p2.isEmpty() && p[p.length() - 1] != '/')) | 55 | if (p.isEmpty() || (!p2.isEmpty() && p[p.length() - 1] != '/')) | ||
57 | p.append('/'); | 56 | p.append('/'); | ||
58 | p.append(p2); | 57 | p.append(p2); | ||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Line(s) | 64 | public: | |||
117 | 116 | | |||
118 | bool addWatch(const QString& path) { | 117 | bool addWatch(const QString& path) { | ||
119 | WatchEvents newMode = mode; | 118 | WatchEvents newMode = mode; | ||
120 | WatchFlags newFlags = flags; | 119 | WatchFlags newFlags = flags; | ||
121 | 120 | | |||
122 | // we always need the unmount event to maintain our path hash | 121 | // we always need the unmount event to maintain our path hash | ||
123 | const int mask = newMode | newFlags | EventUnmount | FlagExclUnlink; | 122 | const int mask = newMode | newFlags | EventUnmount | FlagExclUnlink; | ||
124 | 123 | | |||
125 | const QByteArray encpath = stripTrailingSlash(QFile::encodeName(path)); | 124 | const QByteArray encpath = normalizeTrailingSlash(QFile::encodeName(path)); | ||
126 | int wd = inotify_add_watch(inotify(), encpath.data(), mask); | 125 | int wd = inotify_add_watch(inotify(), encpath.data(), mask); | ||
127 | if (wd > 0) { | 126 | if (wd > 0) { | ||
128 | // qCDebug(BALOO) << "Successfully added watch for" << path << watchPathHash.count(); | 127 | // qCDebug(BALOO) << "Successfully added watch for" << path << watchPathHash.count(); | ||
129 | watchPathHash.insert(wd, encpath); | 128 | watchPathHash.insert(wd, encpath); | ||
130 | pathWatchHash.insert(encpath, wd); | 129 | pathWatchHash.insert(encpath, wd); | ||
131 | return true; | 130 | return true; | ||
132 | } else { | 131 | } else { | ||
133 | qCDebug(BALOO) << "Failed to create watch for" << path << strerror(errno); | 132 | qCDebug(BALOO) << "Failed to create watch for" << path << strerror(errno); | ||
▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Line(s) | 229 | { | |||
247 | } else { | 246 | } else { | ||
248 | return false; | 247 | return false; | ||
249 | } | 248 | } | ||
250 | } | 249 | } | ||
251 | 250 | | |||
252 | 251 | | |||
253 | bool KInotify::watchingPath(const QString& path) const | 252 | bool KInotify::watchingPath(const QString& path) const | ||
254 | { | 253 | { | ||
255 | const QByteArray p(stripTrailingSlash(QFile::encodeName(path))); | 254 | const QByteArray p = normalizeTrailingSlash(QFile::encodeName(path)); | ||
256 | return d->pathWatchHash.contains(p); | 255 | return d->pathWatchHash.contains(p); | ||
257 | } | 256 | } | ||
258 | 257 | | |||
259 | void KInotify::resetUserLimit() | 258 | void KInotify::resetUserLimit() | ||
260 | { | 259 | { | ||
261 | d->userLimitReachedSignaled = false; | 260 | d->userLimitReachedSignaled = false; | ||
262 | } | 261 | } | ||
263 | 262 | | |||
▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Line(s) | 344 | while (i < len) { | |||
358 | // a watched folder. Otherwise we should ignore it | 357 | // a watched folder. Otherwise we should ignore it | ||
359 | if (event->mask & (EventDeleteSelf | EventMoveSelf)) { | 358 | if (event->mask & (EventDeleteSelf | EventMoveSelf)) { | ||
360 | path = d->watchPathHash.value(event->wd); | 359 | path = d->watchPathHash.value(event->wd); | ||
361 | } else { | 360 | } else { | ||
362 | // we cannot use event->len here since it contains the size of the buffer and not the length of the string | 361 | // we cannot use event->len here since it contains the size of the buffer and not the length of the string | ||
363 | const QByteArray eventName = QByteArray::fromRawData(event->name, qstrnlen(event->name, event->len)); | 362 | const QByteArray eventName = QByteArray::fromRawData(event->name, qstrnlen(event->name, event->len)); | ||
364 | const QByteArray hashedPath = d->watchPathHash.value(event->wd); | 363 | const QByteArray hashedPath = d->watchPathHash.value(event->wd); | ||
365 | path = concatPath(hashedPath, eventName); | 364 | path = concatPath(hashedPath, eventName); | ||
365 | if (event->mask & IN_ISDIR) { | ||||
366 | path = normalizeTrailingSlash(std::move(path)); | ||||
367 | } | ||||
366 | } | 368 | } | ||
367 | 369 | | |||
368 | Q_ASSERT(!path.isEmpty() || event->mask & EventIgnored); | 370 | Q_ASSERT(!path.isEmpty() || event->mask & EventIgnored); | ||
369 | Q_ASSERT(path != "/" || event->mask & EventIgnored || event->mask & EventUnmount); | 371 | Q_ASSERT(path != "/" || event->mask & EventIgnored || event->mask & EventUnmount); | ||
370 | 372 | | |||
371 | // All events which need a decoded path, i.e. everything | 373 | // All events which need a decoded path, i.e. everything | ||
372 | // but EventMoveFrom | EventQueueOverflow | EventIgnored | 374 | // but EventMoveFrom | EventQueueOverflow | EventIgnored | ||
373 | uint32_t fileEvents = EventAll & ~(EventMoveFrom | EventQueueOverflow | EventIgnored); | 375 | uint32_t fileEvents = EventAll & ~(EventMoveFrom | EventQueueOverflow | EventIgnored); | ||
▲ Show 20 Lines • Show All 139 Lines • Show Last 20 Lines |