Show More
@@ -119,6 +119,27 b' class _CONSOLE_SCREEN_BUFFER_INFO(ctypes' | |||
|
119 | 119 | |
|
120 | 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 | 143 | # types of parameters of C functions used (required by pypy) |
|
123 | 144 | |
|
124 | 145 | _kernel32.CreateFileA.argtypes = [_LPCSTR, _DWORD, _DWORD, ctypes.c_void_p, |
@@ -186,6 +207,15 b' except AttributeError:' | |||
|
186 | 207 | _user32.EnumWindows.argtypes = [_WNDENUMPROC, _LPARAM] |
|
187 | 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 | 219 | def _raiseoserror(name): |
|
190 | 220 | err = ctypes.WinError() |
|
191 | 221 | raise OSError(err.errno, '%s: %s' % (name, err.strerror)) |
@@ -309,6 +339,51 b' def termwidth():' | |||
|
309 | 339 | width = csbi.srWindow.Right - csbi.srWindow.Left |
|
310 | 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 | 387 | def spawndetached(args): |
|
313 | 388 | # No standard library function really spawns a fully detached |
|
314 | 389 | # process under win32 because they allocate pipes or other objects |
@@ -339,7 +414,8 b' def spawndetached(args):' | |||
|
339 | 414 | if not res: |
|
340 | 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 | 420 | def unlink(f): |
|
345 | 421 | '''try to implement POSIX' unlink semantics on Windows''' |
General Comments 0
You need to be logged in to leave comments.
Login now