1 | // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. |
2 | // |
3 | // SPDX-License-Identifier: GPL-3.0-or-later |
4 | |
5 | #include "inotify.h" |
6 | #include "private/inotify_p.h" |
7 | #include <QHash> |
8 | #include <QRunnable> |
9 | #include <QtConcurrent> |
10 | #include <QReadWriteLock> |
11 | |
12 | #include <poll.h> |
13 | #include <stdio.h> |
14 | #include <stdlib.h> |
15 | #include <sys/inotify.h> |
16 | #include <unistd.h> |
17 | #include <string.h> |
18 | |
19 | namespace { |
20 | static Inotify *ins {nullptr}; |
21 | } |
22 | |
23 | Inotify::Inotify(QObject *parent) |
24 | : QObject(parent) |
25 | , d(new InotifyPrivate(this)) |
26 | { |
27 | |
28 | } |
29 | |
30 | Inotify::~Inotify() |
31 | { |
32 | if (d) { |
33 | delete d; |
34 | } |
35 | } |
36 | |
37 | Inotify *Inotify::globalInstance() |
38 | { |
39 | if (ins == nullptr) { |
40 | ::ins = new Inotify; |
41 | QObject::connect(qApp, &QCoreApplication::aboutToQuit, [=](){ |
42 | delete ::ins; |
43 | }); |
44 | } |
45 | if (qApp->thread() != QThread::currentThread()) |
46 | ins->moveToThread(qApp->thread()); |
47 | return ins; |
48 | } |
49 | |
50 | void Inotify::addPath(const QString &path) |
51 | { |
52 | d->addPath(path); |
53 | } |
54 | |
55 | void Inotify::removePath(const QString &path) |
56 | { |
57 | d->removePath(path); |
58 | } |
59 | |
60 | void Inotify::addIgnorePath(const QString &path) |
61 | { |
62 | d->ignoreList.append(path); |
63 | } |
64 | |
65 | void Inotify::removeIgnorePath(const QString &path) |
66 | { |
67 | d->ignoreList.removeOne(path); |
68 | } |
69 | |
70 | InotifyPrivate::InotifyPrivate(Inotify *q) |
71 | : q (q) |
72 | , ignoreList() |
73 | , hook(InotifyImpl::createInotify()) |
74 | { |
75 | QObject::connect(hook, &InotifyHook::inotifyEvent, |
76 | this, &InotifyPrivate::doInotifyEvent, |
77 | Qt::QueuedConnection); |
78 | } |
79 | |
80 | InotifyPrivate::~InotifyPrivate() |
81 | { |
82 | if (hook) |
83 | InotifyImpl::removeInotify(hook); |
84 | } |
85 | |
86 | void InotifyPrivate::addPath(const QString &path) |
87 | { |
88 | hook->addPath(path); |
89 | } |
90 | |
91 | void InotifyPrivate::removePath(const QString &path) |
92 | { |
93 | hook->removePath(path); |
94 | } |
95 | |
96 | void InotifyPrivate::doInotifyEvent(InotifyHook::Type type, const QString &path) |
97 | { |
98 | if (qApp->thread() != QThread::currentThread()) |
99 | qInfo() << qApp->thread() << QThread::currentThread(); |
100 | |
101 | if (ignoreList.contains(path)) { |
102 | if (type == InotifyHook::Type::MODIFY) |
103 | emit q->ignoreModified(path); |
104 | else if (type == InotifyHook::Type::CLOSE) |
105 | emit q->ignoreClosed(path); |
106 | else if (type == InotifyHook::Type::OPEN) |
107 | emit q->ignoreOpened(path); |
108 | else if (type == InotifyHook::Type::MOVE) |
109 | emit q->ignoreMovedSub(path); |
110 | else if (type == InotifyHook::Type::DELETE) |
111 | emit q->ignoreDeletedSub(path); |
112 | else if (type == InotifyHook::Type::CREATE) |
113 | emit q->ignoreCreatedSub(path); |
114 | else if (type == InotifyHook::Type::DELETE_SELF) |
115 | emit q->ignoreDeletedSelf(path); |
116 | else if (type == InotifyHook::Type::MOVE_SELF) |
117 | emit q->ignoreMovedSelf(path); |
118 | return; |
119 | } |
120 | |
121 | if (type == InotifyHook::Type::MODIFY) |
122 | emit q->modified(path); |
123 | else if (type == InotifyHook::Type::CLOSE) |
124 | emit q->closed(path); |
125 | else if (type == InotifyHook::Type::OPEN) |
126 | emit q->opened(path); |
127 | else if (type == InotifyHook::Type::MOVE) |
128 | emit q->movedSub(path); |
129 | else if (type == InotifyHook::Type::DELETE) |
130 | emit q->deletedSub(path); |
131 | else if (type == InotifyHook::Type::CREATE) |
132 | emit q->createdSub(path); |
133 | else if (type == InotifyHook::Type::DELETE_SELF) |
134 | emit q->deletedSelf(path); |
135 | else if (type == InotifyHook::Type::MOVE_SELF) |
136 | emit q->movedSelf(path); |
137 | } |
138 | |