
    iC                        d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlmZ ddlmZmZmZ ddlmZmZ  ej,                  d      j.                  Zdeddfd	ZdZ ej6                  e      Zd
Z G d dej>                        Z  G d dejB                        Z" G d d      Z# G d de ejH                        Z$ G d de       Z% G d d      Z&y)zKBi-directional asyncio.Transport implementations based on file descriptors.    N)Thread)AnyClassVarSequence   )
JsonObjectget_intargsreturnc                  0    t        |  dk7  rt        d      y )Nr   zprctl() failed)	sys_prctlOSError)r
   s    4/usr/lib/python3/dist-packages/cockpit/transports.pyprctlr      s     $1&''     i   c                       e Zd ZU dZee   ed<   ej                  ed<   ej                  ed<   ded<   eed<   eed<   e
ed	<   e
ed
<   e
ed<   dZe
ed<   	 	 d.dej                  dej                  dededdf
 fdZd/dZde
fdZd/dZd/dZd/dZd/dZd0d1dZde
fdZd/dZdefd Zd2d!Zd3d4d"Zd/d#Zd/d$Zd/d%Zd&eddfd'Zd&eddfd(Zd/d)Zdej@                  fd*Z!de
fd+Z"dej@                  ddfd,Z#d/d-Z$ xZ%S )5
_Transporti   
BLOCK_SIZE_loop	_protocolzcollections.deque[bytes] | None_queue_in_fd_out_fd_closing_is_reading_eofF_eio_is_eofNloopprotocolin_fdout_fdextrazdict[str, object] | Nonec                 ~   t         |   |       || _        || _        t        j                  d| |||       d | _        d| _        d| _        d| _	        || _
        || _        t        j                  |d       ||k7  rt        j                  |d       | j                  j                  |        | j                          y )Nz/Created transport %s for protocol %s, fds %d %dF)super__init__r   r   loggerdebugr   r   r   r   r   r   osset_blockingconnection_maderesume_reading)selfr   r   r    r!   r"   	__class__s         r   r%   z_Transport.__init__9   s    
 	
!FhX]_ef 	
u%U?OOFE*&&t,r   r   c                    t         j                  d| | j                  | j                         	 t	        j
                  | j                  t        j                        }|dk7  r;t         j                  dt        |             | j                  j                  |       y t         j                  d       | j!                          | j                  j#                         }|s| j%                          y y # t        $ r Y y t        $ rL}| j                  r |j                  t        j                  k(  rd}n| j                  |       Y d }~y Y d }~d }~ww xY w)NzRead ready on %s %s %dr   z  read %d bytesz	  got EOF)r&   r'   r   r   r(   readr   r   BlockingIOErrorr   r   errnoEIOabortlendata_received_close_readereof_receivedclose)r,   dataexc	keep_opens       r   _read_readyz_Transport._read_readyT   s    -tT^^T[[Q	774;;
(=(=>D 3;LL*CI6NN((.LL% 335I

 %  	 	CII$: 

3	 	s   .C/ /	E:E=E		Ec                     | j                   S N)r   r,   s    r   
is_readingz_Transport.is_readingm       r   c                 2    | j                          d| _        y N)pause_readingr   r?   s    r   r6   z_Transport._close_readerp   s    r   c                 v    | j                   r-| j                  j                  | j                         d| _         y y NF)r   r   remove_readerr   r?   s    r   rE   z_Transport.pause_readingt   s.    JJ$$T[[1$D r   c                     | j                   sH| j                  dk7  r8| j                  j                  | j                  | j                         d| _         y y y )NrD   T)r   r   r   
add_readerr<   r?   s    r   r+   z_Transport.resume_readingy   sF     DKK2$5JJ!!$++t/?/?@#D %6r   c                      y r>    r?   s    r   _closez_Transport._close   s    r   c                     d| _         | j                          | j                          | j                  j	                  | j
                  j                  |       | j                          y NT)r   r6   _remove_write_queuer   	call_soonr   connection_lostrM   )r,   r:   s     r   r3   z_Transport.abort   sH      "

T^^;;SAr   c                     t         r>   NotImplementedErrorr?   s    r   can_write_eofz_Transport.can_write_eof       !!r   c                     | j                   rJ d| _         | j                  't        j                  d|        | j	                          y t        j                  d|        y )NTz%s got EOF.  closing backend.z,%s got EOF.  bytes in queue, deferring close)r   r   r&   r'   _write_eof_nowr?   s    r   	write_eofz_Transport.write_eof   sI    99}	;;LL8$?!LLGNr   c                 T    | j                   yt        d | j                   D              S )Nr   c              3   2   K   | ]  }t        |        y wr>   )r4   ).0blocks     r   	<genexpr>z3_Transport.get_write_buffer_size.<locals>.<genexpr>   s     7%3u:7s   )r   sumr?   s    r   get_write_buffer_sizez _Transport.get_write_buffer_size   s$    ;;74;;777r   c                      y)N)r   r   rL   r?   s    r   get_write_buffer_limitsz"_Transport.get_write_buffer_limits   s    r   c                 *    ||dk(  sJ ||dk(  sJ y y Nr   rL   )r,   highlows      r   set_write_buffer_limitsz"_Transport.set_write_buffer_limits   s(    |tqy(({cQh&&h{r   c                     t         r>   rT   r?   s    r   rY   z_Transport._write_eof_now   rW   r   c                 @   t         j                  d|        | j                  J 	 t        j                  | j
                  | j                        }t         j                  d|       |r| j                  j                         }t        |      |kD  r4t         j                  d       | j                  j                  ||d         n'|t        |      z  }t         j                  d|       |r| j                  stt         j                  d       | j                          | j                  r%t         j                  d       | j                          | j                  r| j                          y y y # t        $ r d}Y *t        $ r}| j                  |       Y d }~y d }~ww xY w)Nz%s _write_readyr   z,  successfully wrote %d bytes from the queuez  incomplete block.  Stop.z&  removed complete block.  %d remains.z%s queue drained.z'%s queue drained.  closing backend now.)r&   r'   r   r(   writevr   r0   r   r3   popleftr4   
appendleftrP   r   rY   r   )r,   n_bytesr:   r^   s       r   _write_readyz_Transport._write_ready   sC   &-{{&&&	iidkk:G 	CWMKK'')E5zG#9:&&uWX7s5z!GLLA7K  {{LL,-$$&yyFG##%}}

  %  	G 	JJsO	s   *E, ,F:FFFc                     | j                   G| j                  j                          | j                  j	                  | j
                         d | _         y y r>   )r   r   resume_writingr   remove_writerr   r?   s    r   rP   z_Transport._remove_write_queue   s>    ;;"NN))+JJ$$T\\2DK #r   r9   c                 ,   t         j                  d| | j                         | j                  J | j                  j                  | j                  | j                         t        j                  |f      | _        | j                  j                          y )Nz!%s creating write queue for fd %s)r&   r'   r   r   r   
add_writerro   collectionsdequer   pause_writingr,   r9   s     r   _create_write_queuez_Transport._create_write_queue   si    8$M{{"""

dllD,=,=>!''0$$&r   c                    | j                   r!t        j                  d| j                         y | j                  rJ | j
                  | j
                  j                  |       t        | j
                        t        kD  rPdj                  | j
                        }| j
                  j                          | j
                  j                  |       y 	 t        j                  | j                  |      }|t        |      k7  r| j!                  ||d         y y # t        $ r d}Y 1t        $ r}| j                  |       Y d }~y d }~ww xY w)Nz+ignoring write() to closing transport fd %ir   r   )r   r&   r'   r   r   r   appendr4   IOV_MAXjoinclearr(   writer0   r   r3   ry   )r,   r9   all_datarn   r:   s        r   r   z_Transport.write   s     ==LLFU99};;"KKt$ 4;;')88DKK0!!#""8,	hht||T2G c$i$$T'(^4    	G 	JJsO	s    D E"E*E  Ec                     | j                   ry d| _         | j                          | j                  y | j                          y rO   )r   r6   r   r3   r?   s    r   r8   z_Transport.close   s5    ==;;"

r   c                     | j                   S r>   )r   r?   s    r   get_protocolz_Transport.get_protocol  s    ~~r   c                     | j                   S r>   )r   r?   s    r   
is_closingz_Transport.is_closing  s    }}r   c                     t         r>   rT   )r,   r   s     r   set_protocolz_Transport.set_protocol  rW   r   c                 $    | j                          y r>   )rM   r?   s    r   __del__z_Transport.__del__
  s    r   )rD   rD   Nr   Nr>   )r:   zException | Noner   N)r   ztuple[int, int])NN)rf   
int | Nonerg   r   r   N)&__name__
__module____qualname__r   r   int__annotations__asyncioAbstractEventLoopProtocolboolr   r%   r<   r@   r6   rE   r+   rM   r3   rV   rZ   ra   rc   rh   rY   ro   rP   bytesry   r   r8   BaseProtocolr   r   r   r   __classcell__r-   s   @r   r   r   *   sf    +J+ $$$--KLN
JK
 1359	00"++  +. 3	62 D  %
$"t "O8s 8
'"B' '$ '5% 5D 5@g22 D "W%9%9 "d "r   r   c                       e Zd ZdZddZy)SubprocessProtocolzBAn extension to asyncio.Protocol for use with SubprocessTransport.Nc                     t         )z"Called when subprocess has exited.rT   r?   s    r   process_exitedz!SubprocessProtocol.process_exited  s    !!r   r   )r   r   r   __doc__r   rL   r   r   r   r     s
    L"r   r   c                       e Zd ZdefdZy)
WindowSizevaluec                 H    t        |d      | _        t        |d      | _        y )Nrowscols)r	   r   r   )r,   r   s     r   r%   zWindowSize.__init__  s    E6*	E6*	r   N)r   r   r   r   r%   rL   r   r   r   r     s    +j +r   r   c                   J    e Zd ZU dZdZded<   dZded<   dZded<   ded	<   d
ddede	fdZ
d&dZd
dddej                  dedee	   dedddef fdZdeddfdZdefdZd'dZdefdZd(dZdedej2                  fd Zd!ej8                  ddfd"Zd'd#Zd'd$Zd'd%Z  xZ!S ))SubprocessTransporta  A bi-directional transport speaking with stdin/out of a subprocess.

    Note: this is not really a normal SubprocessTransport.  Although it
    implements the entire API of asyncio.SubprocessTransport, it is not
    designed to be used with asyncio.SubprocessProtocol objects.  Instead, it
    pair with normal Protocol objects which also implement the
    SubprocessProtocol defined in this module (which only has a
    process_exited() method).  Whatever the protocol writes is sent to stdin,
    and whatever comes from stdout is given to the Protocol via the
    .data_received() function.

    If stderr is configured as a pipe, the transport will separately collect
    data from it, making it available via the .get_stderr() method.
    Nr   _pty_fdzsubprocess.Popen[bytes] | None_process_returncodezSpooler | None_stderrFresetr   r   c                t    | j                   ,| j                   j                  |      j                  d      S y)Nr   replace)errors )r   getdecode)r,   r   s     r   
get_stderrzSubprocessTransport.get_stderr0  s5    <<#<<##%#077y7IIr   c                 L    dt         dt         dd f fdd
 fd}d
 fd}	 t        j                  j                         j                  j                  |       y # t        t        f$ r, t        dj                   |d	      j                          Y y w xY w)Npidstatusr   c                 P   | j                   k(  sJ t        j                  t              sJ 	 t	        j
                  |      _        t        j                  dj                         j                  sj                  j                          y y # t        $ r
 |_        Y Zw xY w)NzProcess exited with status %d)r   
isinstancer   r   r(   waitstatus_to_exitcoder   
ValueErrorr&   r'   r   r   )r   r   processr,   s     r   child_exitedz4SubprocessTransport.watch_exit.<locals>.child_exited7  s    '++%%%dnn.@AAA*#%#<#<V#D  LL8$:J:JK==--/ !	  *#) *s   B B%$B%c                      t        j                  j                  d      \  } }j                  j	                         t        j
                          | |       y re   )r(   waitpidr   r   rH   r8   )r   r   r   pidfdr   r,   s     r   pidfd_readyz3SubprocessTransport.watch_exit.<locals>.pidfd_readyD  sB    **W[[!4KCJJ$$U+HHUOf%r   c                      t        j                  j                  d      \  } }j                  j	                  | |       y re   )r(   r   r   r   call_soon_threadsafe)r   r   r   r   r,   s     r   waitpid_threadz6SubprocessTransport.watch_exit.<locals>.waitpid_threadJ  s1    **W[[!4KCJJ++L#vFr   zcockpit-waitpid-T)nametargetdaemonr   )
r   r(   
pidfd_openr   r   rJ   AttributeErrorr   r   start)r,   r   r   r   r   r   s   ``  @@r   
watch_exitzSubprocessTransport.watch_exit6  s    	0c 	03 	04 	0	& 	&	G	fMM'++.EJJ!!%5( 	f*7;;-8X\]cce	fs   ;A( (8B#"B#)ptywindowr   r   r
   r   r   zWindowSize | Nonekwargsc                   dfd}rt        j                         \  | _        }|| j                  |       ||d<   t	        j
                  |f|||dd|| _        t        j                  |       | j                  | j                  }
}	d| _        nt	        j
                  |ft        j                  t        j                  |d|| _        | j                  j                  sJ | j                  j                  sJ | j                  j                  j                         }	| j                  j                  j                         }
| j                  j                  4t        || j                  j                  j                               | _        nd | _        t         | E  |||	|
       | j%                  | j                         y )Nc                      t        t        t        j                          r&t	        j
                  dt        j                  d       y y re   )r   SET_PDEATHSIGsignalSIGTERMfcntlioctltermios	TIOCSCTTY)r   s   r   
preexec_fnz0SubprocessTransport.__init__.<locals>.preexec_fn`  s/    -0Aw00!4 r   stderrT)stdinstdoutr   start_new_session)r   r   r   r   )r(   openptyr   set_window_size
subprocessPopenr   r8   r   PIPEr   r   filenor   Spoolerr   r$   r%   r   )r,   r   r   r
   r   r   r   r   
session_fdr    r!   r-   s       `      r   r%   zSubprocessTransport.__init__V  s|   	5
 ')zz|$DL*!$$V,)F8&,,T f3=j8BVZf^dfDM HHZ  LL$,,6E#D ',,T NQ[Q`Q`8BNFLNDM==&&&&==''''MM((//1E]]((//1F==+"4)=)=)D)D)FGDLDLx7&r   sizec           	      (   | j                   J t        dt        |j                  d            }t        dt        |j                  d            }t        j                  | j                   t        j                  t        j                  d||             y )Nr   i  2H4x)r   maxminr   r   r   r   r   
TIOCSWINSZstructpack)r,   r   r   r   s       r   r   z#SubprocessTransport.set_window_size  sh    ||'''1c$))Y/01c$))Y/0DLL'"4"4fkk&$PT6UVr   c                 N    | j                   J | j                   j                  d uS r>   )r   r   r?   s    r   rV   z!SubprocessTransport.can_write_eof  s'    }}(((}}""$..r   c                     | j                   J | j                   j                  J | j                   j                  j                          d| _        y rC   )r   r   r8   r   r?   s    r   rY   z"SubprocessTransport._write_eof_now  sE    }}(((}}""...!!#r   c                 J    | j                   J | j                   j                  S r>   )r   r   r?   s    r   get_pidzSubprocessTransport.get_pid  s"    }}(((}}   r   c                     | j                   S r>   )r   r?   s    r   get_returncodez"SubprocessTransport.get_returncode  rA   r   fdc                     t         r>   rT   )r,   r   s     r   get_pipe_transportz&SubprocessTransport.get_pipe_transport  rW   r   sigc                    | j                   J | j                  ,t        j                  d|| j                   j                         y 	 t        j                  | j                   j                  |       t        j                  d|| j                   j                         y # t        $ r. t        j                  d|| j                   j                         Y y w xY w)Nz3won't attempt %s to process %i.  It exited already.zsent %s to process %iz3can't send %s to process %i.  It's exited just now.)r   r   r&   r'   r   r(   killProcessLookupError)r,   r   s     r   send_signalzSubprocessTransport.send_signal  s    }}((( 'LLNPSUYUbUbUfUfg	hGGDMM%%s+LL0#t}}7H7HI! 	hLLNPSUYUbUbUfUfg	hs   AB 4CCc                 B    | j                  t        j                         y r>   )r   r   r   r?   s    r   	terminatezSubprocessTransport.terminate      (r   c                 B    | j                  t        j                         y r>   )r   r   SIGKILLr?   s    r   r   zSubprocessTransport.kill  r   r   c                    | j                   &t        j                  | j                          d | _         | j                  ]| j                  j                  5| j                  j                  j                          d | j                  _        	 | j                          y y # t        $ r- t        j                  d| j                  j                         Y y w xY w)Nzcan't kill %i due to EPERM)
r   r(   r8   r   r   r   PermissionErrorr&   r'   r   r?   s    r   rM   zSubprocessTransport._close  s    <<#HHT\\"DL==$}}"".##))+&*#N  % # N94==;L;LMNs   B 3CC)r   zsubprocess.Popen[bytes]r   Nr   )r   r   )"r   r   r   r   r   r   r   r   r   strr   r   r   r   r   r   r   r%   r   r   rV   rY   r   r   r   	Transportr   r   Signalsr   r   r   rM   r   r   s   @r   r   r     s    !G\ 15H.5 $K$*/ 4 C fJ #/3,'00,'-,'  },'
 ,' -,' ,'\WJ W4 W/t /! ! "S "W->-> "hv~~ h$ h0))Nr   r   c            	       r     e Zd ZdZd
dej
                  dej                  dedef fdZde	fdZ
dd	Z xZS )StdioTransportzA bi-directional transport that corresponds to stdin/out.

    Can talk to just about anything:
        - files
        - pipes
        - character devices (including terminals)
        - sockets
    r   r   r   r   c                 *    t         |   ||||       y r>   )r$   r%   )r,   r   r   r   r   r-   s        r   r%   zStdioTransport.__init__  s    x7r   r   c                      yrG   rL   r?   s    r   rV   zStdioTransport.can_write_eof  s    r   c                     t        d      )NzCan't write EOF to stdout)RuntimeErrorr?   s    r   rY   zStdioTransport._write_eof_now  s    677r   )r   r   r   )r   r   r   r   r   r   r   r   r%   r   rV   rY   r   r   s   @r   r  r    sH    8W66 8'BRBR 8[^ 8lo 8t 8r   r  c                       e Zd ZU dZej
                  ed<   eed<   ded<   dej
                  defdZddZ	d	e
fdZddde
d	efdZddZddZy
)r   zConsumes data from an fd, storing it in a buffer.

    This makes a copy of the fd, so you don't have to worry about holding it
    open.
    r   _fdzlist[bytes]	_contentsr   r   c                     || _         d| _        g | _        t        j                  |      | _        t        j
                  | j                  d       |j                  | j                  | j                         y )NrD   F)r   r
  r  r(   dupr)   rJ   r<   )r,   r   r   s      r   r%   zSpooler.__init__  sP    
66":
%($"2"23r   r   Nc                     	 t        j                  | j                  d      }|dk7  r| j
                  j                  |       y | j                          y # t        $ r Y y t        $ r d}Y Iw xY w)Ni    r   )r(   r/   r
  r0   r   r  r{   r8   rx   s     r   r<   zSpooler._read_ready  s`    	77488T*D 3;NN!!$'JJL  	 	D	s    A 	A,
A,+A,c                 t    | j                   dk(  ryt        j                  | j                   gg g d      g g g fk7  S )NrD   Fr   )r
  selectr?   s    r   	_is_readyzSpooler._is_ready  s6    88r>}}dhhZR3B|CCr   Fr   r   c                    | j                         r!| j                          | j                         r!dj                  | j                        }|rg | _        |S )Nr   )r  r<   r}   r  )r,   r   results      r   r   zSpooler.get  sG    nn nn $..)DNr   c                     | j                   dk7  rL| j                  j                  | j                          t        j                  | j                          d| _         y y rC   )r
  r   rH   r(   r8   r?   s    r   r8   zSpooler.close  s?    88r>JJ$$TXX.HHTXXDH r   c                 $    | j                          y r>   )r8   r?   s    r   r   zSpooler.__del__  s    

r   r   )r   r   r   r   r   r   r   r   r%   r<   r   r  r   r   r8   r   rL   r   r   r   r     sn     $$$	H4W66 4C 4D4 D
 $) D U r   r   )'r   r   ru   ctypesr1   r   loggingr(   r  r   r   r   r   	threadingr   typingr   r   r   jsonutilr   r	   CDLLr   r   r   r   	getLoggerr   r&   r|   r  r   r   r   r   r   r  r   rL   r   r   <module>r     s    R       	       * * )FKK##	( ( (
  
		8	$ a"" aH")) "+ +mN*g&A&A mN`8Z 8(8 8r   