Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: pylib/mozrunner/winprocess.py

Issue 6183003: Added third_party python libraries that are needed for browser testing. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/third_party/
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pylib/mozrunner/qijo.py ('k') | pylib/mozrunner/wpk.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # A module to expose various thread/process/job related structures and
2 # methods from kernel32
3 #
4 # The MIT License
5 #
6 # Copyright (c) 2003-2004 by Peter Astrand <astrand@lysator.liu.se>
7 #
8 # Additions and modifications written by Benjamin Smedberg
9 # <benjamin@smedbergs.us> are Copyright (c) 2006 by the Mozilla Foundation
10 # <http://www.mozilla.org/>
11 #
12 # More Modifications
13 # Copyright (c) 2006-2007 by Mike Taylor <bear@code-bear.com>
14 # Copyright (c) 2007-2008 by Mikeal Rogers <mikeal@mozilla.com>
15 #
16 # By obtaining, using, and/or copying this software and/or its
17 # associated documentation, you agree that you have read, understood,
18 # and will comply with the following terms and conditions:
19 #
20 # Permission to use, copy, modify, and distribute this software and
21 # its associated documentation for any purpose and without fee is
22 # hereby granted, provided that the above copyright notice appears in
23 # all copies, and that both that copyright notice and this permission
24 # notice appear in supporting documentation, and that the name of the
25 # author not be used in advertising or publicity pertaining to
26 # distribution of the software without specific, written prior
27 # permission.
28 #
29 # THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
30 # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
31 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
32 # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
33 # OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
34 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
35 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
36
37 from ctypes import c_void_p, POINTER, sizeof, Structure, windll, WinError, WINFU NCTYPE
38 from ctypes.wintypes import BOOL, BYTE, DWORD, HANDLE, LPCWSTR, LPWSTR, UINT, WO RD
39 from qijo import QueryInformationJobObject
40
41 LPVOID = c_void_p
42 LPBYTE = POINTER(BYTE)
43 LPDWORD = POINTER(DWORD)
44 LPBOOL = POINTER(BOOL)
45
46 def ErrCheckBool(result, func, args):
47 """errcheck function for Windows functions that return a BOOL True
48 on success"""
49 if not result:
50 raise WinError()
51 return args
52
53
54 # AutoHANDLE
55
56 class AutoHANDLE(HANDLE):
57 """Subclass of HANDLE which will call CloseHandle() on deletion."""
58
59 CloseHandleProto = WINFUNCTYPE(BOOL, HANDLE)
60 CloseHandle = CloseHandleProto(("CloseHandle", windll.kernel32))
61 CloseHandle.errcheck = ErrCheckBool
62
63 def Close(self):
64 if self.value and self.value != HANDLE(-1).value:
65 self.CloseHandle(self)
66 self.value = 0
67
68 def __del__(self):
69 self.Close()
70
71 def __int__(self):
72 return self.value
73
74 def ErrCheckHandle(result, func, args):
75 """errcheck function for Windows functions that return a HANDLE."""
76 if not result:
77 raise WinError()
78 return AutoHANDLE(result)
79
80 # PROCESS_INFORMATION structure
81
82 class PROCESS_INFORMATION(Structure):
83 _fields_ = [("hProcess", HANDLE),
84 ("hThread", HANDLE),
85 ("dwProcessID", DWORD),
86 ("dwThreadID", DWORD)]
87
88 def __init__(self):
89 Structure.__init__(self)
90
91 self.cb = sizeof(self)
92
93 LPPROCESS_INFORMATION = POINTER(PROCESS_INFORMATION)
94
95 # STARTUPINFO structure
96
97 class STARTUPINFO(Structure):
98 _fields_ = [("cb", DWORD),
99 ("lpReserved", LPWSTR),
100 ("lpDesktop", LPWSTR),
101 ("lpTitle", LPWSTR),
102 ("dwX", DWORD),
103 ("dwY", DWORD),
104 ("dwXSize", DWORD),
105 ("dwYSize", DWORD),
106 ("dwXCountChars", DWORD),
107 ("dwYCountChars", DWORD),
108 ("dwFillAttribute", DWORD),
109 ("dwFlags", DWORD),
110 ("wShowWindow", WORD),
111 ("cbReserved2", WORD),
112 ("lpReserved2", LPBYTE),
113 ("hStdInput", HANDLE),
114 ("hStdOutput", HANDLE),
115 ("hStdError", HANDLE)
116 ]
117 LPSTARTUPINFO = POINTER(STARTUPINFO)
118
119 SW_HIDE = 0
120
121 STARTF_USESHOWWINDOW = 0x01
122 STARTF_USESIZE = 0x02
123 STARTF_USEPOSITION = 0x04
124 STARTF_USECOUNTCHARS = 0x08
125 STARTF_USEFILLATTRIBUTE = 0x10
126 STARTF_RUNFULLSCREEN = 0x20
127 STARTF_FORCEONFEEDBACK = 0x40
128 STARTF_FORCEOFFFEEDBACK = 0x80
129 STARTF_USESTDHANDLES = 0x100
130
131 # EnvironmentBlock
132
133 class EnvironmentBlock:
134 """An object which can be passed as the lpEnv parameter of CreateProcess.
135 It is initialized with a dictionary."""
136
137 def __init__(self, dict):
138 if not dict:
139 self._as_parameter_ = None
140 else:
141 values = ["%s=%s" % (key, value)
142 for (key, value) in dict.iteritems()]
143 values.append("")
144 self._as_parameter_ = LPCWSTR("\0".join(values))
145
146 # CreateProcess()
147
148 CreateProcessProto = WINFUNCTYPE(BOOL, # Return type
149 LPCWSTR, # lpApplicationName
150 LPWSTR, # lpCommandLine
151 LPVOID, # lpProcessAttributes
152 LPVOID, # lpThreadAttributes
153 BOOL, # bInheritHandles
154 DWORD, # dwCreationFlags
155 LPVOID, # lpEnvironment
156 LPCWSTR, # lpCurrentDirectory
157 LPSTARTUPINFO, # lpStartupInfo
158 LPPROCESS_INFORMATION # lpProcessInformation
159 )
160
161 CreateProcessFlags = ((1, "lpApplicationName", None),
162 (1, "lpCommandLine"),
163 (1, "lpProcessAttributes", None),
164 (1, "lpThreadAttributes", None),
165 (1, "bInheritHandles", True),
166 (1, "dwCreationFlags", 0),
167 (1, "lpEnvironment", None),
168 (1, "lpCurrentDirectory", None),
169 (1, "lpStartupInfo"),
170 (2, "lpProcessInformation"))
171
172 def ErrCheckCreateProcess(result, func, args):
173 ErrCheckBool(result, func, args)
174 # return a tuple (hProcess, hThread, dwProcessID, dwThreadID)
175 pi = args[9]
176 return AutoHANDLE(pi.hProcess), AutoHANDLE(pi.hThread), pi.dwProcessID, pi.d wThreadID
177
178 CreateProcess = CreateProcessProto(("CreateProcessW", windll.kernel32),
179 CreateProcessFlags)
180 CreateProcess.errcheck = ErrCheckCreateProcess
181
182 # flags for CreateProcess
183 CREATE_BREAKAWAY_FROM_JOB = 0x01000000
184 CREATE_DEFAULT_ERROR_MODE = 0x04000000
185 CREATE_NEW_CONSOLE = 0x00000010
186 CREATE_NEW_PROCESS_GROUP = 0x00000200
187 CREATE_NO_WINDOW = 0x08000000
188 CREATE_SUSPENDED = 0x00000004
189 CREATE_UNICODE_ENVIRONMENT = 0x00000400
190
191 # flags for job limit information
192 # see http://msdn.microsoft.com/en-us/library/ms684147%28VS.85%29.aspx
193 JOB_OBJECT_LIMIT_BREAKAWAY_OK = 0x00000800
194 JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK = 0x00001000
195
196 # XXX these flags should be documented
197 DEBUG_ONLY_THIS_PROCESS = 0x00000002
198 DEBUG_PROCESS = 0x00000001
199 DETACHED_PROCESS = 0x00000008
200
201 # CreateJobObject()
202
203 CreateJobObjectProto = WINFUNCTYPE(HANDLE, # Return type
204 LPVOID, # lpJobAttributes
205 LPCWSTR # lpName
206 )
207
208 CreateJobObjectFlags = ((1, "lpJobAttributes", None),
209 (1, "lpName", None))
210
211 CreateJobObject = CreateJobObjectProto(("CreateJobObjectW", windll.kernel32),
212 CreateJobObjectFlags)
213 CreateJobObject.errcheck = ErrCheckHandle
214
215 # AssignProcessToJobObject()
216
217 AssignProcessToJobObjectProto = WINFUNCTYPE(BOOL, # Return type
218 HANDLE, # hJob
219 HANDLE # hProcess
220 )
221 AssignProcessToJobObjectFlags = ((1, "hJob"),
222 (1, "hProcess"))
223 AssignProcessToJobObject = AssignProcessToJobObjectProto(
224 ("AssignProcessToJobObject", windll.kernel32),
225 AssignProcessToJobObjectFlags)
226 AssignProcessToJobObject.errcheck = ErrCheckBool
227
228 # GetCurrentProcess()
229 # because os.getPid() is way too easy
230 GetCurrentProcessProto = WINFUNCTYPE(HANDLE # Return type
231 )
232 GetCurrentProcessFlags = ()
233 GetCurrentProcess = GetCurrentProcessProto(
234 ("GetCurrentProcess", windll.kernel32),
235 GetCurrentProcessFlags)
236 GetCurrentProcess.errcheck = ErrCheckHandle
237
238 # IsProcessInJob()
239 try:
240 IsProcessInJobProto = WINFUNCTYPE(BOOL, # Return type
241 HANDLE, # Process Handle
242 HANDLE, # Job Handle
243 LPBOOL # Result
244 )
245 IsProcessInJobFlags = ((1, "ProcessHandle"),
246 (1, "JobHandle", HANDLE(0)),
247 (2, "Result"))
248 IsProcessInJob = IsProcessInJobProto(
249 ("IsProcessInJob", windll.kernel32),
250 IsProcessInJobFlags)
251 IsProcessInJob.errcheck = ErrCheckBool
252 except AttributeError:
253 # windows 2k doesn't have this API
254 def IsProcessInJob(process):
255 return False
256
257
258 # ResumeThread()
259
260 def ErrCheckResumeThread(result, func, args):
261 if result == -1:
262 raise WinError()
263
264 return args
265
266 ResumeThreadProto = WINFUNCTYPE(DWORD, # Return type
267 HANDLE # hThread
268 )
269 ResumeThreadFlags = ((1, "hThread"),)
270 ResumeThread = ResumeThreadProto(("ResumeThread", windll.kernel32),
271 ResumeThreadFlags)
272 ResumeThread.errcheck = ErrCheckResumeThread
273
274 # TerminateProcess()
275
276 TerminateProcessProto = WINFUNCTYPE(BOOL, # Return type
277 HANDLE, # hProcess
278 UINT # uExitCode
279 )
280 TerminateProcessFlags = ((1, "hProcess"),
281 (1, "uExitCode", 127))
282 TerminateProcess = TerminateProcessProto(
283 ("TerminateProcess", windll.kernel32),
284 TerminateProcessFlags)
285 TerminateProcess.errcheck = ErrCheckBool
286
287 # TerminateJobObject()
288
289 TerminateJobObjectProto = WINFUNCTYPE(BOOL, # Return type
290 HANDLE, # hJob
291 UINT # uExitCode
292 )
293 TerminateJobObjectFlags = ((1, "hJob"),
294 (1, "uExitCode", 127))
295 TerminateJobObject = TerminateJobObjectProto(
296 ("TerminateJobObject", windll.kernel32),
297 TerminateJobObjectFlags)
298 TerminateJobObject.errcheck = ErrCheckBool
299
300 # WaitForSingleObject()
301
302 WaitForSingleObjectProto = WINFUNCTYPE(DWORD, # Return type
303 HANDLE, # hHandle
304 DWORD, # dwMilliseconds
305 )
306 WaitForSingleObjectFlags = ((1, "hHandle"),
307 (1, "dwMilliseconds", -1))
308 WaitForSingleObject = WaitForSingleObjectProto(
309 ("WaitForSingleObject", windll.kernel32),
310 WaitForSingleObjectFlags)
311
312 INFINITE = -1
313 WAIT_TIMEOUT = 0x0102
314 WAIT_OBJECT_0 = 0x0
315 WAIT_ABANDONED = 0x0080
316
317 # GetExitCodeProcess()
318
319 GetExitCodeProcessProto = WINFUNCTYPE(BOOL, # Return type
320 HANDLE, # hProcess
321 LPDWORD, # lpExitCode
322 )
323 GetExitCodeProcessFlags = ((1, "hProcess"),
324 (2, "lpExitCode"))
325 GetExitCodeProcess = GetExitCodeProcessProto(
326 ("GetExitCodeProcess", windll.kernel32),
327 GetExitCodeProcessFlags)
328 GetExitCodeProcess.errcheck = ErrCheckBool
329
330 def CanCreateJobObject():
331 currentProc = GetCurrentProcess()
332 if IsProcessInJob(currentProc):
333 jobinfo = QueryInformationJobObject(HANDLE(0), 'JobObjectExtendedLimitIn formation')
334 limitflags = jobinfo['BasicLimitInformation']['LimitFlags']
335 return bool(limitflags & JOB_OBJECT_LIMIT_BREAKAWAY_OK) or bool(limitfla gs & JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK)
336 else:
337 return True
338
339 ### testing functions
340
341 def parent():
342 print 'Starting parent'
343 currentProc = GetCurrentProcess()
344 if IsProcessInJob(currentProc):
345 print >> sys.stderr, "You should not be in a job object to test"
346 sys.exit(1)
347 assert CanCreateJobObject()
348 print 'File: %s' % __file__
349 command = [sys.executable, __file__, '-child']
350 print 'Running command: %s' % command
351 process = Popen(command)
352 process.kill()
353 code = process.returncode
354 print 'Child code: %s' % code
355 assert code == 127
356
357 def child():
358 print 'Starting child'
359 currentProc = GetCurrentProcess()
360 injob = IsProcessInJob(currentProc)
361 print "Is in a job?: %s" % injob
362 can_create = CanCreateJobObject()
363 print 'Can create job?: %s' % can_create
364 process = Popen('c:\\windows\\notepad.exe')
365 assert process._job
366 jobinfo = QueryInformationJobObject(process._job, 'JobObjectExtendedLimitInf ormation')
367 print 'Job info: %s' % jobinfo
368 limitflags = jobinfo['BasicLimitInformation']['LimitFlags']
369 print 'LimitFlags: %s' % limitflags
370 process.kill()
371
372 if __name__ == '__main__':
373 import sys
374 from killableprocess import Popen
375 nargs = len(sys.argv[1:])
376 if nargs:
377 if nargs != 1 or sys.argv[1] != '-child':
378 raise AssertionError('Wrong flags; run like `python /path/to/winproc ess.py`')
379 child()
380 else:
381 parent()
OLDNEW
« no previous file with comments | « pylib/mozrunner/qijo.py ('k') | pylib/mozrunner/wpk.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698