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
19namespace {
20static Inotify *ins {nullptr};
21}
22
23Inotify::Inotify(QObject *parent)
24 : QObject(parent)
25 , d(new InotifyPrivate(this))
26{
27
28}
29
30Inotify::~Inotify()
31{
32 if (d) {
33 delete d;
34 }
35}
36
37Inotify *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
50void Inotify::addPath(const QString &path)
51{
52 d->addPath(path);
53}
54
55void Inotify::removePath(const QString &path)
56{
57 d->removePath(path);
58}
59
60void Inotify::addIgnorePath(const QString &path)
61{
62 d->ignoreList.append(path);
63}
64
65void Inotify::removeIgnorePath(const QString &path)
66{
67 d->ignoreList.removeOne(path);
68}
69
70InotifyPrivate::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
80InotifyPrivate::~InotifyPrivate()
81{
82 if (hook)
83 InotifyImpl::removeInotify(hook);
84}
85
86void InotifyPrivate::addPath(const QString &path)
87{
88 hook->addPath(path);
89}
90
91void InotifyPrivate::removePath(const QString &path)
92{
93 hook->removePath(path);
94}
95
96void 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