Exemple #1
0
 def close(self):
     """
     Closes the inotify instance and removes all associated watches.
     """
     with self._lock:
         path = unicode_paths.encode(absolute_path(self._path))
         wd = self._wd_for_path[path]
         inotify_rm_watch(self._inotify_fd, wd)
Exemple #2
0
 def close(self):
     """
     Closes the inotify instance and removes all associated watches.
     """
     with self._lock:
         path = unicode_paths.encode(absolute_path(self._path))
         wd = self._wd_for_path[path]
         inotify_rm_watch(self._inotify_fd, wd)
Exemple #3
0
    def _add_watch(self, path, mask):
        """
        Adds a watch for the given path to monitor events specified by the
        mask.

        :param path:
            Path to monitor
        :param mask:
            Event bit mask.
        """
        wd = inotify_add_watch(self._inotify_fd, unicode_paths.encode(path), mask)
        if wd == -1:
            Inotify._raise_error()
        self._wd_for_path[path] = wd
        self._path_for_wd[wd] = path
        return wd
Exemple #4
0
    def _add_watch(self, path, mask):
        """
        Adds a watch for the given path to monitor events specified by the
        mask.

        :param path:
            Path to monitor
        :param mask:
            Event bit mask.
        """
        wd = inotify_add_watch(self._inotify_fd, unicode_paths.encode(path), mask)
        if wd == -1:
            Inotify._raise_error()
        self._wd_for_path[path] = wd
        self._path_for_wd[wd] = path
        return wd
Exemple #5
0
    def _add_dir_watch(self, path, recursive, mask):
      """
      Adds a watch (optionally recursively) for the given directory path
      to monitor events specified by the mask.

      :param path:
          Path to monitor
      :param recursive:
          ``True`` to monitor recursively.
      :param mask:
          Event bit mask.
      """
      path = unicode_paths.encode(path)
      if not os.path.isdir(path):
        raise OSError('Path is not a directory')
      self._add_watch(path, mask)
      if recursive:
        for root, dirnames, _ in os.walk(path):
          for dirname in dirnames:
            full_path = absolute_path(os.path.join(root, dirname))
            if os.path.islink(full_path):
              continue
            self._add_watch(full_path, mask)
Exemple #6
0
    def _add_dir_watch(self, path, recursive, mask):
        """
        Adds a watch (optionally recursively) for the given directory path
        to monitor events specified by the mask.

        :param path:
            Path to monitor
        :param recursive:
            ``True`` to monitor recursively.
        :param mask:
            Event bit mask.
        """
        path = unicode_paths.encode(path)
        if not os.path.isdir(path):
            raise OSError('Path is not a directory')
        self._add_watch(path, mask)
        if recursive:
            for root, dirnames, _ in os.walk(path):
                for dirname in dirnames:
                    full_path = absolute_path(os.path.join(root, dirname))
                    if os.path.islink(full_path):
                        continue
                    self._add_watch(full_path, mask)
Exemple #7
0
    def read_events(self, event_buffer_size=DEFAULT_EVENT_BUFFER_SIZE):
      """
      Reads events from inotify and yields them.
      """
      while True:
        try:
          event_buffer = os.read(self._inotify_fd, event_buffer_size)
        except OSError as e:
          if e.errno == errno.EINTR:
            continue
        break
      
      with self._lock:
        event_list = []
        for wd, mask, cookie, name in Inotify._parse_event_buffer(event_buffer):
          if wd == -1:
            continue
          wd_path = unicode_paths.encode(self._path_for_wd[wd])
          src_path = absolute_path(os.path.join(wd_path, name))
          inotify_event = InotifyEvent(wd, mask, cookie, name, src_path)

          if inotify_event.is_moved_from:
            # check if next event if moved_to
            # otherwise we might be remembering
            # something that we will never need
            # and the event will be lost
            if idx < len(parsed_events) - 1 and\
               parsed_events[idx+1][2] == cookie:
              self.remember_move_from_event(inotify_event)
            else:
              inotify_event = InotifyEvent(wd, mask, -1, name,
                                           src_path)
          elif inotify_event.is_moved_to:
            move_src_path = self.source_for_move(inotify_event)
            if move_src_path in self._wd_for_path:
              # update old path -> new path
              moved_wd = self._wd_for_path[move_src_path]
              del self._wd_for_path[move_src_path]
              self._wd_for_path[inotify_event.src_path] = moved_wd
              self._path_for_wd[moved_wd] = inotify_event.src_path
            src_path = absolute_path(os.path.join(wd_path, name))
            inotify_event = InotifyEvent(wd, mask, cookie, name, src_path)

          if inotify_event.is_ignored:
          # Clean up book-keeping for deleted watches.
            self._remove_watch_bookkeeping(src_path)
            continue

          event_list.append(inotify_event)

          if self.is_recursive and inotify_event.is_directory and inotify_event.is_create:
            # HACK: We need to traverse the directory path
            # recursively and simulate events for newly
            # created subdirectories/files. This will handle
            # mkdir -p foobar/blah/bar; touch foobar/afile

            # TODO: When a directory from another part of the
            # filesystem is moved into a watched directory, this
            # will not generate events for the directory tree.
            # We need to coalesce IN_MOVED_TO events and those
            # IN_MOVED_TO events which don't pair up with
            # IN_MOVED_FROM events should be marked IN_CREATE
            # instead relative to this directory.
            try:
              self._add_watch(src_path, self._event_mask)
            except OSError:
              continue
            for root, dirnames, filenames in os.walk(src_path):
              for dirname in dirnames:
                try:
                  full_path = absolute_path(os.path.join(root, dirname))
                  wd_dir = self._add_watch(full_path, self._event_mask)
                  event_list.append(InotifyEvent(wd_dir,
                      InotifyConstants.IN_CREATE | InotifyConstants.IN_ISDIR, 0, dirname, full_path))
                except OSError:
                  pass
              for filename in filenames:
                full_path = absolute_path(os.path.join(root, filename))
                wd_parent_dir = self._wd_for_path[absolute_path(os.path.dirname(full_path))]
                event_list.append(InotifyEvent(wd_parent_dir,
                    InotifyConstants.IN_CREATE, 0, filename, full_path))
      return event_list
Exemple #8
0
 def on_thread_start(self):
     path = unicode_paths.encode(self.watch.path)
     self._inotify = InotifyBuffer(path, self.watch.is_recursive)
Exemple #9
0
 def on_thread_start(self):
     path = unicode_paths.encode(self.watch.path)
     self._inotify = InotifyBuffer(path, self.watch.is_recursive)
Exemple #10
0
    def read_events(self, event_buffer_size=DEFAULT_EVENT_BUFFER_SIZE):
        """
        Reads events from inotify and yields them.
        """

        # HACK: We need to traverse the directory path
        # recursively and simulate events for newly
        # created subdirectories/files. This will handle
        # mkdir -p foobar/blah/bar; touch foobar/afile

        def _recursive_simulate(src_path):
            events = []
            for root, dirnames, filenames in os.walk(src_path):
                for dirname in dirnames:
                    try:
                        full_path = absolute_path(os.path.join(root, dirname))
                        wd_dir = self._add_watch(full_path, self._event_mask)
                        e = InotifyEvent(
                            wd_dir, InotifyConstants.IN_CREATE
                            | InotifyConstants.IN_ISDIR, 0, dirname, full_path)
                        events.append(e)
                    except OSError:
                        pass
                for filename in filenames:
                    full_path = absolute_path(os.path.join(root, filename))
                    wd_parent_dir = self._wd_for_path[absolute_path(
                        os.path.dirname(full_path))]
                    e = InotifyEvent(wd_parent_dir, InotifyConstants.IN_CREATE,
                                     0, filename, full_path)
                    events.append(e)
            return events

        while True:
            try:
                event_buffer = os.read(self._inotify_fd, event_buffer_size)
            except OSError as e:
                if e.errno == errno.EINTR:
                    continue
            break

        with self._lock:
            event_list = []
            for wd, mask, cookie, name in Inotify._parse_event_buffer(
                    event_buffer):
                if wd == -1:
                    continue
                wd_path = unicode_paths.encode(self._path_for_wd[wd])
                src_path = absolute_path(os.path.join(wd_path, name))
                inotify_event = InotifyEvent(wd, mask, cookie, name, src_path)

                if inotify_event.is_moved_from:
                    self.remember_move_from_event(inotify_event)
                elif inotify_event.is_moved_to:
                    move_src_path = self.source_for_move(inotify_event)
                    if move_src_path in self._wd_for_path:
                        moved_wd = self._wd_for_path[move_src_path]
                        del self._wd_for_path[move_src_path]
                        self._wd_for_path[inotify_event.src_path] = moved_wd
                        self._path_for_wd[moved_wd] = inotify_event.src_path
                    src_path = absolute_path(os.path.join(wd_path, name))
                    inotify_event = InotifyEvent(wd, mask, cookie, name,
                                                 src_path)

                if inotify_event.is_ignored:
                    # Clean up book-keeping for deleted watches.
                    self._remove_watch_bookkeeping(src_path)
                    continue

                event_list.append(inotify_event)

                if (self.is_recursive and inotify_event.is_directory
                        and inotify_event.is_create):

                    # TODO: When a directory from another part of the
                    # filesystem is moved into a watched directory, this
                    # will not generate events for the directory tree.
                    # We need to coalesce IN_MOVED_TO events and those
                    # IN_MOVED_TO events which don't pair up with
                    # IN_MOVED_FROM events should be marked IN_CREATE
                    # instead relative to this directory.
                    try:
                        self._add_watch(src_path, self._event_mask)
                    except OSError:
                        continue

                    event_list.extend(_recursive_simulate(src_path))

        return event_list
Exemple #11
0
 def __init__(self, event_queue, watch, timeout=DEFAULT_EMITTER_TIMEOUT):
     EventEmitter.__init__(self, event_queue, watch, timeout)
     self._lock = threading.Lock()
     self._inotify = InotifyBuffer(unicode_paths.encode(watch.path),
                                   watch.is_recursive)
Exemple #12
0
 def __init__(self, event_queue, watch, timeout=DEFAULT_EMITTER_TIMEOUT):
     EventEmitter.__init__(self, event_queue, watch, timeout)
     self._lock = threading.Lock()
     self._inotify = InotifyBuffer(unicode_paths.encode(watch.path),
                                   watch.is_recursive)
    def read_events(self, event_buffer_size = DEFAULT_EVENT_BUFFER_SIZE):
        """
        Reads events from inotify and yields them.
        """

        def _recursive_simulate(src_path):
            events = []
            for root, dirnames, filenames in os.walk(src_path):
                for dirname in dirnames:
                    try:
                        full_path = absolute_path(os.path.join(root, dirname))
                        wd_dir = self._add_watch(full_path, self._event_mask)
                        e = InotifyEvent(wd_dir, InotifyConstants.IN_CREATE | InotifyConstants.IN_ISDIR, 0, dirname, full_path)
                        events.append(e)
                    except OSError:
                        pass

                for filename in filenames:
                    full_path = absolute_path(os.path.join(root, filename))
                    wd_parent_dir = self._wd_for_path[absolute_path(os.path.dirname(full_path))]
                    e = InotifyEvent(wd_parent_dir, InotifyConstants.IN_CREATE, 0, filename, full_path)
                    events.append(e)

            return events

        while True:
            try:
                event_buffer = os.read(self._inotify_fd, event_buffer_size)
            except OSError as e:
                if e.errno == errno.EINTR:
                    continue

            break

        with self._lock:
            event_list = []
            for wd, mask, cookie, name in Inotify._parse_event_buffer(event_buffer):
                if wd == -1:
                    continue
                wd_path = unicode_paths.encode(self._path_for_wd[wd])
                src_path = absolute_path(os.path.join(wd_path, name))
                inotify_event = InotifyEvent(wd, mask, cookie, name, src_path)
                if inotify_event.is_moved_from:
                    self.remember_move_from_event(inotify_event)
                elif inotify_event.is_moved_to:
                    move_src_path = self.source_for_move(inotify_event)
                    if move_src_path in self._wd_for_path:
                        moved_wd = self._wd_for_path[move_src_path]
                        del self._wd_for_path[move_src_path]
                        self._wd_for_path[inotify_event.src_path] = moved_wd
                        self._path_for_wd[moved_wd] = inotify_event.src_path
                    src_path = absolute_path(os.path.join(wd_path, name))
                    inotify_event = InotifyEvent(wd, mask, cookie, name, src_path)
                if inotify_event.is_ignored:
                    self._remove_watch_bookkeeping(src_path)
                    continue
                event_list.append(inotify_event)
                if self.is_recursive and inotify_event.is_directory and inotify_event.is_create:
                    try:
                        self._add_watch(src_path, self._event_mask)
                    except OSError:
                        continue

                    event_list.extend(_recursive_simulate(src_path))

        return event_list