def __open_file_by_path(self, file_path, starting_inode=None):
        """Open the file at the specified path and return a file handle and the inode for the file

        Some work is done to ensure that returned inode actually is for the file represented by the file handle.

        @param file_path: The path of the file to open
        @param starting_inode: If not None, then the expected inode of the file.  This is used as a hint, but does
            not guarantee the returned inode will match this.

        @type file_path: str
        @type starting_inode: int

        @return: A tuple of the file handle, the size, and the current inode of the file at that path.
        @rtype: (FileIO, int, int)
        """
        pending_file = None
        try:
            attempts_left = 3

            try:
                # Because there is no atomic way to open a file and get its inode, we have to do a little bit of
                # extra work here.  We look at the inode, open the file, and look at the inode again.. if the
                # inode hasn't changed, then we return it and the file handle.. otherwise, we try again.  We
                # only try three times at most.
                while attempts_left > 0:
                    if starting_inode is None and self.__file_system.trust_inodes:
                        starting_inode = self.__file_system.stat(file_path).st_ino
                    pending_file = self.__file_system.open(file_path)
                    second_stat = self.__file_system.stat(file_path)

                    if not self.__file_system.trust_inodes or starting_inode == second_stat.st_ino:
                        new_file = pending_file
                        pending_file = None
                        return new_file, second_stat.st_size, second_stat.st_ino

                    pending_file.close()
                    pending_file = None
                    attempts_left -= 1
                    starting_inode = None
            except __HOLE__, error:
                if error.errno == 13:
                    log.warn('Permission denied while attempting to read file \'%s\'', file_path,
                             limit_once_per_x_secs=60, limit_key=('invalid-perm' + file_path))
                else:
                    log.warn('Error seen while attempting to read file \'%s\' with errno=%d', file_path, error.errno,
                             limit_once_per_x_secs=60, limit_key=('unknown-io' + file_path))
                return None, None, None
            except OSError, e:
                if e.errno == errno.ENOENT:
                    log.warn('File unexpectantly missing when trying open it')
                else:
                    log.warn('OSError seen while attempting to read file \'%s\' with errno=%d', file_path, e.errno,
                             limit_once_per_x_secs=60, limit_key=('unknown-os' + file_path))
                return None, None, None
        finally:
            if pending_file is not None:
                pending_file.close()

        return None, None, None
dataset/ETHPy150Open scalyr/scalyr-agent-2/scalyr_agent/log_processing.py/LogFileIterator.__open_file_by_path