Mercurial > hg
changeset 14345:bf9a105aed0a
win32.py: add argtypes and restype
This is a feature of ctypes. Without these, pypy complains with
RuntimeWarning: C function without declared arguments called
RuntimeWarning: C function without declared return type called
As a side effect of specifying restypes, the return value of e.g. CreateFileA
is now implicitly converted to an instance of _HANDLE, so we also need to
change the definition
_INVALID_HANDLE_VALUE = -1
to
_INVALID_HANDLE_VALUE = _HANDLE(-1).value
Otherwise, tests for equality to _INVALID_HANDLE_VALUE in code like
def _getfileinfo(name):
fh = _kernel32.CreateFileA(name, 0,
_FILE_SHARE_READ | _FILE_SHARE_WRITE | _FILE_SHARE_DELETE,
None, _OPEN_EXISTING, 0, None)
if fh == _INVALID_HANDLE_VALUE:
_raiseoserror(name)
would now fail to detect an invalid handle, which in turn would lead to
exceptions raised with wrong errno values, like e.g.
>>> nlinks('missing.txt')
Traceback (most recent call last):
...
OSError: [Errno 9] missing.txt: The handle is invalid.
instead of the correct (as per this patch and before it)
>>> nlinks('missing.txt')
Traceback (most recent call last):
...
OSError: [Errno 2] missing.txt: The system cannot find the file specified.
author | Adrian Buehlmann <adrian@cadifra.com> |
---|---|
date | Sun, 15 May 2011 21:33:51 +0200 |
parents | e1db8a00188b |
children | bf85c2639700 |
files | mercurial/win32.py |
diffstat | 1 files changed, 87 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/win32.py Sun May 15 21:27:59 2011 +0200 +++ b/mercurial/win32.py Sun May 15 21:33:51 2011 +0200 @@ -9,15 +9,19 @@ import ctypes, errno, os, struct, subprocess, random _kernel32 = ctypes.windll.kernel32 +_advapi32 = ctypes.windll.advapi32 +_user32 = ctypes.windll.user32 _BOOL = ctypes.c_long _WORD = ctypes.c_ushort _DWORD = ctypes.c_ulong +_UINT = ctypes.c_uint +_LONG = ctypes.c_long _LPCSTR = _LPSTR = ctypes.c_char_p _HANDLE = ctypes.c_void_p _HWND = _HANDLE -_INVALID_HANDLE_VALUE = -1 +_INVALID_HANDLE_VALUE = _HANDLE(-1).value # GetLastError _ERROR_SUCCESS = 0 @@ -122,6 +126,81 @@ _STD_ERROR_HANDLE = _DWORD(-12).value +# types of parameters of C functions used (required by pypy) + +_kernel32.CreateFileA.argtypes = [_LPCSTR, _DWORD, _DWORD, ctypes.c_void_p, + _DWORD, _DWORD, _HANDLE] +_kernel32.CreateFileA.restype = _HANDLE + +_kernel32.GetFileInformationByHandle.argtypes = [_HANDLE, ctypes.c_void_p] +_kernel32.GetFileInformationByHandle.restype = _BOOL + +_kernel32.CloseHandle.argtypes = [_HANDLE] +_kernel32.CloseHandle.restype = _BOOL + +_kernel32.CreateHardLinkA.argtypes = [_LPCSTR, _LPCSTR, ctypes.c_void_p] +_kernel32.CreateHardLinkA.restype = _BOOL + +_kernel32.SetFileAttributesA.argtypes = [_LPCSTR, _DWORD] +_kernel32.SetFileAttributesA.restype = _BOOL + +_kernel32.OpenProcess.argtypes = [_DWORD, _BOOL, _DWORD] +_kernel32.OpenProcess.restype = _HANDLE + +_kernel32.GetExitCodeProcess.argtypes = [_HANDLE, ctypes.c_void_p] +_kernel32.GetExitCodeProcess.restype = _BOOL + +_kernel32.GetLastError.argtypes = [] +_kernel32.GetLastError.restype = _DWORD + +_kernel32.GetModuleFileNameA.argtypes = [_HANDLE, ctypes.c_void_p, _DWORD] +_kernel32.GetModuleFileNameA.restype = _DWORD + +_kernel32.CreateProcessA.argtypes = [_LPCSTR, _LPCSTR, ctypes.c_void_p, + ctypes.c_void_p, _BOOL, _DWORD, ctypes.c_void_p, _LPCSTR, ctypes.c_void_p, + ctypes.c_void_p] +_kernel32.CreateProcessA.restype = _BOOL + +_kernel32.ExitProcess.argtypes = [_UINT] +_kernel32.ExitProcess.restype = None + +_kernel32.GetCurrentProcessId.argtypes = [] +_kernel32.GetCurrentProcessId.restype = _DWORD + +_SIGNAL_HANDLER = ctypes.WINFUNCTYPE(_BOOL, _DWORD) +_kernel32.SetConsoleCtrlHandler.argtypes = [_SIGNAL_HANDLER, _BOOL] +_kernel32.SetConsoleCtrlHandler.restype = _BOOL + +_kernel32.GetStdHandle.argtypes = [_DWORD] +_kernel32.GetStdHandle.restype = _HANDLE + +_kernel32.GetConsoleScreenBufferInfo.argtypes = [_HANDLE, ctypes.c_void_p] +_kernel32.GetConsoleScreenBufferInfo.restype = _BOOL + +_advapi32.RegOpenKeyExA.argtypes = [_HANDLE, _LPCSTR, _DWORD, _DWORD, + ctypes.c_void_p] +_advapi32.RegOpenKeyExA.restype = _LONG + +_advapi32.RegQueryValueExA.argtypes = [_HANDLE, _LPCSTR, ctypes.c_void_p, + ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] +_advapi32.RegQueryValueExA.restype = _LONG + +_advapi32.RegCloseKey.argtypes = [_HANDLE] +_advapi32.RegCloseKey.restype = _LONG + +_advapi32.GetUserNameA.argtypes = [ctypes.c_void_p, ctypes.c_void_p] +_advapi32.GetUserNameA.restype = _BOOL + +_user32.GetWindowThreadProcessId.argtypes = [_HANDLE, ctypes.c_void_p] +_user32.GetWindowThreadProcessId.restype = _DWORD + +_user32.ShowWindow.argtypes = [_HANDLE, ctypes.c_int] +_user32.ShowWindow.restype = _BOOL + +_WNDENUMPROC = ctypes.WINFUNCTYPE(_BOOL, _HWND, _LPARAM) +_user32.EnumWindows.argtypes = [_WNDENUMPROC, _LPARAM] +_user32.EnumWindows.restype = _BOOL + def _raiseoserror(name): err = ctypes.WinError() raise OSError(err.errno, '%s: %s' % (name, err.strerror)) @@ -189,7 +268,6 @@ a sequence of scopes to look up in order. Default (CURRENT_USER, LOCAL_MACHINE). ''' - adv = ctypes.windll.advapi32 byref = ctypes.byref if scope is None: scope = (_HKEY_CURRENT_USER, _HKEY_LOCAL_MACHINE) @@ -197,14 +275,14 @@ scope = (scope,) for s in scope: kh = _HANDLE() - res = adv.RegOpenKeyExA(s, key, 0, _KEY_READ, ctypes.byref(kh)) + res = _advapi32.RegOpenKeyExA(s, key, 0, _KEY_READ, ctypes.byref(kh)) if res != _ERROR_SUCCESS: continue try: size = _DWORD(600) type = _DWORD() buf = ctypes.create_string_buffer(size.value + 1) - res = adv.RegQueryValueExA(kh.value, valname, None, + res = _advapi32.RegQueryValueExA(kh.value, valname, None, byref(type), buf, byref(size)) if res != _ERROR_SUCCESS: continue @@ -216,7 +294,7 @@ s = ctypes.string_at(byref(buf), struct.calcsize(fmt)) return struct.unpack(fmt, s)[0] finally: - adv.RegCloseKey(kh.value) + _advapi32.RegCloseKey(kh.value) def executablepath(): '''return full path of hg.exe''' @@ -231,14 +309,12 @@ def getuser(): '''return name of current user''' - adv = ctypes.windll.advapi32 size = _DWORD(300) buf = ctypes.create_string_buffer(size.value + 1) - if not adv.GetUserNameA(ctypes.byref(buf), ctypes.byref(size)): + if not _advapi32.GetUserNameA(ctypes.byref(buf), ctypes.byref(size)): raise ctypes.WinError() return buf.value -_SIGNAL_HANDLER = ctypes.WINFUNCTYPE(_BOOL, _DWORD) _signalhandler = [] def setsignalhandler(): @@ -256,21 +332,18 @@ if not _kernel32.SetConsoleCtrlHandler(h, True): raise ctypes.WinError() -_WNDENUMPROC = ctypes.WINFUNCTYPE(_BOOL, _HWND, _LPARAM) - def hidewindow(): - user32 = ctypes.windll.user32 def callback(hwnd, pid): wpid = _DWORD() - user32.GetWindowThreadProcessId(hwnd, ctypes.byref(wpid)) + _user32.GetWindowThreadProcessId(hwnd, ctypes.byref(wpid)) if pid == wpid.value: - user32.ShowWindow(hwnd, _SW_HIDE) + _user32.ShowWindow(hwnd, _SW_HIDE) return False # stop enumerating windows return True pid = _kernel32.GetCurrentProcessId() - user32.EnumWindows(_WNDENUMPROC(callback), pid) + _user32.EnumWindows(_WNDENUMPROC(callback), pid) def termwidth(): # cmd.exe does not handle CR like a unix console, the CR is