from __future__ import print_function # Pull in the IN_* macros from _inotifyy import * import _inotifyy import select, os, errno _flags = {} for k in dir(_inotifyy): if k.startswith('IN_') and k!='IN_ALL_EVENTS': _flags[k[3:]] = getattr(_inotifyy, k) del k def decodeMask(mask): ret = [] for k,v in _flags.iteritems(): if mask&v: ret.append(k) return '%s %s'%(hex(mask),ret) class IToken(object): def __init__(self, cb, path, inot, wd): self._cb, self._inot, self._wd = cb, inot, wd self.path = path def __del__(self): self.close() def close(self): if self._inot: self._inot._del(self._wd) self._inot = None def __str__(self): return 'IToken(%d,"%s")'%(self._wd, self.path) __repr__=__str__ class INotify(_inotifyy.INotify): def __init__(self): self.__done = False self.__listen, self.__wake = os.pipe() self.__wds = {} super(INotify, self).__init__() def close(self): self.__done = True os.write(self.__wake,b'*') def add(self, callback, path, mask=IN_ALL_EVENTS): wd = super(INotify, self).add(path, mask) try: return self.__wds[wd] except KeyError: tok = IToken(callback, path, self, wd) self.__wds[wd] = tok return tok def loop(self): while not self.__done: rds, _wts, _exs = select.select([self.fd, self.__listen], [], []) if self.fd in rds: for wd, mask, cookie, path in self.read(): try: tok = self.__wds[wd] except KeyError: pass # ignore unknown wd else: tok._cb(tok, mask, cookie, path) elif self.__listen in rds: os.read(self.__listen,1024) self.__done = False def cmdlisten(files): print("Listening for",*files) if len(files)==0: return def event(evt, mask, cookie, path): print('Event',evt, decodeMask(mask), cookie, path) IN = INotify() wds = [IN.add(event, P) for P in files] print(wds) return IN class cmdtail(object): def __init__(self, fname): import os.path self.fname = fname dirname, self.fpart= os.path.split(fname) self.IN = INotify() self.loop = self.IN.loop mask=IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MODIFY self.dirwd = self.IN.add(self.direvt, dirname, mask) self.fd = None self.startfile() self.catfile() def startfile(self): self.closefile() try: self.fd = open(self.fname, 'r') except IOError as e: if e.errno==errno.ENOENT: print(self.fname, "Doesn't exist yet") return #self.catfile() def closefile(self): if self.fd: print("Closing previous") self.fd.close() self.fd = None def catfile(self): if not self.fd: return op = self.fd.tell() self.fd.seek(0, 2) end = self.fd.tell() if end [path2] ...") print(" or inotifyy tail ") sys.exit(1) elif sys.argv[1]=='listen': IN = cmdlisten(sys.argv[2:]) elif sys.argv[1]=='tail': IN = cmdtail(sys.argv[2]) IN.loop()