Patchwork [1,of,3] win32: add a method to fetch the state of a named pipe

login
register
mail settings
Submitter Matt Harbison
Date April 7, 2015, 2:49 a.m.
Message ID <a2904b4de0c3852644c3.1428374940@Envy>
Download mbox | patch
Permalink /patch/8524/
State Superseded
Headers show

Comments

Matt Harbison - April 7, 2015, 2:49 a.m.
# HG changeset patch
# User Matt Harbison <matt_harbison@yahoo.com>
# Date 1428372434 14400
#      Mon Apr 06 22:07:14 2015 -0400
# Node ID a2904b4de0c3852644c3021901739da23e41e543
# Parent  b2fb1403994e033584aed8a487ab162a9d75fa80
win32: add a method to fetch the state of a named pipe

This will be used in an upcoming patch to do nonblocking reads from the child
process, like on posix platforms.   GetExitCodeProcess() uses ctypes.c_void_p
for LPDWORD, so that is used here too.

Patch

diff --git a/mercurial/win32.py b/mercurial/win32.py
--- a/mercurial/win32.py
+++ b/mercurial/win32.py
@@ -5,7 +5,7 @@ 
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-import ctypes, errno, os, subprocess, random
+import ctypes, errno, msvcrt, os, subprocess, random
 
 _kernel32 = ctypes.windll.kernel32
 _advapi32 = ctypes.windll.advapi32
@@ -174,6 +174,10 @@ 
 _kernel32.GetModuleFileNameA.argtypes = [_HANDLE, ctypes.c_void_p, _DWORD]
 _kernel32.GetModuleFileNameA.restype = _DWORD
 
+_kernel32.GetNamedPipeHandleStateA.argtypes = [_HANDLE, ctypes.c_void_p,
+    ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, _LPSTR, _DWORD]
+_kernel32.GetNamedPipeHandleStateA.restype = _BOOL
+
 _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]
@@ -235,6 +239,19 @@ 
     finally:
         _kernel32.CloseHandle(fh)
 
+def getpipestate(pipe):
+    handle = msvcrt.get_osfhandle(pipe.fileno())
+    if handle == -1:
+        raise ctypes.WinError()
+
+    state = _DWORD()
+
+    if not _kernel32.GetNamedPipeHandleStateA(handle, ctypes.byref(state), None,
+                                              None, None, None, 0):
+        raise ctypes.WinError()
+
+    return state.value
+
 def oslink(src, dst):
     try:
         if not _kernel32.CreateHardLinkA(dst, src, None):