mercurial/cffi/osutil.py
author Martin von Zweigbergk <martinvonz@google.com>
Fri, 20 Nov 2020 13:24:45 -0800
changeset 45886 18489e26d9a0
parent 43077 687b865b95ad
child 46785 521ac0d7047f
permissions -rw-r--r--
tests: make doctests not depend on str(ParseError()) format `ParseError` implements `__bytes__`, but it doesn't implement `__str__`, so it gets the default `__str__` implementation. The next patch will make it so `ParseError` gets a `__str__` implementation, which changes the format slightly. This prepares by making us not depend on the format. Differential Revision: https://phab.mercurial-scm.org/D9349
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
32512
0e8b0b9a7acc cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents: 32506
diff changeset
     1
# osutil.py - CFFI version of osutil.c
8232
823f25b25dea pure/osutil: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 7704
diff changeset
     2
#
32512
0e8b0b9a7acc cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents: 32506
diff changeset
     3
# Copyright 2016 Maciej Fijalkowski <fijall@gmail.com>
8232
823f25b25dea pure/osutil: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 7704
diff changeset
     4
#
823f25b25dea pure/osutil: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 7704
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9031
diff changeset
     6
# GNU General Public License version 2 or any later version.
8232
823f25b25dea pure/osutil: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 7704
diff changeset
     7
27338
810337ae1b76 osutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25645
diff changeset
     8
from __future__ import absolute_import
810337ae1b76 osutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25645
diff changeset
     9
7704
30d1d313370b move mercurial.osutil to mercurial.pure.osutil
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    10
import os
10651
5f091fc1bab7 style: use consistent variable names (*mod) with imports which would shadow
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
    11
import stat as statmod
7704
30d1d313370b move mercurial.osutil to mercurial.pure.osutil
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    12
32512
0e8b0b9a7acc cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents: 32506
diff changeset
    13
from ..pure.osutil import *
0e8b0b9a7acc cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents: 32506
diff changeset
    14
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    15
from .. import pycompat
30304
ba2c04059317 py3: use pycompat.ossep at certain places
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29821
diff changeset
    16
34647
dacfcdd8b94e codemod: use pycompat.isdarwin
Jun Wu <quark@fb.com>
parents: 33572
diff changeset
    17
if pycompat.isdarwin:
32512
0e8b0b9a7acc cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents: 32506
diff changeset
    18
    from . import _osutil
7704
30d1d313370b move mercurial.osutil to mercurial.pure.osutil
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    19
32512
0e8b0b9a7acc cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents: 32506
diff changeset
    20
    ffi = _osutil.ffi
0e8b0b9a7acc cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents: 32506
diff changeset
    21
    lib = _osutil.lib
7704
30d1d313370b move mercurial.osutil to mercurial.pure.osutil
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
    22
29600
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    23
    listdir_batch_size = 4096
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    24
    # tweakable number, only affects performance, which chunks
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    25
    # of bytes do we get back from getattrlistbulk
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    26
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    27
    attrkinds = [None] * 20  # we need the max no for enum VXXX, 20 is plenty
29600
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    28
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    29
    attrkinds[lib.VREG] = statmod.S_IFREG
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    30
    attrkinds[lib.VDIR] = statmod.S_IFDIR
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    31
    attrkinds[lib.VLNK] = statmod.S_IFLNK
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    32
    attrkinds[lib.VBLK] = statmod.S_IFBLK
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    33
    attrkinds[lib.VCHR] = statmod.S_IFCHR
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    34
    attrkinds[lib.VFIFO] = statmod.S_IFIFO
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    35
    attrkinds[lib.VSOCK] = statmod.S_IFSOCK
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    36
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    37
    class stat_res(object):
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    38
        def __init__(self, st_mode, st_mtime, st_size):
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    39
            self.st_mode = st_mode
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    40
            self.st_mtime = st_mtime
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    41
            self.st_size = st_size
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    42
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    43
    tv_sec_ofs = ffi.offsetof(b"struct timespec", b"tv_sec")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    44
    buf = ffi.new(b"char[]", listdir_batch_size)
29600
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    45
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    46
    def listdirinternal(dfd, req, stat, skip):
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    47
        ret = []
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    48
        while True:
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    49
            r = lib.getattrlistbulk(dfd, req, buf, listdir_batch_size, 0)
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    50
            if r == 0:
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    51
                break
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    52
            if r == -1:
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    53
                raise OSError(ffi.errno, os.strerror(ffi.errno))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    54
            cur = ffi.cast(b"val_attrs_t*", buf)
29600
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    55
            for i in range(r):
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    56
                lgt = cur.length
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    57
                assert lgt == ffi.cast(b'uint32_t*', cur)[0]
29600
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    58
                ofs = cur.name_info.attr_dataoffset
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    59
                str_lgt = cur.name_info.attr_length
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    60
                base_ofs = ffi.offsetof(b'val_attrs_t', b'name_info')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    61
                name = str(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    62
                    ffi.buffer(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    63
                        ffi.cast(b"char*", cur) + base_ofs + ofs, str_lgt - 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    64
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    65
                )
29600
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    66
                tp = attrkinds[cur.obj_type]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    67
                if name == b"." or name == b"..":
29600
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    68
                    continue
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    69
                if skip == name and tp == statmod.S_ISDIR:
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    70
                    return []
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    71
                if stat:
29821
8656dcac4ce9 osutil: fix the bug on OS X when we return more in listdir
Maciej Fijalkowski <fijall@gmail.com>
parents: 29698
diff changeset
    72
                    mtime = cur.mtime.tv_sec
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    73
                    mode = (cur.accessmask & ~lib.S_IFMT) | tp
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    74
                    ret.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    75
                        (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    76
                            name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    77
                            tp,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    78
                            stat_res(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    79
                                st_mode=mode,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    80
                                st_mtime=mtime,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    81
                                st_size=cur.datalength,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    82
                            ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    83
                        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    84
                    )
29600
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    85
                else:
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    86
                    ret.append((name, tp))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    87
                cur = ffi.cast(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    88
                    b"val_attrs_t*", int(ffi.cast(b"intptr_t", cur)) + lgt
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    89
                )
29600
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    90
        return ret
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    91
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    92
    def listdir(path, stat=False, skip=None):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    93
        req = ffi.new(b"struct attrlist*")
29600
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
    94
        req.bitmapcount = lib.ATTR_BIT_MAP_COUNT
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    95
        req.commonattr = (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    96
            lib.ATTR_CMN_RETURNED_ATTRS
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    97
            | lib.ATTR_CMN_NAME
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    98
            | lib.ATTR_CMN_OBJTYPE
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
    99
            | lib.ATTR_CMN_ACCESSMASK
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
   100
            | lib.ATTR_CMN_MODTIME
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
   101
        )
29600
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
   102
        req.fileattr = lib.ATTR_FILE_DATALENGTH
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
   103
        dfd = lib.open(path, lib.O_RDONLY, 0)
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
   104
        if dfd == -1:
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
   105
            raise OSError(ffi.errno, os.strerror(ffi.errno))
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
   106
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
   107
        try:
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
   108
            ret = listdirinternal(dfd, req, stat, skip)
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
   109
        finally:
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
   110
            try:
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
   111
                lib.close(dfd)
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
   112
            except BaseException:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
   113
                pass  # we ignore all the errors from closing, not
29600
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
   114
                # much we can do about that
7a157639b8f2 osutil: add darwin-only version of os.listdir using cffi
Maciej Fijalkowski <fijall@gmail.com>
parents: 27971
diff changeset
   115
        return ret