File indexing completed on 2024-04-14 03:49:46
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2007-2010 Sebastian Trueg <trueg@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #ifndef KINOTIFY_H_ 0009 #define KINOTIFY_H_ 0010 0011 #include <QObject> 0012 0013 namespace Baloo { 0014 class FileIndexerConfig; 0015 } 0016 0017 /** 0018 * A simple wrapper around inotify which only allows 0019 * to add folders recursively. 0020 * 0021 * Warning: moving of top-level folders is not supported and 0022 * results in undefined behaviour. 0023 */ 0024 class KInotify : public QObject 0025 { 0026 Q_OBJECT 0027 0028 public: 0029 explicit KInotify(Baloo::FileIndexerConfig* config, QObject* parent = nullptr); 0030 ~KInotify() override; 0031 0032 /** 0033 * Inotify events that can occur. Use with addWatch 0034 * to define the events that should be watched. 0035 * 0036 * These flags correspond to the native Linux inotify flags. 0037 */ 0038 enum WatchEvent { 0039 EventAccess = 0x00000001, /**< File was accessed (read, compare inotify's IN_ACCESS) */ 0040 EventAttributeChange = 0x00000004, /**< Metadata changed (permissions, timestamps, extended attributes, etc., compare inotify's IN_ATTRIB) */ 0041 EventCloseWrite = 0x00000008, /**< File opened for writing was closed (compare inotify's IN_CLOSE_WRITE) */ 0042 EventCloseRead = 0x00000010, /**< File not opened for writing was closed (compare inotify's IN_CLOSE_NOWRITE) */ 0043 EventCreate = 0x00000100, /** File/directory created in watched directory (compare inotify's IN_CREATE) */ 0044 EventDelete = 0x00000200, /**< File/directory deleted from watched directory (compare inotify's IN_DELETE) */ 0045 EventDeleteSelf = 0x00000400, /**< Watched file/directory was itself deleted (compare inotify's IN_DELETE_SELF) */ 0046 EventModify = 0x00000002, /**< File was modified (compare inotify's IN_MODIFY) */ 0047 EventMoveSelf = 0x00000800, /**< Watched file/directory was itself moved (compare inotify's IN_MOVE_SELF) */ 0048 EventMoveFrom = 0x00000040, /**< File moved out of watched directory (compare inotify's IN_MOVED_FROM) */ 0049 EventMoveTo = 0x00000080, /**< File moved into watched directory (compare inotify's IN_MOVED_TO) */ 0050 EventOpen = 0x00000020, /**< File was opened (compare inotify's IN_OPEN) */ 0051 EventUnmount = 0x00002000, /**< Backing fs was unmounted (compare inotify's IN_UNMOUNT) */ 0052 EventQueueOverflow = 0x00004000, /**< Event queued overflowed (compare inotify's IN_Q_OVERFLOW) */ 0053 EventIgnored = 0x00008000, /**< File was ignored (compare inotify's IN_IGNORED) */ 0054 EventMove = (EventMoveFrom | EventMoveTo), 0055 EventAll = (EventAccess | 0056 EventAttributeChange | 0057 EventCloseWrite | 0058 EventCloseRead | 0059 EventCreate | 0060 EventDelete | 0061 EventDeleteSelf | 0062 EventModify | 0063 EventMoveSelf | 0064 EventMoveFrom | 0065 EventMoveTo | 0066 EventOpen), 0067 }; 0068 Q_DECLARE_FLAGS(WatchEvents, WatchEvent) 0069 0070 /** 0071 * Watch flags 0072 * 0073 * These flags correspond to the native Linux inotify flags. 0074 */ 0075 enum WatchFlag { 0076 FlagOnlyDir = 0x01000000, /**< Only watch the path if it is a directory (IN_ONLYDIR) */ 0077 FlagDoNotFollow = 0x02000000, /**< Don't follow a sym link (IN_DONT_FOLLOW) */ 0078 FlagOneShot = 0x80000000, /**< Only send event once (IN_ONESHOT) */ 0079 FlagExclUnlink = 0x04000000, /**< Do not generate events for unlinked files (IN_EXCL_UNLINK) */ 0080 }; 0081 Q_DECLARE_FLAGS(WatchFlags, WatchFlag) 0082 0083 bool watchingPath(const QString& path) const; 0084 0085 /** 0086 * Call this when the inotify limit has been increased. 0087 */ 0088 void resetUserLimit(); 0089 0090 public Q_SLOTS: 0091 bool addWatch(const QString& path, WatchEvents modes, WatchFlags flags = WatchFlags()); 0092 bool removeWatch(const QString& path); 0093 0094 Q_SIGNALS: 0095 /** 0096 * Emitted if a file is accessed (KInotify::EventAccess) 0097 */ 0098 void accessed(const QString& file); 0099 0100 /** 0101 * Emitted if file attributes are changed (KInotify::EventAttributeChange) 0102 */ 0103 void attributeChanged(const QString& file); 0104 0105 /** 0106 * Emitted if FIXME (KInotify::EventCloseWrite) 0107 */ 0108 void closedWrite(const QString& file); 0109 0110 /** 0111 * Emitted if FIXME (KInotify::EventCloseRead) 0112 */ 0113 void closedRead(const QString& file); 0114 0115 /** 0116 * Emitted if a new file has been created in one of the watched 0117 * folders (KInotify::EventCreate) 0118 */ 0119 void created(const QString& file, bool isDir); 0120 0121 /** 0122 * Emitted if a watched file or folder has been deleted. 0123 * This includes files in watched folders (KInotify::EventDelete and KInotify::EventDeleteSelf) 0124 */ 0125 void deleted(const QString& file, bool isDir); 0126 0127 /** 0128 * Emitted if a watched file is modified (KInotify::EventModify) 0129 */ 0130 void modified(const QString& file); 0131 0132 /** 0133 * Emitted if a file or folder has been moved or renamed. 0134 * 0135 * \warning The moved signal will only be emitted if both the source and target folder 0136 * are being watched. 0137 */ 0138 void moved(const QString& oldName, const QString& newName); 0139 0140 /** 0141 * Emitted if a file is opened (KInotify::EventOpen) 0142 */ 0143 void opened(const QString& file); 0144 0145 /** 0146 * Emitted if a watched path has been unmounted (KInotify::EventUnmount) 0147 */ 0148 void unmounted(const QString& file); 0149 0150 /** 0151 * Emitted if during updating the internal watch structures (recursive watches) 0152 * the inotify user watch limit was reached. 0153 * 0154 * This means that not all requested paths can be watched until the user watch 0155 * limit is increased. 0156 * 0157 * The argument is the path being added when the limit was reached. 0158 * 0159 * This signal will only be emitted once until resetUserLimit is called. 0160 */ 0161 void watchUserLimitReached(const QString& path); 0162 0163 /** 0164 * This is emitted once watches have been installed in all the directories 0165 * indicated by addWatch 0166 */ 0167 void installedWatches(); 0168 0169 private Q_SLOTS: 0170 void slotEvent(int); 0171 void slotClearCookies(); 0172 0173 private: 0174 class Private; 0175 Private* const d; 0176 0177 /** 0178 * Recursively iterates over all files/folders inside @param path 0179 * (that are not excluded by the config); 0180 * emits created() signal for each entry (excluding @param path) 0181 * and installs watches for all subdirectories (including @param path) 0182 */ 0183 void handleDirCreated(const QString& path); 0184 }; 0185 0186 #endif