ó »ÏâIc@sƒdZddlZddlZyeWn!ek rIddlmZnXddlZddl Z ddl Z ddl Z de fd„ƒYZ de fd„ƒYZyddlZddlZWnek rád\ZZnXde fd „ƒYZd e fd „ƒYZd e fd „ƒYZde jfd„ƒYZde fd„ƒYZdefd„ƒYZde fd„ƒYZdS(s2Site services for use with a Web Site Process Bus.iÿÿÿÿN(tSett SimplePlugincBs)eZdZd„Zd„Zd„ZRS(sCPlugin base class which auto-subscribes methods for known channels.cCs ||_dS(N(tbus(tselfR((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyt__init__scCsOxH|jjD]:}t||dƒ}|dk r |jj||ƒq q WdS(s>Register this object as a (multi-channel) listener on the bus.N(Rt listenerstgetattrtNonet subscribe(Rtchanneltmethod((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyRs cCsOxH|jjD]:}t||dƒ}|dk r |jj||ƒq q WdS(s0Unregister this object as a listener on the bus.N(RRRRt unsubscribe(RR R ((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR s (t__name__t __module__t__doc__RRR (((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyRs  t SignalHandlercBs¨eZdZiZxLeeƒjƒD]8\ZZej dƒr%ej dƒ r%eee/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR9s   cCsLxE|jjƒD]4\}}y|j||ƒWqtk rCqXqWdS(N(Rt iteritemst set_handlert ValueError(Rtsigtfunc((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyRCs  cCsöxï|jjƒD]Þ\}}|j|}|dkrU|jjd|ƒtj}n|jjd||fƒyEtj||ƒ}|dkr³|jjd||fddƒnWqt k rí|jjd||fdddt ƒqXqWdS( Ns Restoring %s handler to SIG_DFL.sRestoring %s handler %r.s?Restored old %s handler %r, but our handler was not registered.tlevelis Unable to restore %s handler %r.i(t traceback( RRtsignalsRRtlogt_signaltSIG_DFLtsignalRtTrue(Rtsignumthandlertsignamet our_handler((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR Js       cCsàt|tƒrItt|dƒ}|dkr@td|ƒ‚n|}n;y|j|}Wn!tk r}td|ƒ‚nX|}tj||j ƒ}||j |<|dk rÜ|j j d|ƒ|j j ||ƒndS(sMSubscribe a handler for the given signal (number or name). If the optional 'listener' argument is provided, it will be subscribed as a listener for the given signal's channel. If the given signal name or number is not available on the current platform, ValueError is raised. sNo such signal: %rsListening for %s.N(t isinstancet basestringRR#RRR!tKeyErrorR%t_handle_signalRRR"R(RR%tlistenerR'R)tprev((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR^s      cCs5|j|}|jjd|ƒ|jj|ƒdS(s?Python signal handler (self.set_handler subscribes it for you).sCaught signal %s.N(R!RR"tpublish(RR'tframeR)((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR.zs cCsYtjtjjƒƒr8|jjdƒ|jjƒn|jjdƒ|jjƒdS(Ns*SIGHUP caught but not daemonized. Exiting.s+SIGHUP caught while daemonized. Restarting.( tostisattytsyststdintfilenoRR"Rtrestart(R((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR€s N(R R RR!tvarsR#titemstktvt startswithRRR RRR.R(((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR's    tDropPrivilegescBs§eZdZdddd„Zd„Zd„ZeeeddƒZd„Z d„Z ee e ddƒZ d „Z d „Z ee e dd ƒZd „Zd e_RS(s†Drop privileges. uid/gid arguments not available on Windows. Special thanks to Gavin Baker: http://antonym.org/node/100. cCs8tj||ƒt|_||_||_||_dS(N(RRtFalset finalizedtuidtgidtumask(RRRCRARB((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR–s    cCs|jS(N(t_uid(R((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyt_get_uidscCsl|dk r_tdkr7|jjdddƒd}q_t|tƒr_tj|ƒd}q_n||_dS(Ns'pwd module not available; ignoring uid.Rii(RtpwdRR"R+R,tgetpwnamRD(Rtval((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyt_set_uidŸs   tdocsThe uid under which to run.cCs|jS(N(t_gid(R((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyt_get_gidªscCsl|dk r_tdkr7|jjdddƒd}q_t|tƒr_tj|ƒd}q_n||_dS(Ns'grp module not available; ignoring gid.Rii(RtgrpRR"R+R,tgetgrnamRK(RRH((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyt_set_gid¬s   sThe gid under which to run.cCs|jS(N(t_umask(R((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyt _get_umask·scCsW|dk rJy tjWqJtk rF|jjdddƒd}qJXn||_dS(Ns-umask function not available; ignoring umask.Ri(RR3RCtAttributeErrorRR"RP(RRH((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyt _set_umask¹s    sThe umask under which to run.cCsžd„}|jrM|jdko-|jdks|jjd|ƒƒqn¸|jdkr“|jdkr“tswtr|jjdddƒqnr|jjd|ƒƒ|jdk rÌtj |jƒn|jdk rîtj |jƒn|jjd|ƒƒ|jr:|j dk r‘|jjd|j ƒq‘nW|j dkrb|jjd ddƒn/tj |j ƒ}|jjd ||j fƒt |_dS( NcSsZd\}}tr.tjtjƒƒd}ntrPtjtjƒƒd}n||fS(s+Return the current (uid, gid) if available.iN(NN(RRFtgetpwuidR3tgetuidRMtgetgrgidtgetgid(tnametgroup((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyt current_idsÆs  s"Already running as uid: %r gid: %rsuid/gid not setRisStarted as uid: %r gid: %rsRunning as uid: %r gid: %rsumask already set to: %03os umask not setsumask old: %03o, new: %03o( R@RARRBRR"RFRMR3tsetgidtsetuidRCR&(RRZt old_umask((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pytstartÄs.     iMN(R R RRRRERItpropertyRARLRORBRQRSRCR^tpriority(((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR>s       +t DaemonizercBs2eZdZdddd„Zd„Zde_RS(sÎDaemonize the running script. Use this with a Web Site Process Bus via: Daemonizer(bus).subscribe() When this component finishes, the process is completely decoupled from the parent environment. Please note that when this component is used, the return code from the parent process will still be 0 if a startup error occurs in the forked children. Errors in the initial daemonizing process still return proper exit codes. Therefore, if you use this plugin to daemonize, don't use the return code as an accurate indicator of whether the process fully started. In fact, that return code only indicates if the process succesfully finished the first fork. s /dev/nullcCs8tj||ƒ||_||_||_t|_dS(N(RRR6tstdouttstderrR?R@(RRR6RbRc((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyRs    cCs>|jr|jjdƒntjƒdkrQ|jjdtjƒddƒntjjƒtj jƒy<t j ƒ}|dkr‰n|jjdƒt j dƒWn:t k rã}tjdtjd|j|jfƒnXt jƒy<t j ƒ}|dkr)|jjd ƒt j dƒnWn:t k rf}tjd tjd|j|jfƒnXt jd ƒt jdƒt|jd ƒ}t|jd ƒ}t|j d dƒ}t j|jƒtjjƒƒt j|jƒtjjƒƒt j|jƒtj jƒƒ|jjdt jƒƒt|_dS(NsAlready deamonized.isHThere are %r active threads. Daemonizing now may cause strange failures.Riis Forking once.s%s: fork #1 failed: (%d) %s sForking twice.s%s: fork #2 failed: (%d) %s t/trsa+sDaemonized to PID: %s(R@RR"t threadingt activeCountt enumerateR5RbtflushRcR3tforkt_exittOSErrorRtargvterrnotstrerrortsetsidtchdirRCtopenR6tdup2R7tgetpidR&(Rtpidtexctsitsotse((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR^ sF       "    "  iA(R R RRR^R`(((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyRaòs   AtPIDFilecBs2eZdZd„Zd„Zde_d„ZRS(s!Maintain a PID file via a WSPBus.cCs&tj||ƒ||_t|_dS(N(RRtpidfileR?R@(RRR{((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyRRs cCs~tjƒ}|jr5|jjd||jfƒnEt|jdƒjt|ƒƒ|jjd||jfƒt |_dS(NsPID %r already written to %r.twbsPID %r written to %r.( R3RtR@RR"R{RrtwritetstrR&(RRu((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR^Ws    iFcCsRy+tj|jƒ|jjd|jƒWn ttfk rG‚nnXdS(NsPID file removed: %r.(R3tremoveR{RR"tKeyboardInterruptt SystemExit(R((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyRas(R R RRR^R`R(((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyRzOs    tPerpetualTimercBseZdZd„ZRS(s:A subclass of threading._Timer whose run() method repeats.cCsMxFtrH|jj|jƒ|jjƒr/dS|j|j|jŽqWdS(N(R&tfinishedtwaittintervaltisSettfunctiontargstkwargs(R((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pytrunns  (R R RRŠ(((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR‚kstMonitorcBsDeZdZdZdd„Zd„Zde_d„Zd„ZRS(sÞWSPBus listener to periodically run a callback in its own thread. bus: a Web Site Process Bus object. callback: the function to call at intervals. frequency: the time in seconds between callback runs. i<cCs/tj||ƒ||_||_d|_dS(N(RRtcallbackt frequencyRtthread(RRRŒR((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR€s  cCs‘|jdkr|jj}|jdkrvt|j|jƒ|_|jj|ƒ|jjƒ|j j d|ƒq|j j d|ƒndS(s5Start our callback in its own perpetual timer thread.isStarted monitor thread %r.s"Monitor thread %r already started.N( Rt __class__R RŽRR‚RŒtsetNameR^RR"(Rt threadname((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR^†s  iFcCsŽ|jdkr,|jjd|jjƒn^|jtjƒk r|jjƒ}|jj ƒ|jj ƒ|jjd|ƒnd|_dS(s+Stop our callback's perpetual timer thread.sNo thread running for %s.sStopped thread %r.N( RŽRRR"RR Rft currentThreadtgetNametcanceltjoin(RRX((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pytstop“s  cCs|jƒ|jƒdS(s:Stop the callback's perpetual timer thread and restart it.N(R–R^(R((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyRŸs ( R R RRRR^R`R–R(((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR‹vs   t AutoreloadercBsDeZdZdZdZddd„Zd„Zde_d„ZRS(s8Monitor which re-executes the process when files change.is.*cCs;i|_tƒ|_||_tj|||j|ƒdS(N(tmtimestsettfilestmatchR‹RRŠ(RRRR›((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR«s   cCs,|jdkri|_ntj|ƒdS(s2Start our own perpetual timer thread for self.run.N(RŽRR˜R‹R^(R((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR^±s iFcCs±tƒ}x‡tjjƒD]v\}}tj|j|ƒrt|dƒrmt|jdƒrm|jj}qmnt |dd ƒ}|j |ƒqqWx||j BD]}|r¡|j dƒrÉ|d }n|jj|dƒ}|d krðq¡nytj|ƒj}Wntk rd }nX||jkr?||j|/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyRЏs6       ( R R RRR›RR^R`RŠ(((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR—¥s  t ThreadManagercBs8eZdZd„Zd„Zd„Zd„ZeZRS(s¿Manager for HTTP request threads. If you have control over thread creation and destruction, publish to the 'acquire_thread' and 'release_thread' channels (for each thread). This will register/unregister the current thread and publish to 'start_thread' and 'stop_thread' listeners in the bus as needed. If threads are created and destroyed by code you do not control (e.g., Apache), then, at the beginning of every HTTP request, publish to 'acquire_thread' only. You should not publish to 'release_thread' in this case, since you do not know whether the thread will be re-used or not. The bus will call 'stop_thread' listeners for you when it stops. cCsOi|_tj||ƒ|jjjdtƒƒ|jjjdtƒƒdS(Ntacquire_threadtrelease_thread(tthreadsRRRRt setdefaultR™(RR((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyRðs cCsUtjƒ}||jkrQt|jƒd}||j|<|jjd|ƒndS(s·Run 'start_thread' listeners for the current thread. If the current thread has already been seen, any 'start_thread' listeners will not be run again. it start_threadN(Rft _get_identR¯tlenRR1(Rt thread_identti((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR­ös   cCsGtjƒ}|jj|dƒ}|dk rC|jjd|ƒndS(s;Release the current thread and run 'stop_thread' listeners.t stop_threadN(RfR²R¯tpopRRR1(RR´Rµ((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR®s  cCsDx0|jjƒD]\}}|jjd|ƒqW|jjƒdS(s8Release all threads and run all 'stop_thread' listeners.R¶N(R¯RRR1tclear(RR´Rµ((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR– s(R R RRR­R®R–R(((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyR¬às     (NN(RR3R R™t NameErrortsetsRR%R#R5ttimeRftobjectRRRFRMt ImportErrorRR>RaRzt_TimerR‚R‹R—R¬(((s>/usr/lib/python2.7/vendor-packages/cherrypy/process/plugins.pyts.       c b] /;