
    0                     ~   S 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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  SS
KJ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Jr   " S S\R:                  5      r " S S\R:                  5      r " S S\R:                  5      r  \
RB                  r"S r%/ SQr&S r'S r(S7S jr)S r*S  r+S! r,S" r- " S# S$\.5      r/\R`                  S% 5       r1\R`                  S& 5       r2    S8S' jr3     S9S) jr4S7S* jr5S(\Rl                  4S+ jr7S(\Rl                  \Rp                  Rl                  S(4S, jr9S- r:     S9S. jr;      S:S/ jr<S7S0 jr=S1 r>S2 r?S3 r@S4 rAS5 rBS6 rCg! \# a$     " S S\R:                  5      r!\!r" " S S5      r$ Nf = f);z6Functions to help with shelling out to other commands.    )absolute_import)division)unicode_literalsN)
argv_utils)config)
exceptions)log)
properties)named_configs)encoding)parallel)	platforms)mapc                       \ rS rSrSrSrg)OutputStreamProcessingException0   z>Error class for errors raised during output stream processing. N__name__
__module____qualname____firstlineno____doc____static_attributes__r       *lib/googlecloudsdk/core/execution_utils.pyr   r   0   s    Fr   r   c                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )PermissionError4   z'User does not have execute permissions.c                 F   > [         [        U ]  SR                  US95        g )Nz_{err}
Please verify that you have execute permission for all files in your CLOUD SDK bin folder)err)superr   __init__format)selferror	__class__s     r   r#   PermissionError.__init__7   s$    	/4)	--3VV->@r   r   r   r   r   r   r   r#   r   __classcell__r'   s   @r   r   r   4   s    /@ @r   r   c                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )InvalidCommandError=   z Command entered cannot be found.c                 F   > [         [        U ]  SR                  US95        g )Nz{cmd}: command not found)cmd)r"   r-   r#   r$   )r%   r0   r'   s     r   r#   InvalidCommandError.__init__@   s$    	
t-"))c)24r   r   r)   r+   s   @r   r-   r-   =   s    (4 4r   r-   c                       \ rS rSrSrSrg)TimeoutExpiredN   zDSimulate subprocess.TimeoutExpired on old (<3.3) versions of Python.r   Nr   r   r   r   r3   r3   N   s    Nr   r3   c                   .    \ rS rSrSrS rSS jrS rSrg)	SubprocessTimeoutWrapperT   a-  Forwarding wrapper for subprocess.Popen, adds timeout arg to wait.

subprocess.Popen.wait doesn't provide a timeout in versions < 3.3. This
class wraps subprocess.Popen, adds a backported wait that includes the
timeout arg, and forwards other calls to the underlying subprocess.Popen.

Callers generally shouldn't use this class directly: Subprocess will
return either a subprocess.Popen or SubprocessTimeoutWrapper as
appropriate based on the available version of subprocesses.

See
https://docs.python.org/3/library/subprocess.html#subprocess.Popen.wait.
c                     Xl         g Nproc)r%   r;   s     r   r#   !SubprocessTimeoutWrapper.__init__c   s    ir   Nc                 `   Uc  U R                   R                  5       $ [        R                  " 5       nX!-   nSnU R                   R                  5       nUcX  [        R                  " 5       U:  a
  [	        5       e[        R
                  " U5        U R                   R                  5       nUc  MX  U$ )zBusy-wait for wrapped process to have a return code.

Args:
  timeout: int, Seconds to wait before raising TimeoutExpired.

Returns:
  int, The subprocess return code.

Raises:
  TimeoutExpired: if subprocess doesn't finish before the given timeout.
g{Gz?)r;   waittimepollr3   sleep)r%   timeoutnowlaterdelayrets         r   r>   SubprocessTimeoutWrapper.waitg   s     
yy~~IIKcmeeIINNcK99; 
 

5iinn	 K
 jr   c                 .    [        U R                  U5      $ r9   )getattrr;   )r%   names     r   __getattr__$SubprocessTimeoutWrapper.__getattr__   s    TYY%%r   r:   r9   )	r   r   r   r   r   r#   r>   rK   r   r   r   r   r6   r6   T   s    4&r   r6   c                      [         R                  " [        R                  S5      n U (       a  U $ [        R
                  nU(       d  [        S5      eU$ )z<Gets the path to the Python interpreter that should be used.CLOUDSDK_PYTHONz!Could not find Python executable.)r   GetEncodedValueosenvironsys
executable
ValueError)cloudsdk_python
python_bins     r   GetPythonExecutablerW      s@    ,,RZZ9JK/~~*	
8
99	r   )ashbashbusyboxdashkshmkshpdkshshc                  L   SS/n [         R                  " [        R                  S5      nU(       a9  [        R                  R                  U5      [        ;   a  U R                  SU5        U  H+  n[        R                  R                  U5      (       d  M)  Us  $    [        S5      e)aq  Gets the path to the Shell that should be used.

First tries the current environment $SHELL, if set, then `bash` and `sh`. The
first of these that is found is used.

The shell must be Borne-compatible, as the commands that we execute with it
are often bash/sh scripts.

Returns:
  str, the path to the shell

Raises:
  ValueError: if no Borne compatible shell is found
z	/bin/bashz/bin/shSHELLr   zmYou must set your 'SHELL' environment variable to a valid Borne-compatible shell executable to use this tool.)
r   rO   rP   rQ   pathbasename_BORNE_COMPATIBLE_SHELLSinsertisfilerT   )shells
user_shellshells      r   _GetShellExecutableri      s     #&''

G<*BGG$$Z04LL
MM!Z e	ww~~el  	 O 	P Pr   c                     / nU (       a  UR                  U 5        U(       a  UR                  U5        UR                  U5        UR                  [        U5      5        U$ r9   )appendextendlist)interpreterinterpreter_argsexecutable_pathargs	tool_argss        r   _GetToolArgsrs      sP    )[!%&?#4:	r   c                    U c  [        [        R                  5      n [        R                  " U 5      n [        R
                  " U SS5        [        R                   H?  nU H6  n[        R
                  " XR                  5       UR                  SSS95        M8     MA     [        R
                  " U [        R                  [        R                  R                  5       R                  5        U $ )zGenerate the environment that should be used for the subprocess.

Args:
  env: {str, str}, An existing environment to augment.  If None, the current
    environment will be cloned and used as the base for the subprocess.

Returns:
  The modified env.
CLOUDSDK_WRAPPER1F)requiredvalidate)dictrP   rQ   r   	EncodeEnvSetEncodedValuer
   VALUESEnvironmentNameGetr   CLOUDSDK_ACTIVE_CONFIG_NAMEr   ConfigurationStoreActiveConfigrJ   )envsps      r   
GetToolEnvr      s     	[
rzz
C3#
3 2C8
 a
  "AEE55E$IK   	6--&&335::< 
*r   c                 \   [        U5      [        S/5      -
  nU(       a)  [        SR                  SR                  U5      5      5      eUR	                  S5      =(       d
    [        5       n[        R                  " [        R                  SS5      nUR                  5       n[        XFU /UQ76 $ )a  Constructs an argument list for calling the Python interpreter.

Args:
  executable_path: str, The full path to the Python main file.
  *args: args for the command
  **kwargs: python: str, path to Python executable to use (defaults to
    automatically detected)

Returns:
  An argument list to execute the Python interpreter

Raises:
  TypeError: if an unexpected keyword argument is passed
pythonz<ArgsForPythonTool() got unexpected keyword arguments '[{0}]'z, CLOUDSDK_PYTHON_ARGS )set	TypeErrorr$   joingetrW   r   rO   rP   rQ   splitrs   )rp   rq   kwargsunexpected_argumentspython_executablepython_args_strpython_argss          r   ArgsForPythonToolr      s     VsH:6
  &tyy1E'F GI Ijj*C.A.C,,jj("./%%'+	o
>8<
> >r   c                      [        SS/U /UQ76 $ )zConstructs an argument list for calling the cmd interpreter.

Args:
  executable_path: str, The full path to the cmd script.
  *args: args for the command

Returns:
  An argument list to execute the cmd interpreter
r0   z/crs   rp   rq   s     r   ArgsForCMDToolr     s     
edV_	<t	<<r   c                     [        SSU /UQ76 $ )a  Constructs an argument list for an executable.

 Can be used for calling a native binary or shell executable.

Args:
  executable_path: str, The full path to the binary.
  *args: args for the command

Returns:
  An argument list to execute the native binary
Nr   r   s     r   ArgsForExecutableToolr     s     
dD/	9D	99r   c                      [         R                  (       d#  [        SS[        R                  " 5       S   5      $ [        [        R                  " 5       5      $ )z*Constructs an argument list to run gcloud.Nr   )rR   rS   rs   r   GetDecodedArgvr   r   
GcloudPathr   r   r   ArgsForGcloudr   $  s<    	 dJ$=$=$?$BCC	6,,.	//r   c                   $    \ rS rSrSrS rS rSrg)_ProcessHolderi-  z@Process holder that can handle signals raised during processing.c                      S U l         S U l        g r9   processsignum)r%   s    r   r#   _ProcessHolder.__init__0  s    DLDKr   c                    Xl         U R                  (       ao  [        R                  " SR	                  UU R                  R
                  S95        U R                  R                  5       c  U R                  R                  5         ggg)zHandle the intercepted signal.z!Subprocess [{pid}] got [{signum}])r   pidN)r   r   r	   debugr$   r   r@   	terminate)r%   r   unused_frames      r   Handler_ProcessHolder.Handler4  sl    K||	ii3::ll ;  	 
				$  
% r   r   N)r   r   r   r   r   r#   r   r   r   r   r   r   r   -  s    H!r   r   c               +     #    [        [        R                  5      n[        R                  R                  U 5         Sv   [        R                  R	                  5         [        R                  R                  U5        g! [        R                  R	                  5         [        R                  R                  U5        f = f7f)z.Temporarily set process environment variables.N)ry   rP   rQ   updateclear)env_varsold_environs     r   
ReplaceEnvr   H  sv      RZZ +**H#	JJJJk" JJJJk"s   9C A>  >C >?B==C c              #      #    [         R                   " X5      n S v   [         R                   " X5        g ! [         R                   " X5        f = f7fr9   )signal)signohandlerold_handlers      r   _ReplaceSignalr   T  s3     e-+&	
MM%%FMM%%s   A5 AAAc           	         U(       a  [         R                  US'   U(       a  [         R                  US'   U(       a  [         R                  US'    U (       a;  [        U [        5      (       a&  U  Vs/ s H  n[        R
                  " U5      PM     n n[         R                  " U 4S[        US90UD6nXl        UR                   b!  UR#                  5       c  UR%                  5         [        U[&        R(                  5      (       a  UR+                  S5      n[        [-        [        R.                  UR1                  US	95      5      u  pU(       a  U" U
5        U(       a  U" U5        UR2                  $ s  snf ! [         ae  n	U	R                  [        R                  :X  a  [        U	R                  5      eU	R                  [        R                  :X  a  [        U S   5      ee Sn	A	ff = f)
zSee Exec docstring.stdoutstderrstdinr   r   r   Nutf-8)input)
subprocessPIPE
isinstancerm   r   EncodePopenr   OSErrorerrnoEACCESr   strerrorENOENTr-   r   r   r@   r   six	text_typeencoder   Decodecommunicate
returncode)rq   process_holderr   out_funcerr_funcin_strextra_popen_kwargsar   r!   r   r   s               r   _Execr   ]  so    #-??x #-??x ",//w

4&&
 +//$Qhooa $d/M:##6M:LMA & 	vvxkkm&&]]7#FHOOQ]]]-HIJ.&VV	
3 0	 

yyELL CLL))	ell	"Q((	
s+    E7 0 E2"E7 2E7 7
G&A G!!G&Fc           
      4   [         R                  " SU 5        [        5       n[        [        R
                  " 5       [        R                  5      (       ai  [        [        R                  UR                  5         [        [        R                  UR                  5         [        XXXE40 UD6nSSS5        SSS5        O[        XXXE40 UD6nU(       a  UR                  c  W$ [        R                  " W5        g! , (       d  f       NR= f! , (       d  f       NL= f)a|  Emulates the os.exec* set of commands, but uses subprocess.

This executes the given command, waits for it to finish, and then exits this
process with the exit code of the child process.

Args:
  args: [str], The arguments to execute.  The first argument is the command.
  env: {str: str}, An optional environment for the child process.
  no_exit: bool, True to just return the exit code of the child instead of
    exiting.
  out_func: str->None, a function to call with the stdout of the executed
    process. This can be e.g. log.file_only_logger.debug or log.out.write.
  err_func: str->None, a function to call with the stderr of the executed
    process. This can be e.g. log.file_only_logger.debug or log.err.write.
  in_str: bytes or str, input to send to the subprocess' stdin.
  **extra_popen_kwargs: Any additional kwargs will be passed through directly
    to subprocess.Popen

Returns:
  int, The exit code of the child if no_exit is True, else this method does
  not return.

Raises:
  PermissionError: if user does not have execute permission for cloud sdk bin
  files.
  InvalidCommandError: if the command entered cannot be found.
Executing command: %sN)r	   r   r   r   	threadingcurrent_thread_MainThreadr   r   SIGTERMr   SIGINTr   r   rR   exit)	rq   r   no_exitr   r   r   r   r   ret_vals	            r   Execr     s    D ))#T* "#. 	((*I,A,ABB 
(>(>	?&--)?)?@cX .,. A 
@	?
 D# *(*G &&.N((7 A@ 
@	?s$   8%D	C8,D	8
D	D		
Dc                 n    U (       a;  [        U [        5      (       a&  U  Vs/ s H  n[        R                  " U5      PM     n n[        R
                  " U 4S[        US90UD6n[        5       nXFl        UR                   b!  UR#                  5       c  UR%                  5          ['        U5      $ s  snf ! [         ae  nUR                  [        R                  :X  a  [        UR                  5      eUR                  [        R                  :X  a  [        U S   5      ee SnAff = f! [(         a    Us $ f = f)an  Run subprocess.Popen with optional timeout and custom env.

Returns a running subprocess. Depending on the available version of the
subprocess library, this will return either a subprocess.Popen or a
SubprocessTimeoutWrapper (which forwards calls to a subprocess.Popen).
Callers should catch TIMEOUT_EXPIRED_ERR instead of
subprocess.TimeoutExpired to be compatible with both classes.

Args:
  args: [str], The arguments to execute.  The first argument is the command.
  env: {str: str}, An optional environment for the child process.
  **extra_popen_kwargs: Any additional kwargs will be passed through directly
    to subprocess.Popen

Returns:
  subprocess.Popen or SubprocessTimeoutWrapper, The running subprocess.

Raises:
  PermissionError: if user does not have execute permission for cloud sdk bin
  files.
  InvalidCommandError: if the command entered cannot be found.
r   r   r   N)r   rm   r   r   r   r   r   r   r   r   r   r   r   r-   r   r   r   r@   r   r6   	NameError)rq   r   r   r   r   r!   r   s          r   
Subprocessr     s    0	

4&&*./$Qhooa $d/M:##6M:LMA "#.&vvxkkm#A&& 0	 

yyELL CLL))	ell	"Q((	
 
 Hs;    B3  B."B3 #
D% .B3 3
D"=A DD"%D43D4c                 T   U(       a  U R                   OU R                  nUR                  n U" 5       =(       d    SnU(       d#  U R                  5       b   UR	                  5         gUR                  S5      nUR                  S5      nU(       a  U" U5        Mm  ! [
         a     gf = f)z<Process output stream from a running subprocess in realtime.r   Nr   
)r   r   readliner@   closer   decoderstrip)r;   r!   r   streamstream_readerlineline_strs          r   _ProcessStreamHandlerr     s    4;;4;;&//-?!cDDIIK+ {{7#Hv&Hh 	
  s   B 
B'&B'c                    / n/ n[        SS9    U R                  R                  5       =(       d    SnU R                  R                  5       =(       d    SnU(       d  U(       d  U R	                  5       b  OU(       aK  U(       a  UR                  U5        UR                  S5      n	U(       d  U	R                  S5      OU	n	U" U	5        U(       aK  U(       a  UR                  U5        UR                  S5      n
U(       d  U
R                  S5      OU
n
U" U
5        GM  SSS5        U R                  XV4$ ! , (       d  f       N= f)z6Log stdout and stderr output from running sub-process.rv   )PYTHONUNBUFFEREDr   Nr   r   )	r   r   r   r   r@   rk   r   r   r   )r;   rawstdout_handlerstderr_handlercapturer   r   out_lineerr_lineout_strerr_strs              r   _StreamSubprocessOutputr     s     &&3'
%%'.3h%%'.3h(		(?	
--
!//'*03'..(w	
--
!//'*03'..(w#  (& 
&	((' ('s   DD33
Ec                    U (       Ga7  Sn[        U S5      (       a  U R                  nO[        U S5      (       a  U R                  nUb  U R                  5       c  U R	                  5          U R
                  (       a5  U R
                  R                  (       d  U R
                  R                  5         U R                  (       a5  U R                  R                  (       d  U R                  R                  5         U R                  (       a7  U R                  R                  (       d  U R                  R                  5         gggg! [         a     gf = f)z$Kill process and close open streams.Nr   exitcode)hasattrr   r   r@   r   r   closedr   r   r   r   )r;   codes     r   _KillProcIfRunningr   )  s    	Dt\""__d	z	"	"]]d|tyy{*
nn	DJJ--

	T[[//	T[[// 0 
  
s   +CE 
EEc           	      |   [         R                  " SU 5        [        US9n[        5       n[	        [
        R                  UR                  5         [	        [
        R                  UR                  5         U=(       d    [         R                  nU=(       d    [         R                  R                  n	U(       a  [        R                  US'    U (       a;  [        U [        5      (       a&  U  V
s/ s H  n
[        R                   " U
5      PM     n n
[        R"                  " U 4U[        R                  [        R                  S.UD6nXl        U(       a[  [&        R(                  " U5      R+                  S5      n UR,                  R/                  U5        UR,                  R1                  5          [>        R@                  " S5       nURC                  [D        USU45      nURC                  [D        US	U	45      nURG                  5         URG                  5         SSS5        URT                  b  [;        U5        URV                  nSSS5        SSS5        U(       a  URT                  c  W$ [X        RZ                  " W5        gs  sn
f ! [2         a]  nUR4                  [4        R6                  :X  d  UR4                  [4        R8                  :X  a   SnAGN$[;        U5        [=        U5      eSnAff = f! , (       d  f       N= f! [H         a  n[;        U5        [=        U5      eSnAff = f! [2         ae  nUR4                  [4        RJ                  :X  a  [M        URN                  5      eUR4                  [4        RP                  :X  a  [S        U S
   5      ee SnAff = f! , (       d  f       GN^= f! , (       d  f       GNh= f)a  Emulates the os.exec* set of commands, but uses subprocess.

This executes the given command, waits for it to finish, and then exits this
process with the exit code of the child process. Allows realtime processing of
stderr and stdout from subprocess using threads.

Args:
  args: [str], The arguments to execute.  The first argument is the command.
  env: {str: str}, An optional environment for the child process.
  no_exit: bool, True to just return the exit code of the child instead of
    exiting.
  out_func: str->None, a function to call with each line of the stdout of the
    executed process. This can be e.g. log.file_only_logger.debug or
    log.out.write.
  err_func: str->None, a function to call with each line of the stderr of
    the executed process. This can be e.g. log.file_only_logger.debug or
    log.err.write.
  in_str: bytes or str, input to send to the subprocess' stdin.
  **extra_popen_kwargs: Any additional kwargs will be passed through directly
    to subprocess.Popen

Returns:
  int, The exit code of the child if no_exit is True, else this method does
  not return.

Raises:
  PermissionError: if user does not have execute permission for cloud sdk bin
  files.
  InvalidCommandError: if the command entered cannot be found.
r   r   r   r   r   r   r   N   FTr   ).r	   r   r   r   r   r   r   r   r   Printstatusr   r   r   rm   r   r   r   r   r   r   r   r   writer   r   r   EPIPEEINVALr   r   r   GetPool
ApplyAsyncr   r~   	Exceptionr   r   r   r   r-   r   r   rR   r   )rq   r   r   r   r   r   r   r   out_handler_funcerr_handler_funcr   r   excpoolstd_out_futurestd_err_futureer!   r   s                      r   ExecWithStreamingOutputr  >  s   J ))#T* 	s#!#.fnnn&<&<=	~'='=	>!.SYY!5SZZ%5%5	&0oo7#(JtT**
 /33d(//!$d$3T Ks:??$.OOK7IK!"==(//8&	9GGMM&!GGMMO
	3"d!__-B./8H-IKN!__-B./7G-HJN   #$ 
			* 	1gk 
? >p &&.N((7] 4  9		U[[(		U\\) #3C889 #"  	3
Q
/2
2	3  99$-
-YY%,,&#DG,
,Q 
?	> >=s   %N,4AN L(, J A+L(85J.L AK/L $NN, L(
K,<K'L(K''K,,L(/
K=9L <N=L  
L%
L  L%%L((
N2A NNN
N)	$N,,
N;c           	         [         R                  " SU 5        [        US9n[        5       n[	        [
        R                  UR                  5         [	        [
        R                  UR                  5         U=(       d    [         R                  n	U=(       d    [         R                  R                  n
U(       a  [        R                  US'    U (       a;  [        U [        5      (       a&  U  Vs/ s H  n[        R                   " U5      PM     n n[        R"                  " U 4U[        R                  [        R                  S.UD6nU(       a[  [$        R&                  " U5      R)                  S5      n UR*                  R-                  U5        UR*                  R/                  5          [=        XU
US9  Xl%        URL                  b  [9        U5        URN                  nSSS5        SSS5        U(       a  URL                  c  W$ [P        RR                  " W5        gs  snf ! [0         a\  nUR2                  [2        R4                  :X  d  UR2                  [2        R6                  :X  a   SnAN[9        U5        [;        U5      eSnAff = f! [>         a  n[9        U5        [;        U5      eSnAff = f! [0         ae  nUR2                  [2        R@                  :X  a  [C        URD                  5      eUR2                  [2        RF                  :X  a  [I        U S   5      ee SnAff = f! , (       d  f       GNL= f! , (       d  f       GNV= f)	aF  Emulates the os.exec* set of commands, but uses subprocess.

This executes the given command, waits for it to finish, and then exits this
process with the exit code of the child process. Allows realtime processing of
stderr and stdout from subprocess without threads.

Args:
  args: [str], The arguments to execute.  The first argument is the command.
  env: {str: str}, An optional environment for the child process.
  no_exit: bool, True to just return the exit code of the child instead of
    exiting.
  out_func: str->None, a function to call with each line of the stdout of the
    executed process. This can be e.g. log.file_only_logger.debug or
    log.out.write.
  err_func: str->None, a function to call with each line of the stderr of
    the executed process. This can be e.g. log.file_only_logger.debug or
    log.err.write.
  in_str: bytes or str, input to send to the subprocess' stdin.
  raw_output: bool, stream raw lines of output perserving line
    endings/formatting.
  **extra_popen_kwargs: Any additional kwargs will be passed through directly
    to subprocess.Popen

Returns:
  int, The exit code of the child if no_exit is True, else this method does
  not return.

Raises:
  PermissionError: if user does not have execute permission for cloud sdk bin
  files.
  InvalidCommandError: if the command entered cannot be found.
r   r   r   r  r   N)r   r   r   r   )*r	   r   r   r   r   r   r   r   r   r  r  r   r   r   rm   r   r   r   r   r   r   r   r  r   r   r   r  r  r   r   r   r  r   r   r   r   r-   r   r   r   rR   r   )rq   r   r   r   r   r   
raw_outputr   r   r  r  r   r   r  r  r!   r   s                    r   "ExecWithStreamingOutputNonThreadedr    sj   P ))#T* 	s#!#.fnnn&<&<=	~'='=	>!.SYY!5SZZ%5%5	&0oo7##JtT**
 /33d(//!$d$3T Ks:??$.OOK7IK ==(//8&	9GGMM&!GGMMO	3
!!1A&02  !				* 	1gc 
? >h &&.N((7U 4  9		U[[(		U\\) #3C889  	3
Q
/2
2	3  99$-
-YY%,,&#DG,
,G 
?	> >=s   %L44AL" J0, HA%J025H(J3*L"L4J0
J)<J %J0*J  JJ0
J-J((J--J00
L:A LLL""
L1	,L44
Mc                 Z   ^ ^ SR                  T=(       d    SS9mUU 4S jn[        U5      $ )ab  Run a section of code with CTRL-C disabled.

When in this context manager, the ctrl-c signal is caught and a message is
printed saying that the action cannot be cancelled.

Args:
  stream: the stream to write to if SIGINT is received
  message: str, optional: the message to write

Returns:
  Context manager that is uninterruptible during its lifetime.
z

{message}

z#This operation cannot be cancelled.)messagec                 (   > TR                  T5        g r9   )r  )unused_signalr   r  r   s     r   _Handler(UninterruptibleSection.<locals>._Handler   s    
LLr   )r$   CtrlCSection)r   r  r  s   `` r   UninterruptibleSectionr    s4      &&?? ' B'	h	r   c                      S n [        U 5      $ )z<Run a section of code where CTRL-C raises KeyboardInterrupt.c                     A A[         er9   )KeyboardInterrupt)r   frames     r   r  )RaisesKeyboardInterrupt.<locals>._Handler'  s    
r   )r  )r  s    r   RaisesKeyboardInterruptr$  %  s     
h	r   c                 6    [        [        R                  U 5      $ )a   Run a section of code with CTRL-C redirected handler.

Args:
  handler: func(), handler to call if SIGINT is received. In every case
    original Ctrl-C handler is not invoked.

Returns:
  Context manager that redirects ctrl-c handler during its lifetime.
)r   r   r   )r   s    r   r  r  -  s     
w	//r   c           	         Sn[        U S5      (       a  U R                  nO[        U S5      (       a  U R                  nUb  g[        R                  R                  5       [        R                  R                  :X  a  [        R                  " SSSS[        R                  " U R                  5      /[        R                  [        R                  S9nUR                  5       u  p4UR                  S	:w  a6  [        U5      (       a%  [        S
R!                  U R                  X45      5      egg["        R$                  " ['        [(        R*                  5      5      nSUS'   [        R                  " / SQ[        R                  [        R                  US9nUR                  5       u  p4UR-                  S5      nUR                  S	:w  a$  [        SR!                  U R                  5      5      e0 nUR/                  5       R1                  S5       Hp  n[2        R4                  " SU5      R7                  5       u  p[9        U	5      n	[9        U
5      n
UR;                  U	5      nU(       d  U
/Xy'   M_  UR=                  U
5        Mr     U R                  /nU R                  /nU(       aS  UR?                  5       nUR;                  U5      nU(       a"  URA                  U5        URA                  U5        U(       a  MS  U H  n
[C        U
5        M     g)zKills a subprocess using an OS specific method when python can't do it.

This also kills all processes rooted in this process.

Args:
  p: the Popen or multiprocessing.Process object to kill

Raises:
  RuntimeError: if it fails to kill the process
Nr   r   taskkillz/Fz/Tz/PID)r   r   r   z:Failed to call taskkill on pid {0}
stdout: {1}
stderr: {2}zen_US.UTF-8LANG)psz-e-ozppid=r*  zpid=)r   r   r   r   z*Failed to get subprocesses of process: {0}
z\s*(\d+)\s+(\d+))"r   r   r   r   OperatingSystemCurrentWINDOWSr   r   r   r   r   r   r   _IsTaskKillErrorRuntimeErrorr$   r   rz   ry   rP   rQ   r   stripr   rematchgroupsintr   rk   poprl   _KillPID)r   r   taskkill_processr   r   new_envget_pids_processpid_mapr   ppidr   childrenall_pids
to_processcurrents                  r   KillSubprocessrA  :  sl    
$Q<<Dq*::D	
&&(I,E,E,M,MM!''	T4quu)=>  (335V""a',<V,D,D 
H6!%%(* *	 -E'   bjj!12G#GFO!'' )F/9/9,3	5
 (335V]]7#F""a'E &-) ) G$$T*HH0$7>>@ktYdHcT"h + wH%%J
 gW%h	(#! * sm r   c                     Sn[         R                  " S5      4nU H
  nX0;   d  M
    g   U H  nUR                  U 5      (       d  M    g   g)zReturns whether the stderr output of taskkill indicates it failed.

Args:
  stderr: the string error output of the taskkill command

Returns:
  True iff the stderr is considered to represent an actual error.
)zAccess is denied.z)The operation attempted is not supported.z)There is no running instance of the task.z6There is no running instance of the task to terminate.zThe process "\d+" not found\.FT)r2  compilesearch)r   non_error_reasonsnon_error_patternsreasonpatterns        r   r/  r/    sX    @ 	jj125!f " $g~~f $ 
r   c                 0    [         R                  " U [        R                  5        [        R                  " 5       S-   n[        R                  " 5       U:  aB  [        U 5      (       d  g[        R                  " S5        [        R                  " 5       U:  a  MB  [         R                  " U [        R                  5        g! [         aK  nSUR                  ;  a1  [        R                  " [        R                  " 5       S   5         SnAg SnAgSnAff = f)zKills the given process with SIGTERM, then with SIGKILL if it doesn't stop.

Args:
  pid: The process id of the process to check.
   Ng?zNo such process   )rP   killr   r   r?   _IsStillRunningrA   SIGKILLr   r   r   reraiserR   exc_info)r   deadliner&   s      r   r7  r7    s    ,GGC  yy{QH
))+
 S!!
jjo ))+
  GGC 	 ,.*++ /,s$   A&C  )/C  %C   
D
<DDc                     [         R                  " U [         R                  5      u  pX4S:X  a  g g! [         aF  nSUR                  ;  a,  [
        R                  " [        R                  " 5       S   5         SnAgSnAff = f)zDetermines if the given pid is still running.

Args:
  pid: The process id of the process to check.

Returns:
  bool, True if it is still running.
)r   r   TzNo child processesrK  NF)	rP   waitpidWNOHANGr   r   r   rO  rR   rP  )r   
actual_pidr   r&   s       r   rM  rM    sq    ,C4ZV# $
 
 
 ,5>>1*+	,s   .3 
B<A>>Br9   )NNNN)NFNNN)NFNNNF)Dr   
__future__r   r   r   
contextlibr   rP   r2  r   r   rR   r   r?   googlecloudsdk.corer   r   r   r	   r
   "googlecloudsdk.core.configurationsr   googlecloudsdk.core.utilr   r   r   r   	six.movesr   Errorr   r   r-   r3   TIMEOUT_EXPIRED_ERRAttributeErrorr6   rW   rc   ri   rs   r   r   r   r   r   objectr   contextmanagerr   r   r   r   r   r  r   r  r   r   r  r  r  r$  r  rA  r/  r7  rM  r   r   r   <module>ra     s    = &  '   	 	   
   + & * # * < - - . 
 Gj&6&6 G@j&& @4*** 4>&"11@ 	 P:B>6
=:"0!V !6 # # & & -b :z+\ %*399 ( !&+.99+.::+;+;$)	)<, !%$)%)%)#'gV ,0/40404.227fR ( 
0Pl>,0w  6&Oz'' O '.& .&6&s   9F 'F<;F<