
                             S r SSKJr  SSKJr  SSKJr  SSKJr  SSKrSSKrSSKrSSK	r	SSK
r
SSKrSSKJr  SSKJr  SS	KJr  SS
KJr  \(       a  SSKr0 r0 rSS jrS rS rS rS rS rS rg)zSignal handling functions.    )absolute_import)print_function)division)unicode_literalsN)metrics)ControlCException)UTF8)
IS_WINDOWSc                     U [        5       ;  a  [        SX4-  5      eU(       a
  U[        U '   g[        U    R	                  U5        g)an  Registers a handler for signal signal_num.

Unlike calling signal.signal():
  - This function can be called from any thread (and will cause the handler to
    be run by the main thread when the signal is received).
  - Handlers are cumulative: When a given signal is received, all registered
    handlers will be executed (with the exception that only the last handler
    to register with is_final_handler=True will be called).

Handlers should make no ordering assumptions, other than that the last handler
to register with is_final_handler=True will be called after all the other
handlers.

Args:
  signal_num: The signal number with which to associate handler.
  handler: The handler.
  is_final_handler: Bool indicator whether handler should be called last among
                    all the handlers for this signal_num. The last handler to
                    register this way survives; other handlers registered with
                    is_final_handler=True will not be called when the signal
                    is received.
Raises:
  RuntimeError: if attempt is made to register a signal_num not in
      GetCaughtSignals.
zPAttempt to register handler (%s) for signal %d, which is not in GetCaughtSignalsN)GetCaughtSignalsRuntimeError_final_signal_handlers_non_final_signal_handlersappend)
signal_numhandleris_final_handlers      %platform/gsutil/gslib/sig_handling.pyRegisterSignalHandlerr   ,   sQ    4 '))
 47>6KL M M)0:&z*11':    c                 |    U [         ;   a  [         U     H  nU" X5        M     U [        ;   a  [        U    " X5        gg)zGlobal signal handler.

When a signal is caught we execute each registered handler for that signal.

Args:
  signal_num: Signal that was caught.
  cur_stack_frame: Unused.
N)r   r   )r   cur_stack_framer   s      r   _SignalHandlerr   O   s?     ---j9j* :)):&zC *r   c                  n    [        5        H'  n / [        U '   [        R                  " U [        5        M)     g)z^Initializes global signal handling.

Sets up global signal handler for each signal we handle.
N)r   r   signalr   )r   s    r   InitializeSignalHandlingr   _   s*    
 %&j-/z*
MM*n- 'r   c                      [         R                  [         R                  /n [        (       d  U R	                  [         R
                  5        U $ )zCReturns terminating signals that can be caught on this OS platform.)r   SIGINTSIGTERMr
   r   SIGQUIT)signalss    r   r   r   j   s.    ]]FNN+'	NN6>>"	.r   c                 6    [         (       aa  S[        R                  SS s=::  a  S:  aC  O  O@[        R                  R
                  nUR                  SSU 5      nUR                  US5        g[        R                  " U [        R                  5        g!    g= f)zMake best effort to kill the given process.

We ignore all exceptions so a caller looping through a list of processes will
continue attempting to kill each, even if one encounters a problem.

Args:
  pid: The process ID.
)   r   Nr#   )r#         r   )r
   sysversion_infoctypeswindllkernel32OpenProcessTerminateProcessoskillr   SIGKILL)pidr*   handles      r   KillProcessr2   s   st    		zv!1!1"1!5>>''h##Aq#.f*ggc6>>"	s   A+B .%B Bc                    U [         R                  :X  a  [        R                  " 5       R	                  [        R
                  5      (       a  SR                  [        R                  " [        R                  " 5       5      5      nSU [        R                  " SSU5      4-  n [        R                  R                  UR                  [         5      5        O"[        R                  R                  SU -  5        [&        R(                  " [+        5       S9  [&        R,                  " 5         [/        [0        R2                  " 5       5        g! ["        [$        4 a)  n[        R                  R                  U5         SnANSnAff = f)z5Final signal handler for multi-threaded main process. z@DEBUG: Caught CTRL-C (signal %d) - Exception stack trace:
    %sz\nz
    Nz$Caught CTRL-C (signal %d) - exiting
)	exception)r   r   logging	getLoggerisEnabledForDEBUGjoin	tracebackformat_listextract_stackresubr&   stderrwriteencoder	   UnicodeDecodeError	TypeErrorr   LogFatalErrorr   Shutdownr2   r-   getpid)r   r   stack_traceerres        r   MultithreadedMainSignalHandlerrK      s   6== ''66GGI11)2I2I2KLMk#RVVE8[%IJKc

D)* 
jj>KL	"3"56	biik !),  	

	s   "2E F E;;F c                 @    [        [        R                  " 5       5        g)z)Final signal handler for child processes.N)r2   r-   rG   )r   r   s     r   ChildProcessSignalHandlerrM      s    biikr   )F)__doc__
__future__r   r   r   r   r6   r-   r>   r   r&   r;   gslibr   gslib.exceptionr   gslib.utils.constantsr	   gslib.utils.system_utilr
   r(   r   r   r   r   r   r   r2   rK   rM    r   r   <module>rU      so    ! & %  '  	 	  
   - & .      ;FD .	,,r   