File: kinotify.h

package info (click to toggle)
baloo-kf5 5.78.0-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 5,252 kB
  • sloc: cpp: 25,038; sh: 24; xml: 15; makefile: 10
file content (193 lines) | stat: -rw-r--r-- 6,668 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/*
    This file is part of the KDE libraries
    SPDX-FileCopyrightText: 2007-2010 Sebastian Trueg <trueg@kde.org>

    SPDX-License-Identifier: LGPL-2.0-or-later
*/

#ifndef KINOTIFY_H_
#define KINOTIFY_H_

#include <QObject>

namespace Baloo {
    class FileIndexerConfig;
}

/**
 * A simple wrapper around inotify which only allows
 * to add folders recursively.
 *
 * Warning: moving of top-level folders is not supported and
 * results in undefined behaviour.
 */
class KInotify : public QObject
{
    Q_OBJECT

public:
    explicit KInotify(Baloo::FileIndexerConfig* config, QObject* parent = nullptr);
    ~KInotify() override;

    /**
     * Inotify events that can occur. Use with addWatch
     * to define the events that should be watched.
     *
     * These flags correspond to the native Linux inotify flags.
     */
    enum WatchEvent {
        EventAccess = 0x00000001, /**< File was accessed (read, compare inotify's IN_ACCESS) */
        EventAttributeChange = 0x00000004, /**< Metadata changed (permissions, timestamps, extended attributes, etc., compare inotify's IN_ATTRIB) */
        EventCloseWrite = 0x00000008, /**< File opened for writing was closed (compare inotify's IN_CLOSE_WRITE) */
        EventCloseRead = 0x00000010, /**< File not opened for writing was closed (compare inotify's IN_CLOSE_NOWRITE) */
        EventCreate = 0x00000100, /** File/directory created in watched directory (compare inotify's IN_CREATE) */
        EventDelete = 0x00000200, /**< File/directory deleted from watched directory (compare inotify's IN_DELETE) */
        EventDeleteSelf = 0x00000400, /**< Watched file/directory was itself deleted (compare inotify's IN_DELETE_SELF) */
        EventModify = 0x00000002, /**< File was modified (compare inotify's IN_MODIFY) */
        EventMoveSelf = 0x00000800, /**< Watched file/directory was itself moved (compare inotify's IN_MOVE_SELF) */
        EventMoveFrom = 0x00000040, /**< File moved out of watched directory (compare inotify's IN_MOVED_FROM) */
        EventMoveTo = 0x00000080, /**< File moved into watched directory (compare inotify's IN_MOVED_TO) */
        EventOpen = 0x00000020, /**< File was opened (compare inotify's IN_OPEN) */
        EventUnmount = 0x00002000, /**< Backing fs was unmounted (compare inotify's IN_UNMOUNT) */
        EventQueueOverflow = 0x00004000, /**< Event queued overflowed (compare inotify's IN_Q_OVERFLOW) */
        EventIgnored = 0x00008000, /**< File was ignored (compare inotify's IN_IGNORED) */
        EventMove = (EventMoveFrom | EventMoveTo),
        EventAll = (EventAccess |
                    EventAttributeChange |
                    EventCloseWrite |
                    EventCloseRead |
                    EventCreate |
                    EventDelete |
                    EventDeleteSelf |
                    EventModify |
                    EventMoveSelf |
                    EventMoveFrom |
                    EventMoveTo |
                    EventOpen)
    };
    Q_DECLARE_FLAGS(WatchEvents, WatchEvent)

    /**
     * Watch flags
     *
     * These flags correspond to the native Linux inotify flags.
     */
    enum WatchFlag {
        FlagOnlyDir = 0x01000000, /**< Only watch the path if it is a directory (IN_ONLYDIR) */
        FlagDoNotFollow = 0x02000000, /**< Don't follow a sym link (IN_DONT_FOLLOW) */
        FlagOneShot = 0x80000000, /**< Only send event once (IN_ONESHOT) */
        FlagExclUnlink = 0x04000000 /**< Do not generate events for unlinked files (IN_EXCL_UNLINK) */
    };
    Q_DECLARE_FLAGS(WatchFlags, WatchFlag)

    /**
     * \return \p true if inotify is available and usable.
     */
    bool available() const;

    bool watchingPath(const QString& path) const;

    /**
     * Call this when the inotify limit has been increased.
     */
    void resetUserLimit();

public Q_SLOTS:
    bool addWatch(const QString& path, WatchEvents modes, WatchFlags flags = WatchFlags());
    bool removeWatch(const QString& path);

Q_SIGNALS:
    /**
     * Emitted if a file is accessed (KInotify::EventAccess)
     */
    void accessed(const QString& file);

    /**
     * Emitted if file attributes are changed (KInotify::EventAttributeChange)
     */
    void attributeChanged(const QString& file);

    /**
     * Emitted if FIXME (KInotify::EventCloseWrite)
     */
    void closedWrite(const QString& file);

    /**
     * Emitted if FIXME (KInotify::EventCloseRead)
     */
    void closedRead(const QString& file);

    /**
     * Emitted if a new file has been created in one of the watched
     * folders (KInotify::EventCreate)
     */
    void created(const QString& file, bool isDir);

    /**
     * Emitted if a watched file or folder has been deleted.
     * This includes files in watched folders (KInotify::EventDelete and KInotify::EventDeleteSelf)
     */
    void deleted(const QString& file, bool isDir);

    /**
     * Emitted if a watched file is modified (KInotify::EventModify)
     */
    void modified(const QString& file);

    /**
     * Emitted if a file or folder has been moved or renamed.
     *
     * \warning The moved signal will only be emitted if both the source and target folder
     * are being watched.
     */
    void moved(const QString& oldName, const QString& newName);

    /**
     * Emitted if a file is opened (KInotify::EventOpen)
     */
    void opened(const QString& file);

    /**
     * Emitted if a watched path has been unmounted (KInotify::EventUnmount)
     */
    void unmounted(const QString& file);

    /**
     * Emitted if during updating the internal watch structures (recursive watches)
     * the inotify user watch limit was reached.
     *
     * This means that not all requested paths can be watched until the user watch
     * limit is increased.
     *
     * The argument is the path being added when the limit was reached.
     *
     * This signal will only be emitted once until resetUserLimit is called.
     */
    void watchUserLimitReached(const QString& path);

    /**
     * This is emitted once watches have been installed in all the directories
     * indicated by addWatch
     */
    void installedWatches();

private Q_SLOTS:
    void slotEvent(int);
    void slotClearCookies();

private:
    class Private;
    Private* const d;

    /**
     * Recursively iterates over all files/folders inside @param path
     * (that are not excluded by the config);
     * emits created() signal for each entry (excluding @param path)
     * and installs watches for all subdirectories (including @param path)
     */
    void handleDirCreated(const QString& path);

    Q_PRIVATE_SLOT(d, bool _k_addWatches())
};

#endif