summaryrefslogtreecommitdiffstats
path: root/tdecore/ksimpledirwatch_p.h
blob: 7c6986d1ab1f8beb6f3ec3dc9bcf50882e6d0ea9 (plain)
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
/* Private Header for class of KSimpleDirWatchPrivate
 *
 * this separate header file is needed for MOC processing
 * because KSimpleDirWatchPrivate has signals and slots
 *
 * KSimpleDirWatch is a basic copy of KDirWatch
 * but with the TDEIO linking requirement removed
 */

#ifndef _KSIMPLEDIRWATCH_P_H
#define _KSIMPLEDIRWATCH_P_H

#ifdef HAVE_FAM
#include <fam.h>
#endif

#include <ctime>

#define invalid_ctime ((time_t)-1)

/* KSimpleDirWatchPrivate is a singleton and does the watching
 * for every KSimpleDirWatch instance in the application.
 */
class KSimpleDirWatchPrivate : public TQObject
{
  TQ_OBJECT
public:

  enum entryStatus { Normal = 0, NonExistent };
  enum entryMode { UnknownMode = 0, StatMode, DNotifyMode, INotifyMode, FAMMode };
  enum { NoChange=0, Changed=1, Created=2, Deleted=4 };

  struct Client {
    KSimpleDirWatch* instance;
    int count;
    // did the instance stop watching
    bool watchingStopped;
    // events blocked when stopped
    int pending;
  };

  class Entry
  {
  public:
    // the last observed modification time
    time_t m_ctime;
    // the last observed link count
    int m_nlink;
    entryStatus m_status;
    entryMode m_mode;
    bool isDir;
    // instances interested in events
    TQPtrList<Client> m_clients;
    // nonexistent entries of this directory
    TQPtrList<Entry> m_entries;
    TQString path;

    int msecLeft, freq;

    void addClient(KSimpleDirWatch*);
    void removeClient(KSimpleDirWatch*);
    int clients();
    bool isValid() { return m_clients.count() || m_entries.count(); }

    bool dirty;
    void propagate_dirty();

#ifdef HAVE_FAM
    FAMRequest fr;
#endif

#ifdef HAVE_DNOTIFY
    int dn_fd;
#endif
#ifdef HAVE_INOTIFY
    int wd;
#endif
  };

  typedef TQMap<TQString,Entry> EntryMap;

  KSimpleDirWatchPrivate();
  ~KSimpleDirWatchPrivate();

  void resetList (KSimpleDirWatch*,bool);
  void useFreq(Entry* e, int newFreq);
  void addEntry(KSimpleDirWatch*,const TQString&, Entry*, bool);
  void removeEntry(KSimpleDirWatch*,const TQString&, Entry*);
  bool stopEntryScan(KSimpleDirWatch*, Entry*);
  bool restartEntryScan(KSimpleDirWatch*, Entry*, bool );
  void stopScan(KSimpleDirWatch*);
  void startScan(KSimpleDirWatch*, bool, bool);

  void removeEntries(KSimpleDirWatch*);
  void statistics();

  Entry* entry(const TQString&);
  int scanEntry(Entry* e);
  void emitEvent(Entry* e, int event, const TQString &fileName = TQString::null);

  // Memory management - delete when last KSimpleDirWatch gets deleted
  void ref() { m_ref++; }
  bool deref() { return ( --m_ref == 0 ); }

 static bool isNoisyFile( const char *filename );

public slots:
  void slotRescan();
  void famEventReceived(); // for FAM
  void slotActivated(); // for DNOTIFY
  void slotRemoveDelayed();

public:
  TQTimer *timer;
  EntryMap m_mapEntries;

  int freq;
  int statEntries;
  int m_nfsPollInterval, m_PollInterval;
  int m_ref;
  bool useStat(Entry*);

  bool delayRemove;
  TQPtrList<Entry> removeList;

  bool rescan_all;
  TQTimer rescan_timer;

#ifdef HAVE_FAM
  TQSocketNotifier *sn;
  FAMConnection fc;
  bool use_fam;

  void checkFAMEvent(FAMEvent*);
  bool useFAM(Entry*);
#endif

#if defined(HAVE_DNOTIFY) || defined(HAVE_INOTIFY)
   TQSocketNotifier *mSn;
#endif

#ifdef HAVE_DNOTIFY
  bool supports_dnotify;
  int mPipe[2];
  TQIntDict<Entry> fd_Entry;

  static void dnotify_handler(int, siginfo_t *si, void *);
  static void dnotify_sigio_handler(int, siginfo_t *si, void *);
  bool useDNotify(Entry*);
#endif

#ifdef HAVE_INOTIFY
  bool supports_inotify;
  int m_inotify_fd;

  bool useINotify(Entry*);
#endif
};

#endif // KSIMPLEDIRWATCH_P_H