7#include "private/qcore_unix_p.h"
8#include "private/qsystemerror_p.h"
17#if defined(Q_OS_LINUX)
18#include <sys/syscall.h>
24#if defined(QT_NO_INOTIFY)
28#error "Should not get here."
31#include <linux/types.h>
34# define __NR_inotify_init 291
35# define __NR_inotify_add_watch 292
36# define __NR_inotify_rm_watch 293
37# define __NR_inotify_init1 332
38#elif defined(__x86_64__)
39# define __NR_inotify_init 253
40# define __NR_inotify_add_watch 254
41# define __NR_inotify_rm_watch 255
42# define __NR_inotify_init1 294
43#elif defined(__powerpc__) || defined(__powerpc64__)
44# define __NR_inotify_init 275
45# define __NR_inotify_add_watch 276
46# define __NR_inotify_rm_watch 277
47# define __NR_inotify_init1 318
48#elif defined (__ia64__)
49# define __NR_inotify_init 1277
50# define __NR_inotify_add_watch 1278
51# define __NR_inotify_rm_watch 1279
52# define __NR_inotify_init1 1318
53#elif defined (__s390__) || defined (__s390x__)
54# define __NR_inotify_init 284
55# define __NR_inotify_add_watch 285
56# define __NR_inotify_rm_watch 286
57# define __NR_inotify_init1 324
58#elif defined (__alpha__)
59# define __NR_inotify_init 444
60# define __NR_inotify_add_watch 445
61# define __NR_inotify_rm_watch 446
63#elif defined (__sparc__) || defined (__sparc64__)
64# define __NR_inotify_init 151
65# define __NR_inotify_add_watch 152
66# define __NR_inotify_rm_watch 156
67# define __NR_inotify_init1 322
68#elif defined (__arm__)
69# define __NR_inotify_init 316
70# define __NR_inotify_add_watch 317
71# define __NR_inotify_rm_watch 318
72# define __NR_inotify_init1 360
74# define __NR_inotify_init 290
75# define __NR_inotify_add_watch 291
76# define __NR_inotify_rm_watch 292
77# define __NR_inotify_init1 332
78#elif defined (__sh64__)
79# define __NR_inotify_init 318
80# define __NR_inotify_add_watch 319
81# define __NR_inotify_rm_watch 320
82# define __NR_inotify_init1 360
83#elif defined (__mips__)
84# define __NR_inotify_init 284
85# define __NR_inotify_add_watch 285
86# define __NR_inotify_rm_watch 286
87# define __NR_inotify_init1 329
88#elif defined (__hppa__)
89# define __NR_inotify_init 269
90# define __NR_inotify_add_watch 270
91# define __NR_inotify_rm_watch 271
92# define __NR_inotify_init1 314
93#elif defined (__avr32__)
94# define __NR_inotify_init 240
95# define __NR_inotify_add_watch 241
96# define __NR_inotify_rm_watch 242
98#elif defined (__mc68000__)
99# define __NR_inotify_init 284
100# define __NR_inotify_add_watch 285
101# define __NR_inotify_rm_watch 286
102# define __NR_inotify_init1 328
103#elif defined (__aarch64__)
104# define __NR_inotify_init1 26
105# define __NR_inotify_add_watch 27
106# define __NR_inotify_rm_watch 28
109# error "This architecture is not supported. Please see http://www.qt-project.org/"
112#if !defined(IN_CLOEXEC) && defined(O_CLOEXEC) && defined(__NR_inotify_init1)
113# define IN_CLOEXEC O_CLOEXEC
120static inline int syscall(...) {
return -1; }
123static inline int inotify_init()
125#ifdef __NR_inotify_init
126 return syscall(__NR_inotify_init);
128 return syscall(__NR_inotify_init1, 0);
132static inline int inotify_add_watch(
int fd,
const char *
name, __u32
mask)
134 return syscall(__NR_inotify_add_watch,
fd,
name,
mask);
137static inline int inotify_rm_watch(
int fd, __u32 wd)
139 return syscall(__NR_inotify_rm_watch,
fd, wd);
143static inline int inotify_init1(
int flags)
145 return syscall(__NR_inotify_init1,
flags);
152struct inotify_event {
160#define IN_ACCESS 0x00000001
161#define IN_MODIFY 0x00000002
162#define IN_ATTRIB 0x00000004
163#define IN_CLOSE_WRITE 0x00000008
164#define IN_CLOSE_NOWRITE 0x00000010
165#define IN_OPEN 0x00000020
166#define IN_MOVED_FROM 0x00000040
167#define IN_MOVED_TO 0x00000080
168#define IN_CREATE 0x00000100
169#define IN_DELETE 0x00000200
170#define IN_DELETE_SELF 0x00000400
171#define IN_MOVE_SELF 0x00000800
172#define IN_UNMOUNT 0x00002000
173#define IN_Q_OVERFLOW 0x00004000
174#define IN_IGNORED 0x00008000
176#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
177#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO)
186#include <sys/inotify.h>
189# if defined(Q_OS_ANDROID) && (__ANDROID_API__ < 21)
190static inline int inotify_init1(
int flags)
192 return syscall(__NR_inotify_init1,
flags);
203#if defined(IN_CLOEXEC)
204 fd = inotify_init1(IN_CLOEXEC);
214QInotifyFileSystemWatcherEngine::QInotifyFileSystemWatcherEngine(
int fd,
QObject *parent)
219 fcntl(inotifyFd, F_SETFD, FD_CLOEXEC);
221 this, &QInotifyFileSystemWatcherEngine::readFromInotify);
227 for (
int id : std::as_const(pathToID))
228 inotify_rm_watch(inotifyFd,
id < 0 ? -
id :
id);
240 bool isDir = fi.isDir();
243 if (directories->contains(
path))
250 int wd = inotify_add_watch(inotifyFd,
275 int id = isDir ? -wd : wd;
277 directories->append(
path);
304 auto path_it = std::find(path_range.first, path_range.second,
path);
305 if (path_it == idToPath.
end())
308 const ssize_t num_elements = std::distance(path_range.first, path_range.second);
309 idToPath.
erase(path_it);
312 if (num_elements == 1) {
313 int wd =
id < 0 ? -
id :
id;
314 inotify_rm_watch(inotifyFd, wd);
320 directories->removeAll(
path);
329void QInotifyFileSystemWatcherEngine::readFromInotify()
334 if (ioctl(inotifyFd, FIONREAD, (
char *) &buffSize) == -1 || buffSize == 0)
337 QVarLengthArray<char, 4096>
buffer(buffSize);
338 buffSize = int(
read(inotifyFd,
buffer.data(), buffSize));
340 char *
const end =
at + buffSize;
342 QHash<int, inotify_event *> eventForId;
344 inotify_event *
event =
reinterpret_cast<inotify_event *
>(
at);
346 if (eventForId.contains(
event->wd))
351 at +=
sizeof(inotify_event) +
event->len;
356 const inotify_event &
event = **
it;
363 if (
path.isEmpty()) {
366 path = getPathFromID(
id);
373 if ((
event.mask & (IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT)) != 0) {
375 idToPath.
remove(
id, getPathFromID(
id));
377 inotify_rm_watch(inotifyFd,
event.wd);
392template <
typename Hash,
typename Key>
393typename Hash::const_iterator
397 auto i =
c.find(
key);
398 const auto end =
c.cend();
405 }
while (
i !=
end &&
i.key() ==
key);
409QString QInotifyFileSystemWatcherEngine::getPathFromID(
int id)
const
417#include "moc_qfilesystemwatcher_inotify_p.cpp"
DarwinBluetooth::LECBManagerNotifier * notifier
QVariant data() const
Returns the user data as set in QAction::setData.
void directoryChanged(const QString &path, bool removed)
void fileChanged(const QString &path, bool removed)
static QByteArray encodeName(const QString &fileName)
Converts fileName to an 8-bit encoding that you can use in native APIs.
bool remove(const Key &key)
Removes the item that has the key from the hash.
T take(const Key &key)
Removes the item with the key from the hash and returns the value associated with it.
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
~QInotifyFileSystemWatcherEngine()
static QInotifyFileSystemWatcherEngine * create(QObject *parent)
QStringList removePaths(const QStringList &paths, QStringList *files, QStringList *directories) override
QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories) override
std::pair< iterator, iterator > equal_range(const Key &key)
const_iterator cend() const noexcept
bool contains(const Key &key) const noexcept
qsizetype remove(const Key &key)
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
iterator erase(const_iterator it)
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
QObject * parent() const
Returns a pointer to the parent object.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
const_iterator constBegin() const noexcept
const_iterator constEnd() const noexcept
void activated(QSocketDescriptor socket, QSocketNotifier::Type activationEvent, QPrivateSignal)
void setEnabled(bool)
If enable is true, the notifier is enabled; otherwise the notifier is disabled.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QSet< QString >::iterator it
void qErrnoWarning(const char *msg,...)
Combined button and popup list for selecting options.
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
Hash::const_iterator find_last_in_equal_range(const Hash &c, const Key &key)
GLsizei const GLuint * paths
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLsizei const GLchar *const * path
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
ReturnedValue read(const char *data)