Skip to content

Commit

Permalink
Adds wrapper class and struct for inotify_event
Browse files Browse the repository at this point in the history
Signed-off-by: Gora Khargosh <gora.khargosh@gmail.com>
  • Loading branch information
gorakhargosh committed Dec 11, 2010
1 parent a6cb1f9 commit c8b2808
Showing 1 changed file with 131 additions and 3 deletions.
134 changes: 131 additions & 3 deletions watchdog/observers/inotify.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@
c_int, \
c_char_p, \
c_uint32, \
get_errno
get_errno, \
sizeof, \
Structure
from watchdog.utils import absolute_path
from watchdog.observers.api import \
EventEmitter, \
Expand Down Expand Up @@ -124,6 +126,124 @@
("inotify_rm_watch", libc))


class InotifyEvent(object):
"""
Inotify event struct wrapper.
:param wd:
Watch descriptor
:param mask:
Event mask
:param cookie:
Event cookie
:param name:
Event name.
"""
def __init__(self, wd, mask, cookie, name):
self._wd = wd
self._mask = mask
self._cookie = cookie
self._name = name

@property
def wd(self):
return self._wd

@property
def mask(self):
return self._mask

@property
def cookie(self):
return self._cookie

@property
def name(self):
return self._name

# Test event types.
@property
def is_modify(self):
return self._mask & Inotify.IN_MODIFY

@property
def is_close_write(self):
return self._mask & Inotify.IN_CLOSE_WRITE

@property
def is_close_nowrite(self):
return self._mask & Inotify.IN_CLOSE_NOWRITE

@property
def is_access(self):
return self._mask & Inotify.IN_ACCESS

@property
def is_delete(self):
return self._mask & Inotify.IN_DELETE

@property
def is_create(self):
return self._mask & Inotify.IN_CREATE

@property
def is_moved_from(self):
return self._mask & Inotify.IN_MOVED_FROM

@property
def is_moved_to(self):
return self._mask & Inotify.IN_MOVED_TO

@property
def is_move(self):
return self._mask & Inotify.IN_MOVE

@property
def is_attrib(self):
return self._mask & Inotify.IN_ATTRIB

@property
def is_directory(self):
return self._mask & Inotify.IN_ISDIR

# Additional functionality.
@property
def key(self):
return (self._wd, self._mask, self._cookie, self._name)

def __eq__(self, inotify_event):
return self.key == inotify_event.key

def __ne__(self, inotify_event):
return self.key == inotify_event.key

def __hash__(self):
return hash(self.key)


class inotify_event_struct(Structure):
"""
Structure representation of the inotify_event structure.
Used in buffer size calculations::
struct inotify_event {
__s32 wd; /* watch descriptor */
__u32 mask; /* watch mask */
__u32 cookie; /* cookie to synchronize two events */
__u32 len; /* length (including nulls) of name */
char name[0]; /* stub for possible name */
};
"""
_fields_ = [('wd', c_int),
('mask', c_uint32),
('cookie', c_uint32),
('len', c_uint32),
('name', c_char_p)]

EVENT_SIZE = sizeof(inotify_event_struct)
DEFAULT_EVENT_BUFFER_SIZE = 1024 * (EVENT_SIZE + 16)


class Inotify(object):
"""
Linux inotify(7) API wrapper class.
Expand Down Expand Up @@ -292,6 +412,14 @@ def close(self):
self._remove_all_watches()
os.close(self._inotify_fd)

def read_events(self, event_buffer_size=DEFAULT_EVENT_BUFFER_SIZE):
"""
Reads events from inotify and yields them.
"""
event_buffer = os.read(self._inotify_fd, event_buffer_size)
for wd, mask, cookie, name in Inotify._parse_event_buffer(event_buffer):
yield InotifyEvent(wd, mask, cookie, name)

# Non-synchronized methods.
def _add_dir_watch(self, path, recursive, mask):
"""
Expand Down Expand Up @@ -360,7 +488,7 @@ def _raise_error():
raise OSError(strerror(_errnum))

@staticmethod
def parse_event_buffer(buffer):
def _parse_event_buffer(buffer):
"""
Parses an event buffer of ``inotify_event`` structs returned by
inotify::
Expand Down Expand Up @@ -409,7 +537,7 @@ def on_thread_exit(self):
self._inotify.close()

def queue_events(self, timeout):
pass
inotify_events = self._inotify.read_events(event_buffer_size)


class InotifyObserver(BaseObserver):
Expand Down

0 comments on commit c8b2808

Please sign in to comment.