o
    2.a                     @   s   d dl Z d dlZd dlZd dlZd dlZzddlmZ W n ey)   e	dZY nw dZ
dZG dd deZddd	Zd
d Zdd Zdd Zdd Zdd ZdddZdd ZdS )    N   )NpipeSocket   c                   @   s   e Zd ZdS )SocketErrorN)__name__
__module____qualname__ r	   r	   5/usr/lib/python3/dist-packages/docker/utils/socket.pyr      s    r      c              
   C   s   t jt jt jf}t| tst| gg g  z"t| dr!| |W S t| t	t
dr/| |W S t|  |W S  tyP } z|j |vrE W Y d}~dS d}~ww )z+
    Reads at most n bytes from socket
    recvZSocketION)errnoZEINTRZEDEADLKZEWOULDBLOCK
isinstancer   selecthasattrr   getattrpysocketreadosfilenoOSError)socketnZrecoverable_errorser	   r	   r
   r      s   


r   c                 C   sH   t  }t||k r"t| |t| }|std||7 }t||k s	|S )z]
    Reads exactly n bytes from socket
    Raises SocketError if there isn't enough data
    zUnexpected EOF)byteslenr   r   )r   r   dataZ	next_datar	   r	   r
   read_exactly*   s   r   c                 C   s<   zt | d}W n
 ty   Y dS w td|\}}||fS )z
    Returns the stream and size of the next frame of data waiting to be read
    from socket, according to the protocol defined here:

    https://docs.docker.com/engine/api/v1.24/#attach-to-a-container
       )r   z>BxxxL)r   r   structunpack)r   r   streamZactualr	   r	   r
   next_frame_header8   s   r#   c                 C   s   |rdd t | D S t| S )z
    Return a generator of frames read from socket. A frame is a tuple where
    the first item is the stream number and the second item is a chunk of data.

    If the tty setting is enabled, the streams are multiplexed into the stdout
    stream.
    c                 s   s    | ]}t |fV  qd S )N)STDOUT).0framer	   r	   r
   	<genexpr>Q   s    zframes_iter.<locals>.<genexpr>)frames_iter_ttyframes_iter_no_tty)r   Zttyr	   r	   r
   frames_iterH   s   r*   c                 c   sh    	 t | \}}|dk rdS |dkr3t| |}|du rqt|}|dkr&dS ||8 }||fV  |dksq)zc
    Returns a generator of data read from the socket when the tty setting is
    not enabled.
    Tr   N)r#   r   r   )r   r"   r   resultZdata_lengthr	   r	   r
   r)   V   s    

r)   c                 c   s$    	 t | }t|dkrdS |V  q)z^
    Return a generator of data read from the socket when the tty setting is
    enabled.
    Tr   N)r   r   )r   r+   r	   r	   r
   r(   k   s   r(   Fc                 C   s   |du r
t  | S ddg}| D ]=}|dksJ |d dur6|d du r+|d |d< q|d  |d 7  < q|d du rC|d |d< q|d  |d 7  < qt|S )a  
    Iterate through frames read from the socket and return the result.

    Args:

        demux (bool):
            If False, stdout and stderr are multiplexed, and the result is the
            concatenation of all the frames. If True, the streams are
            demultiplexed, and the result is a 2-tuple where each item is the
            concatenation of frames belonging to the same stream.
    FN)NNr   r   )r   jointuple)ZframesZdemuxoutr&   r	   r	   r
   consume_socket_outputx   s   r/   c                 C   s.   | t kr|dfS | tkrd|fS t|  d)z[
    Utility to demultiplex stdout and stderr when reading frames from the
    socket.
    Nz is not a valid stream)r$   STDERR
ValueError)Z	stream_idr   r	   r	   r
   demux_adaptor   s
   r2   )r   )F)r   r   r   r   r   r    Z	transportr   ImportErrortyper$   r0   	Exceptionr   r   r   r#   r*   r)   r(   r/   r2   r	   r	   r	   r
   <module>   s*    

%