##// END OF EJS Templates
dirstate: move parent state handling in the dirstatemap...
dirstate: move parent state handling in the dirstatemap This involves dirstatemap data mostly. Moving this one level down will remove the needs for the dirstatemap to expose some of its internals. This will help us to simplify more code further. Differential Revision: https://phab.mercurial-scm.org/D11505

File last commit:

r47575:d4ba4d51 default
r48873:5d68c4ee default
Show More
osutil.py
305 lines | 9.3 KiB | text/x-python | PythonLexer
Martin Geisler
pure/osutil: add copyright and license header
r8232 # osutil.py - pure Python version of osutil.c
#
Raphaël Gomès
contributor: change mentions of mpm to olivia...
r47575 # Copyright 2009 Olivia Mackall <olivia@selenic.com> and others
Martin Geisler
pure/osutil: add copyright and license header
r8232 #
# This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Martin Geisler
pure/osutil: add copyright and license header
r8232
Rodrigo Damazio Bovendorp
py3: use integer division for the value passed to xrange...
r42724 from __future__ import absolute_import, division
Gregory Szorc
osutil: use absolute_import
r27338
Yuya Nishihara
osutil: implement pure version of recvfds() for PyPy...
r27474 import ctypes
import ctypes.util
Martin Geisler
move mercurial.osutil to mercurial.pure.osutil
r7704 import os
Yuya Nishihara
osutil: implement pure version of recvfds() for PyPy...
r27474 import socket
Benoit Boissinot
style: use consistent variable names (*mod) with imports which would shadow
r10651 import stat as statmod
Martin Geisler
move mercurial.osutil to mercurial.pure.osutil
r7704
Gregory Szorc
py3: manually import getattr where it is needed...
r43359 from ..pycompat import getattr
Yuya Nishihara
osutil: switch to policy importer...
r32367 from .. import (
Matt Harbison
py3: fix str vs bytes in enough places to run `hg version` on Windows...
r39680 encoding,
Pulkit Goyal
py3: use pycompat.ossep at certain places...
r30304 pycompat,
)
Augie Fackler
formatting: blacken the codebase...
r43346
Martin Geisler
move mercurial.osutil to mercurial.pure.osutil
r7704 def _mode_to_kind(mode):
Benoit Boissinot
style: use consistent variable names (*mod) with imports which would shadow
r10651 if statmod.S_ISREG(mode):
return statmod.S_IFREG
if statmod.S_ISDIR(mode):
return statmod.S_IFDIR
if statmod.S_ISLNK(mode):
return statmod.S_IFLNK
if statmod.S_ISBLK(mode):
return statmod.S_IFBLK
if statmod.S_ISCHR(mode):
return statmod.S_IFCHR
if statmod.S_ISFIFO(mode):
return statmod.S_IFIFO
if statmod.S_ISSOCK(mode):
return statmod.S_IFSOCK
Martin Geisler
move mercurial.osutil to mercurial.pure.osutil
r7704 return mode
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
cffi: split modules from pure...
r32512 def listdir(path, stat=False, skip=None):
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """listdir(path, stat=False) -> list_of_tuples
Martin Geisler
move mercurial.osutil to mercurial.pure.osutil
r7704
Return a sorted list containing information about the entries
in the directory.
If stat is True, each element is a 3-tuple:
(name, type, stat object)
Otherwise, each element is a 2-tuple:
(name, type)
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """
Martin Geisler
move mercurial.osutil to mercurial.pure.osutil
r7704 result = []
prefix = path
Pulkit Goyal
py3: use pycompat.ossep at certain places...
r30304 if not prefix.endswith(pycompat.ossep):
prefix += pycompat.ossep
Martin Geisler
move mercurial.osutil to mercurial.pure.osutil
r7704 names = os.listdir(path)
names.sort()
for fn in names:
st = os.lstat(prefix + fn)
Benoit Boissinot
style: use consistent variable names (*mod) with imports which would shadow
r10651 if fn == skip and statmod.S_ISDIR(st.st_mode):
Martin Geisler
move mercurial.osutil to mercurial.pure.osutil
r7704 return []
if stat:
result.append((fn, _mode_to_kind(st.st_mode), st))
else:
result.append((fn, _mode_to_kind(st.st_mode)))
return result
Sune Foldager
posixfile: remove posixfile_nt and fix import bug in windows.py...
r8421
Augie Fackler
formatting: blacken the codebase...
r43346
Jun Wu
codemod: use pycompat.iswindows...
r34646 if not pycompat.iswindows:
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413 posixfile = open
Yuya Nishihara
osutil: implement pure version of recvfds() for PyPy...
r27474
_SCM_RIGHTS = 0x01
_socklen_t = ctypes.c_uint
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if pycompat.sysplatform.startswith(b'linux'):
Yuya Nishihara
osutil: implement pure version of recvfds() for PyPy...
r27474 # socket.h says "the type should be socklen_t but the definition of
# the kernel is incompatible with this."
_cmsg_len_t = ctypes.c_size_t
_msg_controllen_t = ctypes.c_size_t
_msg_iovlen_t = ctypes.c_size_t
else:
_cmsg_len_t = _socklen_t
_msg_controllen_t = _socklen_t
_msg_iovlen_t = ctypes.c_int
class _iovec(ctypes.Structure):
_fields_ = [
Pulkit Goyal
py3: use unicode literals in pure/osutil.py...
r29698 (u'iov_base', ctypes.c_void_p),
(u'iov_len', ctypes.c_size_t),
Yuya Nishihara
osutil: implement pure version of recvfds() for PyPy...
r27474 ]
class _msghdr(ctypes.Structure):
_fields_ = [
Pulkit Goyal
py3: use unicode literals in pure/osutil.py...
r29698 (u'msg_name', ctypes.c_void_p),
(u'msg_namelen', _socklen_t),
(u'msg_iov', ctypes.POINTER(_iovec)),
(u'msg_iovlen', _msg_iovlen_t),
(u'msg_control', ctypes.c_void_p),
(u'msg_controllen', _msg_controllen_t),
(u'msg_flags', ctypes.c_int),
Yuya Nishihara
osutil: implement pure version of recvfds() for PyPy...
r27474 ]
class _cmsghdr(ctypes.Structure):
_fields_ = [
Pulkit Goyal
py3: use unicode literals in pure/osutil.py...
r29698 (u'cmsg_len', _cmsg_len_t),
(u'cmsg_level', ctypes.c_int),
(u'cmsg_type', ctypes.c_int),
(u'cmsg_data', ctypes.c_ubyte * 0),
Yuya Nishihara
osutil: implement pure version of recvfds() for PyPy...
r27474 ]
Pulkit Goyal
py3: use unicode literals in pure/osutil.py...
r29698 _libc = ctypes.CDLL(ctypes.util.find_library(u'c'), use_errno=True)
Yuya Nishihara
osutil: do not abort loading pure module just because libc has no recvmsg()...
r27971 _recvmsg = getattr(_libc, 'recvmsg', None)
if _recvmsg:
_recvmsg.restype = getattr(ctypes, 'c_ssize_t', ctypes.c_long)
Augie Fackler
formatting: blacken the codebase...
r43346 _recvmsg.argtypes = (
ctypes.c_int,
ctypes.POINTER(_msghdr),
ctypes.c_int,
)
Yuya Nishihara
osutil: do not abort loading pure module just because libc has no recvmsg()...
r27971 else:
# recvmsg isn't always provided by libc; such systems are unsupported
def _recvmsg(sockfd, msg, flags):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise NotImplementedError(b'unsupported platform')
Yuya Nishihara
osutil: implement pure version of recvfds() for PyPy...
r27474
def _CMSG_FIRSTHDR(msgh):
if msgh.msg_controllen < ctypes.sizeof(_cmsghdr):
return
cmsgptr = ctypes.cast(msgh.msg_control, ctypes.POINTER(_cmsghdr))
return cmsgptr.contents
# The pure version is less portable than the native version because the
# handling of socket ancillary data heavily depends on C preprocessor.
# Also, some length fields are wrongly typed in Linux kernel.
def recvfds(sockfd):
"""receive list of file descriptors via socket"""
dummy = (ctypes.c_ubyte * 1)()
iov = _iovec(ctypes.cast(dummy, ctypes.c_void_p), ctypes.sizeof(dummy))
cbuf = ctypes.create_string_buffer(256)
Augie Fackler
formatting: blacken the codebase...
r43346 msgh = _msghdr(
None,
0,
ctypes.pointer(iov),
1,
ctypes.cast(cbuf, ctypes.c_void_p),
ctypes.sizeof(cbuf),
0,
)
Yuya Nishihara
osutil: implement pure version of recvfds() for PyPy...
r27474 r = _recvmsg(sockfd, ctypes.byref(msgh), 0)
if r < 0:
e = ctypes.get_errno()
raise OSError(e, os.strerror(e))
# assumes that the first cmsg has fds because it isn't easy to write
# portable CMSG_NXTHDR() with ctypes.
cmsg = _CMSG_FIRSTHDR(msgh)
if not cmsg:
return []
Augie Fackler
formatting: blacken the codebase...
r43346 if (
cmsg.cmsg_level != socket.SOL_SOCKET
or cmsg.cmsg_type != _SCM_RIGHTS
):
Yuya Nishihara
osutil: implement pure version of recvfds() for PyPy...
r27474 return []
rfds = ctypes.cast(cmsg.cmsg_data, ctypes.POINTER(ctypes.c_int))
Augie Fackler
formatting: blacken the codebase...
r43346 rfdscount = (
cmsg.cmsg_len - _cmsghdr.cmsg_data.offset
) // ctypes.sizeof(ctypes.c_int)
Gregory Szorc
global: use pycompat.xrange()...
r38806 return [rfds[i] for i in pycompat.xrange(rfdscount)]
Yuya Nishihara
osutil: implement pure version of recvfds() for PyPy...
r27474
Augie Fackler
formatting: blacken the codebase...
r43346
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413 else:
Gregory Szorc
osutil: use absolute_import
r27338 import msvcrt
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413
Matt Harbison
typing: disable module attribute warnings for properly conditionalized code...
r47544 _kernel32 = ctypes.windll.kernel32 # pytype: disable=module-attr
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413
_DWORD = ctypes.c_ulong
_LPCSTR = _LPSTR = ctypes.c_char_p
_HANDLE = ctypes.c_void_p
_INVALID_HANDLE_VALUE = _HANDLE(-1).value
Mads Kiilerich
check-code: catch trailing space in comments
r18959 # CreateFile
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413 _FILE_SHARE_READ = 0x00000001
_FILE_SHARE_WRITE = 0x00000002
_FILE_SHARE_DELETE = 0x00000004
_CREATE_ALWAYS = 2
_OPEN_EXISTING = 3
_OPEN_ALWAYS = 4
_GENERIC_READ = 0x80000000
_GENERIC_WRITE = 0x40000000
_FILE_ATTRIBUTE_NORMAL = 0x80
Mads Kiilerich
declare local constants instead of using magic values and comments
r17429 # open_osfhandle flags
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413 _O_RDONLY = 0x0000
_O_RDWR = 0x0002
_O_APPEND = 0x0008
_O_TEXT = 0x4000
_O_BINARY = 0x8000
# types of parameters of C functions used (required by pypy)
Augie Fackler
formatting: blacken the codebase...
r43346 _kernel32.CreateFileA.argtypes = [
_LPCSTR,
_DWORD,
_DWORD,
ctypes.c_void_p,
_DWORD,
_DWORD,
_HANDLE,
]
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413 _kernel32.CreateFileA.restype = _HANDLE
def _raiseioerror(name):
Matt Harbison
typing: disable module attribute warnings for properly conditionalized code...
r47544 err = ctypes.WinError() # pytype: disable=module-attr
Augie Fackler
formatting: blacken the codebase...
r43346 raise IOError(
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 err.errno, '%s: %s' % (encoding.strfromlocal(name), err.strerror)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413
class posixfile(object):
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """a file object aiming for POSIX-like semantics
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413
CPython's open() returns a file that was opened *without* setting the
_FILE_SHARE_DELETE flag, which causes rename and unlink to abort.
This even happens if any hardlinked copy of the file is in open state.
We set _FILE_SHARE_DELETE here, so files opened with posixfile can be
renamed and deleted while they are held open.
Note that if a file opened with posixfile is unlinked, the file
remains but cannot be opened again or be recreated under the same name,
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 until all reading processes have closed the file."""
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413
Matt Harbison
py3: fix str vs bytes in enough places to run `hg version` on Windows...
r39680 def __init__(self, name, mode=b'r', bufsize=-1):
if b'b' in mode:
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413 flags = _O_BINARY
else:
flags = _O_TEXT
Matt Harbison
py3: fix str vs bytes in enough places to run `hg version` on Windows...
r39680 m0 = mode[0:1]
if m0 == b'r' and b'+' not in mode:
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413 flags |= _O_RDONLY
access = _GENERIC_READ
else:
# work around http://support.microsoft.com/kb/899149 and
# set _O_RDWR for 'w' and 'a', even if mode has no '+'
flags |= _O_RDWR
access = _GENERIC_READ | _GENERIC_WRITE
Matt Harbison
py3: fix str vs bytes in enough places to run `hg version` on Windows...
r39680 if m0 == b'r':
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413 creation = _OPEN_EXISTING
Matt Harbison
py3: fix str vs bytes in enough places to run `hg version` on Windows...
r39680 elif m0 == b'w':
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413 creation = _CREATE_ALWAYS
Matt Harbison
py3: fix str vs bytes in enough places to run `hg version` on Windows...
r39680 elif m0 == b'a':
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413 creation = _OPEN_ALWAYS
flags |= _O_APPEND
else:
Augie Fackler
cleanup: remove pointless r-prefixes on double-quoted strings...
r43809 raise ValueError("invalid mode: %s" % pycompat.sysstr(mode))
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413
Augie Fackler
formatting: blacken the codebase...
r43346 fh = _kernel32.CreateFileA(
name,
access,
_FILE_SHARE_READ | _FILE_SHARE_WRITE | _FILE_SHARE_DELETE,
None,
creation,
_FILE_ATTRIBUTE_NORMAL,
None,
)
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413 if fh == _INVALID_HANDLE_VALUE:
_raiseioerror(name)
Matt Harbison
typing: disable module attribute warnings for properly conditionalized code...
r47544 fd = msvcrt.open_osfhandle(fh, flags) # pytype: disable=module-attr
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413 if fd == -1:
_kernel32.CloseHandle(fh)
_raiseioerror(name)
Pulkit Goyal
py3: convert the mode argument of os.fdopen to unicodes (2 of 2)
r30925 f = os.fdopen(fd, pycompat.sysstr(mode), bufsize)
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413 # unfortunately, f.name is '<fdopen>' at this point -- so we store
# the name on this wrapper. We cannot just assign to f.name,
# because that attribute is read-only.
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 object.__setattr__(self, 'name', name)
object.__setattr__(self, '_file', f)
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413
def __iter__(self):
return self._file
def __getattr__(self, name):
return getattr(self._file, name)
def __setattr__(self, name, value):
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """mimics the read-only attributes of Python file objects
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413 by raising 'TypeError: readonly attribute' if someone tries:
f = posixfile('foo.txt')
Augie Fackler
osutil: reformat triple-quoted string so black doesn't confuse itself...
r46553 f.name = 'bla'
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """
Adrian Buehlmann
pure: provide more correct implementation of posixfile for Windows...
r14413 return self._file.__setattr__(name, value)
Gregory Szorc
osutil: implement __enter__ and __exit__ on posixfile...
r27704
def __enter__(self):
Matt Harbison
windows: ensure pure posixfile fd doesn't escape by entering context manager...
r40976 self._file.__enter__()
return self
Gregory Szorc
osutil: implement __enter__ and __exit__ on posixfile...
r27704
def __exit__(self, exc_type, exc_value, exc_tb):
return self._file.__exit__(exc_type, exc_value, exc_tb)