<s> __author__ = '<STR_LIT>' <EOL> import os <EOL> import sys <EOL> import errno <EOL> import socket <EOL> import select <EOL> import signal <EOL> import optparse <EOL> import StringIO <EOL> import ConfigParser <EOL> from cynic . utils import LOG_UNIX_SOCKET , get_console_logger , get_stream_logger <EOL> READ_ONLY = select . POLLIN <EOL> POLL_TIMEOUT = <NUM_LIT> <EOL> BACKLOG = <NUM_LIT:5> <EOL> DEFAULT_CONFIG = """<STR_LIT>""" % dict ( socketpath = LOG_UNIX_SOCKET ) <EOL> logger = get_console_logger ( '<STR_LIT>' ) <EOL> def _resolve ( name ) : <EOL> """<STR_LIT>""" <EOL> name = name . split ( '<STR_LIT:.>' ) <EOL> used = name . pop ( <NUM_LIT:0> ) <EOL> found = __import__ ( used ) <EOL> for n in name : <EOL> used = used + '<STR_LIT:.>' + n <EOL> try : <EOL> found = getattr ( found , n ) <EOL> except AttributeError : <EOL> __import__ ( used ) <EOL> found = getattr ( found , n ) <EOL> return found <EOL> def _reap_children ( signum , frame ) : <EOL> """<STR_LIT>""" <EOL> while True : <EOL> try : <EOL> pid , status = os . waitpid ( - <NUM_LIT:1> , os . WNOHANG ) <EOL> if pid == <NUM_LIT:0> : <EOL> break <EOL> except : <EOL> break <EOL> def _load_config ( fname ) : <EOL> """<STR_LIT>""" <EOL> config = ConfigParser . ConfigParser ( ) <EOL> if hasattr ( fname , '<STR_LIT>' ) : <EOL> config . readfp ( fname ) <EOL> else : <EOL> config . read ( fname ) <EOL> return config <EOL> class HandlerConfig ( object ) : <EOL> def __init__ ( self , klass , args , host , port , family ) : <EOL> self . klass = klass <EOL> self . args = args <EOL> self . host = host <EOL> self . port = port <EOL> self . family = family <EOL> self . socket = None <EOL> def _get_handler_configs ( config ) : <EOL> configs = [ ] <EOL> for section in config . sections ( ) : <EOL> if not section . startswith ( '<STR_LIT>' ) : <EOL> continue <EOL> clsname = config . get ( section , '<STR_LIT:class>' ) <EOL> klass = _resolve ( clsname ) <EOL> host = config . get ( section , '<STR_LIT:host>' ) <EOL> port = config . getint ( section , '<STR_LIT:port>' ) <EOL> args = ( ) <EOL> if config . has_option ( section , '<STR_LIT:args>' ) : <EOL> args = eval ( config . get ( section , '<STR_LIT:args>' ) , { } ) <EOL> if config . has_option ( section , '<STR_LIT>' ) : <EOL> family = config . get ( section , '<STR_LIT>' ) <EOL> else : <EOL> family = '<STR_LIT>' <EOL> hconfig = HandlerConfig ( klass , args , host , port , family ) <EOL> configs . append ( hconfig ) <EOL> return configs <EOL> class IOLoop ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , handler_configs ) : <EOL> self . handler_configs = handler_configs <EOL> self . fd2config = { } <EOL> self . poller = None <EOL> self . _setup ( ) <EOL> def _get_address ( self , hconfig ) : <EOL> address = { <EOL> '<STR_LIT>' : ( hconfig . host , hconfig . port ) , <EOL> '<STR_LIT>' : hconfig . host , <EOL> } . get ( hconfig . family ) <EOL> return address <EOL> def _get_family ( self , hconfig ) : <EOL> family = { <EOL> '<STR_LIT>' : socket . AF_INET , <EOL> '<STR_LIT>' : socket . AF_UNIX <EOL> } . get ( hconfig . family ) <EOL> return family <EOL> def _unlink_file ( self , hconfig ) : <EOL> if hconfig . family == '<STR_LIT>' : <EOL> try : <EOL> os . unlink ( hconfig . host ) <EOL> except : <EOL> pass <EOL> def _setup ( self ) : <EOL> signal . signal ( signal . SIGCHLD , _reap_children ) <EOL> self . poller = poller = select . poll ( ) <EOL> for config in self . handler_configs : <EOL> server = socket . socket ( <EOL> self . _get_family ( config ) , socket . SOCK_STREAM ) <EOL> server . setsockopt ( socket . SOL_SOCKET , socket . SO_REUSEADDR , <NUM_LIT:1> ) <EOL> server . setblocking ( <NUM_LIT:0> ) <EOL> logger . info ( <EOL> '<STR_LIT>' , <EOL> config . klass . __name__ , config . port or config . host <EOL> ) <EOL> self . fd2config [ server . fileno ( ) ] = config <EOL> self . _unlink_file ( config ) <EOL> server . bind ( self . _get_address ( config ) ) <EOL> server . listen ( BACKLOG ) <EOL> config . socket = server <EOL> poller . register ( server , READ_ONLY ) <EOL> def run ( self ) : <EOL> try : <EOL> child_pids = [ ] <EOL> while True : <EOL> try : <EOL> events = self . poller . poll ( POLL_TIMEOUT ) <EOL> except select . error as e : <EOL> code , msg = e . args <EOL> if code == errno . EINTR : <EOL> continue <EOL> else : <EOL> raise <EOL> for fd , flag in events : <EOL> if not flag & READ_ONLY : <EOL> continue <EOL> handler_config = self . fd2config [ fd ] <EOL> socket = handler_config . socket <EOL> try : <EOL> conn , client_address = socket . accept ( ) <EOL> except IOError as e : <EOL> code , msg = e . args <EOL> if code == errno . EINTR : <EOL> continue <EOL> else : <EOL> raise <EOL> pid = os . fork ( ) <EOL> if pid == <NUM_LIT:0> : <EOL> for config in self . fd2config . values ( ) : <EOL> config . socket . close ( ) <EOL> klass = handler_config . klass <EOL> handler = klass ( <EOL> conn , client_address , * handler_config . args ) <EOL> try : <EOL> handler . handle ( ) <EOL> except KeyboardInterrupt : <EOL> pass <EOL> except : <EOL> log = get_console_logger ( klass . __name__ ) <EOL> log . exception ( '<STR_LIT>' ) <EOL> os . _exit ( <NUM_LIT:0> ) <EOL> else : <EOL> child_pids . append ( pid ) <EOL> conn . close ( ) <EOL> except KeyboardInterrupt : <EOL> for pid in child_pids : <EOL> try : <EOL> os . kill ( pid , signal . SIGTERM ) <EOL> except : <EOL> pass <EOL> def main ( ) : <EOL> parser = optparse . OptionParser ( <EOL> description = '<STR_LIT>' ) <EOL> parser . add_option ( <EOL> '<STR_LIT:-c>' , '<STR_LIT>' , dest = '<STR_LIT>' , <EOL> help = ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> ) <EOL> ) <EOL> parser . add_option ( <EOL> '<STR_LIT>' , '<STR_LIT>' , dest = '<STR_LIT>' , action = '<STR_LIT:store_true>' , <EOL> default = False , help = '<STR_LIT>' <EOL> ) <EOL> options , args = parser . parse_args ( ) <EOL> if options . dump : <EOL> print DEFAULT_CONFIG <EOL> sys . exit ( <NUM_LIT:0> ) <EOL> path = options . config_path <EOL> if path is None : <EOL> path = StringIO . StringIO ( DEFAULT_CONFIG ) <EOL> config = _load_config ( path ) <EOL> handlers = _get_handler_configs ( config ) <EOL> ioloop = IOLoop ( handlers ) <EOL> ioloop . run ( ) </s>
