Commit 5deb683d authored by Denis Bilenko's avatar Denis Bilenko

Merge pull request #431 from surfly/minor

simpler impl of backdoor.py and few minor changes
parents 16af4620 ddf1f0dc
# @author Bob Ippolito # Copyright (c) 2009-2014, gevent contributors
# # Based on eventlet.backdoor Copyright (c) 2005-2006, Bob Ippolito
# Copyright (c) 2005-2006, Bob Ippolito
# Copyright (c) 2007, Linden Research, Inc.
# Copyright (c) 2008, Donovan Preston
# Copyright (c) 2009-2010, Denis Bilenko
# Copyright (c) 2011, gevent contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from __future__ import print_function from __future__ import print_function
import sys import sys
...@@ -30,7 +7,7 @@ from code import InteractiveConsole ...@@ -30,7 +7,7 @@ from code import InteractiveConsole
from gevent import socket from gevent import socket
from gevent.greenlet import Greenlet from gevent.greenlet import Greenlet
from gevent.hub import PY3 from gevent.hub import PY3, getcurrent
from gevent.server import StreamServer from gevent.server import StreamServer
__all__ = ['BackdoorServer'] __all__ = ['BackdoorServer']
...@@ -45,58 +22,61 @@ except AttributeError: ...@@ -45,58 +22,61 @@ except AttributeError:
sys.ps2 = '... ' sys.ps2 = '... '
class SocketConsole(Greenlet): class _Greenlet_stdreplace(Greenlet):
_fileobj = None
def __init__(self, locals, conn, banner=None):
Greenlet.__init__(self)
self.locals = locals
self.desc = _fileobject(conn)
self.banner = banner
def finalize(self):
self.desc = None
def switch(self, *args, **kw): def switch(self, *args, **kw):
self.saved = sys.stdin, sys.stderr, sys.stdout if self._fileobj is not None:
sys.stdin = sys.stdout = sys.stderr = self.desc self.switch_in()
Greenlet.switch(self, *args, **kw) Greenlet.switch(self, *args, **kw)
def switch_in(self):
self.saved = sys.stdin, sys.stderr, sys.stdout
sys.stdin = sys.stdout = sys.stderr = self._fileobj
def switch_out(self): def switch_out(self):
sys.stdin, sys.stderr, sys.stdout = self.saved sys.stdin, sys.stderr, sys.stdout = self.saved
self.saved = None
def _run(self): def run(self):
try: try:
try: return Greenlet.run(self)
console = InteractiveConsole(self.locals)
# __builtins__ may either be the __builtin__ module or
# __builtin__.__dict__ in the latter case typing
# locals() at the backdoor prompt spews out lots of
# useless stuff
try:
import __builtin__
console.locals["__builtins__"] = __builtin__
except ImportError:
import builtins
console.locals["builtins"] = builtins
console.interact(banner=self.banner)
except SystemExit: # raised by quit()
if not PY3:
sys.exc_clear()
finally: finally:
# XXX why is this necessary?
self.switch_out() self.switch_out()
self.finalize()
class BackdoorServer(StreamServer): class BackdoorServer(StreamServer):
def __init__(self, listener, locals=None, banner=None, **server_args): def __init__(self, listener, locals=None, banner=None, **server_args):
StreamServer.__init__(self, listener, spawn=None, **server_args) StreamServer.__init__(self, listener, spawn=_Greenlet_stdreplace.spawn, **server_args)
self.locals = locals self.locals = locals
self.banner = banner self.banner = banner
# QQQ passing pool instance as 'spawn' is not possible; should it be fixed? self.stderr = sys.stderr
def handle(self, conn, address): def handle(self, conn, address):
SocketConsole.spawn(self.locals, conn, banner=self.banner) f = getcurrent()._fileobj = _fileobject(conn)
f.stderr = self.stderr
getcurrent().switch_in()
try:
console = InteractiveConsole(self.locals)
# __builtins__ may either be the __builtin__ module or
# __builtin__.__dict__ in the latter case typing
# locals() at the backdoor prompt spews out lots of
# useless stuff
try:
import __builtin__
console.locals["__builtins__"] = __builtin__
except ImportError:
import builtins
console.locals["builtins"] = builtins
console.interact(banner=self.banner)
except SystemExit: # raised by quit()
if not PY3:
sys.exc_clear()
finally:
conn.close()
f.close()
class _fileobject(socket._fileobject): class _fileobject(socket._fileobject):
...@@ -118,4 +98,4 @@ if __name__ == '__main__': ...@@ -118,4 +98,4 @@ if __name__ == '__main__':
if not sys.argv[1:]: if not sys.argv[1:]:
print('USAGE: %s PORT' % sys.argv[0]) print('USAGE: %s PORT' % sys.argv[0])
else: else:
BackdoorServer(('127.0.0.1', int(sys.argv[1]))).serve_forever() BackdoorServer(('127.0.0.1', int(sys.argv[1])), locals={'hello': 'world'}).serve_forever()
...@@ -114,6 +114,12 @@ class Event(object): ...@@ -114,6 +114,12 @@ class Event(object):
except: except:
self.hub.handle_error((link, self), *sys.exc_info()) self.hub.handle_error((link, self), *sys.exc_info())
def _reset_internal_locks(self):
# for compatibility with threading.Event (only in case of patch_all(Event=True), by default Event is not pathed)
# Exception AttributeError: AttributeError("'Event' object has no attribute '_reset_internal_locks'",)
# in <module 'threading' from '/usr/lib/python2.7/threading.pyc'> ignored
pass
class AsyncResult(object): class AsyncResult(object):
"""A one-time event that stores a value or an exception. """A one-time event that stores a value or an exception.
......
...@@ -188,21 +188,21 @@ class ThreadPool(object): ...@@ -188,21 +188,21 @@ class ThreadPool(object):
# otherwise, _adjust might think there's one more idle thread that # otherwise, _adjust might think there's one more idle thread that
# needs to be killed # needs to be killed
return return
func, args, kwargs, result = task func, args, kwargs, thread_result = task
try: try:
value = func(*args, **kwargs) value = func(*args, **kwargs)
except: except:
exc_info = getattr(sys, 'exc_info', None) exc_info = getattr(sys, 'exc_info', None)
if exc_info is None: if exc_info is None:
return return
result.handle_error((self, func), exc_info()) thread_result.handle_error((self, func), exc_info())
else: else:
if sys is None: if sys is None:
return return
result.set(value) thread_result.set(value)
del value del value
finally: finally:
del func, args, kwargs, result, task del func, args, kwargs, thread_result, task
finally: finally:
if sys is None: if sys is None:
return return
......
...@@ -10,7 +10,6 @@ import time ...@@ -10,7 +10,6 @@ import time
from datetime import timedelta from datetime import timedelta
SLEEP = 0.1
runtimelog = [] runtimelog = []
MIN_RUNTIME = 1.0 MIN_RUNTIME = 1.0
BUFFER_OUTPUT = False BUFFER_OUTPUT = False
...@@ -189,7 +188,7 @@ def run(command, **kwargs): ...@@ -189,7 +188,7 @@ def run(command, **kwargs):
assert not err assert not err
with lock: with lock:
if out: if out:
out = out.strip().decode() out = out.strip().decode('utf-8', 'ignore')
if out: if out:
out = ' ' + out.replace('\n', '\n ') out = ' ' + out.replace('\n', '\n ')
out = out.rstrip() out = out.rstrip()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment