
][\                 @   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 d  d l Z d d l m Z d d d d d g Z	 e j
 d	 k p e e d
  o e e d  o e e j d  Z Gd d   d e j  Z e j Z d d d  Z e j
 d	 k rfe	 d d d g 7Z	 d  d l Z d d d d  Z d d   Z d d   Z d d   Z Gd d   d e  Z nj e	 d d d g 7Z	 d  d l Z e j
 d k Z d d   Z d d   Z d d   Z d d   Z d  d   Z d! d"   Z Gd# d$   d$  Z e e e   j   e  d% d&   Z! e e e" j#  e!  e e e$ j%  e!  d' d(   Z& d) d*   Z' e e j( e&  e j
 d	 k rd+ d,   Z) d- d.   Z* e e j e)  n( d/ d,   Z) d0 d.   Z* e e j e)  d S)1    N   )contextsend_handlerecv_handleForkingPicklerregisterdumpZwin32CMSG_LEN
SCM_RIGHTSsendmsgc                   sg   e  Z d  Z d Z i  Z e j Z   f d d   Z e	 d d    Z
 e	 d d d   Z e j Z   S)	r   z)Pickler subclass used by multiprocessing.c                s9   t    j |   |  j j   |  _ |  j j |  j  d  S)N)super__init___copyreg_dispatch_tablecopydispatch_tableupdate_extra_reducers)selfargs)	__class__ //usr/lib/python3.4/multiprocessing/reduction.pyr   %   s    zForkingPickler.__init__c             C   s   | |  j  | <d S)z&Register a reduce function for a type.N)r   )clstypereducer   r   r   r   *   s    zForkingPickler.registerNc             C   s,   t  j   } |  | |  j |  | j   S)N)ioBytesIOr   	getbuffer)r   objprotocolZbufr   r   r   dumps/   s    zForkingPickler.dumps)__name__
__module____qualname____doc__r   copyregr   r   r   classmethodr   r    pickleloadsr   r   )r   r   r       s   	c             C   s   t  | |  j |   d S)z3Replacement for pickle.dump() using ForkingPickler.N)r   r   )r   filer   r   r   r   r   9   s    	DupHandle	duplicatesteal_handleFc             C   s@   | d k r t  j   } n  t  j t  j   |  | d | t  j  S)z<Duplicate a handle.  (target_process is a handle not a pid!)Nr   )_winapiGetCurrentProcessDuplicateHandleDUPLICATE_SAME_ACCESS)handleZtarget_processZinheritabler   r   r   r+   F   s
    c             C   s]   t  j t  j d |   } z0 t  j | | t  j   d d t  j t  j B SWd t  j |  Xd S)z5Steal a handle from process identified by source_pid.Fr   N)r-   OpenProcessPROCESS_DUP_HANDLEr/   r.   r0   DUPLICATE_CLOSE_SOURCECloseHandle)Z
source_pidr1   Zsource_process_handler   r   r   r,   N   s    c             C   s&   t  | t j |  } |  j |  d S)z&Send a handle over a local connection.N)r*   r-   r0   send)connr1   destination_pidZdhr   r   r   r   Z   s    c             C   s   |  j    j   S)z)Receive a handle over a local connection.)recvdetach)r7   r   r   r   r   _   s    c               @   s1   e  Z d  Z d Z d d d  Z d d   Z d S)r*   zPicklable wrapper for a handle.Nc             C   s   | d  k r t  j   } n  t j t j d |  } z+ t j t j   | | | d d  |  _ Wd  t j |  X| |  _	 | |  _
 d  S)NFr   )osgetpidr-   r2   r3   r/   r.   _handler5   _access_pid)r   r1   accesspidprocr   r   r   r   e   s    		zDupHandle.__init__c             C   s{   |  j  t j   k r |  j St j t j d |  j   } z/ t j | |  j t j   |  j	 d t j
  SWd t j |  Xd S)z1Get the handle.  This should only be called once.FN)r?   r;   r<   r=   r-   r2   r3   r/   r.   r>   r4   r5   )r   rB   r   r   r   r:   t   s    zDupHandle.detach)r!   r"   r#   r$   r   r:   r   r   r   r   r*   c   s   DupFdsendfdsrecvfdsdarwinc             C   s~   t  j  d |  } t t |  d g  } |  j | g t j t j | f g  t rz |  j d  d k rz t	 d   n  d S)z,Send an array of fds over an AF_UNIX socket.i   r      Az%did not receive acknowledgement of fdN)
arraybyteslenr   socket
SOL_SOCKETr
   ACKNOWLEDGEr9   RuntimeError)sockZfdsmsgr   r   r   rD      s
    %c             C   sT  t  j  d  } | j | } |  j d t j |   \ } } } } | rZ | rZ t  n  y t rs |  j d  n  t |  d k r t	 d t |    n  | d \ } }	 }
 | t j
 k r(|	 t j k r(t |
  | j d k r t  n  | j |
  t |  d | d k st  t |  SWn t t f k
 rCYn Xt	 d   d S)	z/Receive an array of fds over an AF_UNIX socket.rG   r   rI   zreceived %d items of ancdatar   rH   zInvalid data receivedN)rJ   itemsizeZrecvmsgrM   r	   EOFErrorrO   r6   rL   rP   rN   r
   
ValueErrorZ	frombytesAssertionErrorlist
IndexError)rQ   sizeaZ
bytes_sizerR   ZancdataflagsZaddrZ
cmsg_levelZ	cmsg_typeZ	cmsg_datar   r   r   rE      s,    '		 c          
   C   s>   t  j |  j   t  j t  j   } t | | g  Wd QXd S)z&Send a handle over a local connection.N)rM   fromfdfilenoAF_UNIXSOCK_STREAMrD   )r7   r1   r8   sr   r   r   r      s    $c          
   C   s?   t  j |  j   t  j t  j   } t | d  d SWd QXd S)z)Receive a handle over a local connection.r   r   N)rM   r\   r]   r^   r_   rE   )r7   r`   r   r   r   r      s    $c             C   sa   t  j   } | d k	 r. | j | j |    St rQ d d l m } | j |   St d   d S)zReturn a wrapper for an fd.Nr   )resource_sharerz&SCM_RIGHTS appears not to be available)r   Zget_spawning_popenrC   Zduplicate_for_childHAVE_SEND_HANDLE ra   rU   )fdZ	popen_objra   r   r   r   rC      s    c             C   sE   |  j  d  k r( t |  j |  j j f f St |  j  |  j j f f Sd  S)N)__self__getattrr   __func__r!   )mr   r   r   _reduce_method   s    ri   c               @   s   e  Z d  Z d d   Z d S)_Cc             C   s   d  S)Nr   )r   r   r   r   f   s    z_C.fN)r!   r"   r#   rk   r   r   r   r   rj      s   rj   c             C   s   t  |  j |  j f f S)N)rf   __objclass__r!   )rh   r   r   r   _reduce_method_descriptor   s    rm   c             C   s"   t  |  j |  j |  j p i  f f S)N)_rebuild_partialfuncr   keywords)pr   r   r   _reduce_partial   s    rr   c             C   s   t  j |  | |  S)N)	functoolspartial)ro   r   rp   r   r   r   rn      s    rn   c             C   s#   d d l  m } t | |   f f S)Nr   )	DupSocket)ra   ru   _rebuild_socket)r`   ru   r   r   r   _reduce_socket   s    rw   c             C   s
   |  j    S)N)r:   )Zdsr   r   r   rv      s    rv   c             C   s1   t  |  j    } t | |  j |  j |  j f f S)N)rC   r]   rv   familyr   proto)r`   dfr   r   r   rw      s    c             C   s%   |  j    } t j | | | d | S)Nr]   )r:   rM   )rz   rx   r   ry   rd   r   r   r   rv      s    )+r%   rs   r   r;   r'   rM   sysrc   r   __all__platformhasattrrb   ZPicklerr   r   r   r-   r+   r,   r   r   objectr*   rJ   rO   rD   rE   rC   ri   rj   r   rk   rm   rW   appendint__add__rr   rn   rt   rw   rv   r   r   r   r   <module>
   s^   	#