
    mg*                     
   d Z ddlmZmZmZmZ ddlmZmZmZm	Z	 ddl
mZ ddlmZ ddlmZ erddlmZmZ eg d	f   Z G d
 dee         Z G d dee         Z G d dee         Z G d d	ee         Z G d dee         Zy)zSSH subprocess handlers    )TYPE_CHECKINGAnyAnyStrCallable)DictGenericIterableOptional   )EXTENDED_DATA_STDERR)SSHClientProcess)DataType)
SSHChannelSSHClientChannelSSHSubprocessProtocolc                   B    e Zd ZdZ	 ddddefdZddZdd	ed
edefdZ	y)SSHSubprocessPipezSSH subprocess pipeNchanSSHClientChannel[AnyStr]datatypec                      || _         || _        y N)_chan	_datatype)selfr   r   s      3lib/python3.12/site-packages/asyncssh/subprocess.py__init__zSSHSubprocessPipe.__init__*   s    15
!    returnc                 8    | j                   j                          y)zShut down the remote processN)r   closer   s    r   r!   zSSHSubprocessPipe.close/        	

r   namedefaultc                 :    | j                   j                  ||      S )a>  Return additional information about the remote process

           This method returns extra information about the channel
           associated with this subprocess. See :meth:`get_extra_info()
           <SSHClientChannel.get_extra_info>` on :class:`SSHClientChannel`
           for additional information.

        )r   get_extra_info)r   r$   r%   s      r   r'   z SSHSubprocessPipe.get_extra_info4   s     zz((w77r   r   r   N)
__name__
__module____qualname____doc__r   r   r!   strr   r'    r   r   r   r   '   s>     '+"7 "#"


83 
8 
8 
8r   r   c                        e Zd ZdZddZddZy)SSHSubprocessReadPipezSSH subprocess pipe readerNc                 8    | j                   j                          y)z7Pause delivery of incoming data from the remote processN)r   pause_readingr"   s    r   r2   z#SSHSubprocessReadPipe.pause_readingD   s     	

  "r   c                 8    | j                   j                          y)z8Resume delivery of incoming data from the remote processN)r   resume_readingr"   s    r   r4   z$SSHSubprocessReadPipe.resume_readingI   s     	

!!#r   r(   )r)   r*   r+   r,   r2   r4   r.   r   r   r0   r0   A   s    $#
$r   r0   c                       e Zd ZdZddZdefdZdefdZ	 	 dde	e   de	e   ddfd	Z
d
eddfdZdee   ddfdZddZy)SSHSubprocessWritePipezSSH subprocess pipe writerr   Nc                 8    | j                   j                          y)z0Forcibly close the channel to the remote processN)r   abortr"   s    r   r8   zSSHSubprocessWritePipe.abortR   r#   r   c                 6    | j                   j                         S )z2Return whether the pipe supports :meth:`write_eof`)r   can_write_eofr"   s    r   r:   z$SSHSubprocessWritePipe.can_write_eofW   s     zz''))r   c                 6    | j                   j                         S )z3Return the current size of the pipe's output buffer)r   get_write_buffer_sizer"   s    r   r<   z,SSHSubprocessWritePipe.get_write_buffer_size\   s     zz//11r   highlowc                 <    | j                   j                  ||       y)z9Set the high- and low-water limits for write flow controlN)r   set_write_buffer_limits)r   r=   r>   s      r   r@   z.SSHSubprocessWritePipe.set_write_buffer_limitsa   s     	

**45r   datac                 P    | j                   j                  || j                         y)zWrite data on this pipeN)r   writer   )r   rA   s     r   rC   zSSHSubprocessWritePipe.writeg   s     	

t~~.r   list_of_datac                 P    | j                   j                  || j                         y)z'Write a list of data bytes on this pipeN)r   
writelinesr   )r   rD   s     r   rF   z!SSHSubprocessWritePipe.writelinesl   s     	

lDNN;r   c                 8    | j                   j                          y)zWrite EOF on this pipeN)r   	write_eofr"   s    r   rH   z SSHSubprocessWritePipe.write_eofq   s     	

r   r(   )NN)r)   r*   r+   r,   r8   boolr:   intr<   r
   r@   r   rC   r	   rF   rH   r.   r   r   r6   r6   O   s    $
*t *
2s 2
 =A596HSM 6%-c]6>B6/& /T /
<x'7 <D <
r   r6   c                   V    e Zd ZdZ	 	 	 	 ddZdededdfdZdedee	   ddfd	Z
dd
Zy)r   a  SSH subprocess protocol

       This class conforms to :class:`asyncio.SubprocessProtocol`, but with
       the following enhancement:

           * If encoding is set when the subprocess is created, all data
             passed to :meth:`pipe_data_received` will be string values
             containing Unicode data. However, for compatibility with
             :class:`asyncio.SubprocessProtocol`, encoding defaults to
             `None`, in which case all data is delivered as bytes.

    r   Nc                      y)a  Called when a remote process is successfully started

           This method is called when a remote process is successfully
           started. The transport parameter should be stored if needed
           for later use.

           :param transport:
               The transport to use to communicate with the remote process.
           :type transport: :class:`SSHSubprocessTransport`

        Nr.   )r   	transports     r   connection_madez%SSHSubprocessProtocol.connection_made       r   fdrA   c                      y)a  Called when data is received from the remote process

           This method is called when data is received from the remote
           process. If an encoding was specified when the process was
           started, the data will be delivered as a string after decoding
           with the requested encoding. Otherwise, the data will be
           delivered as bytes.

           :param fd:
               The integer file descriptor of the pipe data was received
               on. This will be 1 for stdout or 2 for stderr.
           :param data:
               The data received from the remote process
           :type fd: `int`
           :type data: `str` or `bytes`

        Nr.   )r   rP   rA   s      r   pipe_data_receivedz(SSHSubprocessProtocol.pipe_data_received   rO   r   excc                      y)a  Called when the pipe to a remote process is closed

           This method is called when a pipe to a remote process is
           closed. If the channel is shut down cleanly, *exc* will be
           `None`. Otherwise, it will be an exception explaining the
           reason the pipe was closed.

           :param fd:
               The integer file descriptor of the pipe which was
               closed. This will be 1 for stdout or 2 for stderr.
           :param exc:
               The exception which caused the channel to close, or
               `None` if the channel closed cleanly.
           :type fd: `int`
           :type exc: :class:`Exception` or `None`

        Nr.   )r   rP   rS   s      r   pipe_connection_lostz*SSHSubprocessProtocol.pipe_connection_lost   rO   r   c                      y)aC  Called when a remote process has exited

           This method is called when the remote process has exited.
           Exit status information can be retrieved by calling
           :meth:`get_returncode() <SSHSubprocessTransport.get_returncode>`
           on the transport provided in :meth:`connection_made`.

        Nr.   r"   s    r   process_exitedz$SSHSubprocessProtocol.process_exited   rO   r   )rM   zSSHSubprocessTransport[AnyStr]r   Nr(   )r)   r*   r+   r,   rN   rJ   r   rR   r
   	ExceptionrU   rW   r.   r   r   r   r   w   sZ    #CHLS  4 &s )1D  &r   c            
            e Zd ZU dZded<   def fdZdee   fdZ	d fd	Z
dd
Zdee   ddf fdZdededdfdZdeddf fdZdededededdf
 fdZdee   fdZdedeee      fdZdee   fdZ xZS )SSHSubprocessTransporta  SSH subprocess transport

       This class conforms to :class:`asyncio.SubprocessTransport`, but with
       the following enhancements:

           * All functionality available through :class:`SSHClientProcess`
             is also available here, such as the ability to dynamically
             redirect stdin, stdout, and stderr at any time during the
             lifetime of the process.

           * If encoding is set when the subprocess is created, all data
             written to the transports created by :meth:`get_pipe_transport`
             should be strings containing Unicode data. The encoding defaults
             to `None`, though, to preserve compatibility with
             :class:`asyncio.SubprocessTransport`, which expects data
             to be written as bytes.

    r   r   protocol_factoryc                 H    t         |           i | _         |       | _        y r   )superr   _pipes	_protocol)r   r[   	__class__s     r   r   zSSHSubprocessTransport.__init__   s    <>8H8Jr   r   c                     | j                   S )z=Return the subprocess protocol associated with this transport)r_   r"   s    r   get_protocolz#SSHSubprocessTransport.get_protocol   s     ~~r   Nc                     t         |   |       | j                  j                  |        t        | j                        t        | j                        t        | j                  t              d| _        y)zHandle a newly opened channel)r   r      N)r]   rN   r_   r6   r   r0   r   r^   )r   r   r`   s     r   rN   z&SSHSubprocessTransport.connection_made   sV     	%&&t, &djj1$TZZ0$TZZ1EF
r   c                      y)zOverride SSHClientProcess to avoid creating SSHReader/SSHWriter
           streams, since this class uses read/write pipe objects insteadNr.   r"   s    r   session_startedz&SSHSubprocessTransport.session_started   rO   r   rS   c                     | j                   j                  d|       | j                   j                  d|       t        |   |       y)z Handle an incoming channel closer   rd   N)r_   rU   r]   connection_lost)r   rS   r`   s     r   rh   z&SSHSubprocessTransport.connection_lost   s:     	++As3++As3$r   rA   r   c                     | j                   j                  |      }|r|j                  |       y|t        k(  rdnd}| j                  j                  ||       y)z,Handle incoming data from the remote processrd   r   N)_writersgetrC   r   r_   rR   )r   rA   r   writerrP   s        r   data_receivedz$SSHSubprocessTransport.data_received   sJ     ""8,LL"66ABNN--b$7r   statusc                 X    t         |   |       | j                  j                          y)z)Handle exit status for the remote processN)r]   exit_status_receivedr_   rW   )r   rn   r`   s     r   rp   z+SSHSubprocessTransport.exit_status_received  s"     	$V,%%'r   signalcore_dumpedmsglangc                 ^    t         |   ||||       | j                  j                          y)z)Handle exit signal for the remote processN)r]   exit_signal_receivedr_   rW   )r   rq   rr   rs   rt   r`   s        r   rv   z+SSHSubprocessTransport.exit_signal_received  s(     	$V[#tD%%'r   c                      y)zReturn the PID of the remote process

           This method always returns `None`, since SSH doesn't report
           remote PIDs.

        Nr.   r"   s    r   get_pidzSSHSubprocessTransport.get_pid  s     r   rP   c                 8    | j                   j                  |      S )am  Return a transport for the requested stream

           :param fd:
               The integer file descriptor (0-2) to return the transport for,
               where 0 means stdin, 1 means stdout, and 2 means stderr.
           :type fd: `int`

           :returns: an :class:`SSHSubprocessReadPipe` or
                     :class:`SSHSubprocessWritePipe`

        )r^   rk   )r   rP   s     r   get_pipe_transportz)SSHSubprocessTransport.get_pipe_transport!  s     {{r""r   c                     | j                   S )a  Return the exit status or signal for the remote process

           This method returns the exit status of the session if one has
           been sent. If an exit signal was sent, this method returns
           the negative of the numeric value of that signal, matching
           the behavior of :meth:`asyncio.SubprocessTransport.get_returncode`.
           If neither has been sent, this method returns `None`.

           :returns: `int` or `None`

        )
returncoder"   s    r   get_returncodez%SSHSubprocessTransport.get_returncode1  s     r   )r   zSSHChannel[AnyStr]r   Nr(   )r)   r*   r+   r,   __annotations__SubprocessFactoryr   r   r   rb   rN   rf   r
   rX   rh   r   rm   rJ   rp   r-   rI   rv   rx   r   rz   r}   __classcell__)r`   s   @r   rZ   rZ      s    & &%K): K3F; 

M%8I#6 %4 %	8& 	8H 	8 	8(3 (4 ((3 (T ("%(-0(59(
# 
#S #&v./#  r   rZ   N)r,   typingr   r   r   r   r   r   r	   r
   	constantsr   processr   sessionr   channelr   r   r   r   r0   r6   r   rZ   r.   r   r   <module>r      s   *  7 7 4 4 + %  5 R!889 8 84$-f5 $%.v6 %PJGFO JZz-f5 zr   