1#!/usr/bin/env python
2
3# pyinotify.py - python interface to inotify
4# Copyright (c) 2005-2015 Sebastien Martini <seb@dbzteam.org>
5#
6# Permission is hereby granted, free of charge, to any person obtaining a copy
7# of this software and associated documentation files (the "Software"), to deal
8# in the Software without restriction, including without limitation the rights
9# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10# copies of the Software, and to permit persons to whom the Software is
11# furnished to do so, subject to the following conditions:
12#
13# The above copyright notice and this permission notice shall be included in
14# all copies or substantial portions of the Software.
15#
16# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22# THE SOFTWARE.
23"""
24pyinotify
25
26@author: Sebastien Martini
27@license: MIT License
28@contact: seb@dbzteam.org
29"""
30
31class PyinotifyError(Exception):
32    """Indicates exceptions raised by a Pyinotify class."""
33    pass
34
35
36class UnsupportedPythonVersionError(PyinotifyError):
37    """
38    Raised on unsupported Python versions.
39    """
40    def __init__(self, version):
41        """
42        @param version: Current Python version
43        @type version: string
44        """
45        err = 'Python %s is unsupported, requires at least Python 2.4'
46        PyinotifyError.__init__(self, err % version)
47
48
49# Check Python version
50import sys
51if sys.version_info < (2, 4):
52    raise UnsupportedPythonVersionError(sys.version)
53
54
55# Import directives
56import threading
57import os
58import select
59import struct
60import fcntl
61import errno
62import termios
63import array
64import logging
65import atexit
66from collections import deque
67from datetime import datetime, timedelta
68import time
69import re
70import asyncore
71import subprocess
72
73try:
74    from functools import reduce
75except ImportError:
76    pass  # Will fail on Python 2.4 which has reduce() builtin anyway.
77
78try:
79    from glob import iglob as glob
80except ImportError:
81    # Python 2.4 does not have glob.iglob().
82    from glob import glob as glob
83
84try:
85    import ctypes
86    import ctypes.util
87except ImportError:
88    ctypes = None
89
90try:
91    import inotify_syscalls
92except ImportError:
93    inotify_syscalls = None
94
95
96__author__ = "seb@dbzteam.org (Sebastien Martini)"
97
98__version__ = "0.9.6"
99
100__metaclass__ = type  # Use new-style classes by default
101
102
103# Compatibity mode: set to True to improve compatibility with
104# Pyinotify 0.7.1. Do not set this variable yourself, call the
105# function compatibility_mode() instead.
106COMPATIBILITY_MODE = False
107
108
109class InotifyBindingNotFoundError(PyinotifyError):
110    """
111    Raised when no inotify support couldn't be found.
112    """
113    def __init__(self):
114        err = "Couldn't find any inotify binding"
115        PyinotifyError.__init__(self, err)
116
117
118class INotifyWrapper:
119    """
120    Abstract class wrapping access to inotify's functions. This is an
121    internal class.
122    """
123    @staticmethod
124    def create():
125        # First, try to use ctypes.
126        if ctypes:
127            inotify = _CtypesLibcINotifyWrapper()
128            if inotify.init():
129                return inotify
130        # Second, see if C extension is compiled.
131        if inotify_syscalls:
132            inotify = _INotifySyscallsWrapper()
133            if inotify.init():
134                return inotify
135
136    def get_errno(self):
137        """
138        Return None is no errno code is available.
139        """
140        return self._get_errno()
141
142    def str_errno(self):
143        code = self.get_errno()
144        if code is None:
145            return 'Errno: no errno support'
146        return 'Errno=%s (%s)' % (os.strerror(code), errno.errorcode[code])
147
148    def inotify_init(self):
149        return self._inotify_init()
150
151    def inotify_add_watch(self, fd, pathname, mask):
152        # Unicode strings must be encoded to string prior to calling this
153        # method.
154        assert isinstance(pathname, str)
155        return self._inotify_add_watch(fd, pathname, mask)
156
157    def inotify_rm_watch(self, fd, wd):
158        return self._inotify_rm_watch(fd, wd)
159
160
161class _INotifySyscallsWrapper(INotifyWrapper):
162    def __init__(self):
163        # Stores the last errno value.
164        self._last_errno = None
165
166    def init(self):
167        assert inotify_syscalls
168        return True
169
170    def _get_errno(self):
171        return self._last_errno
172
173    def _inotify_init(self):
174        try:
175            fd = inotify_syscalls.inotify_init()
176        except IOError, err:
177            self._last_errno = err.errno
178            return -1
179        return fd
180
181    def _inotify_add_watch(self, fd, pathname, mask):
182        try:
183            wd = inotify_syscalls.inotify_add_watch(fd, pathname, mask)
184        except IOError, err:
185            self._last_errno = err.errno
186            return -1
187        return wd
188
189    def _inotify_rm_watch(self, fd, wd):
190        try:
191            ret = inotify_syscalls.inotify_rm_watch(fd, wd)
192        except IOError, err:
193            self._last_errno = err.errno
194            return -1
195        return ret
196
197
198class _CtypesLibcINotifyWrapper(INotifyWrapper):
199    def __init__(self):
200        self._libc = None
201        self._get_errno_func = None
202
203    def init(self):
204        assert ctypes
205
206        try_libc_name = 'c'
207        if sys.platform.startswith('freebsd') or sys.platform.startswith('dragonfly'):
208            try_libc_name = 'inotify'
209
210        libc_name = None
211        try:
212            libc_name = ctypes.util.find_library(try_libc_name)
213        except (OSError, IOError):
214            pass  # Will attemp to load it with None anyway.
215
216        if sys.version_info >= (2, 6):
217            self._libc = ctypes.CDLL(libc_name, use_errno=True)
218            self._get_errno_func = ctypes.get_errno
219        else:
220            self._libc = ctypes.CDLL(libc_name)
221            try:
222                location = self._libc.__errno_location
223                location.restype = ctypes.POINTER(ctypes.c_int)
224                self._get_errno_func = lambda: location().contents.value
225            except AttributeError:
226                pass
227
228        # Eventually check that libc has needed inotify bindings.
229        if (not hasattr(self._libc, 'inotify_init') or
230            not hasattr(self._libc, 'inotify_add_watch') or
231            not hasattr(self._libc, 'inotify_rm_watch')):
232            return False
233
234        self._libc.inotify_init.argtypes = []
235        self._libc.inotify_init.restype = ctypes.c_int
236        self._libc.inotify_add_watch.argtypes = [ctypes.c_int, ctypes.c_char_p,
237                                                 ctypes.c_uint32]
238        self._libc.inotify_add_watch.restype = ctypes.c_int
239        self._libc.inotify_rm_watch.argtypes = [ctypes.c_int, ctypes.c_int]
240        self._libc.inotify_rm_watch.restype = ctypes.c_int
241        return True
242
243    def _get_errno(self):
244        if self._get_errno_func is not None:
245            return self._get_errno_func()
246        return None
247
248    def _inotify_init(self):
249        assert self._libc is not None
250        return self._libc.inotify_init()
251
252    def _inotify_add_watch(self, fd, pathname, mask):
253        assert self._libc is not None
254        pathname = ctypes.create_string_buffer(pathname)
255        return self._libc.inotify_add_watch(fd, pathname, mask)
256
257    def _inotify_rm_watch(self, fd, wd):
258        assert self._libc is not None
259        return self._libc.inotify_rm_watch(fd, wd)
260
261
262# Logging
263def logger_init():
264    """Initialize logger instance."""
265    log = logging.getLogger("pyinotify")
266    console_handler = logging.StreamHandler()
267    console_handler.setFormatter(
268        logging.Formatter("[%(asctime)s %(name)s %(levelname)s] %(message)s"))
269    log.addHandler(console_handler)
270    log.setLevel(20)
271    return log
272
273log = logger_init()
274
275
276# inotify's variables
277class ProcINotify:
278    """
279    Access (read, write) inotify's variables through /proc/sys/. Note that
280    usually it requires administrator rights to update them.
281
282    Examples:
283      - Read max_queued_events attribute: myvar = max_queued_events.value
284      - Update max_queued_events attribute: max_queued_events.value = 42
285    """
286    def __init__(self, attr):
287        self._base = "/proc/sys/fs/inotify"
288        self._attr = attr
289
290    def get_val(self):
291        """
292        Gets attribute's value.
293
294        @return: stored value.
295        @rtype: int
296        @raise IOError: if corresponding file in /proc/sys cannot be read.
297        """
298        file_obj = file(os.path.join(self._base, self._attr), 'r')
299        try:
300            val = int(file_obj.readline())
301        finally:
302            file_obj.close()
303        return val
304
305    def set_val(self, nval):
306        """
307        Sets new attribute's value.
308
309        @param nval: replaces current value by nval.
310        @type nval: int
311        @raise IOError: if corresponding file in /proc/sys cannot be written.
312        """
313        file_obj = file(os.path.join(self._base, self._attr), 'w')
314        try:
315            file_obj.write(str(nval) + '\n')
316        finally:
317            file_obj.close()
318
319    value = property(get_val, set_val)
320
321    def __repr__(self):
322        return '<%s=%d>' % (self._attr, self.get_val())
323
324
325# Inotify's variables
326#
327# Note: may raise IOError if the corresponding value in /proc/sys
328#       cannot be accessed.
329#
330# Examples:
331#  - read: myvar = max_queued_events.value
332#  - update: max_queued_events.value = 42
333#
334for attrname in ('max_queued_events', 'max_user_instances', 'max_user_watches'):
335    globals()[attrname] = ProcINotify(attrname)
336
337
338class EventsCodes:
339    """
340    Set of codes corresponding to each kind of events.
341    Some of these flags are used to communicate with inotify, whereas
342    the others are sent to userspace by inotify notifying some events.
343
344    @cvar IN_ACCESS: File was accessed.
345    @type IN_ACCESS: int
346    @cvar IN_MODIFY: File was modified.
347    @type IN_MODIFY: int
348    @cvar IN_ATTRIB: Metadata changed.
349    @type IN_ATTRIB: int
350    @cvar IN_CLOSE_WRITE: Writtable file was closed.
351    @type IN_CLOSE_WRITE: int
352    @cvar IN_CLOSE_NOWRITE: Unwrittable file closed.
353    @type IN_CLOSE_NOWRITE: int
354    @cvar IN_OPEN: File was opened.
355    @type IN_OPEN: int
356    @cvar IN_MOVED_FROM: File was moved from X.
357    @type IN_MOVED_FROM: int
358    @cvar IN_MOVED_TO: File was moved to Y.
359    @type IN_MOVED_TO: int
360    @cvar IN_CREATE: Subfile was created.
361    @type IN_CREATE: int
362    @cvar IN_DELETE: Subfile was deleted.
363    @type IN_DELETE: int
364    @cvar IN_DELETE_SELF: Self (watched item itself) was deleted.
365    @type IN_DELETE_SELF: int
366    @cvar IN_MOVE_SELF: Self (watched item itself) was moved.
367    @type IN_MOVE_SELF: int
368    @cvar IN_UNMOUNT: Backing fs was unmounted.
369    @type IN_UNMOUNT: int
370    @cvar IN_Q_OVERFLOW: Event queued overflowed.
371    @type IN_Q_OVERFLOW: int
372    @cvar IN_IGNORED: File was ignored.
373    @type IN_IGNORED: int
374    @cvar IN_ONLYDIR: only watch the path if it is a directory (new
375                      in kernel 2.6.15).
376    @type IN_ONLYDIR: int
377    @cvar IN_DONT_FOLLOW: don't follow a symlink (new in kernel 2.6.15).
378                          IN_ONLYDIR we can make sure that we don't watch
379                          the target of symlinks.
380    @type IN_DONT_FOLLOW: int
381    @cvar IN_EXCL_UNLINK: Events are not generated for children after they
382                          have been unlinked from the watched directory.
383                          (new in kernel 2.6.36).
384    @type IN_EXCL_UNLINK: int
385    @cvar IN_MASK_ADD: add to the mask of an already existing watch (new
386                       in kernel 2.6.14).
387    @type IN_MASK_ADD: int
388    @cvar IN_ISDIR: Event occurred against dir.
389    @type IN_ISDIR: int
390    @cvar IN_ONESHOT: Only send event once.
391    @type IN_ONESHOT: int
392    @cvar ALL_EVENTS: Alias for considering all of the events.
393    @type ALL_EVENTS: int
394    """
395
396    # The idea here is 'configuration-as-code' - this way, we get our nice class
397    # constants, but we also get nice human-friendly text mappings to do lookups
398    # against as well, for free:
399    FLAG_COLLECTIONS = {'OP_FLAGS': {
400        'IN_ACCESS'        : 0x00000001,  # File was accessed
401        'IN_MODIFY'        : 0x00000002,  # File was modified
402        'IN_ATTRIB'        : 0x00000004,  # Metadata changed
403        'IN_CLOSE_WRITE'   : 0x00000008,  # Writable file was closed
404        'IN_CLOSE_NOWRITE' : 0x00000010,  # Unwritable file closed
405        'IN_OPEN'          : 0x00000020,  # File was opened
406        'IN_MOVED_FROM'    : 0x00000040,  # File was moved from X
407        'IN_MOVED_TO'      : 0x00000080,  # File was moved to Y
408        'IN_CREATE'        : 0x00000100,  # Subfile was created
409        'IN_DELETE'        : 0x00000200,  # Subfile was deleted
410        'IN_DELETE_SELF'   : 0x00000400,  # Self (watched item itself)
411                                          # was deleted
412        'IN_MOVE_SELF'     : 0x00000800,  # Self (watched item itself) was moved
413        },
414                        'EVENT_FLAGS': {
415        'IN_UNMOUNT'       : 0x00002000,  # Backing fs was unmounted
416        'IN_Q_OVERFLOW'    : 0x00004000,  # Event queued overflowed
417        'IN_IGNORED'       : 0x00008000,  # File was ignored
418        },
419                        'SPECIAL_FLAGS': {
420        'IN_ONLYDIR'       : 0x01000000,  # only watch the path if it is a
421                                          # directory
422        'IN_DONT_FOLLOW'   : 0x02000000,  # don't follow a symlink
423        'IN_EXCL_UNLINK'   : 0x04000000,  # exclude events on unlinked objects
424        'IN_MASK_ADD'      : 0x20000000,  # add to the mask of an already
425                                          # existing watch
426        'IN_ISDIR'         : 0x40000000,  # event occurred against dir
427        'IN_ONESHOT'       : 0x80000000,  # only send event once
428        },
429                        }
430
431    def maskname(mask):
432        """
433        Returns the event name associated to mask. IN_ISDIR is appended to
434        the result when appropriate. Note: only one event is returned, because
435        only one event can be raised at a given time.
436
437        @param mask: mask.
438        @type mask: int
439        @return: event name.
440        @rtype: str
441        """
442        ms = mask
443        name = '%s'
444        if mask & IN_ISDIR:
445            ms = mask - IN_ISDIR
446            name = '%s|IN_ISDIR'
447        return name % EventsCodes.ALL_VALUES[ms]
448
449    maskname = staticmethod(maskname)
450
451
452# So let's now turn the configuration into code
453EventsCodes.ALL_FLAGS = {}
454EventsCodes.ALL_VALUES = {}
455for flagc, valc in EventsCodes.FLAG_COLLECTIONS.items():
456    # Make the collections' members directly accessible through the
457    # class dictionary
458    setattr(EventsCodes, flagc, valc)
459
460    # Collect all the flags under a common umbrella
461    EventsCodes.ALL_FLAGS.update(valc)
462
463    # Make the individual masks accessible as 'constants' at globals() scope
464    # and masknames accessible by values.
465    for name, val in valc.items():
466        globals()[name] = val
467        EventsCodes.ALL_VALUES[val] = name
468
469
470# all 'normal' events
471ALL_EVENTS = reduce(lambda x, y: x | y, EventsCodes.OP_FLAGS.values())
472EventsCodes.ALL_FLAGS['ALL_EVENTS'] = ALL_EVENTS
473EventsCodes.ALL_VALUES[ALL_EVENTS] = 'ALL_EVENTS'
474
475
476class _Event:
477    """
478    Event structure, represent events raised by the system. This
479    is the base class and should be subclassed.
480
481    """
482    def __init__(self, dict_):
483        """
484        Attach attributes (contained in dict_) to self.
485
486        @param dict_: Set of attributes.
487        @type dict_: dictionary
488        """
489        for tpl in dict_.items():
490            setattr(self, *tpl)
491
492    def __repr__(self):
493        """
494        @return: Generic event string representation.
495        @rtype: str
496        """
497        s = ''
498        for attr, value in sorted(self.__dict__.items(), key=lambda x: x[0]):
499            if attr.startswith('_'):
500                continue
501            if attr == 'mask':
502                value = hex(getattr(self, attr))
503            elif isinstance(value, basestring) and not value:
504                value = "''"
505            s += ' %s%s%s' % (output_format.field_name(attr),
506                              output_format.punctuation('='),
507                              output_format.field_value(value))
508
509        s = '%s%s%s %s' % (output_format.punctuation('<'),
510                           output_format.class_name(self.__class__.__name__),
511                           s,
512                           output_format.punctuation('>'))
513        return s
514
515    def __str__(self):
516        return repr(self)
517
518
519class _RawEvent(_Event):
520    """
521    Raw event, it contains only the informations provided by the system.
522    It doesn't infer anything.
523    """
524    def __init__(self, wd, mask, cookie, name):
525        """
526        @param wd: Watch Descriptor.
527        @type wd: int
528        @param mask: Bitmask of events.
529        @type mask: int
530        @param cookie: Cookie.
531        @type cookie: int
532        @param name: Basename of the file or directory against which the
533                     event was raised in case where the watched directory
534                     is the parent directory. None if the event was raised
535                     on the watched item itself.
536        @type name: string or None
537        """
538        # Use this variable to cache the result of str(self), this object
539        # is immutable.
540        self._str = None
541        # name: remove trailing '\0'
542        d = {'wd': wd,
543             'mask': mask,
544             'cookie': cookie,
545             'name': name.rstrip('\0')}
546        _Event.__init__(self, d)
547        log.debug(str(self))
548
549    def __str__(self):
550        if self._str is None:
551            self._str = _Event.__str__(self)
552        return self._str
553
554
555class Event(_Event):
556    """
557    This class contains all the useful informations about the observed
558    event. However, the presence of each field is not guaranteed and
559    depends on the type of event. In effect, some fields are irrelevant
560    for some kind of event (for example 'cookie' is meaningless for
561    IN_CREATE whereas it is mandatory for IN_MOVE_TO).
562
563    The possible fields are:
564      - wd (int): Watch Descriptor.
565      - mask (int): Mask.
566      - maskname (str): Readable event name.
567      - path (str): path of the file or directory being watched.
568      - name (str): Basename of the file or directory against which the
569              event was raised in case where the watched directory
570              is the parent directory. None if the event was raised
571              on the watched item itself. This field is always provided
572              even if the string is ''.
573      - pathname (str): Concatenation of 'path' and 'name'.
574      - src_pathname (str): Only present for IN_MOVED_TO events and only in
575              the case where IN_MOVED_FROM events are watched too. Holds the
576              source pathname from where pathname was moved from.
577      - cookie (int): Cookie.
578      - dir (bool): True if the event was raised against a directory.
579
580    """
581    def __init__(self, raw):
582        """
583        Concretely, this is the raw event plus inferred infos.
584        """
585        _Event.__init__(self, raw)
586        self.maskname = EventsCodes.maskname(self.mask)
587        if COMPATIBILITY_MODE:
588            self.event_name = self.maskname
589        try:
590            if self.name:
591                self.pathname = os.path.abspath(os.path.join(self.path,
592                                                             self.name))
593            else:
594                self.pathname = os.path.abspath(self.path)
595        except AttributeError, err:
596            # Usually it is not an error some events are perfectly valids
597            # despite the lack of these attributes.
598            log.debug(err)
599
600
601class ProcessEventError(PyinotifyError):
602    """
603    ProcessEventError Exception. Raised on ProcessEvent error.
604    """
605    def __init__(self, err):
606        """
607        @param err: Exception error description.
608        @type err: string
609        """
610        PyinotifyError.__init__(self, err)
611
612
613class _ProcessEvent:
614    """
615    Abstract processing event class.
616    """
617    def __call__(self, event):
618        """
619        To behave like a functor the object must be callable.
620        This method is a dispatch method. Its lookup order is:
621          1. process_MASKNAME method
622          2. process_FAMILY_NAME method
623          3. otherwise calls process_default
624
625        @param event: Event to be processed.
626        @type event: Event object
627        @return: By convention when used from the ProcessEvent class:
628                 - Returning False or None (default value) means keep on
629                 executing next chained functors (see chain.py example).
630                 - Returning True instead means do not execute next
631                   processing functions.
632        @rtype: bool
633        @raise ProcessEventError: Event object undispatchable,
634                                  unknown event.
635        """
636        stripped_mask = event.mask - (event.mask & IN_ISDIR)
637        maskname = EventsCodes.ALL_VALUES.get(stripped_mask)
638        if maskname is None:
639            raise ProcessEventError("Unknown mask 0x%08x" % stripped_mask)
640
641        # 1- look for process_MASKNAME
642        meth = getattr(self, 'process_' + maskname, None)
643        if meth is not None:
644            return meth(event)
645        # 2- look for process_FAMILY_NAME
646        meth = getattr(self, 'process_IN_' + maskname.split('_')[1], None)
647        if meth is not None:
648            return meth(event)
649        # 3- default call method process_default
650        return self.process_default(event)
651
652    def __repr__(self):
653        return '<%s>' % self.__class__.__name__
654
655
656class _SysProcessEvent(_ProcessEvent):
657    """
658    There is three kind of processing according to each event:
659
660      1. special handling (deletion from internal container, bug, ...).
661      2. default treatment: which is applied to the majority of events.
662      3. IN_ISDIR is never sent alone, he is piggybacked with a standard
663         event, he is not processed as the others events, instead, its
664         value is captured and appropriately aggregated to dst event.
665    """
666    def __init__(self, wm, notifier):
667        """
668
669        @param wm: Watch Manager.
670        @type wm: WatchManager instance
671        @param notifier: Notifier.
672        @type notifier: Notifier instance
673        """
674        self._watch_manager = wm  # watch manager
675        self._notifier = notifier  # notifier
676        self._mv_cookie = {}  # {cookie(int): (src_path(str), date), ...}
677        self._mv = {}  # {src_path(str): (dst_path(str), date), ...}
678
679    def cleanup(self):
680        """
681        Cleanup (delete) old (>1mn) records contained in self._mv_cookie
682        and self._mv.
683        """
684        date_cur_ = datetime.now()
685        for seq in [self._mv_cookie, self._mv]:
686            for k in seq.keys():
687                if (date_cur_ - seq[k][1]) > timedelta(minutes=1):
688                    log.debug('Cleanup: deleting entry %s', seq[k][0])
689                    del seq[k]
690
691    def process_IN_CREATE(self, raw_event):
692        """
693        If the event affects a directory and the auto_add flag of the
694        targetted watch is set to True, a new watch is added on this
695        new directory, with the same attribute values than those of
696        this watch.
697        """
698        if raw_event.mask & IN_ISDIR:
699            watch_ = self._watch_manager.get_watch(raw_event.wd)
700            created_dir = os.path.join(watch_.path, raw_event.name)
701            if watch_.auto_add and not watch_.exclude_filter(created_dir):
702                addw = self._watch_manager.add_watch
703                # The newly monitored directory inherits attributes from its
704                # parent directory.
705                addw_ret = addw(created_dir, watch_.mask,
706                                proc_fun=watch_.proc_fun,
707                                rec=False, auto_add=watch_.auto_add,
708                                exclude_filter=watch_.exclude_filter)
709
710                # Trick to handle mkdir -p /d1/d2/t3 where d1 is watched and
711                # d2 and t3 (directory or file) are created.
712                # Since the directory d2 is new, then everything inside it must
713                # also be new.
714                created_dir_wd = addw_ret.get(created_dir)
715                if ((created_dir_wd is not None) and (created_dir_wd > 0) and
716                    os.path.isdir(created_dir)):
717                    try:
718                        for name in os.listdir(created_dir):
719                            inner = os.path.join(created_dir, name)
720                            if self._watch_manager.get_wd(inner) is not None:
721                                continue
722                            # Generate (simulate) creation events for sub-
723                            # directories and files.
724                            if os.path.isfile(inner):
725                                # symlinks are handled as files.
726                                flags = IN_CREATE
727                            elif os.path.isdir(inner):
728                                flags = IN_CREATE | IN_ISDIR
729                            else:
730                                # This path should not be taken.
731                                continue
732                            rawevent = _RawEvent(created_dir_wd, flags, 0, name)
733                            self._notifier.append_event(rawevent)
734                    except OSError, err:
735                        msg = "process_IN_CREATE, invalid directory %s: %s"
736                        log.debug(msg % (created_dir, str(err)))
737        return self.process_default(raw_event)
738
739    def process_IN_MOVED_FROM(self, raw_event):
740        """
741        Map the cookie with the source path (+ date for cleaning).
742        """
743        watch_ = self._watch_manager.get_watch(raw_event.wd)
744        path_ = watch_.path
745        src_path = os.path.normpath(os.path.join(path_, raw_event.name))
746        self._mv_cookie[raw_event.cookie] = (src_path, datetime.now())
747        return self.process_default(raw_event, {'cookie': raw_event.cookie})
748
749    def process_IN_MOVED_TO(self, raw_event):
750        """
751        Map the source path with the destination path (+ date for
752        cleaning).
753        """
754        watch_ = self._watch_manager.get_watch(raw_event.wd)
755        path_ = watch_.path
756        dst_path = os.path.normpath(os.path.join(path_, raw_event.name))
757        mv_ = self._mv_cookie.get(raw_event.cookie)
758        to_append = {'cookie': raw_event.cookie}
759        if mv_ is not None:
760            self._mv[mv_[0]] = (dst_path, datetime.now())
761            # Let's assume that IN_MOVED_FROM event is always queued before
762            # that its associated (they share a common cookie) IN_MOVED_TO
763            # event is queued itself. It is then possible in that scenario
764            # to provide as additional information to the IN_MOVED_TO event
765            # the original pathname of the moved file/directory.
766            to_append['src_pathname'] = mv_[0]
767        elif (raw_event.mask & IN_ISDIR and watch_.auto_add and
768              not watch_.exclude_filter(dst_path)):
769            # We got a diretory that's "moved in" from an unknown source and
770            # auto_add is enabled. Manually add watches to the inner subtrees.
771            # The newly monitored directory inherits attributes from its
772            # parent directory.
773            self._watch_manager.add_watch(dst_path, watch_.mask,
774                                          proc_fun=watch_.proc_fun,
775                                          rec=True, auto_add=True,
776                                          exclude_filter=watch_.exclude_filter)
777        return self.process_default(raw_event, to_append)
778
779    def process_IN_MOVE_SELF(self, raw_event):
780        """
781        STATUS: the following bug has been fixed in recent kernels (FIXME:
782        which version ?). Now it raises IN_DELETE_SELF instead.
783
784        Old kernels were bugged, this event raised when the watched item
785        were moved, so we had to update its path, but under some circumstances
786        it was impossible: if its parent directory and its destination
787        directory wasn't watched. The kernel (see include/linux/fsnotify.h)
788        doesn't bring us enough informations like the destination path of
789        moved items.
790        """
791        watch_ = self._watch_manager.get_watch(raw_event.wd)
792        src_path = watch_.path
793        mv_ = self._mv.get(src_path)
794        if mv_:
795            dest_path = mv_[0]
796            watch_.path = dest_path
797            # add the separator to the source path to avoid overlapping
798            # path issue when testing with startswith()
799            src_path += os.path.sep
800            src_path_len = len(src_path)
801            # The next loop renames all watches with src_path as base path.
802            # It seems that IN_MOVE_SELF does not provide IN_ISDIR information
803            # therefore the next loop is iterated even if raw_event is a file.
804            for w in self._watch_manager.watches.values():
805                if w.path.startswith(src_path):
806                    # Note that dest_path is a normalized path.
807                    w.path = os.path.join(dest_path, w.path[src_path_len:])
808        else:
809            log.error("The pathname '%s' of this watch %s has probably changed "
810                      "and couldn't be updated, so it cannot be trusted "
811                      "anymore. To fix this error move directories/files only "
812                      "between watched parents directories, in this case e.g. "
813                      "put a watch on '%s'.",
814                      watch_.path, watch_,
815                      os.path.normpath(os.path.join(watch_.path,
816                                                    os.path.pardir)))
817            if not watch_.path.endswith('-unknown-path'):
818                watch_.path += '-unknown-path'
819        return self.process_default(raw_event)
820
821    def process_IN_Q_OVERFLOW(self, raw_event):
822        """
823        Only signal an overflow, most of the common flags are irrelevant
824        for this event (path, wd, name).
825        """
826        return Event({'mask': raw_event.mask})
827
828    def process_IN_IGNORED(self, raw_event):
829        """
830        The watch descriptor raised by this event is now ignored (forever),
831        it can be safely deleted from the watch manager dictionary.
832        After this event we can be sure that neither the event queue nor
833        the system will raise an event associated to this wd again.
834        """
835        event_ = self.process_default(raw_event)
836        self._watch_manager.del_watch(raw_event.wd)
837        return event_
838
839    def process_default(self, raw_event, to_append=None):
840        """
841        Commons handling for the followings events:
842
843        IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE,
844        IN_OPEN, IN_DELETE, IN_DELETE_SELF, IN_UNMOUNT.
845        """
846        watch_ = self._watch_manager.get_watch(raw_event.wd)
847        if raw_event.mask & (IN_DELETE_SELF | IN_MOVE_SELF):
848            # Unfornulately this information is not provided by the kernel
849            dir_ = watch_.dir
850        else:
851            dir_ = bool(raw_event.mask & IN_ISDIR)
852        dict_ = {'wd': raw_event.wd,
853                 'mask': raw_event.mask,
854                 'path': watch_.path,
855                 'name': raw_event.name,
856                 'dir': dir_}
857        if COMPATIBILITY_MODE:
858            dict_['is_dir'] = dir_
859        if to_append is not None:
860            dict_.update(to_append)
861        return Event(dict_)
862
863
864class ProcessEvent(_ProcessEvent):
865    """
866    Process events objects, can be specialized via subclassing, thus its
867    behavior can be overriden:
868
869    Note: you should not override __init__ in your subclass instead define
870    a my_init() method, this method will be called automatically from the
871    constructor of this class with its optionals parameters.
872
873      1. Provide specialized individual methods, e.g. process_IN_DELETE for
874         processing a precise type of event (e.g. IN_DELETE in this case).
875      2. Or/and provide methods for processing events by 'family', e.g.
876         process_IN_CLOSE method will process both IN_CLOSE_WRITE and
877         IN_CLOSE_NOWRITE events (if process_IN_CLOSE_WRITE and
878         process_IN_CLOSE_NOWRITE aren't defined though).
879      3. Or/and override process_default for catching and processing all
880         the remaining types of events.
881    """
882    pevent = None
883
884    def __init__(self, pevent=None, **kargs):
885        """
886        Enable chaining of ProcessEvent instances.
887
888        @param pevent: Optional callable object, will be called on event
889                       processing (before self).
890        @type pevent: callable
891        @param kargs: This constructor is implemented as a template method
892                      delegating its optionals keyworded arguments to the
893                      method my_init().
894        @type kargs: dict
895        """
896        self.pevent = pevent
897        self.my_init(**kargs)
898
899    def my_init(self, **kargs):
900        """
901        This method is called from ProcessEvent.__init__(). This method is
902        empty here and must be redefined to be useful. In effect, if you
903        need to specifically initialize your subclass' instance then you
904        just have to override this method in your subclass. Then all the
905        keyworded arguments passed to ProcessEvent.__init__() will be
906        transmitted as parameters to this method. Beware you MUST pass
907        keyword arguments though.
908
909        @param kargs: optional delegated arguments from __init__().
910        @type kargs: dict
911        """
912        pass
913
914    def __call__(self, event):
915        stop_chaining = False
916        if self.pevent is not None:
917            # By default methods return None so we set as guideline
918            # that methods asking for stop chaining must explicitely
919            # return non None or non False values, otherwise the default
920            # behavior will be to accept chain call to the corresponding
921            # local method.
922            stop_chaining = self.pevent(event)
923        if not stop_chaining:
924            return _ProcessEvent.__call__(self, event)
925
926    def nested_pevent(self):
927        return self.pevent
928
929    def process_IN_Q_OVERFLOW(self, event):
930        """
931        By default this method only reports warning messages, you can overredide
932        it by subclassing ProcessEvent and implement your own
933        process_IN_Q_OVERFLOW method. The actions you can take on receiving this
934        event is either to update the variable max_queued_events in order to
935        handle more simultaneous events or to modify your code in order to
936        accomplish a better filtering diminishing the number of raised events.
937        Because this method is defined, IN_Q_OVERFLOW will never get
938        transmitted as arguments to process_default calls.
939
940        @param event: IN_Q_OVERFLOW event.
941        @type event: dict
942        """
943        log.warning('Event queue overflowed.')
944
945    def process_default(self, event):
946        """
947        Default processing event method. By default does nothing. Subclass
948        ProcessEvent and redefine this method in order to modify its behavior.
949
950        @param event: Event to be processed. Can be of any type of events but
951                      IN_Q_OVERFLOW events (see method process_IN_Q_OVERFLOW).
952        @type event: Event instance
953        """
954        pass
955
956
957class PrintAllEvents(ProcessEvent):
958    """
959    Dummy class used to print events strings representations. For instance this
960    class is used from command line to print all received events to stdout.
961    """
962    def my_init(self, out=None):
963        """
964        @param out: Where events will be written.
965        @type out: Object providing a valid file object interface.
966        """
967        if out is None:
968            out = sys.stdout
969        self._out = out
970
971    def process_default(self, event):
972        """
973        Writes event string representation to file object provided to
974        my_init().
975
976        @param event: Event to be processed. Can be of any type of events but
977                      IN_Q_OVERFLOW events (see method process_IN_Q_OVERFLOW).
978        @type event: Event instance
979        """
980        self._out.write(str(event))
981        self._out.write('\n')
982        self._out.flush()
983
984
985class ChainIfTrue(ProcessEvent):
986    """
987    Makes conditional chaining depending on the result of the nested
988    processing instance.
989    """
990    def my_init(self, func):
991        """
992        Method automatically called from base class constructor.
993        """
994        self._func = func
995
996    def process_default(self, event):
997        return not self._func(event)
998
999
1000class Stats(ProcessEvent):
1001    """
1002    Compute and display trivial statistics about processed events.
1003    """
1004    def my_init(self):
1005        """
1006        Method automatically called from base class constructor.
1007        """
1008        self._start_time = time.time()
1009        self._stats = {}
1010        self._stats_lock = threading.Lock()
1011
1012    def process_default(self, event):
1013        """
1014        Processes |event|.
1015        """
1016        self._stats_lock.acquire()
1017        try:
1018            events = event.maskname.split('|')
1019            for event_name in events:
1020                count = self._stats.get(event_name, 0)
1021                self._stats[event_name] = count + 1
1022        finally:
1023            self._stats_lock.release()
1024
1025    def _stats_copy(self):
1026        self._stats_lock.acquire()
1027        try:
1028            return self._stats.copy()
1029        finally:
1030            self._stats_lock.release()
1031
1032    def __repr__(self):
1033        stats = self._stats_copy()
1034
1035        elapsed = int(time.time() - self._start_time)
1036        elapsed_str = ''
1037        if elapsed < 60:
1038            elapsed_str = str(elapsed) + 'sec'
1039        elif 60 <= elapsed < 3600:
1040            elapsed_str = '%dmn%dsec' % (elapsed / 60, elapsed % 60)
1041        elif 3600 <= elapsed < 86400:
1042            elapsed_str = '%dh%dmn' % (elapsed / 3600, (elapsed % 3600) / 60)
1043        elif elapsed >= 86400:
1044            elapsed_str = '%dd%dh' % (elapsed / 86400, (elapsed % 86400) / 3600)
1045        stats['ElapsedTime'] = elapsed_str
1046
1047        l = []
1048        for ev, value in sorted(stats.items(), key=lambda x: x[0]):
1049            l.append(' %s=%s' % (output_format.field_name(ev),
1050                                 output_format.field_value(value)))
1051        s = '<%s%s >' % (output_format.class_name(self.__class__.__name__),
1052                         ''.join(l))
1053        return s
1054
1055    def dump(self, filename):
1056        """
1057        Dumps statistics.
1058
1059        @param filename: filename where stats will be dumped, filename is
1060                         created and must not exist prior to this call.
1061        @type filename: string
1062        """
1063        flags = os.O_WRONLY|os.O_CREAT|os.O_NOFOLLOW|os.O_EXCL
1064        fd = os.open(filename, flags, 0600)
1065        os.write(fd, str(self))
1066        os.close(fd)
1067
1068    def __str__(self, scale=45):
1069        stats = self._stats_copy()
1070        if not stats:
1071            return ''
1072
1073        m = max(stats.values())
1074        unity = float(scale) / m
1075        fmt = '%%-26s%%-%ds%%s' % (len(output_format.field_value('@' * scale))
1076                                   + 1)
1077        def func(x):
1078            return fmt % (output_format.field_name(x[0]),
1079                          output_format.field_value('@' * int(x[1] * unity)),
1080                          output_format.simple('%d' % x[1], 'yellow'))
1081        s = '\n'.join(map(func, sorted(stats.items(), key=lambda x: x[0])))
1082        return s
1083
1084
1085class NotifierError(PyinotifyError):
1086    """
1087    Notifier Exception. Raised on Notifier error.
1088
1089    """
1090    def __init__(self, err):
1091        """
1092        @param err: Exception string's description.
1093        @type err: string
1094        """
1095        PyinotifyError.__init__(self, err)
1096
1097
1098class Notifier:
1099    """
1100    Read notifications, process events.
1101
1102    """
1103    def __init__(self, watch_manager, default_proc_fun=None, read_freq=0,
1104                 threshold=0, timeout=None):
1105        """
1106        Initialization. read_freq, threshold and timeout parameters are used
1107        when looping.
1108
1109        @param watch_manager: Watch Manager.
1110        @type watch_manager: WatchManager instance
1111        @param default_proc_fun: Default processing method. If None, a new
1112                                 instance of PrintAllEvents will be assigned.
1113        @type default_proc_fun: instance of ProcessEvent
1114        @param read_freq: if read_freq == 0, events are read asap,
1115                          if read_freq is > 0, this thread sleeps
1116                          max(0, read_freq - (timeout / 1000)) seconds. But
1117                          if timeout is None it may be different because
1118                          poll is blocking waiting for something to read.
1119        @type read_freq: int
1120        @param threshold: File descriptor will be read only if the accumulated
1121                          size to read becomes >= threshold. If != 0, you likely
1122                          want to use it in combination with an appropriate
1123                          value for read_freq because without that you would
1124                          keep looping without really reading anything and that
1125                          until the amount of events to read is >= threshold.
1126                          At least with read_freq set you might sleep.
1127        @type threshold: int
1128        @param timeout: see read_freq above. If provided, it must be set in
1129                        milliseconds. See
1130                        https://docs.python.org/2/library/select.html#polling-objects
1131        @type timeout: int
1132        """
1133        # Watch Manager instance
1134        self._watch_manager = watch_manager
1135        # File descriptor
1136        self._fd = self._watch_manager.get_fd()
1137        # Poll object and registration
1138        self._pollobj = select.poll()
1139        self._pollobj.register(self._fd, select.POLLIN)
1140        # This pipe is correctely initialized and used by ThreadedNotifier
1141        self._pipe = (-1, -1)
1142        # Event queue
1143        self._eventq = deque()
1144        # System processing functor, common to all events
1145        self._sys_proc_fun = _SysProcessEvent(self._watch_manager, self)
1146        # Default processing method
1147        self._default_proc_fun = default_proc_fun
1148        if default_proc_fun is None:
1149            self._default_proc_fun = PrintAllEvents()
1150        # Loop parameters
1151        self._read_freq = read_freq
1152        self._threshold = threshold
1153        self._timeout = timeout
1154        # Coalesce events option
1155        self._coalesce = False
1156        # set of str(raw_event), only used when coalesce option is True
1157        self._eventset = set()
1158
1159    def append_event(self, event):
1160        """
1161        Append a raw event to the event queue.
1162
1163        @param event: An event.
1164        @type event: _RawEvent instance.
1165        """
1166        self._eventq.append(event)
1167
1168    def proc_fun(self):
1169        return self._default_proc_fun
1170
1171    def coalesce_events(self, coalesce=True):
1172        """
1173        Coalescing events. Events are usually processed by batchs, their size
1174        depend on various factors. Thus, before processing them, events received
1175        from inotify are aggregated in a fifo queue. If this coalescing
1176        option is enabled events are filtered based on their unicity, only
1177        unique events are enqueued, doublons are discarded. An event is unique
1178        when the combination of its fields (wd, mask, cookie, name) is unique
1179        among events of a same batch. After a batch of events is processed any
1180        events is accepted again. By default this option is disabled, you have
1181        to explictly call this function to turn it on.
1182
1183        @param coalesce: Optional new coalescing value. True by default.
1184        @type coalesce: Bool
1185        """
1186        self._coalesce = coalesce
1187        if not coalesce:
1188            self._eventset.clear()
1189
1190    def check_events(self, timeout=None):
1191        """
1192        Check for new events available to read, blocks up to timeout
1193        milliseconds.
1194
1195        @param timeout: If specified it overrides the corresponding instance
1196                        attribute _timeout. timeout must be sepcified in
1197                        milliseconds.
1198        @type timeout: int
1199
1200        @return: New events to read.
1201        @rtype: bool
1202        """
1203        while True:
1204            try:
1205                # blocks up to 'timeout' milliseconds
1206                if timeout is None:
1207                    timeout = self._timeout
1208                ret = self._pollobj.poll(timeout)
1209            except select.error, err:
1210                if err[0] == errno.EINTR:
1211                    continue # interrupted, retry
1212                else:
1213                    raise
1214            else:
1215                break
1216
1217        if not ret or (self._pipe[0] == ret[0][0]):
1218            return False
1219        # only one fd is polled
1220        return ret[0][1] & select.POLLIN
1221
1222    def read_events(self):
1223        """
1224        Read events from device, build _RawEvents, and enqueue them.
1225        """
1226        buf_ = array.array('i', [0])
1227        # get event queue size
1228        if fcntl.ioctl(self._fd, termios.FIONREAD, buf_, 1) == -1:
1229            return
1230        queue_size = buf_[0]
1231        if queue_size < self._threshold:
1232            log.debug('(fd: %d) %d bytes available to read but threshold is '
1233                      'fixed to %d bytes', self._fd, queue_size,
1234                      self._threshold)
1235            return
1236
1237        try:
1238            # Read content from file
1239            r = os.read(self._fd, queue_size)
1240        except Exception, msg:
1241            raise NotifierError(msg)
1242        log.debug('Event queue size: %d', queue_size)
1243        rsum = 0  # counter
1244        while rsum < queue_size:
1245            s_size = 16
1246            # Retrieve wd, mask, cookie and fname_len
1247            wd, mask, cookie, fname_len = struct.unpack('iIII',
1248                                                        r[rsum:rsum+s_size])
1249            # Retrieve name
1250            fname, = struct.unpack('%ds' % fname_len,
1251                                   r[rsum + s_size:rsum + s_size + fname_len])
1252            rawevent = _RawEvent(wd, mask, cookie, fname)
1253            if self._coalesce:
1254                # Only enqueue new (unique) events.
1255                raweventstr = str(rawevent)
1256                if raweventstr not in self._eventset:
1257                    self._eventset.add(raweventstr)
1258                    self._eventq.append(rawevent)
1259            else:
1260                self._eventq.append(rawevent)
1261            rsum += s_size + fname_len
1262
1263    def process_events(self):
1264        """
1265        Routine for processing events from queue by calling their
1266        associated proccessing method (an instance of ProcessEvent).
1267        It also does internal processings, to keep the system updated.
1268        """
1269        while self._eventq:
1270            raw_event = self._eventq.popleft()  # pop next event
1271            if self._watch_manager.ignore_events:
1272                log.debug("Event ignored: %s" % repr(raw_event))
1273                continue
1274            watch_ = self._watch_manager.get_watch(raw_event.wd)
1275            if (watch_ is None) and not (raw_event.mask & IN_Q_OVERFLOW):
1276                if not (raw_event.mask & IN_IGNORED):
1277                    # Not really sure how we ended up here, nor how we should
1278                    # handle these types of events and if it is appropriate to
1279                    # completly skip them (like we are doing here).
1280                    log.warning("Unable to retrieve Watch object associated to %s",
1281                                repr(raw_event))
1282                continue
1283            revent = self._sys_proc_fun(raw_event)  # system processings
1284            if watch_ and watch_.proc_fun:
1285                watch_.proc_fun(revent)  # user processings
1286            else:
1287                self._default_proc_fun(revent)
1288        self._sys_proc_fun.cleanup()  # remove olds MOVED_* events records
1289        if self._coalesce:
1290            self._eventset.clear()
1291
1292    def __daemonize(self, pid_file=None, stdin=os.devnull, stdout=os.devnull,
1293                    stderr=os.devnull):
1294        """
1295        @param pid_file: file where the pid will be written. If pid_file=None
1296                         the pid is written to
1297                         /var/run/<sys.argv[0]|pyinotify>.pid, if pid_file=False
1298                         no pid_file is written.
1299        @param stdin:
1300        @param stdout:
1301        @param stderr: files associated to common streams.
1302        """
1303        if pid_file is None:
1304            dirname = '/var/run/'
1305            basename = os.path.basename(sys.argv[0]) or 'pyinotify'
1306            pid_file = os.path.join(dirname, basename + '.pid')
1307
1308        if pid_file != False and os.path.lexists(pid_file):
1309            err = 'Cannot daemonize: pid file %s already exists.' % pid_file
1310            raise NotifierError(err)
1311
1312        def fork_daemon():
1313            # Adapted from Chad J. Schroeder's recipe
1314            # @see http://code.activestate.com/recipes/278731/
1315            pid = os.fork()
1316            if (pid == 0):
1317                # parent 2
1318                os.setsid()
1319                pid = os.fork()
1320                if (pid == 0):
1321                    # child
1322                    os.chdir('/')
1323                    os.umask(022)
1324                else:
1325                    # parent 2
1326                    os._exit(0)
1327            else:
1328                # parent 1
1329                os._exit(0)
1330
1331            fd_inp = os.open(stdin, os.O_RDONLY)
1332            os.dup2(fd_inp, 0)
1333            fd_out = os.open(stdout, os.O_WRONLY|os.O_CREAT, 0600)
1334            os.dup2(fd_out, 1)
1335            fd_err = os.open(stderr, os.O_WRONLY|os.O_CREAT, 0600)
1336            os.dup2(fd_err, 2)
1337
1338        # Detach task
1339        fork_daemon()
1340
1341        # Write pid
1342        if pid_file != False:
1343            flags = os.O_WRONLY|os.O_CREAT|os.O_NOFOLLOW|os.O_EXCL
1344            fd_pid = os.open(pid_file, flags, 0600)
1345            os.write(fd_pid, str(os.getpid()) + '\n')
1346            os.close(fd_pid)
1347            # Register unlink function
1348            atexit.register(lambda : os.unlink(pid_file))
1349
1350    def _sleep(self, ref_time):
1351        # Only consider sleeping if read_freq is > 0
1352        if self._read_freq > 0:
1353            cur_time = time.time()
1354            sleep_amount = self._read_freq - (cur_time - ref_time)
1355            if sleep_amount > 0:
1356                log.debug('Now sleeping %d seconds', sleep_amount)
1357                time.sleep(sleep_amount)
1358
1359    def loop(self, callback=None, daemonize=False, **args):
1360        """
1361        Events are read only one time every min(read_freq, timeout)
1362        seconds at best and only if the size to read is >= threshold.
1363        After this method returns it must not be called again for the same
1364        instance.
1365
1366        @param callback: Functor called after each event processing iteration.
1367                         Expects to receive the notifier object (self) as first
1368                         parameter. If this function returns True the loop is
1369                         immediately terminated otherwise the loop method keeps
1370                         looping.
1371        @type callback: callable object or function
1372        @param daemonize: This thread is daemonized if set to True.
1373        @type daemonize: boolean
1374        @param args: Optional and relevant only if daemonize is True. Remaining
1375                     keyworded arguments are directly passed to daemonize see
1376                     __daemonize() method. If pid_file=None or is set to a
1377                     pathname the caller must ensure the file does not exist
1378                     before this method is called otherwise an exception
1379                     pyinotify.NotifierError will be raised. If pid_file=False
1380                     it is still daemonized but the pid is not written in any
1381                     file.
1382        @type args: various
1383        """
1384        if daemonize:
1385            self.__daemonize(**args)
1386
1387        # Read and process events forever
1388        while 1:
1389            try:
1390                self.process_events()
1391                if (callback is not None) and (callback(self) is True):
1392                    break
1393                ref_time = time.time()
1394                # check_events is blocking
1395                if self.check_events():
1396                    self._sleep(ref_time)
1397                    self.read_events()
1398            except KeyboardInterrupt:
1399                # Stop monitoring if sigint is caught (Control-C).
1400                log.debug('Pyinotify stops monitoring.')
1401                break
1402        # Close internals
1403        self.stop()
1404
1405    def stop(self):
1406        """
1407        Close inotify's instance (close its file descriptor).
1408        It destroys all existing watches, pending events,...
1409        This method is automatically called at the end of loop().
1410        Afterward it is invalid to access this instance.
1411        """
1412        if self._fd is not None:
1413            self._pollobj.unregister(self._fd)
1414            os.close(self._fd)
1415            self._fd = None
1416        self._sys_proc_fun = None
1417
1418
1419class ThreadedNotifier(threading.Thread, Notifier):
1420    """
1421    This notifier inherits from threading.Thread for instanciating a separate
1422    thread, and also inherits from Notifier, because it is a threaded notifier.
1423
1424    Note that every functionality provided by this class is also provided
1425    through Notifier class. Moreover Notifier should be considered first because
1426    it is not threaded and could be easily daemonized.
1427    """
1428    def __init__(self, watch_manager, default_proc_fun=None, read_freq=0,
1429                 threshold=0, timeout=None):
1430        """
1431        Initialization, initialize base classes. read_freq, threshold and
1432        timeout parameters are used when looping.
1433
1434        @param watch_manager: Watch Manager.
1435        @type watch_manager: WatchManager instance
1436        @param default_proc_fun: Default processing method. See base class.
1437        @type default_proc_fun: instance of ProcessEvent
1438        @param read_freq: if read_freq == 0, events are read asap,
1439                          if read_freq is > 0, this thread sleeps
1440                          max(0, read_freq - (timeout / 1000)) seconds.
1441        @type read_freq: int
1442        @param threshold: File descriptor will be read only if the accumulated
1443                          size to read becomes >= threshold. If != 0, you likely
1444                          want to use it in combination with an appropriate
1445                          value set for read_freq because without that you would
1446                          keep looping without really reading anything and that
1447                          until the amount of events to read is >= threshold. At
1448                          least with read_freq you might sleep.
1449        @type threshold: int
1450        @param timeout: see read_freq above. If provided, it must be set in
1451                        milliseconds. See
1452                        https://docs.python.org/2/library/select.html#select.poll.poll
1453        @type timeout: int
1454        """
1455        # Init threading base class
1456        threading.Thread.__init__(self)
1457        # Stop condition
1458        self._stop_event = threading.Event()
1459        # Init Notifier base class
1460        Notifier.__init__(self, watch_manager, default_proc_fun, read_freq,
1461                          threshold, timeout)
1462        # Create a new pipe used for thread termination
1463        self._pipe = os.pipe()
1464        self._pollobj.register(self._pipe[0], select.POLLIN)
1465
1466    def stop(self):
1467        """
1468        Stop notifier's loop. Stop notification. Join the thread.
1469        """
1470        self._stop_event.set()
1471        os.write(self._pipe[1], 'stop')
1472        threading.Thread.join(self)
1473        Notifier.stop(self)
1474        self._pollobj.unregister(self._pipe[0])
1475        os.close(self._pipe[0])
1476        os.close(self._pipe[1])
1477
1478    def loop(self):
1479        """
1480        Thread's main loop. Don't meant to be called by user directly.
1481        Call inherited start() method instead.
1482
1483        Events are read only once time every min(read_freq, timeout)
1484        seconds at best and only if the size of events to read is >= threshold.
1485        """
1486        # When the loop must be terminated .stop() is called, 'stop'
1487        # is written to pipe fd so poll() returns and .check_events()
1488        # returns False which make evaluate the While's stop condition
1489        # ._stop_event.isSet() wich put an end to the thread's execution.
1490        while not self._stop_event.isSet():
1491            self.process_events()
1492            ref_time = time.time()
1493            if self.check_events():
1494                self._sleep(ref_time)
1495                self.read_events()
1496
1497    def run(self):
1498        """
1499        Start thread's loop: read and process events until the method
1500        stop() is called.
1501        Never call this method directly, instead call the start() method
1502        inherited from threading.Thread, which then will call run() in
1503        its turn.
1504        """
1505        self.loop()
1506
1507
1508class AsyncNotifier(asyncore.file_dispatcher, Notifier):
1509    """
1510    This notifier inherits from asyncore.file_dispatcher in order to be able to
1511    use pyinotify along with the asyncore framework.
1512
1513    """
1514    def __init__(self, watch_manager, default_proc_fun=None, read_freq=0,
1515                 threshold=0, timeout=None, channel_map=None):
1516        """
1517        Initializes the async notifier. The only additional parameter is
1518        'channel_map' which is the optional asyncore private map. See
1519        Notifier class for the meaning of the others parameters.
1520
1521        """
1522        Notifier.__init__(self, watch_manager, default_proc_fun, read_freq,
1523                          threshold, timeout)
1524        asyncore.file_dispatcher.__init__(self, self._fd, channel_map)
1525
1526    def handle_read(self):
1527        """
1528        When asyncore tells us we can read from the fd, we proceed processing
1529        events. This method can be overridden for handling a notification
1530        differently.
1531
1532        """
1533        self.read_events()
1534        self.process_events()
1535
1536
1537class TornadoAsyncNotifier(Notifier):
1538    """
1539    Tornado ioloop adapter.
1540
1541    """
1542    def __init__(self, watch_manager, ioloop, callback=None,
1543                 default_proc_fun=None, read_freq=0, threshold=0, timeout=None,
1544                 channel_map=None):
1545        """
1546        Note that if later you must call ioloop.close() be sure to let the
1547        default parameter to all_fds=False.
1548
1549        See example tornado_notifier.py for an example using this notifier.
1550
1551        @param ioloop: Tornado's IO loop.
1552        @type ioloop: tornado.ioloop.IOLoop instance.
1553        @param callback: Functor called at the end of each call to handle_read
1554                         (IOLoop's read handler). Expects to receive the
1555                         notifier object (self) as single parameter.
1556        @type callback: callable object or function
1557        """
1558        self.io_loop = ioloop
1559        self.handle_read_callback = callback
1560        Notifier.__init__(self, watch_manager, default_proc_fun, read_freq,
1561                          threshold, timeout)
1562        ioloop.add_handler(self._fd, self.handle_read, ioloop.READ)
1563
1564    def stop(self):
1565        self.io_loop.remove_handler(self._fd)
1566        Notifier.stop(self)
1567
1568    def handle_read(self, *args, **kwargs):
1569        """
1570        See comment in AsyncNotifier.
1571
1572        """
1573        self.read_events()
1574        self.process_events()
1575        if self.handle_read_callback is not None:
1576            self.handle_read_callback(self)
1577
1578
1579class AsyncioNotifier(Notifier):
1580    """
1581
1582    asyncio/trollius event loop adapter.
1583
1584    """
1585    def __init__(self, watch_manager, loop, callback=None,
1586                 default_proc_fun=None, read_freq=0, threshold=0, timeout=None):
1587        """
1588
1589        See examples/asyncio_notifier.py for an example usage.
1590
1591        @param loop: asyncio or trollius event loop instance.
1592        @type loop: asyncio.BaseEventLoop or trollius.BaseEventLoop instance.
1593        @param callback: Functor called at the end of each call to handle_read.
1594                         Expects to receive the notifier object (self) as
1595                         single parameter.
1596        @type callback: callable object or function
1597
1598        """
1599        self.loop = loop
1600        self.handle_read_callback = callback
1601        Notifier.__init__(self, watch_manager, default_proc_fun, read_freq,
1602                          threshold, timeout)
1603        loop.add_reader(self._fd, self.handle_read)
1604
1605    def stop(self):
1606        self.loop.remove_reader(self._fd)
1607        Notifier.stop(self)
1608
1609    def handle_read(self, *args, **kwargs):
1610        self.read_events()
1611        self.process_events()
1612        if self.handle_read_callback is not None:
1613            self.handle_read_callback(self)
1614
1615
1616class Watch:
1617    """
1618    Represent a watch, i.e. a file or directory being watched.
1619
1620    """
1621    __slots__ = ('wd', 'path', 'mask', 'proc_fun', 'auto_add',
1622                 'exclude_filter', 'dir')
1623
1624    def __init__(self, wd, path, mask, proc_fun, auto_add, exclude_filter):
1625        """
1626        Initializations.
1627
1628        @param wd: Watch descriptor.
1629        @type wd: int
1630        @param path: Path of the file or directory being watched.
1631        @type path: str
1632        @param mask: Mask.
1633        @type mask: int
1634        @param proc_fun: Processing callable object.
1635        @type proc_fun:
1636        @param auto_add: Automatically add watches on new directories.
1637        @type auto_add: bool
1638        @param exclude_filter: Boolean function, used to exclude new
1639                               directories from being automatically watched.
1640                               See WatchManager.__init__
1641        @type exclude_filter: callable object
1642        """
1643        self.wd = wd
1644        self.path = path
1645        self.mask = mask
1646        self.proc_fun = proc_fun
1647        self.auto_add = auto_add
1648        self.exclude_filter = exclude_filter
1649        self.dir = os.path.isdir(self.path)
1650
1651    def __repr__(self):
1652        """
1653        @return: String representation.
1654        @rtype: str
1655        """
1656        s = ' '.join(['%s%s%s' % (output_format.field_name(attr),
1657                                  output_format.punctuation('='),
1658                                  output_format.field_value(getattr(self,
1659                                                                    attr))) \
1660                      for attr in self.__slots__ if not attr.startswith('_')])
1661
1662        s = '%s%s %s %s' % (output_format.punctuation('<'),
1663                            output_format.class_name(self.__class__.__name__),
1664                            s,
1665                            output_format.punctuation('>'))
1666        return s
1667
1668
1669class ExcludeFilter:
1670    """
1671    ExcludeFilter is an exclusion filter.
1672
1673    """
1674    def __init__(self, arg_lst):
1675        """
1676        Examples:
1677          ef1 = ExcludeFilter(["/etc/rc.*", "/etc/hostname"])
1678          ef2 = ExcludeFilter("/my/path/exclude.lst")
1679          Where exclude.lst contains:
1680          /etc/rc.*
1681          /etc/hostname
1682
1683        Note: it is not possible to exclude a file if its encapsulating
1684              directory is itself watched. See this issue for more details
1685              https://github.com/seb-m/pyinotify/issues/31
1686
1687        @param arg_lst: is either a list of patterns or a filename from which
1688                        patterns will be loaded.
1689        @type arg_lst: list of str or str
1690        """
1691        if isinstance(arg_lst, str):
1692            lst = self._load_patterns_from_file(arg_lst)
1693        elif isinstance(arg_lst, list):
1694            lst = arg_lst
1695        else:
1696            raise TypeError
1697
1698        self._lregex = []
1699        for regex in lst:
1700            self._lregex.append(re.compile(regex, re.UNICODE))
1701
1702    def _load_patterns_from_file(self, filename):
1703        lst = []
1704        file_obj = file(filename, 'r')
1705        try:
1706            for line in file_obj.readlines():
1707                # Trim leading an trailing whitespaces
1708                pattern = line.strip()
1709                if not pattern or pattern.startswith('#'):
1710                    continue
1711                lst.append(pattern)
1712        finally:
1713            file_obj.close()
1714        return lst
1715
1716    def _match(self, regex, path):
1717        return regex.match(path) is not None
1718
1719    def __call__(self, path):
1720        """
1721        @param path: Path to match against provided regexps.
1722        @type path: str
1723        @return: Return True if path has been matched and should
1724                 be excluded, False otherwise.
1725        @rtype: bool
1726        """
1727        for regex in self._lregex:
1728            if self._match(regex, path):
1729                return True
1730        return False
1731
1732
1733class WatchManagerError(Exception):
1734    """
1735    WatchManager Exception. Raised on error encountered on watches
1736    operations.
1737
1738    """
1739    def __init__(self, msg, wmd):
1740        """
1741        @param msg: Exception string's description.
1742        @type msg: string
1743        @param wmd: This dictionary contains the wd assigned to paths of the
1744                    same call for which watches were successfully added.
1745        @type wmd: dict
1746        """
1747        self.wmd = wmd
1748        Exception.__init__(self, msg)
1749
1750
1751class WatchManager:
1752    """
1753    Provide operations for watching files and directories. Its internal
1754    dictionary is used to reference watched items. When used inside
1755    threaded code, one must instanciate as many WatchManager instances as
1756    there are ThreadedNotifier instances.
1757
1758    """
1759    def __init__(self, exclude_filter=lambda path: False):
1760        """
1761        Initialization: init inotify, init watch manager dictionary.
1762        Raise OSError if initialization fails, raise InotifyBindingNotFoundError
1763        if no inotify binding was found (through ctypes or from direct access to
1764        syscalls).
1765
1766        @param exclude_filter: boolean function, returns True if current
1767                               path must be excluded from being watched.
1768                               Convenient for providing a common exclusion
1769                               filter for every call to add_watch.
1770        @type exclude_filter: callable object
1771        """
1772        self._ignore_events = False
1773        self._exclude_filter = exclude_filter
1774        self._wmd = {}  # watch dict key: watch descriptor, value: watch
1775
1776        self._inotify_wrapper = INotifyWrapper.create()
1777        if self._inotify_wrapper is None:
1778            raise InotifyBindingNotFoundError()
1779
1780        self._fd = self._inotify_wrapper.inotify_init() # file descriptor
1781        if self._fd < 0:
1782            err = 'Cannot initialize new instance of inotify, %s'
1783            raise OSError(err % self._inotify_wrapper.str_errno())
1784
1785    def close(self):
1786        """
1787        Close inotify's file descriptor, this action will also automatically
1788        remove (i.e. stop watching) all its associated watch descriptors.
1789        After a call to this method the WatchManager's instance become useless
1790        and cannot be reused, a new instance must then be instanciated. It
1791        makes sense to call this method in few situations for instance if
1792        several independant WatchManager must be instanciated or if all watches
1793        must be removed and no other watches need to be added.
1794        """
1795        os.close(self._fd)
1796
1797    def get_fd(self):
1798        """
1799        Return assigned inotify's file descriptor.
1800
1801        @return: File descriptor.
1802        @rtype: int
1803        """
1804        return self._fd
1805
1806    def get_watch(self, wd):
1807        """
1808        Get watch from provided watch descriptor wd.
1809
1810        @param wd: Watch descriptor.
1811        @type wd: int
1812        """
1813        return self._wmd.get(wd)
1814
1815    def del_watch(self, wd):
1816        """
1817        Remove watch entry associated to watch descriptor wd.
1818
1819        @param wd: Watch descriptor.
1820        @type wd: int
1821        """
1822        try:
1823            del self._wmd[wd]
1824        except KeyError, err:
1825            log.error('Cannot delete unknown watch descriptor %s' % str(err))
1826
1827    @property
1828    def watches(self):
1829        """
1830        Get a reference on the internal watch manager dictionary.
1831
1832        @return: Internal watch manager dictionary.
1833        @rtype: dict
1834        """
1835        return self._wmd
1836
1837    def __format_path(self, path):
1838        """
1839        Format path to its internal (stored in watch manager) representation.
1840        """
1841        # Unicode strings are converted back to strings, because it seems
1842        # that inotify_add_watch from ctypes does not work well when
1843        # it receives an ctypes.create_unicode_buffer instance as argument.
1844        # Therefore even wd are indexed with bytes string and not with
1845        # unicode paths.
1846        if isinstance(path, unicode):
1847            path = path.encode(sys.getfilesystemencoding())
1848        return os.path.normpath(path)
1849
1850    def __add_watch(self, path, mask, proc_fun, auto_add, exclude_filter):
1851        """
1852        Add a watch on path, build a Watch object and insert it in the
1853        watch manager dictionary. Return the wd value.
1854        """
1855        path = self.__format_path(path)
1856        if auto_add and not mask & IN_CREATE:
1857            mask |= IN_CREATE
1858        wd = self._inotify_wrapper.inotify_add_watch(self._fd, path, mask)
1859        if wd < 0:
1860            return wd
1861        watch = Watch(wd=wd, path=path, mask=mask, proc_fun=proc_fun,
1862                      auto_add=auto_add, exclude_filter=exclude_filter)
1863        self._wmd[wd] = watch
1864        log.debug('New %s', watch)
1865        return wd
1866
1867    def __glob(self, path, do_glob):
1868        if do_glob:
1869            return glob(path)
1870        else:
1871            return [path]
1872
1873    def add_watch(self, path, mask, proc_fun=None, rec=False,
1874                  auto_add=False, do_glob=False, quiet=True,
1875                  exclude_filter=None):
1876        """
1877        Add watch(s) on the provided |path|(s) with associated |mask| flag
1878        value and optionally with a processing |proc_fun| function and
1879        recursive flag |rec| set to True.
1880        Ideally |path| components should not be unicode objects. Note that
1881        although unicode paths are accepted there are converted to byte
1882        strings before a watch is put on that path. The encoding used for
1883        converting the unicode object is given by sys.getfilesystemencoding().
1884        If |path| is already watched it is ignored, but if it is called with
1885        option rec=True a watch is put on each one of its not-watched
1886        subdirectory.
1887
1888        @param path: Path to watch, the path can either be a file or a
1889                     directory. Also accepts a sequence (list) of paths.
1890        @type path: string or list of strings
1891        @param mask: Bitmask of events.
1892        @type mask: int
1893        @param proc_fun: Processing object.
1894        @type proc_fun: function or ProcessEvent instance or instance of
1895                        one of its subclasses or callable object.
1896        @param rec: Recursively add watches from path on all its
1897                    subdirectories, set to False by default (doesn't
1898                    follows symlinks in any case).
1899        @type rec: bool
1900        @param auto_add: Automatically add watches on newly created
1901                         directories in watched parent |path| directory.
1902                         If |auto_add| is True, IN_CREATE is ored with |mask|
1903                         when the watch is added.
1904        @type auto_add: bool
1905        @param do_glob: Do globbing on pathname (see standard globbing
1906                        module for more informations).
1907        @type do_glob: bool
1908        @param quiet: if False raises a WatchManagerError exception on
1909                      error. See example not_quiet.py.
1910        @type quiet: bool
1911        @param exclude_filter: predicate (boolean function), which returns
1912                               True if the current path must be excluded
1913                               from being watched. This argument has
1914                               precedence over exclude_filter passed to
1915                               the class' constructor.
1916        @type exclude_filter: callable object
1917        @return: dict of paths associated to watch descriptors. A wd value
1918                 is positive if the watch was added sucessfully,
1919                 otherwise the value is negative. If the path was invalid
1920                 or was already watched it is not included into this returned
1921                 dictionary.
1922        @rtype: dict of {str: int}
1923        """
1924        ret_ = {} # return {path: wd, ...}
1925
1926        if exclude_filter is None:
1927            exclude_filter = self._exclude_filter
1928
1929        # normalize args as list elements
1930        for npath in self.__format_param(path):
1931            # unix pathname pattern expansion
1932            for apath in self.__glob(npath, do_glob):
1933                # recursively list subdirs according to rec param
1934                for rpath in self.__walk_rec(apath, rec):
1935                    if not exclude_filter(rpath):
1936                        wd = ret_[rpath] = self.__add_watch(rpath, mask,
1937                                                            proc_fun,
1938                                                            auto_add,
1939                                                            exclude_filter)
1940                        if wd < 0:
1941                            err = ('add_watch: cannot watch %s WD=%d, %s' % \
1942                                       (rpath, wd,
1943                                        self._inotify_wrapper.str_errno()))
1944                            if quiet:
1945                                log.error(err)
1946                            else:
1947                                raise WatchManagerError(err, ret_)
1948                    else:
1949                        # Let's say -2 means 'explicitely excluded
1950                        # from watching'.
1951                        ret_[rpath] = -2
1952        return ret_
1953
1954    def __get_sub_rec(self, lpath):
1955        """
1956        Get every wd from self._wmd if its path is under the path of
1957        one (at least) of those in lpath. Doesn't follow symlinks.
1958
1959        @param lpath: list of watch descriptor
1960        @type lpath: list of int
1961        @return: list of watch descriptor
1962        @rtype: list of int
1963        """
1964        for d in lpath:
1965            root = self.get_path(d)
1966            if root is not None:
1967                # always keep root
1968                yield d
1969            else:
1970                # if invalid
1971                continue
1972
1973            # nothing else to expect
1974            if not os.path.isdir(root):
1975                continue
1976
1977            # normalization
1978            root = os.path.normpath(root)
1979            # recursion
1980            lend = len(root)
1981            for iwd in self._wmd.items():
1982                cur = iwd[1].path
1983                pref = os.path.commonprefix([root, cur])
1984                if root == os.sep or (len(pref) == lend and \
1985                                      len(cur) > lend and \
1986                                      cur[lend] == os.sep):
1987                    yield iwd[1].wd
1988
1989    def update_watch(self, wd, mask=None, proc_fun=None, rec=False,
1990                     auto_add=False, quiet=True):
1991        """
1992        Update existing watch descriptors |wd|. The |mask| value, the
1993        processing object |proc_fun|, the recursive param |rec| and the
1994        |auto_add| and |quiet| flags can all be updated.
1995
1996        @param wd: Watch Descriptor to update. Also accepts a list of
1997                   watch descriptors.
1998        @type wd: int or list of int
1999        @param mask: Optional new bitmask of events.
2000        @type mask: int
2001        @param proc_fun: Optional new processing function.
2002        @type proc_fun: function or ProcessEvent instance or instance of
2003                        one of its subclasses or callable object.
2004        @param rec: Optionally adds watches recursively on all
2005                    subdirectories contained into |wd| directory.
2006        @type rec: bool
2007        @param auto_add: Automatically adds watches on newly created
2008                         directories in the watch's path corresponding to |wd|.
2009                         If |auto_add| is True, IN_CREATE is ored with |mask|
2010                         when the watch is updated.
2011        @type auto_add: bool
2012        @param quiet: If False raises a WatchManagerError exception on
2013                      error. See example not_quiet.py
2014        @type quiet: bool
2015        @return: dict of watch descriptors associated to booleans values.
2016                 True if the corresponding wd has been successfully
2017                 updated, False otherwise.
2018        @rtype: dict of {int: bool}
2019        """
2020        lwd = self.__format_param(wd)
2021        if rec:
2022            lwd = self.__get_sub_rec(lwd)
2023
2024        ret_ = {}  # return {wd: bool, ...}
2025        for awd in lwd:
2026            apath = self.get_path(awd)
2027            if not apath or awd < 0:
2028                err = 'update_watch: invalid WD=%d' % awd
2029                if quiet:
2030                    log.error(err)
2031                    continue
2032                raise WatchManagerError(err, ret_)
2033
2034            if mask:
2035                wd_ = self._inotify_wrapper.inotify_add_watch(self._fd, apath,
2036                                                              mask)
2037                if wd_ < 0:
2038                    ret_[awd] = False
2039                    err = ('update_watch: cannot update %s WD=%d, %s' % \
2040                               (apath, wd_, self._inotify_wrapper.str_errno()))
2041                    if quiet:
2042                        log.error(err)
2043                        continue
2044                    raise WatchManagerError(err, ret_)
2045
2046                assert(awd == wd_)
2047
2048            if proc_fun or auto_add:
2049                watch_ = self._wmd[awd]
2050
2051            if proc_fun:
2052                watch_.proc_fun = proc_fun
2053
2054            if auto_add:
2055                watch_.auto_add = auto_add
2056
2057            ret_[awd] = True
2058            log.debug('Updated watch - %s', self._wmd[awd])
2059        return ret_
2060
2061    def __format_param(self, param):
2062        """
2063        @param param: Parameter.
2064        @type param: string or int
2065        @return: wrap param.
2066        @rtype: list of type(param)
2067        """
2068        if isinstance(param, list):
2069            for p_ in param:
2070                yield p_
2071        else:
2072            yield param
2073
2074    def get_wd(self, path):
2075        """
2076        Returns the watch descriptor associated to path. This method
2077        presents a prohibitive cost, always prefer to keep the WD
2078        returned by add_watch(). If the path is unknown it returns None.
2079
2080        @param path: Path.
2081        @type path: str
2082        @return: WD or None.
2083        @rtype: int or None
2084        """
2085        path = self.__format_path(path)
2086        for iwd in self._wmd.items():
2087            if iwd[1].path == path:
2088                return iwd[0]
2089
2090    def get_path(self, wd):
2091        """
2092        Returns the path associated to WD, if WD is unknown it returns None.
2093
2094        @param wd: Watch descriptor.
2095        @type wd: int
2096        @return: Path or None.
2097        @rtype: string or None
2098        """
2099        watch_ = self._wmd.get(wd)
2100        if watch_ is not None:
2101            return watch_.path
2102
2103    def __walk_rec(self, top, rec):
2104        """
2105        Yields each subdirectories of top, doesn't follow symlinks.
2106        If rec is false, only yield top.
2107
2108        @param top: root directory.
2109        @type top: string
2110        @param rec: recursive flag.
2111        @type rec: bool
2112        @return: path of one subdirectory.
2113        @rtype: string
2114        """
2115        if not rec or os.path.islink(top) or not os.path.isdir(top):
2116            yield top
2117        else:
2118            for root, dirs, files in os.walk(top):
2119                yield root
2120
2121    def rm_watch(self, wd, rec=False, quiet=True):
2122        """
2123        Removes watch(s).
2124
2125        @param wd: Watch Descriptor of the file or directory to unwatch.
2126                   Also accepts a list of WDs.
2127        @type wd: int or list of int.
2128        @param rec: Recursively removes watches on every already watched
2129                    subdirectories and subfiles.
2130        @type rec: bool
2131        @param quiet: If False raises a WatchManagerError exception on
2132                      error. See example not_quiet.py
2133        @type quiet: bool
2134        @return: dict of watch descriptors associated to booleans values.
2135                 True if the corresponding wd has been successfully
2136                 removed, False otherwise.
2137        @rtype: dict of {int: bool}
2138        """
2139        lwd = self.__format_param(wd)
2140        if rec:
2141            lwd = self.__get_sub_rec(lwd)
2142
2143        ret_ = {}  # return {wd: bool, ...}
2144        for awd in lwd:
2145            # remove watch
2146            wd_ = self._inotify_wrapper.inotify_rm_watch(self._fd, awd)
2147            if wd_ < 0:
2148                ret_[awd] = False
2149                err = ('rm_watch: cannot remove WD=%d, %s' % \
2150                           (awd, self._inotify_wrapper.str_errno()))
2151                if quiet:
2152                    log.error(err)
2153                    continue
2154                raise WatchManagerError(err, ret_)
2155
2156            # Remove watch from our dictionary
2157            if awd in self._wmd:
2158                del self._wmd[awd]
2159            ret_[awd] = True
2160            log.debug('Watch WD=%d (%s) removed', awd, self.get_path(awd))
2161        return ret_
2162
2163
2164    def watch_transient_file(self, filename, mask, proc_class):
2165        """
2166        Watch a transient file, which will be created and deleted frequently
2167        over time (e.g. pid file).
2168
2169        @attention: Currently under the call to this function it is not
2170        possible to correctly watch the events triggered into the same
2171        base directory than the directory where is located this watched
2172        transient file. For instance it would be wrong to make these
2173        two successive calls: wm.watch_transient_file('/var/run/foo.pid', ...)
2174        and wm.add_watch('/var/run/', ...)
2175
2176        @param filename: Filename.
2177        @type filename: string
2178        @param mask: Bitmask of events, should contain IN_CREATE and IN_DELETE.
2179        @type mask: int
2180        @param proc_class: ProcessEvent (or of one of its subclass), beware of
2181                           accepting a ProcessEvent's instance as argument into
2182                           __init__, see transient_file.py example for more
2183                           details.
2184        @type proc_class: ProcessEvent's instance or of one of its subclasses.
2185        @return: Same as add_watch().
2186        @rtype: Same as add_watch().
2187        """
2188        dirname = os.path.dirname(filename)
2189        if dirname == '':
2190            return {}  # Maintains coherence with add_watch()
2191        basename = os.path.basename(filename)
2192        # Assuming we are watching at least for IN_CREATE and IN_DELETE
2193        mask |= IN_CREATE | IN_DELETE
2194
2195        def cmp_name(event):
2196            if getattr(event, 'name') is None:
2197                return False
2198            return basename == event.name
2199        return self.add_watch(dirname, mask,
2200                              proc_fun=proc_class(ChainIfTrue(func=cmp_name)),
2201                              rec=False,
2202                              auto_add=False, do_glob=False,
2203                              exclude_filter=lambda path: False)
2204
2205    def get_ignore_events(self):
2206        return self._ignore_events
2207
2208    def set_ignore_events(self, nval):
2209        self._ignore_events = nval
2210
2211    ignore_events = property(get_ignore_events, set_ignore_events,
2212                             "Make watch manager ignoring new events.")
2213
2214
2215
2216class RawOutputFormat:
2217    """
2218    Format string representations.
2219    """
2220    def __init__(self, format=None):
2221        self.format = format or {}
2222
2223    def simple(self, s, attribute):
2224        if not isinstance(s, str):
2225            s = str(s)
2226        return (self.format.get(attribute, '') + s +
2227                self.format.get('normal', ''))
2228
2229    def punctuation(self, s):
2230        """Punctuation color."""
2231        return self.simple(s, 'normal')
2232
2233    def field_value(self, s):
2234        """Field value color."""
2235        return self.simple(s, 'purple')
2236
2237    def field_name(self, s):
2238        """Field name color."""
2239        return self.simple(s, 'blue')
2240
2241    def class_name(self, s):
2242        """Class name color."""
2243        return self.format.get('red', '') + self.simple(s, 'bold')
2244
2245output_format = RawOutputFormat()
2246
2247class ColoredOutputFormat(RawOutputFormat):
2248    """
2249    Format colored string representations.
2250    """
2251    def __init__(self):
2252        f = {'normal': '\033[0m',
2253             'black': '\033[30m',
2254             'red': '\033[31m',
2255             'green': '\033[32m',
2256             'yellow': '\033[33m',
2257             'blue': '\033[34m',
2258             'purple': '\033[35m',
2259             'cyan': '\033[36m',
2260             'bold': '\033[1m',
2261             'uline': '\033[4m',
2262             'blink': '\033[5m',
2263             'invert': '\033[7m'}
2264        RawOutputFormat.__init__(self, f)
2265
2266
2267def compatibility_mode():
2268    """
2269    Use this function to turn on the compatibility mode. The compatibility
2270    mode is used to improve compatibility with Pyinotify 0.7.1 (or older)
2271    programs. The compatibility mode provides additional variables 'is_dir',
2272    'event_name', 'EventsCodes.IN_*' and 'EventsCodes.ALL_EVENTS' as
2273    Pyinotify 0.7.1 provided. Do not call this function from new programs!!
2274    Especially if there are developped for Pyinotify >= 0.8.x.
2275    """
2276    setattr(EventsCodes, 'ALL_EVENTS', ALL_EVENTS)
2277    for evname in globals():
2278        if evname.startswith('IN_'):
2279            setattr(EventsCodes, evname, globals()[evname])
2280    global COMPATIBILITY_MODE
2281    COMPATIBILITY_MODE = True
2282
2283
2284def command_line():
2285    """
2286    By default the watched path is '/tmp' and all types of events are
2287    monitored. Events monitoring serves forever, type c^c to stop it.
2288    """
2289    from optparse import OptionParser
2290
2291    usage = "usage: %prog [options] [path1] [path2] [pathn]"
2292
2293    parser = OptionParser(usage=usage)
2294    parser.add_option("-v", "--verbose", action="store_true",
2295                      dest="verbose", help="Verbose mode")
2296    parser.add_option("-r", "--recursive", action="store_true",
2297                      dest="recursive",
2298                      help="Add watches recursively on paths")
2299    parser.add_option("-a", "--auto_add", action="store_true",
2300                      dest="auto_add",
2301                      help="Automatically add watches on new directories")
2302    parser.add_option("-g", "--glob", action="store_true",
2303                      dest="glob",
2304                      help="Treat paths as globs")
2305    parser.add_option("-e", "--events-list", metavar="EVENT[,...]",
2306                      dest="events_list",
2307                      help=("A comma-separated list of events to watch for - "
2308                           "see the documentation for valid options (defaults"
2309                           " to everything)"))
2310    parser.add_option("-s", "--stats", action="store_true",
2311                      dest="stats",
2312                      help="Display dummy statistics")
2313    parser.add_option("-V", "--version", action="store_true",
2314                      dest="version",  help="Pyinotify version")
2315    parser.add_option("-f", "--raw-format", action="store_true",
2316                      dest="raw_format",
2317                      help="Disable enhanced output format.")
2318    parser.add_option("-c", "--command", action="store",
2319                      dest="command",
2320                      help="Shell command to run upon event")
2321
2322    (options, args) = parser.parse_args()
2323
2324    if options.verbose:
2325        log.setLevel(10)
2326
2327    if options.version:
2328        print(__version__)
2329
2330    if not options.raw_format:
2331        global output_format
2332        output_format = ColoredOutputFormat()
2333
2334    if len(args) < 1:
2335        path = '/tmp'  # default watched path
2336    else:
2337        path = args
2338
2339    # watch manager instance
2340    wm = WatchManager()
2341    # notifier instance and init
2342    if options.stats:
2343        notifier = Notifier(wm, default_proc_fun=Stats(), read_freq=5)
2344    else:
2345        notifier = Notifier(wm, default_proc_fun=PrintAllEvents())
2346
2347    # What mask to apply
2348    mask = 0
2349    if options.events_list:
2350        events_list = options.events_list.split(',')
2351        for ev in events_list:
2352            evcode = EventsCodes.ALL_FLAGS.get(ev, 0)
2353            if evcode:
2354                mask |= evcode
2355            else:
2356                parser.error("The event '%s' specified with option -e"
2357                             " is not valid" % ev)
2358    else:
2359        mask = ALL_EVENTS
2360
2361    # stats
2362    cb_fun = None
2363    if options.stats:
2364        def cb(s):
2365            sys.stdout.write(repr(s.proc_fun()))
2366            sys.stdout.write('\n')
2367            sys.stdout.write(str(s.proc_fun()))
2368            sys.stdout.write('\n')
2369            sys.stdout.flush()
2370        cb_fun = cb
2371
2372    # External command
2373    if options.command:
2374        def cb(s):
2375            subprocess.Popen(options.command, shell=True)
2376        cb_fun = cb
2377
2378    log.debug('Start monitoring %s, (press c^c to halt pyinotify)' % path)
2379
2380    wm.add_watch(path, mask, rec=options.recursive, auto_add=options.auto_add, do_glob=options.glob)
2381    # Loop forever (until sigint signal get caught)
2382    notifier.loop(callback=cb_fun)
2383
2384
2385if __name__ == '__main__':
2386    command_line()
2387