def stopProcess(self, name):
"""
@param name: The name of the process to be stopped
"""
if name not in self.processes:
raise KeyError('Unrecognized process name: %s' % (name,))
proto = self.protocols.get(name, None)
if proto is not None:
proc = proto.transport
try:
proc.signalProcess('TERM')
except error.ProcessExitedAlready:
pass
else:
self.murder[name] = self._reactor.callLater(
self.killTime,
self._forceStopProcess, proc)
python类ProcessExitedAlready()的实例源码
def stop(self):
"""
Twisted reactor function called when we are shutting down.
"""
import signal
self.log.info('stop():stopping zenjmxjava')
self.stopCalled = True
if not self.process:
self.log.debug('stop():no zenjmxjava process to stop')
return
try:
self.process.signalProcess(signal.SIGKILL)
except error.ProcessExitedAlready:
self.log.info('stop():zenjmxjava process already exited')
pass
try:
self.process.loseConnection()
except Exception:
pass
self.process = None
def reallyDie(self):
try:
self.proto.transport.signalProcess('KILL')
except error.ProcessExitedAlready:
pass
def _killProcess(self, ignored):
try:
self.processProtocol.transport.signalProcess('KILL')
except error.ProcessExitedAlready:
pass
def kill(self):
try:
self.transport.signalProcess('KILL')
except internet_error.ProcessExitedAlready:
self.log.debug('Process Exited Already')
def _terminate(self, warn=False):
if self.transport is not None:
if warn:
warning("%s didn't exit. Sending SIGTERM"
% (self.daemon.program,))
try:
self.transport.signalProcess(signal.SIGTERM)
except ProcessExitedAlready:
pass
else:
# Give some time for the process, and then show who's the boss.
delayed = reactor.callLater(SIGKILL_DELAY, self._really_kill)
self._delayed_really_kill = delayed
def _really_kill(self):
try:
self.transport.signalProcess(signal.SIGKILL)
except ProcessExitedAlready:
pass
else:
warning("%s didn't die. Sending SIGKILL." % self.daemon.program)
self._delayed_really_kill = None
def rotate_logs(self):
if self.transport is not None:
try:
self.transport.signalProcess(signal.SIGUSR1)
except ProcessExitedAlready:
pass
def reallyDie(self):
try:
self.proto.transport.signalProcess('KILL')
except error.ProcessExitedAlready:
pass
def _killProcess(self, ignored):
try:
self.processProtocol.transport.signalProcess('KILL')
except error.ProcessExitedAlready:
pass
def tearDown(self):
# Kill the child process. We're done with it.
try:
self.clientTransport.signalProcess("KILL")
except (error.ProcessExitedAlready, OSError):
pass
def trap(failure):
failure.trap(error.ProcessTerminated)
self.assertIsNone(failure.value.exitCode)
self.assertEqual(failure.value.status, 9)
return self.testTerminal.onDisconnection.addErrback(trap)
def _reallyDie(self):
try:
self.transport.signalProcess('KILL')
except ProcessExitedAlready:
pass
def _killProcess(self, ignored):
try:
self.processProtocol.transport.signalProcess('KILL')
except error.ProcessExitedAlready:
pass
def closed(self):
if self.ptyTuple and os.path.exists(self.ptyTuple[2]):
ttyGID = os.stat(self.ptyTuple[2])[5]
os.chown(self.ptyTuple[2], 0, ttyGID)
if self.pty:
try:
self.pty.signalProcess('HUP')
except (OSError, ProcessExitedAlready):
pass
self.pty.loseConnection()
self.addUTMPEntry(0)
log.msg('shell closed')
def signalProcess(self, signalID):
if self.pid is None:
raise error.ProcessExitedAlready()
if signalID in ("INT", "TERM", "KILL"):
win32process.TerminateProcess(self.hProcess, 1)
def _forceStopProcess(self, proc):
"""
@param proc: An L{IProcessTransport} provider
"""
try:
proc.signalProcess('KILL')
except error.ProcessExitedAlready:
pass
def test_process(self):
"""
Test running a process: check its output, it exitCode, some property of
signalProcess.
"""
scriptPath = b"twisted.test.process_tester"
d = defer.Deferred()
p = TestProcessProtocol()
p.deferred = d
reactor.spawnProcess(p, pyExe, [pyExe, b"-u", b"-m", scriptPath],
env=properEnv)
def check(ignored):
self.assertEqual(p.stages, [1, 2, 3, 4, 5])
f = p.reason
f.trap(error.ProcessTerminated)
self.assertEqual(f.value.exitCode, 23)
# would .signal be available on non-posix?
# self.assertIsNone(f.value.signal)
self.assertRaises(
error.ProcessExitedAlready, p.transport.signalProcess, 'INT')
try:
import process_tester, glob
for f in glob.glob(process_tester.test_file_match):
os.remove(f)
except:
pass
d.addCallback(check)
return d
def test_killExited(self):
"""
L{process.Process.signalProcess} raises L{error.ProcessExitedAlready}
if the process has exited.
"""
self.mockos.child = False
cmd = b'/mock/ouch'
p = TrivialProcessProtocol(None)
proc = reactor.spawnProcess(p, cmd, [b'ouch'], env=None, usePTY=False)
# We didn't specify a waitpid value, so the waitpid call in
# registerReapProcessHandler has already reaped the process
self.assertRaises(error.ProcessExitedAlready,
proc.signalProcess, "KILL")
def test_killExitedButNotDetected(self):
"""
L{process.Process.signalProcess} raises L{error.ProcessExitedAlready}
if the process has exited but that twisted hasn't seen it (for example,
if the process has been waited outside of twisted): C{os.kill} then
raise C{OSError} with C{errno.ESRCH} as errno.
"""
self.mockos.child = False
self.mockos.waitChild = (0, 0)
cmd = b'/mock/ouch'
p = TrivialProcessProtocol(None)
proc = reactor.spawnProcess(p, cmd, [b'ouch'], env=None, usePTY=False)
self.mockos.raiseKill = OSError(errno.ESRCH, "Not found")
self.assertRaises(error.ProcessExitedAlready,
proc.signalProcess, "KILL")
def connectionMade(self):
@defer.inlineCallbacks
def killIfAlive():
"""Terminate after timeout if still alive
"""
try:
yield self.transport.signalProcess('KILL')
log.msg('Killed source proccess: Timeout %s exceeded'
% self.timeout)
except error.ProcessExitedAlready:
pass
self.timer = reactor.callLater(self.timeout, killIfAlive)
def test_full_tor_connection(self):
config = txtorcon.TorConfig()
config.ControlPort = net.randomFreePort()
config.SocksPort = net.randomFreePort()
config.DataDirectory = self.tor_datadir
log.msg(
"Connecting to tor %s" %
(onion.tor_details['version']))
config.log = ['notice stdout', 'notice file %s' % self.tor_logfile]
config.save()
def updates(prog, tag, summary):
log.msg("Progress is at: %s%%" % (prog))
self.report['tor_progress'] = int(prog)
self.report['tor_progress_tag'] = tag
self.report['tor_progress_summary'] = summary
d = txtorcon.launch_tor(config, reactor, timeout=self.timeout,
progress_updates=updates)
@d.addCallback
def setup_complete(proto):
try:
proto.transport.signalProcess('TERM')
except error.ProcessExitedAlready:
proto.transport.loseConnection()
log.msg("Successfully connected to Tor")
self.report['success'] = True
@d.addErrback
def setup_failed(failure):
log.msg("Failed to connect to Tor")
self.report['success'] = False
self.report['error'] = 'timeout-reached'
return
@d.addCallback
def write_log(_):
with open(self.tor_logfile) as f:
self.report['tor_log'] = f.read()
os.remove(self.tor_logfile)
try:
shutil.rmtree(self.tor_datadir)
except:
pass
return d