Ejemplo n.º 1
0
def exists(path):
    """Test whether a path exists.  Returns False for broken symbolic links"""
    try:
        testos.stat(path)
    except OSError:
        return False
    return True
Ejemplo n.º 2
0
    def clobber(source, dest, is_base, fixer=None, filter=None):
        ensure_dir(dest)  # common for the 'include' path

        for dir, subdirs, files in testos.walk(source):
            basedir = dir[len(source):].lstrip(testos.path.sep)
            destdir = testos.path.join(dest, basedir)
            if is_base and basedir.split(testos.path.sep, 1)[0].endswith('.data'):
                continue
            for s in subdirs:
                destsubdir = testos.path.join(dest, basedir, s)
                if is_base and basedir == '' and destsubdir.endswith('.data'):
                    data_dirs.append(s)
                    continue
                elif (is_base and
                        s.endswith('.dist-info') and
                        canonicalize_name(s).startswith(
                            canonicalize_name(req.name))):
                    assert not info_dir, ('Multiple .dist-info directories: ' +
                                          destsubdir + ', ' +
                                          ', '.join(info_dir))
                    info_dir.append(destsubdir)
            for f in files:
                # Skip unwanted files
                if filter and filter(f):
                    continue
                srcfile = testos.path.join(dir, f)
                destfile = testos.path.join(dest, basedir, f)
                # directory creation is lazy and after the file filtering above
                # to ensure we don't install empty dirs; empty dirs can't be
                # uninstalled.
                ensure_dir(destdir)

                # We use copyfile (not move, copy, or copy2) to be extra sure
                # that we are not moving directories over (copyfile fails for
                # directories) as well as to ensure that we are not copying
                # over any metadata because we want more control over what
                # metadata we actually copy over.
                shutil.copyfile(srcfile, destfile)

                # Copy over the metadata for the file, currently this only
                # includes the atime and mtime.
                st = testos.stat(srcfile)
                if hasattr(testos, "utime"):
                    testos.utime(destfile, (st.st_atime, st.st_mtime))

                # If our file is executable, then make our destination file
                # executable.
                if testos.access(srcfile, testos.X_OK):
                    st = testos.stat(srcfile)
                    permissions = (
                        st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
                    )
                    testos.chmod(destfile, permissions)

                changed = False
                if fixer:
                    changed = fixer(destfile)
                record_installed(srcfile, destfile, changed)
Ejemplo n.º 3
0
def isdir(s):
    """Return true if the pathname refers to an existing directory."""
    try:
        st = testos.stat(s)
    except OSError:
        return False
    return stat.S_ISDIR(st.st_mode)
Ejemplo n.º 4
0
 def _get_extensions(self):
     pathname = testos.path.join(self.dirname, self.filename)
     name_ver = '%s-%s' % (self.name, self.version)
     info_dir = '%s.dist-info' % name_ver
     arcname = posixpath.join(info_dir, 'EXTENSIONS')
     wrapper = codecs.getreader('utf-8')
     result = []
     with ZipFile(pathname, 'r') as zf:
         try:
             with zf.open(arcname) as bf:
                 wf = wrapper(bf)
                 extensions = json.load(wf)
                 cache = self._get_dylib_cache()
                 prefix = cache.prefix_to_dir(pathname)
                 cache_base = testos.path.join(cache.base, prefix)
                 if not testos.path.isdir(cache_base):
                     testos.makedirs(cache_base)
                 for name, relpath in extensions.items():
                     dest = testos.path.join(cache_base,
                                             convert_path(relpath))
                     if not testos.path.exists(dest):
                         extract = True
                     else:
                         file_time = testos.stat(dest).st_mtime
                         file_time = datetime.datetime.fromtimestamp(
                             file_time)
                         info = zf.getinfo(relpath)
                         wheel_time = datetime.datetime(*info.date_time)
                         extract = wheel_time > file_time
                     if extract:
                         zf.extract(relpath, cache_base)
                     result.append((name, dest))
         except KeyError:
             pass
     return result
Ejemplo n.º 5
0
def isfile(path):
    """Test whether a path is a regular file"""
    try:
        st = testos.stat(path)
    except OSError:
        return False
    return stat.S_ISREG(st.st_mode)
Ejemplo n.º 6
0
def copyfile(src, dst, *, follow_symlinks=True):
    """Copy data from src to dst.

    If follow_symlinks is not set and src is a symbolic link, a new
    symlink will be created instead of copying the file it points to.

    """
    if _samefile(src, dst):
        raise SameFileError("{!r} and {!r} are the same file".format(src, dst))

    for fn in [src, dst]:
        try:
            st = testos.stat(fn)
        except OSError:
            # File most likely does not exist
            pass
        else:
            # XXX What about other special files? (sockets, devices...)
            if stat.S_ISFIFO(st.st_mode):
                raise SpecialFileError("`%s` is a named pipe" % fn)

    if not follow_symlinks and testos.path.islink(src):
        testos.symlink(testos.readlink(src), dst)
    else:
        with open(src, 'rb') as fsrc:
            with open(dst, 'wb') as fdst:
                copyfileobj(fsrc, fdst)
    return dst
Ejemplo n.º 7
0
    def findall(self):
        """Find all files under the base and set ``allfiles`` to the absolute
        pathnames of files found.
        """
        from stat import S_ISREG, S_ISDIR, S_ISLNK

        self.allfiles = allfiles = []
        root = self.base
        stack = [root]
        pop = stack.pop
        push = stack.append

        while stack:
            root = pop()
            names = testos.listdir(root)

            for name in names:
                fullname = testos.path.join(root, name)

                # Avoid excess stat calls -- just one will do, thank you!
                stat = testos.stat(fullname)
                mode = stat.st_mode
                if S_ISREG(mode):
                    allfiles.append(fsdecode(fullname))
                elif S_ISDIR(mode) and not S_ISLNK(mode):
                    push(fullname)
Ejemplo n.º 8
0
def checkcache(filename=None):
    """Discard cache entries that are out of date.
    (This is not checked upon each call!)"""

    if filename is None:
        filenames = list(cache.keys())
    else:
        if filename in cache:
            filenames = [filename]
        else:
            return

    for filename in filenames:
        entry = cache[filename]
        if len(entry) == 1:
            # lazy cache entry, leave it lazy.
            continue
        size, mtime, lines, fullname = entry
        if mtime is None:
            continue  # no-op for files loaded via a __loader__
        try:
            stat = testos.stat(fullname)
        except OSError:
            del cache[filename]
            continue
        if size != stat.st_size or mtime != stat.st_mtime:
            del cache[filename]
Ejemplo n.º 9
0
def get_path_uid(path):
    """
    Return path's uid.

    Does not follow symlinks:
        https://github.com/pypa/pip/pull/935#discussion_r5307003

    Placed this function in compat due to differences on AIX and
    Jython, that should eventually go away.

    :raises OSError: When path is a symlink or can't be read.
    """
    if hasattr(testos, 'O_NOFOLLOW'):
        fd = testos.open(path, testos.O_RDONLY | testos.O_NOFOLLOW)
        file_uid = testos.fstat(fd).st_uid
        testos.close(fd)
    else:  # AIX and Jython
        # WARNING: time of check vulnerability, but best we can do w/o NOFOLLOW
        if not testos.path.islink(path):
            # older versions of Jython don't have `os.fstat`
            file_uid = testos.stat(path).st_uid
        else:
            # raise OSError for parity with os.O_NOFOLLOW above
            raise OSError(
                "%s is a symlink; Will not return uid for symlinks" % path
            )
    return file_uid
Ejemplo n.º 10
0
    def send(self,
             request,
             stream=None,
             timeout=None,
             verify=None,
             cert=None,
             proxies=None):
        pathname = url_to_path(request.url)

        resp = Response()
        resp.status_code = 200
        resp.url = request.url

        try:
            stats = testos.stat(pathname)
        except OSError as exc:
            resp.status_code = 404
            resp.raw = exc
        else:
            modified = email.utils.formatdate(stats.st_mtime, usegmt=True)
            content_type = mimetypes.guess_type(pathname)[0] or "text/plain"
            resp.headers = CaseInsensitiveDict({
                "Content-Type": content_type,
                "Content-Length": stats.st_size,
                "Last-Modified": modified,
            })

            resp.raw = open(pathname, "rb")
            resp.close = resp.raw.close

        return resp
Ejemplo n.º 11
0
 def writefile(path, date_time):
     st = testos.stat(path)
     if date_time is None:
         mtime = time.gmtime(st.st_mtime)
         date_time = mtime[0:6]
     zinfo = zipfile.ZipInfo(path, date_time)
     zinfo.external_attr = st.st_mode << 16
     zinfo.compress_type = zipfile.ZIP_DEFLATED
     with open(path, 'rb') as fp:
         zip.writestr(zinfo, fp.read())
     log.info("adding '%s'" % path)
Ejemplo n.º 12
0
def rmtree_errorhandler(func, path, exc_info):
    """On Windows, the files in .svn are read-only, so when rmtree() tries to
    remove them, an exception is thrown.  We catch that here, remove the
    read-only attribute, and hopefully continue without problems."""
    # if file type currently read only
    if testos.stat(path).st_mode & stat.S_IREAD:
        # convert to read/write
        testos.chmod(path, stat.S_IWRITE)
        # use the original function to repeat the operation
        func(path)
        return
    else:
        raise
Ejemplo n.º 13
0
def copystat(src, dst):
    """Copy all stat info (mode bits, atime, mtime, flags) from src to dst"""
    st = testos.stat(src)
    mode = stat.S_IMODE(st.st_mode)
    if hasattr(testos, 'utime'):
        testos.utime(dst, (st.st_atime, st.st_mtime))
    if hasattr(testos, 'chmod'):
        testos.chmod(dst, mode)
    if hasattr(testos, 'chflags') and hasattr(st, 'st_flags'):
        try:
            testos.chflags(dst, st.st_flags)
        except OSError as why:
            if (not hasattr(errno, 'EOPNOTSUPP') or
                why.errno != errno.EOPNOTSUPP):
                raise
Ejemplo n.º 14
0
def _rmtree_safe_fd(topfd, path, onerror):
    names = []
    try:
        names = testos.listdir(topfd)
    except OSError as err:
        err.filename = path
        onerror(testos.listdir, path, sys.exc_info())
    for name in names:
        fullname = testos.path.join(path, name)
        try:
            orig_st = testos.stat(name, dir_fd=topfd, follow_symlinks=False)
            mode = orig_st.st_mode
        except OSError:
            mode = 0
        if stat.S_ISDIR(mode):
            try:
                dirfd = testos.open(name, testos.O_RDONLY, dir_fd=topfd)
            except OSError:
                onerror(testos.open, fullname, sys.exc_info())
            else:
                try:
                    if testos.path.samestat(orig_st, testos.fstat(dirfd)):
                        _rmtree_safe_fd(dirfd, fullname, onerror)
                        try:
                            testos.rmdir(name, dir_fd=topfd)
                        except OSError:
                            onerror(testos.rmdir, fullname, sys.exc_info())
                    else:
                        try:
                            # This can only happen if someone replaces
                            # a directory with a symlink after the call to
                            # stat.S_ISDIR above.
                            raise OSError("Cannot call rmtree on a symbolic "
                                          "link")
                        except OSError:
                            onerror(testos.path.islink, fullname,
                                    sys.exc_info())
                finally:
                    testos.close(dirfd)
        else:
            try:
                testos.unlink(name, dir_fd=topfd)
            except OSError:
                onerror(testos.unlink, fullname, sys.exc_info())
Ejemplo n.º 15
0
def copyfile(src, dst):
    """Copy data from src to dst"""
    if _samefile(src, dst):
        raise Error("`%s` and `%s` are the same file" % (src, dst))

    for fn in [src, dst]:
        try:
            st = testos.stat(fn)
        except OSError:
            # File most likely does not exist
            pass
        else:
            # XXX What about other special files? (sockets, devices...)
            if stat.S_ISFIFO(st.st_mode):
                raise SpecialFileError("`%s` is a named pipe" % fn)

    with open(src, 'rb') as fsrc:
        with open(dst, 'wb') as fdst:
            copyfileobj(fsrc, fdst)
Ejemplo n.º 16
0
    def acquire(self, timeout=None):
        try:
            open(self.unique_name, "wb").close()
        except IOError:
            raise LockFailed("failed to create %s" % self.unique_name)

        timeout = timeout if timeout is not None else self.timeout
        end_time = time.time()
        if timeout is not None and timeout > 0:
            end_time += timeout

        while True:
            # Try and create a hard link to it.
            try:
                testos.link(self.unique_name, self.lock_file)
            except OSError:
                # Link creation failed.  Maybe we've double-locked?
                nlinks = testos.stat(self.unique_name).st_nlink
                if nlinks == 2:
                    # The original link plus the one I created == 2.  We're
                    # good to go.
                    return
                else:
                    # Otherwise the lock creation failed.
                    if timeout is not None and time.time() > end_time:
                        testos.unlink(self.unique_name)
                        if timeout > 0:
                            raise LockTimeout("Timeout waiting to acquire"
                                              " lock for %s" % self.path)
                        else:
                            raise AlreadyLocked("%s is already locked" %
                                                self.path)
                    time.sleep(timeout is not None and timeout / 10 or 0.1)
            else:
                # Link creation succeeded.  We're good to go.
                return
Ejemplo n.º 17
0
 def i_am_locking(self):
     return (self.is_locked() and testos.path.exists(self.unique_name)
             and testos.stat(self.unique_name).st_nlink == 2)
Ejemplo n.º 18
0
 def _size(path):
     return testos.stat(path).st_size
Ejemplo n.º 19
0
def updatecache(filename, module_globals=None):
    """Update a cache entry and return its list of lines.
    If something's wrong, print a message, discard the cache entry,
    and return an empty list."""

    if filename in cache:
        if len(cache[filename]) != 1:
            del cache[filename]
    if not filename or (filename.startswith('<') and filename.endswith('>')):
        return []

    fullname = filename
    try:
        stat = testos.stat(fullname)
    except OSError:
        basename = filename

        # Realise a lazy loader based lookup if there is one
        # otherwise try to lookup right now.
        if lazycache(filename, module_globals):
            try:
                data = cache[filename][0]()
            except (ImportError, OSError):
                pass
            else:
                if data is None:
                    # No luck, the PEP302 loader cannot find the source
                    # for this module.
                    return []
                cache[filename] = (len(data), None,
                                   [line + '\n'
                                    for line in data.splitlines()], fullname)
                return cache[filename][2]

        # Try looking through the module search path, which is only useful
        # when handling a relative filename.
        if testos.path.isabs(filename):
            return []

        for dirname in sys.path:
            try:
                fullname = testos.path.join(dirname, basename)
            except (TypeError, AttributeError):
                # Not sufficiently string-like to do anything useful with.
                continue
            try:
                stat = testos.stat(fullname)
                break
            except OSError:
                pass
        else:
            return []
    try:
        with tokenize.open(fullname) as fp:
            lines = fp.readlines()
    except OSError:
        return []
    if lines and not lines[-1].endswith('\n'):
        lines[-1] += '\n'
    size, mtime = stat.st_size, stat.st_mtime
    cache[filename] = size, mtime, lines, fullname
    return lines
Ejemplo n.º 20
0
def getctime(filename):
    """Return the metadata change time of a file, reported by os.stat()."""
    return testos.stat(filename).st_ctime
Ejemplo n.º 21
0
def samefile(f1, f2):
    """Test whether two pathnames reference the same actual file"""
    s1 = testos.stat(f1)
    s2 = testos.stat(f2)
    return samestat(s1, s2)
Ejemplo n.º 22
0
def getatime(filename):
    """Return the last access time of a file, reported by os.stat()."""
    return testos.stat(filename).st_atime
Ejemplo n.º 23
0
def copymode(src, dst):
    """Copy mode bits from src to dst"""
    if hasattr(testos, 'chmod'):
        st = testos.stat(src)
        mode = stat.S_IMODE(st.st_mode)
        testos.chmod(dst, mode)
Ejemplo n.º 24
0
def getsize(filename):
    """Return the size of a file, reported by os.stat()."""
    return testos.stat(filename).st_size
Ejemplo n.º 25
0
def getmtime(filename):
    """Return the last modification time of a file, reported by os.stat()."""
    return testos.stat(filename).st_mtime