3 # class to allow watching multiple files and
4 # calling a callback when any change (size or mtime)
6 # We take exclusive use of SIGIO and maintain a global list of
8 # As we cannot get siginfo in python, we check every file
9 # every time we get a signal.
10 # we report change is size, mtime, or ino of the file (given by name)
12 # Copyright (C) 2011 Neil Brown <neilb@suse.de>
14 # This program is free software; you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation; either version 2 of the License, or
17 # (at your option) any later version.
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
24 # You should have received a copy of the GNU General Public License along
25 # with this program; if not, write to the Free Software Foundation, Inc.,
26 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 import os, fcntl, signal
33 def notified(sig, stack):
35 fcntl.fcntl(d.fd, fcntl.F_NOTIFY, (fcntl.DN_MODIFY|fcntl.DN_RENAME|
36 fcntl.DN_CREATE|fcntl.DN_DELETE))
40 def __init__(self, dname):
42 self.fd = os.open(dname, 0)
45 fcntl.fcntl(self.fd, fcntl.F_NOTIFY, (fcntl.DN_MODIFY|fcntl.DN_RENAME|
46 fcntl.DN_CREATE|fcntl.DN_DELETE))
48 signal.signal(signal.SIGIO, notified)
51 def watch(self, fname, callback):
52 f = file(os.path.join(self.dname, fname), callback)
56 def watchall(self, callback):
57 self.callbacks.append(callback)
61 for c in self.callbacks:
64 self.callbacks = newlist
69 def cancel(self, victim):
70 if victim in self.files:
71 self.files.remove(victim)
74 def __init__(self, fname, callback):
77 stat = os.stat(self.name)
83 self.ino = stat.st_ino
84 self.size = stat.st_size
85 self.mtime = stat.st_mtime
86 self.callback = callback
90 stat = os.stat(self.name)
98 if stat.st_size == self.size and stat.st_mtime == self.mtime \
99 and stat.st_ino == self.ino:
101 self.size = stat.st_size
102 self.mtime = stat.st_mtime
103 self.ino = stat.st_ino
114 if __name__ == "__main__" :
119 def ping(f): print "got ", f.name
122 a = d.watch("a", ping)
123 b = d.watch("b", ping)
124 c = d.watch("c", ping)