Exemple #1
0
 def stop(self):
     if not self._run: return
     self._run = False
     inotifyx.rm_watch(self._id, self._wd)
     os.close(self._id)
     self._id = None
     self._wd = None
Exemple #2
0
 def stop ( self ):
   if not self._run: return
   self._run = False
   inotifyx.rm_watch(self._id, self._wd)
   self._id  = None
   self._wd  = None
   self._devmon.stop()
	def run(self):
		# watch intel vbtn for event to know when to parse dmesg for what it was
		self.log.info("StanceWatcher started")
		vbtnWatchFd = inotifyx.init()
		try:
			self.log.debug("Add Watch for Intel Virtual Button input...")
			vbtnWatch = inotifyx.add_watch(vbtnWatchFd, Config['intelVbtnInput'], inotifyx.IN_ACCESS)
			
			lastEventTime = 0.0
			while not self.stopEv.is_set():
				vbtnEvent = inotifyx.get_events(vbtnWatchFd,0.8)
				if len(vbtnEvent) > 0:
					now = time.time();
					# vbtn event file is modified multiple times on a lid rotation, a quick solution to fire stance change only once
					# assuming the user won't rotate the lid very frequently (like under a second...)
					if now - lastEventTime > 0.8:
						self.log.debug("lid rotate event occurred, parse syslog...")
						time.sleep(0.2) #give time for event to appear in syslog
						readStance = self.parseStanceFromSyslog()
						if readStance:
							self.stance = readStance
							self.log.debug("Stance updated to %s", self.stance)
							self.changeEvent.set()
						else:
							self.log.warning("Got None, stance NOT updated.")
					else:
						self.log.debug("event discarded, too soon")
					lastEventTime = now
			inotifyx.rm_watch(vbtnWatchFd, vbtnWatch)
			self.log.debug("Removed watch for Intel Virtual Button input")
		finally:
			os.close(vbtnWatchFd)
Exemple #4
0
    def stop(self):
        """Implementation of the abstract method stop.
        """

        if self.cleanup_thread is not None:
            self.cleanup_thread.stop()

        try:
            for watch_descriptor, watch_path in self.wd_to_path.items():
                try:
                    inotifyx.rm_watch(self.file_descriptor, watch_descriptor)
                except Exception:
                    self.log.error("Unable to remove watch: %s for %s",
                                   watch_descriptor,
                                   watch_path,
                                   exc_info=True)
            self.wd_to_path = {}
        finally:
            if self.file_descriptor is not None:
                try:
                    os.close(self.file_descriptor)
                except OSError:
                    self.log.error("Unable to close file descriptor")

                common_stop(self.config, self.log)
                self.file_descriptor = None
 def __removeWatch(self, wd):
     self.log.debug('Removing wd:%s from fd:%s' % (wd, self.fd))
     try:
         rm_watch(self.fd, wd)
     except IOError as error:
         self.log.debug('Ignoring rm_watch IOError %s' % error)
         pass
Exemple #6
0
 def stop ( self ):
   if not self._run: return
   self._run = False
   inotifyx.rm_watch(self._id, self._wd)
   os.close(self._id)
   self._id  = None
   self._wd  = None
Exemple #7
0
	def close(self):
		if self.monitor is not None:
			self.monitor.cancel()
			self.monitor = None
		if inotifyx and self.monitor_fd:
			inotifyx.rm_watch(self.monitor_fd)
			os.close(self.monitor_fd)
			self.monitor_fd = None
Exemple #8
0
	def _close(self, fd):
		"""
		Close the descriptor used for a path regardless
		of mode.
	"""
		if self._mode == WF_INOTIFYX:
			try: inotifyx.rm_watch(self._inx_fd, fd)
			except: pass
		else:
			try: os.close(fd)
			except: pass
Exemple #9
0
	def _unwatch_down(self, monitor):
		try:
			inotifyx.rm_watch(monitor.fd, self.wd)
		except IOError as e:
			if e.errno != errno.EINVAL:
				raise
			# we ignore DELETE_SELF on non-roots, so unwatch() on DELETE may be too late
		monitor.wds.pop(self.wd)
		for child in (self.children or {}).itervalues():
			child._unwatch_down(monitor)
		self.children = None
Exemple #10
0
 def ivisit(self):
     try:
         fd = inotifyx.init()
         wd = inotifyx.add_watch(fd, self.items[0], inotifyx.IN_CLOSE)
         self.urlvisit()
         inotifyx.get_events(fd, self.keep)
         inotifyx.rm_watch(fd, wd)
         os.close(fd)
     except IOError:
         hint = "consider increasing " "/proc/sys/fs/inotify/max_user_watches"
         raise util.DeadMan("failed to enable inotify", hint=hint)
Exemple #11
0
 def ivisit(self):
     try:
         fd = inotifyx.init()
         wd = inotifyx.add_watch(fd, self.items[0], inotifyx.IN_CLOSE)
         self.urlvisit()
         inotifyx.get_events(fd, self.keep)
         inotifyx.rm_watch(fd, wd)
         os.close(fd)
     except IOError:
         hint = ('consider increasing '
                 '/proc/sys/fs/inotify/max_user_watches')
         raise util.DeadMan('failed to enable inotify', hint=hint)
Exemple #12
0
    def tail(self):
        fd = inotifyx.init()
        try:
            wd = inotifyx.add_watch(fd, '/var/log/emerge.log', inotifyx.IN_MODIFY)

            self.log_currentcompile(1) # only wait for a second for the sandbox

            while True:
		self.log_heartbeat()
                events = inotifyx.get_events(fd, float(self.nap))
                if len(events) != 0: # not timeout
                    self.log_currentcompile(self.sandboxwait)

            inotifyx.rm_watch(fd, wd)
        finally:
            os.close(fd)
Exemple #13
0
def watchFiles(queue):
    mediaFound = False
    fd = inotifyx.init()
    wd = inotifyx.add_watch(fd, watchPath, inotifyx.IN_CLOSE)

    while (1):
	# Wait for an event with timeout.
	event = inotifyx.get_events(fd, eventTimeout)
	print("Event caught, or timed-out.")

	# Wait before reading files
	time.sleep(readDelay)

	for fname in os.listdir(watchPath):
	    fpath = os.path.join(watchPath, fname)
	    if (os.path.isfile(fpath) and fname.startswith(watchFilePrefix)
			and fname.endswith(watchFileSuffix)):
		mediaFound = False
		print ("Processing file: " + fpath)
		f = open(fpath, "r")

		for line in f:
		    pieces = shlex.split(line.strip())
		    for p in pieces:
			queue.put(p)
			print ("Found: " + p)
			mediaFound = True
		f.close()

		# Only remove the file if we found something in it
		if(mediaFound):
		    os.remove(fpath)
		    print("Deleting file.")

	# Drain events from file operations.
	e = inotifyx.get_events(fd, 0)
	while e:
	    e = inotifyx.get_events(fd, 0)

    inotifyx.rm_watch(fd, wd)
    os.close(fd)
Exemple #14
0
def xzCompress(inputFile, outputFile):
    # Compresses a file, that may be actively written to, with xz.
    # Returns the file name on success, or None on failure

    # command uses custom streaming build of xz
    xzCommand = "export LD_LIBRARY_PATH=/usr/local/lib; /usr/local/bin/xz2 -z1 > %s" % (outputFile)
    # xzCommand = "/usr/local/bin/xz -z1 | pv -B 1024 -L 100 > %s" % (outputFile)

    IN_WATCH_EVENTS = inotifyx.IN_MODIFY

    try:
        # Sets up the main inotify watcher
        fd = inotifyx.init()
        watcher = inotifyx.add_watch(fd, inputFile, IN_WATCH_EVENTS)
        with io.open(inputFile, mode='r+b') as fileStream:
            # Loop until no more data
            try:
                xzp = subprocess.Popen(
                    xzCommand, stdin=subprocess.PIPE, shell=True,
                    close_fds=False, preexec_fn=subprocessSetup)

                # Counter for retrys
                trycount = 0
                while 1:
                    # Main loop which reads the file and writes to xz stdin
                    data = fileStream.read(1024000)
                    current = False
                    # Assume reading a normal file until we get to the end

                    if len(data) == 0:
                        current = currentFile(inputFile, fd)
                        if not current:
                            # Reached EOF, check next file exists
                            sleep(0.1)  # Prevent race condition

                            if nextFile(inputFile) is not None:
                                logger.debug("Breaking, next file exists!")
                                break

                            trycount += 1
                            logger.debug("Waiting for next file or more data.."
                                         + str(trycount))
                            sleep(1)

                    logger.debug("Writing %s" % len(data))
                    xzp.stdin.write(data)

                    if current:
                        # Reduce looping, wait a bit for more data
                        sleep(0.5)
            except(KeyboardInterrupt, SystemExit):
                raise
            finally:
                xzp.stdin.flush()
                xzp.stdin.close()

            position = fileStream.tell()

        inotifyx.rm_watch(fd, watcher)
    finally:
        os.close(fd)

    # Get return code
    xzp.wait()
    if xzp.returncode is not 0:
        logger.error("xz gave non-zero exit status")
        return None
    # logger.debug("xz return code: %s" % (returnCode))

    # Check new compressed file exists (before this we don't *actually* know
    # it does because it's a shell redirect)
    try:
        with open(outputFile):
            pass
    except IOError:
        logger.error("Failed to create xz file")
        return None

    return (outputFile, position)
Exemple #15
0
 def remove_observer(self, observer):
     inotifyx.rm_watch(self._fd, observer._wd)
     self._observers.remove(observer)
     del self._wd[observer._wd]
Exemple #16
0
def main(charnames):
    pygame.init()
    window_size = (200*len(charnames), 400)
    screen = pygame.display.set_mode(window_size)
    skins, wds = load_entities(charnames)

    anim = 0
    display_hardshape = True
    speed = 1.0
    font = pygame.font.Font(pygame.font.get_default_font(), 12)
    pause = False
    shield = False
    frame = 0
    mouse_click = False
    mouse_xy = [0, 0]

    bottom_center_hardshape = [window_size[0]/2, window_size[1]*2/3]
    last_time = time.time()
    while True:
        # frame limiter
        while time.time() < last_time + 0.05:
            time.sleep(0.05)

        last_time = time.time()

        # get key events
        pygame.event.pump()
        if inotifyx:
            for i, w in enumerate(wds):
                if inotifyx.get_events(fd, 0):
                    print "events"
                    for i in range(3):
                        try:
                            skins = load_entities(charnames)[0]
                            break
                        except:
                            time.sleep(0.5)
                    else:
                        print "doh!"

        if mouse_click and not pygame.mouse.get_pressed()[0]:
            print "click released"
            print """
            <agressiv-point
            coords="%s,%s"
            vector="%s,%s"
            ></agressiv-point>
            """ % (
                (mouse_xy[0] - image_position[0]) % 200,
                mouse_xy[1] - image_position[1],
                2 * (pygame.mouse.get_pos()[0] - mouse_xy[0]),
                2 * (pygame.mouse.get_pos()[1] - mouse_xy[1])
                )

            print """
            <vector
            time="%s"
            vector="%s,%s"
            ></agressiv-point>
            """ % (
                img.time,
                2 * (pygame.mouse.get_pos()[0] - mouse_xy[0]),
                2 * (pygame.mouse.get_pos()[1] - mouse_xy[1])
                )
            mouse_click = False

        if not mouse_click and pygame.mouse.get_pressed()[0]:
            print "click pressed"
            mouse_xy = pygame.mouse.get_pos()
            mouse_click = True

        for event in pygame.event.get(
            [KEYDOWN, KEYUP]
            ):
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    return
                elif event.key == K_F5:
                    entity_skins = load_entities(charnames)[0]
                    print "reloaded"
                elif event.key == K_s:
                    shield = not shield
                elif event.key == K_p:
                    if pause:
                        print "normal mode"
                    else:
                        print "pause: frame mode, chose frame with ← and →"
                    pause = not pause
                elif event.key == K_RIGHT:
                    frame +=1
                elif event.key == K_LEFT:
                    frame -=1
                elif event.key == K_UP:
                    anim +=1
                elif event.key == K_DOWN:
                    anim -=1
                elif event.key == K_SPACE:
                    display_hardshape = not display_hardshape
                elif event.key == K_PLUS or event.key == K_KP_PLUS:
                    speed *= 2
                elif event.key == K_MINUS or event.key == K_KP_MINUS:
                    speed /= 2

        pygame.event.clear( [MOUSEMOTION, MOUSEBUTTONUP, MOUSEBUTTONDOWN] )
        screen.fill(pygame.Color('green'))
        for i, skin in enumerate(skins):
            animation = animations[anim % len(animations)]
            # update screen
            if animation in skin.animations:
                if not pause:
                    try:
                        img = filter(
                                    lambda f : f.time <= (
                                        (time.time()*1000.0*speed) %
                                        skin.animations[animation].duration
                                        ),
                                    skin.animations[animation].frames
                                    )[-1]
                    except ZeroDivisionError:
                        print "error: duration of 0 in", charnames[i], "in animation", animation
                        continue

                    bottom_center_hardshape[0] = (window_size[0]/(len(charnames)
                            * 2)) + (int(time.time() * CONFIG.general.WALKSPEED) % 200 if
                                    "walk" in animation else 0)

                    #if "walk" in animation:
                        #bottom_center_hardshape[0] = int(
                            #time.time() * CONFIG.general.WALKSPEED']
                            #) % window_size[0]
                    #else:
                        #bottom_center_hardshape[0] = window_size[0]/(len(charnames) * 2)
                else:
                    img = skin.animations[animation].frames[frame % len(skin.animations[animation].frames)]
            else:
                img = Placeholder()

            # update the image_position of the up-left corner of image, so that the
            # bottom-middle of the hardhape never moves (as in the game)
            image_position = (
                (bottom_center_hardshape[0] - img.hardshape[0] -
                img.hardshape[2]/2 + 200 * i) % window_size[0],
                bottom_center_hardshape[1] - img.hardshape[1] - img.hardshape[3]
            )

            if display_hardshape:
                screen.fill(
                    pygame.Color('grey'),
                    pygame.Rect((
                        image_position[0],
                        image_position[1],
                        image(img.image)[1][2],
                        image(img.image)[1][3]
                    ))
                    )

                screen.fill(
                    pygame.Color('blue'),
                    pygame.Rect((
                        image_position[0] + img.hardshape[0],
                        image_position[1] + img.hardshape[1],
                        img.hardshape[2],
                        img.hardshape[3]
                    ))
                    )

            screen.blit(image(img.image)[0], image_position)
            screen.blit(
                font.render( charnames[i], True, pygame.Color('red')),
                (10 + 200 * i,10))

            screen.blit(
                font.render(str(anim)+': '+animation, True, pygame.Color('red')),
                (10 + 200 * i,20))

            screen.blit(
                font.render(str(img.time), True, pygame.Color('red')),
                (10 + 200 * i,30))

            if shield:
                pygame.draw.circle(
                    screen,
                    pygame.Color('red'),
                    (
                        image_position[0] + img.hardshape[0] +
                        skin.shield_center[0] - 100 + 200 * i,
                        image_position[1] + img.hardshape[1] + skin.shield_center[1]
                    ),
                    10
                )

                image_shield = image(
                        os.path.sep.join(('..','data','misc','shield.png')),
                        zoom=3
                        )

                screen.blit(
                    image_shield[0],
                    (
                        image_position[0]
                        + skin.shield_center[0]
                        - .5 * image_shield[1][2]
                        ,
                        image_position[1]
                        + skin.shield_center[1]
                        - .5 * image_shield[1][3]
                        )
                    )

            for i in img.agressivpoints:
                pygame.draw.ellipse(
                    screen,
                    pygame.Color('red'),
                    pygame.Rect(
                        image_position[0]+i[0][0]-1, image_position[1]+i[0][1]-1, 2, 2
                        )
                    )
                pygame.draw.line(
                    screen,
                    pygame.Color('red'),
                        (
                        image_position[0]+i[0][0],
                        image_position[1]+i[0][1],
                        ),
                        (
                        image_position[0]+i[0][0]+i[1][0]/2,
                        image_position[1]+i[0][1]+i[1][1]/2,
                        ),
                    1
                )

        if mouse_click:
            pygame.draw.line(
                screen,
                pygame.color.Color("red"),
                mouse_xy,
                pygame.mouse.get_pos(),
                1
                )

        pygame.display.flip()
    for wd in wds:
        inotifyx.rm_watch(wd)
Exemple #17
0
    def get_new_event(self):
        """Implementation of the abstract method get_new_event.

        Returns:
            A list of event messages generated from inotify events.
        """

        remaining_events = self.get_remaining_events()

        # only take the events which are not handles yet
        event_message_list = [
            event for event in remaining_events if [
                os.path.join(event["source_path"], event["relative_path"]),
                event["filename"]
            ] not in self.history
        ]
        self.history += [[
            os.path.join(event["source_path"], event["relative_path"]),
            event["filename"]
        ] for event in remaining_events]

        # event_message_list = self.get_remaining_events()
        event_message = {}

        events = inotifyx.get_events(self.file_descriptor, self.timeout)
        removed_wd = None

        for event in events:

            if not event.name:
                continue

            try:
                path = self.wd_to_path[event.wd]
            except Exception:
                path = removed_wd
            parts = event.get_mask_description()
            parts_array = parts.split("|")

            is_dir = ("IN_ISDIR" in parts_array)
            is_created = ("IN_CREATE" in parts_array)
            is_moved_from = ("IN_MOVED_FROM" in parts_array)
            is_moved_to = ("IN_MOVED_TO" in parts_array)

            current_mon_event = None
            current_mon_regex = None
            for key, value in iteritems(self.mon_regex_per_event):
                if key in parts_array:
                    current_mon_event = key
                    current_mon_regex = value
#                    current_mon_regex = self.mon_regex_per_event[key]

#            if not is_dir:
#                self.log.debug("{} {} {}".format(path, event.name, parts))
#                self.log.debug("current_mon_event: {}"
#                               .format(current_mon_event))
#            self.log.debug(event.name)
#            self.log.debug("is_dir: {}".format(is_dir))
#            self.log.debug("is_created: {}".format(is_created))
#            self.log.debug("is_moved_from: {}".format(is_moved_from))
#            self.log.debug("is_moved_to: {}".format(is_moved_to))

# if a new directory is created or a directory is renamed inside
# the monitored one, this one has to be monitored as well
            if is_dir and (is_created or is_moved_to):

                # self.log.debug("is_dir and is_created: {} or is_moved_to: "
                #                "{}".format(is_created, is_moved_to))
                # self.log.debug("{} {} {}".format(path, event.name, parts)
                # self.log.debug(event.name)

                dirname = os.path.join(path, event.name)
                self.log.info("Directory event detected: %s, %s", dirname,
                              parts)
                if dirname in self.paths:
                    self.log.debug(
                        "Directory already contained in path list:"
                        " %s", dirname)
                else:
                    watch_descriptor = inotifyx.add_watch(  # noqa E501
                        self.file_descriptor, dirname)
                    self.wd_to_path[watch_descriptor] = dirname
                    self.log.info("Added new directory to watch: %s", dirname)

                    # because inotify misses subdirectory creations if they
                    # happen to fast, the newly created directory has to be
                    # walked to get catch this misses
                    # http://stackoverflow.com/questions/15806488/
                    #        inotify-missing-events
                    for dirpath, directories, files in os.walk(dirname):
                        # Add the found dirs to the list for the inotify-watch
                        for dname in directories:
                            subdir = os.path.join(dirpath, dname)
                            watch_descriptor = inotifyx.add_watch(
                                self.file_descriptor, subdir)
                            self.wd_to_path[watch_descriptor] = subdir
                            self.log.info(
                                "Added new subdirectory to watch: "
                                "%s", subdir)
                        self.log.debug("files: %s", files)

                        for filename in files:
                            # self.log.debug("filename: {}".format(filename))
                            # pylint: disable=no-member
                            if self.mon_regex.match(filename) is None:
                                self.log.debug(
                                    "File does not match monitored "
                                    "regex: %s", filename)
                                self.log.debug("detected events were: %s",
                                               parts)
                                continue

                            event_message = get_event_message(
                                dirpath, filename, self.paths)
                            self.log.debug("event_message: %s", event_message)
                            event_message_list.append(event_message)
#                            self.log.debug("event_message_list: {}"
#                                           .format(event_message_list))
                continue

            # if a directory is renamed the old watch has to be removed
            if is_dir and is_moved_from:

                # self.log.debug("is_dir and is_moved_from")
                # self.log.debug("{} {} {}".format(path, event.name, parts)
                # self.log.debug(event.name)

                dirname = os.path.join(path, event.name)
                found_watch = None
                for watch, watch_path in iteritems(self.wd_to_path):
                    if watch_path == dirname:
                        found_watch = watch
                        break
                inotifyx.rm_watch(self.file_descriptor, found_watch)
                self.log.info("Removed directory from watch: %s", dirname)
                # the IN_MOVE_FROM event always apears before the IN_MOVE_TO
                # (+ additional) events and thus has to be stored till loop
                # is finished
                removed_wd = self.wd_to_path[found_watch]
                # removing the watch out of the dictionary cannot be done
                # inside the loop (would throw error: dictionary changed size
                # during iteration)
                del self.wd_to_path[found_watch]
                continue

            # only files of the configured event type are send
            if (not is_dir and current_mon_event
                    and [path, event.name] not in self.history):

                # only files matching the regex specified with the current
                # event are monitored
                if current_mon_regex.match(event.name) is None:
                    # self.log.debug("File ending not in monitored Suffixes: "
                    #                "%s", event.name)
                    # self.log.debug("detected events were: %s", parts)
                    continue

                event_message = get_event_message(path, event.name, self.paths)
                self.log.debug("event_message %s", event_message)
                event_message_list.append(event_message)

                self.history.append([path, event.name])

        return event_message_list
Exemple #18
0
         # change was in the file we specifically care about. While we
         # have the watch in place we compare the symlink to what was last
         # deployed, if it is different then we don't bother waiting, we
         # just set start_deploy and then loop.
         wd = inotifyx.add_watch(fd, dirname, inotifyx.IN_DELETE)
         if deployed_symlink_value != read_symlink():
             log.info('Symlink changed from "%s" to "%s", deploying.',
                      deployed_symlink_value, read_symlink())
             start_deploy = True
         else:
             events = inotifyx.get_events(fd, 24 * 60 * 60)
             if deployed_symlink_value != read_symlink():
                 log.info('Symlink changed from "%s" to "%s", deploying.',
                          deployed_symlink_value, read_symlink())
                 start_deploy = True
         inotifyx.rm_watch(fd, wd)
     except IOError as e:
         if e.errno == 2:
             # Errno2 is thrown when the file we are attempting to watch
             # does not exist. If this happens then we fall back to a
             # simple sleep loop. Sleep will be interrupted by a signal.
             time.sleep(1)
         elif e.errno == 4:
             # Errno 4 is used when a syscall gets interrupted. This will
             # most likely be due to a signal so we repeat our loop to check
             # the various conditions.
             pass
     finally:
         os.close(fd)
 elif health_check_failures > max_health_check_failures:
     # The stead state health checker has failed too many times in a row.
Exemple #19
0
 def close (self):
     try:
         inotifyx.rm_watch (self.fd, self.wd)
     finally:
         os.close (self.fd)
Exemple #20
0
	def commit(self, **params):
		"""
		Rebuild kevent operations by removing open files that no longer need to
		be watched, and adding new files if they are not currently being watched.

		This is done by comparing self.paths to self.paths_open.
	"""
		log = self._getparam('log', self._discard, **params)

		#  Find all the modules that no longer need watching
		#
		removed = 0
		added = 0
		for path in list(self.paths_open):
			if path not in self.paths:
				fd = self.paths_open[path]
				if self._mode == WF_KQUEUE:
					#  kevent automatically deletes the event when the fd is closed
					try:
						os.close(fd)
					except Exception as e:
						log.warning("close failed on watched file '%s' -- %s", path, str(e))
				elif self._mode == WF_INOTIFYX:
					try:
						inotifyx.rm_watch(self._inx_fd, fd)
					except Exception as e:
						log.warning("remove failed on watched file '%s' -- %s", path, str(e))
					if path in self._inx_inode:
						del self._inx_inode[path]
				elif self._mode == WF_POLLING:
					if fd in self._poll_stat:
						del self._poll_stat[fd]
					else:
						log.warning("fd watched path '%s' missing from _poll_stat map", path)
					try:
						os.close(fd)
					except Exception as e:
						log.warning("close failed on watched file '%s' -- %s", path, str(e))
				if fd in self.fds_open:
					del self.fds_open[fd]
				else:
					log.warning("fd watched path '%s' missing from fd map", path)
				del self.paths_open[path]
				log.debug("Removed watch for path '%s'", path)
				removed += 1

		#  Find all the paths that are new and should be watched
		#
		fdlist = []
		failed = []
		last_exc = None
		log.debug("%d watched path%s", len(self.paths), ses(len(self.paths)))
		for path in list(self.paths):
			if path not in self.paths_open:
				try:
					if not self._add_file(path, **params):
						continue
				except Exception as e:
					last_exc = e
					failed.append(path)
					continue
				fdlist.append(self.paths_open[path])

				if path in self.paths_pending:
					log.debug("pending path '%s' has now appeared", path)
					del self.paths_pending[path]
					self._trigger(self.paths_open[path], **params)

				added += 1
				log.debug("Added watch for path '%s' with ident %d", path, self.paths_open[path])
		if failed:
			self._clean_failed_fds(fdlist)
			raise Exception("Failed to set watch on %s -- %s" % (str(failed), str(last_exc)))
		log.debug("%d added, %d removed", added, removed)