o
    8g+^                     @   s   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlZddlZddlm	Z	 ddl
mZ dd	l
mZ dd
l
mZ ddlmZ eeddZdd Zdd Zdd Ze Zdd Zdd ZG dd deZdS )a#  
    pyudev._os.pipe
    ===============

    Fallback implementations for pipe.

    1. pipe2 from python os module
    2. pipe2 from libc
    3. pipe from python os module

    The Pipe class wraps the chosen implementation.

    .. moduleauthor:: Sebastian Wiesner  <lunaryorn@gmail.com>
    )absolute_import)division)print_function)unicode_literalsN)partial)ERROR_CHECKERS)FD_PAIR)
SIGNATURES)load_ctypes_library	O_CLOEXECi   c                 C   s"   t  }| || |d |d fS )zA ``pipe2`` implementation using ``pipe2`` from ctypes.

    ``libc`` is a :class:`ctypes.CDLL` object for libc.  ``flags`` is an
    integer providing the flags to ``pipe2``.

    Return a pair of file descriptors ``(r, w)``.

    r      )r   pipe2)libcflagsfds r   1/usr/lib/python3/dist-packages/pyudev/_os/pipe.py_pipe2_ctypes2   s   	r   c                 C   sP   t  }| t j@ dkr|D ]}t|t j q| t@ dkr&|D ]}t|t q|S )zA ``pipe2`` implementation using :func:`os.pipe`.

    ``flags`` is an integer providing the flags to ``pipe2``.

    .. warning::

       This implementation is not atomic!

    Return a pair of file descriptors ``(r, w)``.

    r   )ospipe
O_NONBLOCKset_fd_status_flagr   set_fd_flag)r   r   fdr   r   r   _pipe2_by_pipe@   s   r   c                  C   sP   t tdrtjS ztdtt} t | drtt| W S tW S  t	y'   t Y S w )z]Find the appropriate implementation for ``pipe2``.

Return a function implementing ``pipe2``.r   r   )
hasattrr   r   r
   r	   r   r   r   r   ImportError)r   r   r   r   _get_pipe2_implementationV   s   
r   c                 C   (   t  | t jd}t  | t j||B  dS )zwSet a flag on a file descriptor.

    ``fd`` is the file descriptor or file object, ``flag`` the flag as integer.

    r   N)fcntlF_GETFDF_SETFDr   flagr   r   r   r   r   h      r   c                 C   r   )z~Set a status flag on a file descriptor.

    ``fd`` is the file descriptor or file object, ``flag`` the flag as integer.

    r   N)r   F_GETFLF_SETFLr"   r   r   r   r   r   r$   r   c                   @   s,   e Zd ZdZedd Zdd Zdd ZdS )	PipezA unix pipe.

    A pipe object provides two file objects: :attr:`source` is a readable file
    object, and :attr:`sink` a writeable.  Bytes written to :attr:`sink` appear
    at :attr:`source`.

    Open a pipe with :meth:`open()`.

    c                 C   s   t tjtB \}}| ||S )zLOpen and return a new :class:`Pipe`.

        The pipe uses non-blocking IO.)_PIPE2r   r   r   )clssourcesinkr   r   r   open   s   
z	Pipe.openc                 C   s$   t |dd| _t |dd| _dS )zCreate a new pipe object from the given file descriptors.

        ``source_fd`` is a file descriptor for the readable side of the pipe,
        ``sink_fd`` is a file descriptor for the writeable side.rbr   wbN)r   fdopenr*   r+   )self	source_fdsink_fdr   r   r   __init__   s   zPipe.__init__c                 C   s(   z| j   W | j  dS | j  w )zCloses both sides of the pipe.N)r*   closer+   )r0   r   r   r   r4      s   z
Pipe.closeN)__name__
__module____qualname____doc__classmethodr,   r3   r4   r   r   r   r   r'   |   s    

r'   )r8   
__future__r   r   r   r   r   r   	functoolsr   pyudev._ctypeslib.libcr   r   r	   pyudev._ctypeslib.utilsr
   getattrr   r   r   r   r(   r   r   objectr'   r   r   r   r   <module>   s(   

