U
    ™K7\\  ã                   @   s¾   d dl Z 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	k
r\   e
dƒZY nX 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jr0t| tƒs0t | gg g ¡ zJt	| dƒrH|  
|¡W S tjrjt| ttdƒƒrj|  |¡W S t |  ¡ |¡W S  tk
r¨ } z|j |kr˜‚ W 5 d}~X Y nX dS )z+
    Reads at most n bytes from socket
    ÚrecvZSocketION)ÚerrnoZEINTRZEDEADLKZEWOULDBLOCKÚsixZPY3Ú
isinstancer   ÚselectÚhasattrr   ÚgetattrÚpysocketÚreadÚosÚfilenoÚEnvironmentError)ÚsocketÚnZrecoverable_errorsÚer	   r	   r
   r      s    

r   c                 C   s@   t  ¡ }t|ƒ|k r<t| |t|ƒ ƒ}|s2tdƒ‚||7 }q|S )z]
    Reads exactly n bytes from socket
    Raises SocketError if there isn't enough data
    zUnexpected EOF)r   Úbinary_typeÚlenr   r   )r   r   ÚdataZ	next_datar	   r	   r
   Úread_exactly,   s    
r   c                 C   s>   zt | dƒ}W n tk
r$   Y dS X 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   ÚstructZunpack)r   r   ÚstreamZactualr	   r	   r
   Únext_frame_header:   s    r#   c                 C   s"   |rdd„ t | ƒD ƒS t| ƒS d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>S   s     zframes_iter.<locals>.<genexpr>N)Úframes_iter_ttyÚframes_iter_no_tty)r   Zttyr	   r	   r
   Úframes_iterJ   s    r*   c                 c   s`   t | ƒ\}}|dk rq\|dkr t| |ƒ}|dkr2qt|ƒ}|dkrFdS ||8 }||fV  qq dS )zc
    Returns a generator of data read from the socket when the tty setting is
    not enabled.
    r   N)r#   r   r   )r   r"   r   ÚresultZdata_lengthr	   r	   r
   r)   X   s    
r)   c                 c   s$   t | ƒ}t|ƒdkrdS |V  q dS )z^
    Return a generator of data read from the socket when the tty setting is
    enabled.
    r   N)r   r   )r   r+   r	   r	   r
   r(   m   s    r(   Fc                 C   s¦   |dkrt  ¡  | ¡S ddg}| D ]z}|dks2t‚|d dk	rn|d dkrX|d |d< qœ|d  |d 7  < q"|d dkrˆ|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   r   ÚjoinÚAssertionErrorÚtuple)ZframesZdemuxÚoutr&   r	   r	   r
   Úconsume_socket_outputz   s    r0   c                 C   s2   | t kr|dfS | tkr d|fS td | ¡ƒ‚dS )z[
    Utility to demultiplex stdout and stderr when reading frames from the
    socket.
    Nz{0} is not a valid stream)r$   ÚSTDERRÚ
ValueErrorÚformat)Z	stream_idr   r	   r	   r
   Údemux_adaptorŸ   s
    r4   )r   )F)r   r   r   r   r   r!   r   Z	transportr   ÚImportErrorÚtyper$   r1   Ú	Exceptionr   r   r   r#   r*   r)   r(   r0   r4   r	   r	   r	   r
   Ú<module>   s(   

%