Changeset 27780
- Timestamp:
- 12/15/2009 10:17:02 AM (9 months ago)
- Location:
- branches/signal-process-group-2726-4/twisted
- Files:
-
- 5 modified
- 2 copied
-
internet/_dumbwin32proc.py (modified) (5 diffs)
-
internet/interfaces.py (modified) (2 diffs)
-
internet/process.py (modified) (1 diff)
-
test/mock_win32process.py (modified) (1 diff)
-
test/process_signalgroup.py (copied) (copied from branches/signal-process-group-2726-3/twisted/test/process_signalgroup.py)
-
test/process_signaljob.py (copied) (copied from branches/signal-process-group-2726-3/twisted/test/process_signaljob.py)
-
test/test_process.py (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/signal-process-group-2726-4/twisted/internet/_dumbwin32proc.py
r27356 r27780 17 17 import win32process 18 18 import win32security 19 import win32job 19 20 20 21 import pywintypes … … 35 36 from twisted.internet._baseprocess import BaseProcess 36 37 37 def debug(msg): 38 import sys 39 print msg 40 sys.stdout.flush() 38 41 39 42 40 class _Reaper(_pollingfile._PollableResource): … … 169 167 170 168 cmdline = quoteArguments(args) 169 170 self.job = win32job.CreateJobObject(None, None) 171 171 # TODO: error detection here. 172 172 def doCreate(): 173 173 self.hProcess, self.hThread, self.pid, dwTid = win32process.CreateProcess( 174 command, cmdline, None, None, 1, 0, env, path, StartupInfo) 174 command, cmdline, None, None, 1, win32con.CREATE_SUSPENDED, 175 env, path, StartupInfo) 175 176 try: 176 177 doCreate() … … 206 207 raise OSError(pwte2) 207 208 209 win32job.AssignProcessToJobObject(self.job, self.hProcess) 210 win32process.ResumeThread(self.hThread) 211 212 win32file.CloseHandle(self.hThread) 213 208 214 # close handles which only the child will use 209 215 win32file.CloseHandle(hStderrW) … … 235 241 236 242 243 def _raiseUnknownSignal(self, signalID): 244 """ 245 Helper method raising an error when a given signal can't be handled. 246 """ 247 raise ValueError( 248 "Signal not handled: %s. " 249 "Only 'INT', 'TERM' or 'KILL' can be used." % (signalID,)) 250 251 237 252 def signalProcess(self, signalID): 253 """ 254 Terminate process if C{signalID} is one of "INT", "TERM", or "KILL". 255 256 @type signalID: C{str} 257 """ 238 258 if self.pid is None: 239 259 raise error.ProcessExitedAlready() 240 260 if signalID in ("INT", "TERM", "KILL"): 241 261 win32process.TerminateProcess(self.hProcess, 1) 262 else: 263 self._raiseUnknownSignal(signalID) 264 265 266 def signalProcessGroup(self, signalID): 267 """ 268 Terminate process group if C{signalID} is one of "INT", "TERM", or 269 "KILL". 270 271 @type signalID: C{str} 272 """ 273 if self.pid is None: 274 raise error.ProcessExitedAlready() 275 if signalID in ("INT", "TERM", "KILL"): 276 win32job.TerminateJobObject(self.job, 1) 277 else: 278 self._raiseUnknownSignal(signalID) 242 279 243 280 -
branches/signal-process-group-2726-4/twisted/internet/interfaces.py
r27770 r27780 1506 1506 """ 1507 1507 1508 1508 1509 def signalProcess(signalID): 1509 1510 """ … … 1519 1520 1520 1521 @raise twisted.internet.error.ProcessExitedAlready: The process has 1521 already exited. 1522 """ 1522 already exited. 1523 """ 1524 1525 1526 def signalProcessGroup(signalID): 1527 """ 1528 Send a signal to every processes in the process group. C{signalID} 1529 takes the value as in L{signalProcess}. 1530 """ 1531 1523 1532 1524 1533 -
branches/signal-process-group-2726-4/twisted/internet/process.py
r26050 r27780 332 332 if self.pid is None: 333 333 raise ProcessExitedAlready() 334 os.kill(self.pid, signalID) 335 336 337 def signalProcessGroup(self, signalID): 338 """ 339 Send the given signal C{signalID} to the process group. It does the 340 same translation as L{signalProcess}. 341 342 @type signalID: C{str} or C{int} 343 """ 344 if signalID in ('HUP', 'STOP', 'INT', 'KILL', 'TERM'): 345 signalID = getattr(signal, 'SIG%s' % (signalID,)) 346 if self.pid is None: 347 raise ProcessExitedAlready() 348 self.pid = -self.pid 334 349 os.kill(self.pid, signalID) 335 350 -
branches/signal-process-group-2726-4/twisted/test/mock_win32process.py
r23212 r27780 12 12 import win32process 13 13 GetExitCodeProcess = win32process.GetExitCodeProcess 14 ResumeThread = win32process.ResumeThread 14 15 STARTUPINFO = win32process.STARTUPINFO 15 16 -
branches/signal-process-group-2726-4/twisted/test/test_process.py
r27135 r27780 266 266 """ 267 267 268 def __init__(self, deferred, sig ):268 def __init__(self, deferred, sig, method="signalProcess"): 269 269 self.deferred = deferred 270 270 self.signal = sig 271 self.method = method 271 272 272 273 273 274 def outReceived(self, data): 274 self.transport.signalProcess(self.signal)275 getattr(self.transport, self.method)(self.signal) 275 276 276 277 … … 1099 1100 1100 1101 1102 def test_signalProcessGroup(self): 1103 """ 1104 Send a INT signal to a group of processes. 1105 """ 1106 exe = sys.executable 1107 scriptPath = util.sibpath(__file__, "process_signalgroup.py") 1108 d = defer.Deferred() 1109 p = SignalProtocol(d, "INT", "signalProcessGroup") 1110 reactor._handleSignals() 1111 proc = reactor.spawnProcess(p, exe, [exe, "-u", scriptPath, "parent"], 1112 env=None, 1113 usePTY=self.usePTY) 1114 pid = proc.pid 1115 def check(result): 1116 error = self.assertRaises(OSError, os.kill, -pid, 0) 1117 self.assertEquals(error[0], errno.ESRCH) 1118 return d.addCallback(check) 1119 1120 1101 1121 def test_errorInProcessEnded(self): 1102 1122 """ … … 1937 1957 1938 1958 1959 1960 1939 1961 class PosixProcessTestCasePTY(unittest.TestCase, PosixProcessBase): 1940 1962 """ … … 2076 2098 """ 2077 2099 import win32api 2078 2079 2100 connected = defer.Deferred() 2080 2101 ended = defer.Deferred() … … 2119 2140 2120 2141 return defer.gatherResults([connected, ended]) 2142 2143 2144 def test_signalProcessGroup(self): 2145 """ 2146 Send a INT signal to a group of processes. 2147 """ 2148 exe = sys.executable 2149 scriptPath = util.sibpath(__file__, "process_signaljob.py") 2150 d = defer.Deferred() 2151 p = Win32SignalProtocol(d, "INT", "signalProcessGroup") 2152 reactor._handleSignals() 2153 proc = reactor.spawnProcess(p, exe, [exe, "-u", scriptPath, "parent"], 2154 env=None) 2155 2156 def check(result): 2157 # If we're here, both processes must have terminated, so it's just 2158 # a sanity check 2159 import win32job 2160 jobProcesses = win32job.QueryInformationJobObject(proc.job, 2161 win32job.JobObjectBasicProcessIdList) 2162 self.assertEquals(len(jobProcesses), 0) 2163 return d.addCallback(check) 2121 2164 2122 2165
