[PATCH 1 of 5] port win32.py to using the Python ctypes library
Patrick Mézard
pmezard at gmail.com
Sun Feb 13 07:53:12 CST 2011
Le 13/02/11 14:07, Adrian Buehlmann a écrit :
> On 2011-02-13 12:39, Patrick Mézard wrote:
>> Le 08/02/11 17:52, Adrian Buehlmann a écrit :
>>> # HG changeset patch
>>> # User Adrian Buehlmann <adrian at cadifra.com>
>>> # Date 1297121623 -3600
>>> # Node ID 3ba4920422e9abcdc8b8634c5c12c68051286a8c
>>> # Parent 69e69b131458023d21ec40aa48fc5299e43ce69b
>>> port win32.py to using the Python ctypes library
[...]
>>> + adv.RegCloseKey(kh.value)
>>>
>>> def system_rcpath_win32():
>>> '''return default os-specific hgrc search path'''
>>> - filename = win32api.GetModuleFileName(0)
>>> + rcpath = []
>>> + size = 600
>>> + buf = ctypes.create_string_buffer(size + 1)
>>> + len = _kernel32.GetModuleFileNameA(None, ctypes.byref(buf), size)
>>> + if not len:
>>
>> This should check the case where buf is too small, testing if len == size should be good enough.
>>
>> http://msdn.microsoft.com/en-us/library/ms683197(VS.85).aspx
>
> Sounds a bit difficult to me to put an exe in a path location with a path length
>> 600 on a file system if the OS' maximum path length is 260.
>
> Can an exe be started from a path longer than 260?
>
> After all, the buffer has a size of 600...
>
> But adding a check for truncation is certainly an improvement and won't harm.
>
> FWIW, GetModuleFileNameA will never write more than size chars, so it's not like
> we are talking about a potential buffer overrun case here (truncation at worst).
I was just worried about NUL termination. It is not clear to me whether ctypes.create_string_buffer() zero-initialize the returned buffer (it is not mentioned in the doc) and I don't know what happens if we try to read it as a string while no NUL terminated. Avoiding it entirely just sound less work to me than trying to answer these questions.
> (although it's quite beyond comprehension why Microsoft returns success on
> GetModuleFileNameA if the target buffer is too small)
Yes, I felt the need to skim the MSDN entry (at least the "Return Value" part) for every function you wrapped. Win32 API is such a minefield...
[...]
>>> +_SIGNAL_HANDLER = ctypes.WINFUNCTYPE(_BOOL, _DWORD)
>>> +_signal_handler = []
>>>
>>> def set_signal_handler_win32():
>>> - """Register a termination handler for console events including
>>> + '''Register a termination handler for console events including
>>> CTRL+C. python signal handlers do not work well with socket
>>> operations.
>>> - """
>>> + '''
>>> def handler(event):
>>> - win32process.ExitProcess(1)
>>> - win32api.SetConsoleCtrlHandler(handler)
>>> + _kernel32.ExitProcess(1)
>>> +
>>> + if _signal_handler:
>>> + return # already registered
>>
>> (This behaviour change could have gone in another patch too, unless the ctypes version does behave differently than the pywin32 one.)
>
> What behavior change?
The part about not-registering the handler more than once. Perhaps pywin32 was doing it. When reading the code, it just appeared like an additional feature, and I am not sure it is completely necessary given the handler already ExitProcess(). But I may be missing something.
--
Patrick Mézard
More information about the Mercurial-devel
mailing list