##// END OF EJS Templates
win32: spawndetached returns pid of detached process and not of cmd.exe...
Simon Heimberg -
r20425:ca6aa836 default
parent child Browse files
Show More
@@ -119,6 +119,27 b' class _CONSOLE_SCREEN_BUFFER_INFO(ctypes'
119
119
120 _STD_ERROR_HANDLE = _DWORD(-12).value
120 _STD_ERROR_HANDLE = _DWORD(-12).value
121
121
122 # CreateToolhelp32Snapshot, Process32First, Process32Next
123 _TH32CS_SNAPPROCESS = 0x00000002
124 _MAX_PATH = 260
125
126 class _tagPROCESSENTRY32(ctypes.Structure):
127 _fields_ = [('dwsize', _DWORD),
128 ('cntUsage', _DWORD),
129 ('th32ProcessID', _DWORD),
130 ('th32DefaultHeapID', ctypes.c_void_p),
131 ('th32ModuleID', _DWORD),
132 ('cntThreads', _DWORD),
133 ('th32ParentProcessID', _DWORD),
134 ('pcPriClassBase', _LONG),
135 ('dwFlags', _DWORD),
136 ('szExeFile', ctypes.c_char * _MAX_PATH)]
137
138 def __init__(self):
139 super(_tagPROCESSENTRY32, self).__init__()
140 self.dwsize = ctypes.sizeof(self)
141
142
122 # types of parameters of C functions used (required by pypy)
143 # types of parameters of C functions used (required by pypy)
123
144
124 _kernel32.CreateFileA.argtypes = [_LPCSTR, _DWORD, _DWORD, ctypes.c_void_p,
145 _kernel32.CreateFileA.argtypes = [_LPCSTR, _DWORD, _DWORD, ctypes.c_void_p,
@@ -186,6 +207,15 b' except AttributeError:'
186 _user32.EnumWindows.argtypes = [_WNDENUMPROC, _LPARAM]
207 _user32.EnumWindows.argtypes = [_WNDENUMPROC, _LPARAM]
187 _user32.EnumWindows.restype = _BOOL
208 _user32.EnumWindows.restype = _BOOL
188
209
210 _kernel32.CreateToolhelp32Snapshot.argtypes = [_DWORD, _DWORD]
211 _kernel32.CreateToolhelp32Snapshot.restype = _BOOL
212
213 _kernel32.Process32First.argtypes = [_HANDLE, ctypes.c_void_p]
214 _kernel32.Process32First.restype = _BOOL
215
216 _kernel32.Process32Next.argtypes = [_HANDLE, ctypes.c_void_p]
217 _kernel32.Process32Next.restype = _BOOL
218
189 def _raiseoserror(name):
219 def _raiseoserror(name):
190 err = ctypes.WinError()
220 err = ctypes.WinError()
191 raise OSError(err.errno, '%s: %s' % (name, err.strerror))
221 raise OSError(err.errno, '%s: %s' % (name, err.strerror))
@@ -309,6 +339,51 b' def termwidth():'
309 width = csbi.srWindow.Right - csbi.srWindow.Left
339 width = csbi.srWindow.Right - csbi.srWindow.Left
310 return width
340 return width
311
341
342 def _1stchild(pid):
343 '''return the 1st found child of the given pid
344
345 None is returned when no child is found'''
346 pe = _tagPROCESSENTRY32()
347
348 # create handle to list all processes
349 ph = _kernel32.CreateToolhelp32Snapshot(_TH32CS_SNAPPROCESS, 0)
350 if ph == _INVALID_HANDLE_VALUE:
351 raise ctypes.WinError
352 try:
353 r = _kernel32.Process32First(ph, ctypes.byref(pe))
354 # loop over all processes
355 while r:
356 if pe.th32ParentProcessID == pid:
357 # return first child found
358 return pe.th32ProcessID
359 r = _kernel32.Process32Next(ph, ctypes.byref(pe))
360 finally:
361 _kernel32.CloseHandle(ph)
362 if _kernel32.GetLastError() != _ERROR_NO_MORE_FILES:
363 raise ctypes.WinError
364 return None # no child found
365
366 class _tochildpid(int): # pid is _DWORD, which always matches in an int
367 '''helper for spawndetached, returns the child pid on conversion to string
368
369 Does not resolve the child pid immediately because the child may not yet be
370 started.
371 '''
372 def childpid(self):
373 '''returns the child pid of the first found child of the process
374 with this pid'''
375 return _1stchild(self)
376 def __str__(self):
377 # run when the pid is written to the file
378 ppid = self.childpid()
379 if ppid is None:
380 # race, child has exited since check
381 # fall back to this pid. Its process will also have disappeared,
382 # raising the same error type later as when the child pid would
383 # be returned.
384 return " %d" % self
385 return str(ppid)
386
312 def spawndetached(args):
387 def spawndetached(args):
313 # No standard library function really spawns a fully detached
388 # No standard library function really spawns a fully detached
314 # process under win32 because they allocate pipes or other objects
389 # process under win32 because they allocate pipes or other objects
@@ -339,7 +414,8 b' def spawndetached(args):'
339 if not res:
414 if not res:
340 raise ctypes.WinError
415 raise ctypes.WinError
341
416
342 return pi.dwProcessId
417 # _tochildpid because the process is the child of COMSPEC
418 return _tochildpid(pi.dwProcessId)
343
419
344 def unlink(f):
420 def unlink(f):
345 '''try to implement POSIX' unlink semantics on Windows'''
421 '''try to implement POSIX' unlink semantics on Windows'''
General Comments 0
You need to be logged in to leave comments. Login now